void fs_private_bin_list(void) { char *private_list = cfg.bin_private_keep; assert(private_list); // create /tmp/firejail/mnt/bin directory fs_build_mnt_dir(); int rv = mkdir(RUN_BIN_DIR, 0755); if (rv == -1) errExit("mkdir"); if (chown(RUN_BIN_DIR, 0, 0) < 0) errExit("chown"); if (chmod(RUN_BIN_DIR, 0755) < 0) errExit("chmod"); // copy the list of files in the new etc directory // using a new child process without root privileges fs_logger_print(); // save the current log pid_t child = fork(); if (child < 0) errExit("fork"); if (child == 0) { if (arg_debug) printf("Copying files in the new home:\n"); // elevate privileges - files in the new /bin directory belong to root if (setreuid(0, 0) < 0) errExit("setreuid"); if (setregid(0, 0) < 0) errExit("setregid"); // copy the list of files in the new home directory char *dlist = strdup(private_list); if (!dlist) errExit("strdup"); char *ptr = strtok(dlist, ","); duplicate(ptr); while ((ptr = strtok(NULL, ",")) != NULL) duplicate(ptr); free(dlist); fs_logger_print(); exit(0); } // wait for the child to finish waitpid(child, NULL, 0); // mount-bind int i = 0; while (paths[i]) { struct stat s; if (stat(paths[i], &s) == 0) { if (arg_debug) printf("Mount-bind %s on top of %s\n", RUN_BIN_DIR, paths[i]); if (mount(RUN_BIN_DIR, paths[i], NULL, MS_BIND|MS_REC, NULL) < 0) errExit("mount bind"); fs_logger2("tmpfs", paths[i]); fs_logger2("mount", paths[i]); } i++; } // log cloned files char *dlist = strdup(private_list); if (!dlist) errExit("strdup"); char *ptr = strtok(dlist, ","); while (ptr) { i = 0; while (paths[i]) { struct stat s; if (stat(paths[i], &s) == 0) { char *fname; if (asprintf(&fname, "%s/%s", paths[i], ptr) == -1) errExit("asprintf"); fs_logger2("clone", fname); free(fname); } i++; } ptr = strtok(NULL, ","); } free(dlist); }
void call_setreuid (gid_t ruid, gid_t euid, gid_t suid) { setreuid(ruid, euid); }
/* A binary wrapper is needed around python scripts if we want * to run them in sgid/suid mode. * * This is such a wrapper. */ int main(int argc, char **argv) { /* * We disallow passing of arguments which point to writable dirs * and other files possibly not accessible to calling user. * This way, the script will always use default values for these arguments. */ char **pp = argv; char *arg; while ((arg = *++pp) != NULL) { /* Allow taking ids from stdin */ if (strcmp(arg, "--ids=-") == 0) continue; if (strncmp(arg, "--cache", 7) == 0) error_msg_and_die("bad option", arg); if (strncmp(arg, "--tmpdir", 8) == 0) error_msg_and_die("bad option", arg); if (strncmp(arg, "--ids", 5) == 0) error_msg_and_die("bad option", arg); } /* Switch real user/group to effective ones. * Otherwise yum library gets confused - gets EPERM (why??). */ gid_t g = getegid(); /* do setregid only if we have to, to not upset selinux needlessly */ if (g != getgid()) setregid(g, g); uid_t u = geteuid(); if (u != getuid()) { setreuid(u, u); /* We are suid'ed! */ /* Prevent malicious user from messing up with suid'ed process: */ /* Set safe PATH */ // TODO: honor configure --prefix here by adding it to PATH // (otherwise abrt-action-install-debuginfo would fail to spawn abrt-action-trim-files): if (u == 0) putenv((char*) "PATH=/usr/sbin:/sbin:/usr/bin:/bin"); else putenv((char*) "PATH=/usr/bin:/bin"); /* Clear dangerous stuff from env */ static const char forbid[] = "LD_LIBRARY_PATH" "\0" "LD_PRELOAD" "\0" "LD_TRACE_LOADED_OBJECTS" "\0" "LD_BIND_NOW" "\0" "LD_AOUT_LIBRARY_PATH" "\0" "LD_AOUT_PRELOAD" "\0" "LD_NOWARN" "\0" "LD_KEEPDIR" "\0" ; const char *p = forbid; do { unsetenv(p); p += strlen(p) + 1; } while (*p); } execvp(EXECUTABLE, argv); error_msg_and_die("Can't execute", EXECUTABLE); }
/* Specify what privileges an suid root binary needs. */ int __init_suid_priv (int flags, ...) { int res = 0; priv_set_t *permit = NULL, *inherit = NULL, *scratch = NULL; /* Check flags. */ if (flags != PU_LIMITPRIVS && flags != PU_CLEARLIMITSET) return -1; /* We can only initialize once. */ if (__suidset) return -1; /* Do nothing if we are running as root but not setuid root. */ uid_t uid = getuid (); uid_t euid = geteuid (); if (uid == 0 && euid == 0) return 0; /* Allocate a scratch set. */ scratch = priv_allocset (); if (!scratch) goto error; /* Get the basic set. */ const priv_data_t *pd = __priv_parse_data_cached (); if (!pd) goto error; priv_set_t *basic = pd->pd_basicprivs; /* Get the inherited set. */ inherit = priv_allocset (); if (!inherit) goto error; if (getppriv (PRIV_INHERITABLE, inherit) != 0) goto error; /* Get the permitted set. */ permit = priv_allocset (); if (!permit) goto error; if (getppriv (PRIV_PERMITTED, permit) != 0) goto error; /* Get passed privileges. */ __suidset = priv_allocset (); if (!__suidset) goto error; priv_emptyset (__suidset); va_list ap; va_start (ap, flags); const char *priv; while ((priv = va_arg (ap, const char *))) if (priv_addset (__suidset, priv) != 0) goto error; /* Make sure that the passed privileges are a subset of the current permitted privileges. */ if (priv_issubset (__suidset, permit) != _B_TRUE) goto error; /* Set the effective privileges to the inherited ones. */ if (setppriv (PRIV_SET, PRIV_EFFECTIVE, inherit) != 0) goto error; /* Set the permitted privileges to those currently permitted privileges in set of the ones passed in, the inherited ones, and the basic set. */ priv_copyset (__suidset, scratch); priv_union (inherit, scratch); if (basic) priv_union (basic, scratch); priv_intersect (permit, scratch); if (setppriv (PRIV_SET, PRIV_PERMITTED, scratch) != 0) goto error; /* Check if we need to set the limit set. */ if (flags & PU_CLEARLIMITSET) { priv_emptyset (scratch); if (setppriv (PRIV_SET, PRIV_LIMIT, scratch) != 0) goto error; } else if (flags & PU_LIMITPRIVS) { if (setppriv (PRIV_SET, PRIV_LIMIT, scratch) != 0) goto error; } /* Change the uid to the caller's uid if we're setuid root. */ if (euid == 0 && setreuid (uid, uid) != 0) goto error; goto out; error: res = -1; if (__suidset) { priv_freeset (__suidset); __suidset = NULL; } if (euid == 0) setreuid (uid, uid); out: priv_freeset (permit); priv_freeset (inherit); priv_freeset (scratch); return res; }
int main(int argc, char **argv) { const char *socket_path = UUIDD_SOCKET_PATH; const char *pidfile_path = UUIDD_PIDFILE_PATH; const char *err_context; char buf[1024], *cp; char str[37], *tmp; uuid_t uu; uid_t uid; gid_t gid; int i, c, ret; int debug = 0, do_type = 0, do_kill = 0, num = 0; int timeout = 0, quiet = 0, drop_privs = 0; #ifdef ENABLE_NLS setlocale(LC_MESSAGES, ""); setlocale(LC_CTYPE, ""); bindtextdomain(NLS_CAT_NAME, LOCALEDIR); textdomain(NLS_CAT_NAME); #endif while ((c = getopt (argc, argv, "dkn:qp:s:tT:r")) != EOF) { switch (c) { case 'd': debug++; drop_privs = 1; break; case 'k': do_kill++; drop_privs = 1; break; case 'n': num = strtol(optarg, &tmp, 0); if ((num < 0) || *tmp) { fprintf(stderr, _("Bad number: %s\n"), optarg); exit(1); } break; case 'p': pidfile_path = optarg; drop_privs = 1; break; case 'q': quiet++; break; case 's': socket_path = optarg; drop_privs = 1; break; case 't': do_type = UUIDD_OP_TIME_UUID; drop_privs = 1; break; case 'T': timeout = strtol(optarg, &tmp, 0); if ((timeout < 0) || *tmp) { fprintf(stderr, _("Bad number: %s\n"), optarg); exit(1); } break; case 'r': do_type = UUIDD_OP_RANDOM_UUID; drop_privs = 1; break; default: usage(argv[0]); } } uid = getuid(); if (uid && drop_privs) { gid = getgid(); #ifdef HAVE_SETRESGID if (setresgid(gid, gid, gid) < 0) die("setresgid"); #else if (setregid(gid, gid) < 0) die("setregid"); #endif #ifdef HAVE_SETRESUID if (setresuid(uid, uid, uid) < 0) die("setresuid"); #else if (setreuid(uid, uid) < 0) die("setreuid"); #endif } if (num && do_type) { ret = call_daemon(socket_path, do_type+2, buf, sizeof(buf), &num, &err_context); if (ret < 0) { printf(_("Error calling uuidd daemon (%s): %s\n"), err_context, strerror(errno)); exit(1); } if (do_type == UUIDD_OP_TIME_UUID) { if (ret != sizeof(uu) + sizeof(num)) goto unexpected_size; uuid_unparse((unsigned char *) buf, str); printf(P_("%s and subsequent UUID\n", "%s and subsequent %d UUIDs\n", num), str, num); } else { printf("%s", _("List of UUID's:\n")); cp = buf + 4; if (ret != (int) (sizeof(num) + num*sizeof(uu))) goto unexpected_size; for (i=0; i < num; i++, cp+=16) { uuid_unparse((unsigned char *) cp, str); printf("\t%s\n", str); } } exit(0); } if (do_type) { ret = call_daemon(socket_path, do_type, (char *) &uu, sizeof(uu), 0, &err_context); if (ret < 0) { printf(_("Error calling uuidd daemon (%s): %s\n"), err_context, strerror(errno)); exit(1); } if (ret != sizeof(uu)) { unexpected_size: printf(_("Unexpected reply length from server %d\n"), ret); exit(1); } uuid_unparse(uu, str); printf("%s\n", str); exit(0); } if (do_kill) { ret = call_daemon(socket_path, 0, buf, sizeof(buf), 0, 0); if ((ret > 0) && ((do_kill = atoi((char *) buf)) > 0)) { ret = kill(do_kill, SIGTERM); if (ret < 0) { if (!quiet) fprintf(stderr, _("Couldn't kill uuidd running " "at pid %d: %s\n"), do_kill, strerror(errno)); exit(1); } if (!quiet) printf(_("Killed uuidd running at pid %d\n"), do_kill); } exit(0); } server_loop(socket_path, pidfile_path, debug, timeout, quiet); return 0; }
bool init(InitOptions options, int & retval) { init_options = new InitOptions(options); if (init_options->show_help()) return true; if ( options.daemonize() ) { fawkes::daemon::init(options.daemon_pid_file(), options.basename()); if (options.daemonize_kill()) { fawkes::daemon::kill(); retval = 0; return false; } else if (options.daemonize_status()) { retval = fawkes::daemon::running() ? 0 : 1; return false; } else { if (fawkes::daemon::start()) { retval = 0; return false; } } } // *** set user group if requested const char *user = NULL; const char *group = NULL; if (options.has_username()) { user = options.username(); } if (options.has_groupname()) { group = options.groupname(); } if (user != NULL) { struct passwd *pw; if (! (pw = getpwnam(user))) { printf("Failed to find user %s, check -u argument.\n", user); retval = 203; return false; } int r = 0; r = setreuid(pw->pw_uid, pw->pw_uid); if (r < 0) { perror("Failed to drop privileges (user)"); } } if (group != NULL) { struct group *gr; if (! (gr = getgrnam(group))) { printf("Failed to find group %s, check -g argument.\n", user); retval = 204; return false; } int r = 0; r = setregid(gr->gr_gid, gr->gr_gid); if (r < 0) { perror("Failed to drop privileges (group)"); } } // *** setup base thread and shm registry Thread::init_main(); shm_registry = NULL; struct passwd *uid_pw = getpwuid(getuid()); if (uid_pw == NULL) { shm_registry = new SharedMemoryRegistry(); } else { char *registry_name; if (asprintf(®istry_name, USER_SHM_NAME, uid_pw->pw_name) == -1) { shm_registry = new SharedMemoryRegistry(); } else { shm_registry = new SharedMemoryRegistry(registry_name); free(registry_name); } } if (! shm_registry) { throw Exception("Failed to create shared memory registry"); } // *** setup logging if (options.has_loggers()) { try { logger = LoggerFactory::multilogger_instance(options.loggers()); } catch (Exception &e) { e.append("Initializing multi logger failed"); throw; } } else { logger = new MultiLogger(new ConsoleLogger()); } logger->set_loglevel(options.log_level()); LibLogger::init(logger); // *** Prepare home dir directory, just in case const char *homedir = getenv("HOME"); if (homedir) { char *userdir; if (asprintf(&userdir, "%s/%s", homedir, USERDIR) != -1) { if (access(userdir, W_OK) != 0) { if (mkdir(userdir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1) { logger->log_warn("FawkesMainThread", "Failed to create .fawkes " "directory %s, trying without", userdir); } } free(userdir); } } // *** setup config SQLiteConfiguration *sqconfig = NULL; if (options.config_file() && fnmatch("*.sql", options.config_file(), FNM_PATHNAME) == 0) { sqconfig = new SQLiteConfiguration(CONFDIR); config = sqconfig; } else { config = new YamlConfiguration(CONFDIR); } config->load(options.config_file()); if (sqconfig) { try { SQLiteConfiguration::SQLiteValueIterator *i = sqconfig->modified_iterator(); while (i->next()) { std::string modtype = i->get_modtype(); if (modtype == "changed") { logger->log_warn("FawkesMainThread", "Default config value CHANGED: %s" "(was: %s now: %s)", i->path(), i->get_oldvalue().c_str(), i->get_as_string().c_str()); } else if (modtype == "erased") { logger->log_warn("FawkesMainThread", "Default config value ERASED: %s", i->path()); } else { logger->log_debug("FawkesMainThread", "Default config value ADDED: %s " "(value: %s)", i->path(), i->get_as_string().c_str()); } } delete i; } catch (Exception &e) { logger->log_warn("FawkesMainThread", "Failed to read modified default " "config values, no dump?"); } } if (! options.has_loggers()) { // Allow configuration override from config if (config->exists("/fawkes/mainapp/loggers")) { try { std::string loggers = config->get_string("/fawkes/mainapp/loggers"); MultiLogger *new_logger = LoggerFactory::multilogger_instance(loggers.c_str(), options.log_level()); logger = new_logger; LibLogger::finalize(); LibLogger::init(new_logger); } catch (Exception &e) { logger->log_warn("FawkesMainThread", "Loggers set in config file, " "but failed to read, exception follows."); logger->log_warn("FawkesMainThread", e); } } } if (config->exists("/fawkes/mainapp/log_stderr_as_warn")) { try { bool log_stderr_as_warn = config->get_bool("/fawkes/mainapp/log_stderr_as_warn"); if (log_stderr_as_warn) { #ifdef HAVE_LOGGING_FD_REDIRECT log_fd_redirect_stderr_ = new LogFileDescriptorToLog(STDERR_FILENO, logger, "stderr", Logger::LL_WARN); #else logger->log_warn("FawkesMainThread", "stderr log redirection enabled but not available at compile time"); #endif } } catch (Exception &e) {} // ignored } // *** Determine network parameters bool enable_ipv4 = true; bool enable_ipv6 = true; std::string listen_ipv4; std::string listen_ipv6; unsigned int net_tcp_port = 1910; std::string net_service_name = "Fawkes on %h"; if (options.has_net_tcp_port()) { net_tcp_port = options.net_tcp_port(); } else { try { net_tcp_port = config->get_uint("/network/fawkes/tcp_port"); } catch (Exception &e) {} // ignore, we stick with the default } if (options.has_net_service_name()) { net_service_name = options.net_service_name(); } else { try { net_service_name = config->get_string("/network/fawkes/service_name"); } catch (Exception &e) {} // ignore, we stick with the default } if (net_tcp_port > 65535) { logger->log_warn("FawkesMainThread", "Invalid port '%u', using 1910", net_tcp_port); net_tcp_port = 1910; } try { enable_ipv4 = config->get_bool("/network/ipv4/enable"); } catch (Exception &e) {} // ignore, we stick with the default try { enable_ipv6 = config->get_bool("/network/ipv6/enable"); } catch (Exception &e) {} // ignore, we stick with the default try { listen_ipv4 = config->get_string("/network/ipv4/listen"); } catch (Exception &e) {} // ignore, we stick with the default try { listen_ipv6 = config->get_string("/network/ipv6/listen"); } catch (Exception &e) {} // ignore, we stick with the default if (! enable_ipv4) { logger->log_warn("FawkesMainThread", "Disabling IPv4 support"); } if (! enable_ipv6) { logger->log_warn("FawkesMainThread", "Disabling IPv6 support"); } if (! listen_ipv4.empty()) { logger->log_info("FawkesMainThread", "Listening on IPv4 address %s", listen_ipv4.c_str()); } if (! listen_ipv6.empty()) { logger->log_info("FawkesMainThread", "Listening on IPv6 address %s", listen_ipv4.c_str()); } // *** Setup blackboard std::string bb_magic_token = ""; unsigned int bb_size = 2097152; try { bb_magic_token = config->get_string("/fawkes/mainapp/blackboard_magic_token"); logger->log_info("FawkesMainApp", "BlackBoard magic token defined. " "Using shared memory BlackBoard."); } catch (Exception &e) { // ignore } try { bb_size = config->get_uint("/fawkes/mainapp/blackboard_size"); } catch (Exception &e) { logger->log_warn("FawkesMainApp", "BlackBoard size not defined. " "Will use %u, saving to default DB", bb_size); config->set_default_uint("/fawkes/mainapp/blackboard_size", bb_size); } // Cleanup stale BlackBoard shared memory segments if requested if ( options.bb_cleanup()) { LocalBlackBoard::cleanup(bb_magic_token.c_str(), /* output with lister? */ true); SharedMemoryRegistry::cleanup(); } LocalBlackBoard *lbb = NULL; if ( bb_magic_token == "") { lbb = new LocalBlackBoard(bb_size); } else { lbb = new LocalBlackBoard(bb_size, bb_magic_token.c_str()); } blackboard = lbb; #ifdef HAVE_TF tf_transformer = new tf::Transformer(); tf_listener = new tf::TransformListener(blackboard, tf_transformer); #endif aspect_manager = new AspectManager(); thread_manager = new ThreadManager(aspect_manager, aspect_manager); plugin_manager = new PluginManager(thread_manager, config, "/fawkes/meta_plugins/", options.plugin_module_flags(), options.init_plugin_cache()); network_manager = new FawkesNetworkManager(thread_manager, enable_ipv4, enable_ipv6, listen_ipv4, listen_ipv6, net_tcp_port, net_service_name.c_str()); nethandler_config = new ConfigNetworkHandler(config, network_manager->hub()); nethandler_plugin = new PluginNetworkHandler(plugin_manager, network_manager->hub()); nethandler_plugin->start(); network_logger = new NetworkLogger(network_manager->hub(), logger->loglevel()); logger->add_logger(network_logger); clock = Clock::instance(); start_time = new Time(clock); lbb->start_nethandler(network_manager->hub()); // *** Create main thread, but do not start, yet main_thread = new fawkes::FawkesMainThread(config, logger, thread_manager, plugin_manager, options.load_plugin_list(), options.default_plugin()); aspect_manager->register_default_inifins(blackboard, thread_manager->aspect_collector(), config, logger, clock, network_manager->hub(), main_thread, logger, thread_manager, network_manager->nnresolver(), network_manager->service_publisher(), network_manager->service_browser(), plugin_manager, tf_transformer); retval = 0; return true; }
qboolean VID_LoadRefresh ( char *name ) { refimport_t ri; R_GetRefAPI_t R_GetRefAPI; char fn [ MAX_OSPATH ]; char *path; struct stat st; extern uid_t saved_euid; if ( reflib_active ) { if ( IN_Close_fp ) { IN_Close_fp(); } if ( IN_BackendShutdown_fp ) { IN_BackendShutdown_fp(); } IN_Close_fp = NULL; IN_BackendShutdown_fp = NULL; re.Shutdown(); VID_FreeReflib(); } Com_Printf( "----- refresher initialization -----\n"); /* regain root */ seteuid( saved_euid ); path = Cvar_Get( "basedir", ".", CVAR_NOSET )->string; snprintf( fn, MAX_OSPATH, "%s/%s", path, name ); if ( stat( fn, &st ) == -1 ) { Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name, strerror( errno ) ); return ( false ); } if ( ( reflib_library = dlopen( fn, RTLD_LAZY ) ) == 0 ) { Com_Printf( "LoadLibrary(\"%s\") failed: %s\n", name, dlerror() ); return ( false ); } Com_Printf( "LoadLibrary(\"%s\")\n", fn ); ri.Cmd_AddCommand = Cmd_AddCommand; ri.Cmd_RemoveCommand = Cmd_RemoveCommand; ri.Cmd_Argc = Cmd_Argc; ri.Cmd_Argv = Cmd_Argv; ri.Cmd_ExecuteText = Cbuf_ExecuteText; ri.Con_Printf = VID_Printf; ri.Sys_Error = VID_Error; ri.Sys_Mkdir = Sys_Mkdir; ri.FS_LoadFile = FS_LoadFile; ri.FS_FreeFile = FS_FreeFile; ri.FS_Gamedir = FS_Gamedir; ri.Cvar_Get = Cvar_Get; ri.Cvar_Set = Cvar_Set; ri.Cvar_SetValue = Cvar_SetValue; ri.Vid_GetModeInfo = VID_GetModeInfo; ri.Vid_MenuInit = VID_MenuInit; ri.Vid_NewWindow = VID_NewWindow; if ( ( R_GetRefAPI = (void *) dlsym( reflib_library, "R_GetRefAPI" ) ) == 0 ) { Com_Error( ERR_FATAL, "dlsym failed on %s", name ); } re = R_GetRefAPI( ri ); if ( re.api_version != API_VERSION ) { VID_FreeReflib(); Com_Error( ERR_FATAL, "%s has incompatible api_version", name ); } /* Init IN (Mouse) */ in_state.IN_CenterView_fp = IN_CenterView; in_state.Key_Event_fp = Do_Key_Event; in_state.viewangles = cl.viewangles; in_state.in_strafe_state = &in_strafe.state; in_state.in_speed_state = &in_speed.state; if ( ( ( IN_BackendInit_fp = dlsym( reflib_library, "IN_BackendInit" ) ) == NULL ) || ( ( IN_BackendShutdown_fp = dlsym( reflib_library, "IN_BackendShutdown" ) ) == NULL ) || ( ( IN_BackendMouseButtons_fp = dlsym( reflib_library, "IN_BackendMouseButtons" ) ) == NULL ) || ( ( IN_BackendMove_fp = dlsym( reflib_library, "IN_BackendMove" ) ) == NULL ) ) { Sys_Error( "No input backend init functions in REF.\n" ); } if ( IN_BackendInit_fp ) { IN_BackendInit_fp( &in_state ); } if ( re.Init( 0, 0 ) == -1 ) { re.Shutdown(); VID_FreeReflib(); return ( false ); } /* Init IN */ if ( ( ( IN_KeyboardInit_fp = dlsym( reflib_library, "IN_KeyboardInit" ) ) == NULL ) || ( ( IN_Update_fp = dlsym( reflib_library, "IN_Update" ) ) == NULL ) || ( ( IN_Close_fp = dlsym( reflib_library, "IN_Close" ) ) == NULL ) ) { Sys_Error( "No keyboard input functions in REF.\n" ); } IN_KeyboardInit_fp( Do_Key_Event ); Key_ClearStates(); /* give up root now */ setreuid( getuid(), getuid() ); setegid( getgid() ); Com_Printf( "------------------------------------\n\n" ); reflib_active = true; return ( true ); }
int main(int ac, char **av) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ pid_t pid, pid1; int status; /* parse standard options */ if ((msg = parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *)NULL) { tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); } setup(); /* set up the expected errnos */ TEST_EXP_ENOS(exp_enos); /* check for looping state if -i option is given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; if ((pid = FORK_OR_VFORK()) < 0) { tst_brkm(TBROK, cleanup, "first fork failed"); } if (pid == 0) { /* first child */ /* set the child's ID to ltpuser1 */ if (setreuid(ltpuser1->pw_uid, ltpuser1->pw_uid) != 0) { tst_resm(TINFO, "setreuid failed in child #1"); exit(1); } if (mkdir(good_dir, 00700) != 0) { tst_resm(TINFO, "mkdir failed in child #1"); exit(1); } exit(0); } wait(&status); if ((pid1 = FORK_OR_VFORK()) < 0) { tst_brkm(TBROK, cleanup, "second fork failed"); } if (pid1 == 0) { /* second child */ /* * set the child's ID to ltpuser2 using seteuid() * so that the ID can be changed back after the * TEST call is made. */ if (seteuid(ltpuser2->pw_uid) != 0) { tst_resm(TINFO, "setreuid failed in child #2"); exit(1); } TEST(chdir(good_dir)); if (TEST_RETURN != -1) { tst_resm(TFAIL, "call succeeded unexpectedly"); } else if (TEST_ERRNO != EACCES) { tst_resm(TFAIL|TTERRNO, "expected EACCES"); } else { TEST_ERROR_LOG(TEST_ERRNO); tst_resm(TPASS|TTERRNO, "expected failure"); } /* reset the process ID to the saved ID (root) */ if (setuid(0) == -1) { tst_resm(TINFO|TERRNO, "setuid(0) failed"); } } else { /* parent */ wait(&status); /* let the child carry on */ exit(0); } /* clean up things in case we are looping */ if (rmdir(good_dir) == -1) { tst_brkm(TBROK|TERRNO, cleanup, "rmdir(%s) failed", good_dir); } } cleanup(); return 0; /*NOTREACHED*/}
int main(int ac, char **av) { int ch, i=0; pid_t pid; FILE *fp; uid_t uid; #ifdef USE_THREAD pthread_t tid; pthread_attr_t attr; struct rlimit rl; rlim_t max_fd = (rlim_t)MAX_FD; rlim_t save_fd = 0; #endif #ifdef USE_THREAD threading = 1; max_thread = MAX_THREAD; #endif max_child = MAX_CHILD; cur_child = 0; /* create service socket table (malloc) */ if (serv_init(NULL) < 0) { msg_out(crit, "cannot malloc: %m\n"); exit(-1); } proxy_tbl = NULL; proxy_tbl_ind = 0; method_num = 0; uid = getuid(); openlog(ident, LOG_PID | LOG_NDELAY, SYSLOGFAC); while((ch = getopt(ac, av, "a:c:i:J:m:o:p:u:frstbwgIqvh?")) != -1) switch (ch) { case 'a': if (optarg != NULL) { for (i=0; i<sizeof method_tab; optarg++) { if (*optarg == '\0') break; switch (*optarg) { case 'p': if ( uid != 0 ) { /* process does not started by root */ msg_out(warn, "uid == %d (!=0)," "user/pass auth will not work, ignored.\n", uid); break; } method_tab[i++] = S5AUSRPAS; method_num++; break; case 'n': method_tab[i++] = S5ANOAUTH; method_num++; break; default: break; } } } break; case 'b': bind_restrict = 0; break; case 'c': if (optarg != NULL) { config = strdup(optarg); } break; case 'u': if (optarg != NULL) { pwdfile = strdup(optarg); } break; case 'i': if (optarg != NULL) { if (serv_init(optarg) < 0) { msg_out(warn, "cannot init server socket(-i %s): %m\n", optarg); break; } } break; #ifdef SO_BINDTODEVICE case 'J': if (optarg != NULL) { bindtodevice = strdup(optarg); } break; #endif case 'o': if (optarg != NULL) { idle_timeout = atol(optarg); } break; case 'p': if (optarg != NULL) { pidfile = strdup(optarg); } break; case 'm': if (optarg != NULL) { #ifdef USE_THREAD max_thread = atoi(optarg); #endif max_child = atoi(optarg); } break; case 't': #ifdef USE_THREAD threading = 0; /* threading disabled. */ #endif break; case 'g': same_interface = 1; break; case 'f': fg = 1; break; case 'r': resolv_client = 1; break; case 's': forcesyslog = 1; break; case 'w': #ifdef HAVE_LIBWRAP use_tcpwrap = 1; #endif /* HAVE_LIBWRAP */ break; case 'I': inetd_mode = 1; break; case 'q': be_quiet = 1; break; case 'v': show_version(); exit(1); case 'h': case '?': default: usage(); } ac -= optind; av += optind; if ((fp = fopen(config, "r")) != NULL) { if (readconf(fp) != 0) { /* readconf error */ exit(1); } fclose(fp); } if (inetd_mode) { /* close all server socket if opened */ close_all_serv(); /* assuming that STDIN_FILENO handles bi-directional */ exit(inetd_service(STDIN_FILENO)); /* not reached */ } if (serv_sock_ind == 0) { /* no valid ifs yet */ if (serv_init(":") < 0) { /* use default */ /* fatal */ msg_out(crit, "cannot open server socket\n"); exit(1); } } #ifdef USE_THREAD if ( ! threading ) { #endif if (queue_init() != 0) { msg_out(crit, "cannot init signal queue\n"); exit(1); } #ifdef USE_THREAD } #endif /* try changing working directory */ if ( chdir(WORKDIR0) != 0 ) if ( chdir(WORKDIR1) != 0 ) msg_out(norm, "giving up chdir to workdir"); if (!fg) { /* force stdin/out/err allocate to /dev/null */ fclose(stdin); fp = fopen("/dev/null", "w+"); if (fileno(fp) != STDIN_FILENO) { msg_out(crit, "fopen: %m"); exit(1); } if (dup2(STDIN_FILENO, STDOUT_FILENO) == -1) { msg_out(crit, "dup2-1: %m"); exit(1); } if (dup2(STDIN_FILENO, STDERR_FILENO) == -1) { msg_out(crit, "dup2-2: %m"); exit(1); } switch(fork()) { case -1: msg_out(crit, "fork: %m"); exit(1); case 0: /* child */ pid = setsid(); if (pid == -1) { msg_out(crit, "setsid: %m"); exit(1); } break; default: /* parent */ exit(0); } } master_pid = getpid(); umask(S_IWGRP|S_IWOTH); if ((fp = fopen(pidfile, "w")) != NULL) { fprintf(fp, "%u\n", (unsigned)master_pid); fchown(fileno(fp), PROCUID, PROCGID); fclose(fp); } else { msg_out(warn, "cannot open pidfile %s", pidfile); } setsignal(SIGHUP, reload); setsignal(SIGINT, SIG_IGN); setsignal(SIGQUIT, SIG_IGN); setsignal(SIGILL, SIG_IGN); setsignal(SIGTRAP, SIG_IGN); setsignal(SIGABRT, SIG_IGN); #ifdef SIGEMT setsignal(SIGEMT, SIG_IGN); #endif setsignal(SIGFPE, SIG_IGN); setsignal(SIGBUS, SIG_IGN); setsignal(SIGSEGV, SIG_IGN); setsignal(SIGSYS, SIG_IGN); setsignal(SIGPIPE, SIG_IGN); setsignal(SIGALRM, SIG_IGN); setsignal(SIGTERM, cleanup); setsignal(SIGUSR1, SIG_IGN); setsignal(SIGUSR2, SIG_IGN); #ifdef SIGPOLL setsignal(SIGPOLL, SIG_IGN); #endif setsignal(SIGVTALRM, SIG_IGN); setsignal(SIGPROF, SIG_IGN); setsignal(SIGXCPU, SIG_IGN); setsignal(SIGXFSZ, SIG_IGN); #ifdef USE_THREAD if ( threading ) { if (max_thread <= 0 || max_thread > THREAD_LIMIT) { max_thread = THREAD_LIMIT; } /* resource limit is problem in threadig (e.g. Solaris:=64)*/ memset((caddr_t)&rl, 0, sizeof rl); if (getrlimit(RLIMIT_NOFILE, &rl) != 0) msg_out(warn, "getrlimit: %m"); else save_fd = rl.rlim_cur; if (rl.rlim_cur < (rlim_t)max_fd) rl.rlim_cur = max_fd; /* willing to fix to max_fd */ if ( rl.rlim_cur != save_fd ) /* if rlim_cur is changed */ if (setrlimit(RLIMIT_NOFILE, &rl) != 0) msg_out(warn, "cannot set rlimit(max_fd)"); setregid(0, PROCGID); setreuid(0, PROCUID); pthread_mutex_init(&mutex_select, NULL); pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); msg_out(norm, "Starting: MAX_TH(%d)", max_thread); for (i=0; i<max_thread; i++) { if (pthread_create(&tid, &attr, (void *)&serv_loop, (void *)NULL) != 0) exit(1); } main_thread = pthread_self(); /* store main thread ID */ for (;;) { pause(); } } else { #endif setsignal(SIGCHLD, reapchild); setregid(0, PROCGID); setreuid(0, PROCUID); msg_out(norm, "Starting: MAX_CH(%d)", max_child); serv_loop(); #ifdef USE_THREAD } #endif return(0); }
int sh_access(register const char *name, register int mode) { Shell_t *shp = sh_getinterp(); struct stat statb; if(*name==0) return(-1); if(sh_isdevfd(name)) return(sh_ioaccess((int)strtol(name+8, (char**)0, 10),mode)); /* can't use access function for execute permission with root */ if(mode==X_OK && shp->gd->euserid==0) goto skip; if(shp->gd->userid==shp->gd->euserid && shp->gd->groupid==shp->gd->egroupid) return(access(name,mode)); #ifdef _lib_setreuid /* swap the real uid to effective, check access then restore */ /* first swap real and effective gid, if different */ if(shp->gd->groupid==shp->gd->euserid || setregid(shp->gd->egroupid,shp->gd->groupid)==0) { /* next swap real and effective uid, if needed */ if(shp->gd->userid==shp->gd->euserid || setreuid(shp->gd->euserid,shp->gd->userid)==0) { mode = access(name,mode); /* restore ids */ if(shp->gd->userid!=shp->gd->euserid) setreuid(shp->gd->userid,shp->gd->euserid); if(shp->gd->groupid!=shp->gd->egroupid) setregid(shp->gd->groupid,shp->gd->egroupid); return(mode); } else if(shp->gd->groupid!=shp->gd->egroupid) setregid(shp->gd->groupid,shp->gd->egroupid); } #endif /* _lib_setreuid */ skip: if(test_stat(name, &statb) == 0) { if(mode == F_OK) return(mode); else if(shp->gd->euserid == 0) { if(!S_ISREG(statb.st_mode) || mode!=X_OK) return(0); /* root needs execute permission for someone */ mode = (S_IXUSR|S_IXGRP|S_IXOTH); } else if(shp->gd->euserid == statb.st_uid) mode <<= 6; else if(shp->gd->egroupid == statb.st_gid) mode <<= 3; #ifdef _lib_getgroups /* on some systems you can be in several groups */ else { static int maxgroups; gid_t *groups; register int n; if(maxgroups==0) { /* first time */ if((maxgroups=getgroups(0,(gid_t*)0)) <= 0) { /* pre-POSIX system */ maxgroups=NGROUPS_MAX; } } groups = (gid_t*)stakalloc((maxgroups+1)*sizeof(gid_t)); n = getgroups(maxgroups,groups); while(--n >= 0) { if(groups[n] == statb.st_gid) { mode <<= 3; break; } } } # endif /* _lib_getgroups */ if(statb.st_mode & mode) return(0); } return(-1); }
/*@-bounds -boundswrite @*/ static int execCommand(poptContext con) /*@globals internalState @*/ /*@modifies internalState @*/ { poptItem item = con->doExec; const char ** argv; int argc = 0; int rc; if (item == NULL) /*XXX can't happen*/ return POPT_ERROR_NOARG; if (item->argv == NULL || item->argc < 1 || (!con->execAbsolute && strchr(item->argv[0], '/'))) return POPT_ERROR_NOARG; argv = malloc(sizeof(*argv) * (6 + item->argc + con->numLeftovers + con->finalArgvCount)); if (argv == NULL) return POPT_ERROR_MALLOC; if (!strchr(item->argv[0], '/') && con->execPath != NULL) { char *s = alloca(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/")); sprintf(s, "%s/%s", con->execPath, item->argv[0]); argv[argc] = s; } else argv[argc] = findProgramPath(item->argv[0]); if (argv[argc++] == NULL) return POPT_ERROR_NOARG; if (item->argc > 1) { memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1)); argc += (item->argc - 1); } if (con->finalArgv != NULL && con->finalArgvCount > 0) { memcpy(argv + argc, con->finalArgv, sizeof(*argv) * con->finalArgvCount); argc += con->finalArgvCount; } if (con->leftovers != NULL && con->numLeftovers > 0) { memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers); argc += con->numLeftovers; } argv[argc] = NULL; #if defined(hpux) || defined(__hpux) rc = setresgid(getgid(), getgid(),-1); if (rc) return POPT_ERROR_ERRNO; rc = setresuid(getuid(), getuid(),-1); if (rc) return POPT_ERROR_ERRNO; #else /* * XXX " ... on BSD systems setuid() should be preferred over setreuid()" * XXX sez' Timur Bakeyev <*****@*****.**> * XXX from Norbert Warmuth <*****@*****.**> */ #if defined(HAVE_SETUID) rc = setgid(getgid()); if (rc) return POPT_ERROR_ERRNO; rc = setuid(getuid()); if (rc) return POPT_ERROR_ERRNO; #elif defined (HAVE_SETREUID) rc = setregid(getgid(), getgid()); if (rc) return POPT_ERROR_ERRNO; rc = setreuid(getuid(), getuid()); if (rc) return POPT_ERROR_ERRNO; #else ; /* Can't drop privileges */ #endif #endif if (argv[0] == NULL) return POPT_ERROR_NOARG; #ifdef MYDEBUG if (_popt_debug) { const char ** avp; fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc); for (avp = argv; *avp; avp++) fprintf(stderr, " '%s'", *avp); fprintf(stderr, "\n"); } #endif rc = execvp(argv[0], (char *const *)argv); return POPT_ERROR_ERRNO; }
int main(int argc, char **argv) { char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; char buf[32], passwd[256], passdisp[256]; int num, screen, width, height, update, sleepmode, term, pid; #ifndef HAVE_BSD_AUTH const char *pws; #endif unsigned int len; Bool running = True; Cursor invisible; Display *dpy; KeySym ksym; Pixmap pmap; Window root, w; XColor black, red, dummy; XEvent ev; XSetWindowAttributes wa; XFontStruct* font; GC gc; XGCValues values; // defaults char* passchar = "*"; char* fontname = "-*-dejavu sans-bold-r-*-*-*-420-100-100-*-*-iso8859-1"; char* username = ""; int showline = 1; int xshift = 0; for (int i = 0; i < argc; i++) { if (!strcmp(argv[i], "-c")) { if (i + 1 < argc) passchar = argv[i + 1]; else die("error: no password character given.\n"); } else if (!strcmp(argv[i], "-f")) { if (i + 1 < argc) fontname = argv[i + 1]; else die("error: font not specified.\n"); } else if (!strcmp(argv[i], "-v")) die("sflock-"VERSION", © 2015 Ben Ruijl\n"); else if (!strcmp(argv[i], "-h")) showline = 0; else if (!strcmp(argv[i], "-xshift")) xshift = atoi(argv[i + 1]); else if (!strcmp(argv[i], "?")) die("usage: sflock [-v] [-c passchars] [-f fontname] [-xshift horizontal shift]\n"); } // fill with password characters for (int i = 0; i < sizeof passdisp; i+= strlen(passchar)) for (int j = 0; j < strlen(passchar) && i + j < sizeof passdisp; j++) passdisp[i + j] = passchar[j]; /* disable tty switching */ if ((term = open("/dev/console", O_RDWR)) == -1) { perror("error opening console"); } if ((ioctl(term, VT_LOCKSWITCH)) == -1) { perror("error locking console"); } /* deamonize */ pid = fork(); if (pid < 0) die("Could not fork sflock."); if (pid > 0) exit(0); // exit parent #ifndef HAVE_BSD_AUTH pws = get_password(); username = getpwuid(geteuid())->pw_name; #else username = getlogin(); #endif if(!(dpy = XOpenDisplay(0))) die("sflock: cannot open dpy\n"); screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); width = DisplayWidth(dpy, screen); height = DisplayHeight(dpy, screen); wa.override_redirect = 1; wa.background_pixel = XBlackPixel(dpy, screen); w = XCreateWindow(dpy, root, 0, 0, width, height, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixel, &wa); XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "orange red", &red, &dummy); XAllocNamedColor(dpy, DefaultColormap(dpy, screen), "black", &black, &dummy); pmap = XCreateBitmapFromData(dpy, w, curs, 8, 8); invisible = XCreatePixmapCursor(dpy, pmap, pmap, &black, &black, 0, 0); XDefineCursor(dpy, w, invisible); XMapRaised(dpy, w); font = XLoadQueryFont(dpy, fontname); if (font == 0) { die("error: could not find font. Try using a full description.\n"); } gc = XCreateGC(dpy, w, (unsigned long)0, &values); XSetFont(dpy, gc, font->fid); XSetForeground(dpy, gc, XWhitePixel(dpy, screen)); for(len = 1000; len; len--) { if(XGrabPointer(dpy, root, False, ButtonPressMask | ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, None, invisible, CurrentTime) == GrabSuccess) break; usleep(1000); } if((running = running && (len > 0))) { for(len = 1000; len; len--) { if(XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess) break; usleep(1000); } running = (len > 0); } len = 0; XSync(dpy, False); update = True; sleepmode = False; /* main event loop */ while(running && !XNextEvent(dpy, &ev)) { if (sleepmode) { DPMSEnable(dpy); DPMSForceLevel(dpy, DPMSModeOff); XFlush(dpy); } if (update) { int x, y, dir, ascent, descent; XCharStruct overall; XClearWindow(dpy, w); XTextExtents (font, passdisp, len, &dir, &ascent, &descent, &overall); x = (width - overall.width) / 2; y = (height + ascent - descent) / 2; XDrawString(dpy,w,gc, (width - XTextWidth(font, username, strlen(username))) / 2 + xshift, y - ascent - 20, username, strlen(username)); if (showline) XDrawLine(dpy, w, gc, width * 3 / 8 + xshift, y - ascent - 10, width * 5 / 8 + xshift, y - ascent - 10); XDrawString(dpy,w,gc, x + xshift, y, passdisp, len); update = False; } if (ev.type == MotionNotify) { sleepmode = False; } if(ev.type == KeyPress) { sleepmode = False; buf[0] = 0; num = XLookupString(&ev.xkey, buf, sizeof buf, &ksym, 0); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) ksym = XK_Return; else if(ksym >= XK_KP_0 && ksym <= XK_KP_9) ksym = (ksym - XK_KP_0) + XK_0; } if(IsFunctionKey(ksym) || IsKeypadKey(ksym) || IsMiscFunctionKey(ksym) || IsPFKey(ksym) || IsPrivateKeypadKey(ksym)) continue; switch(ksym) { case XK_Return: passwd[len] = 0; #ifdef HAVE_BSD_AUTH running = !auth_userokay(getlogin(), NULL, "auth-xlock", passwd); #else running = strcmp(crypt(passwd, pws), pws); #endif if (running != 0) // change background on wrong password XSetWindowBackground(dpy, w, red.pixel); len = 0; break; case XK_Escape: len = 0; if (DPMSCapable(dpy)) { sleepmode = True; } break; case XK_BackSpace: if(len) --len; break; default: if(num && !iscntrl((int) buf[0]) && (len + num < sizeof passwd)) { memcpy(passwd + len, buf, num); len += num; } break; } update = True; // show changes } } /* free and unlock */ setreuid(geteuid(), 0); if ((ioctl(term, VT_UNLOCKSWITCH)) == -1) { perror("error unlocking console"); } close(term); setuid(getuid()); // drop rights permanently XUngrabPointer(dpy, CurrentTime); XFreePixmap(dpy, pmap); XFreeFont(dpy, font); XFreeGC(dpy, gc); XDestroyWindow(dpy, w); XCloseDisplay(dpy); return 0; }
int main(int argc, char * argv[]) { server_configuration config; bzero(&config, sizeof(config)); if(!network_subsystem_init()) { fprintf(stderr, "Network subsystem init failed.\n"); return error_network_subsystem; } if(!read_configuration(argc, argv, &config)) { fprintf(stderr, PROG_NAME ": configuration error! Exit.\n"); return error_config; } if(config.discover) interfaces_discover(0); if(config.print_header_offsets) { print_dhcp_header_offsets(); return 0; } if(!log_init(config.log_file_name, (config.debug_mode ? LOG_DEBUG_FLAG : 0) | (config.log_stdout ? LOG_STDOUT_FLAG : 0), config.uid) ) { fprintf(stderr, "Can't open log file.\n"); return error_log; } log_wr(ILOG, "Program " PROG_NAME " " PROG_VERS " " PROG_DESC " started."); struct sigaction sig_handler_s; sig_handler_s.sa_handler = sig_handler; sigemptyset(&sig_handler_s.sa_mask); sig_handler_s.sa_flags = 0; if(config.daemon) daemonize(); /* Init DHCP cache */ if(config.cache_ttl && !dhcp_cache_init(config.cache_ttl)) { log_wr(CLOG, "Can't init DHCP cache. Exit."); return error_abnormal; } /* STARTING DATABASE CLIENTS */ /* Create array of childen threads */ request_handler_thread_t **handler_threads = (request_handler_thread_t **) malloc(sizeof(request_handler_thread_t *) * config.db_clients_count); CHECK_VALUE(handler_threads, "Can't allocate memory for array of children threads for connecting to DB.", error_memory); /* Create DHCP messages queue */ config.dhcp_queue = dhcp_queue_create("DHCP requests", YES, DEFAULT_QUEUE_MAX_SIZE); CHECK_VALUE(config.dhcp_queue, "Can't create DHCP queue.", error_queue_init); /* Running DB clients */ CHECK_VALUE(run_requests_handlers(handler_threads, &config), "", error_run_db_clients); /* STARTING DHCP PROCESSES */ dhcp_proc_thread_t **dhcp_threads = (dhcp_proc_thread_t**) malloc(sizeof(dhcp_proc_thread_t *) * config.if_count); CHECK_VALUE(dhcp_threads, "Can't allocate memory for array of children threads for " "processing DHCP clients.", error_run_dhcp_procs); CHECK_VALUE(run_dhcp_threads(dhcp_threads, &config, handler_threads), "", error_run_dhcp_procs); /* Set signal handlers */ if( sigaction(SIGINT, &sig_handler_s, NULL) || sigaction(SIGTERM, &sig_handler_s, NULL) || sigaction(SIGUSR1, &sig_handler_s, NULL)) { log_wr(CLOG, "Can't set signal handlers: '%s'", strerror(errno)); return error_abnormal; } #ifndef _WIN32 if(config.uid) { log_wr(DLOG, "Set effective and real user ID to %u.", config.uid); if(setreuid(config.uid, config.uid)) { log_wr(CLOG, "Can't execute setreuid(%u): '%s'", config.uid, strerror(errno)); return 0; } } else log_wr(WLOG, "Running with uid 0 - it is not safe!!! Use configuration directive 'User' for set uid."); #endif int i; for(i = 0; i < config.if_count; ++i) pthread_join(dhcp_threads[i]->thread_id, 0); log_wr(ILOG, "All DHCP threads finished"); for(i = 0; i < config.db_clients_count; ++i) pthread_join(handler_threads[i]->thread_id, 0); log_wr(ILOG, "All DB threads finished."); /* Cleaning up */ /* TODO 30 Need gracefull cleanup database connections and free all allocated memory */ log_wr(ILOG, "Program exited."); log_close(); return EXIT_SUCCESS; }
int main(int argc, char **argv) { extern int optind; extern char *optarg, **environ; struct group *gr; register int ch; register char *p; int ask, fflag, hflag, pflag, cnt, errsv; int quietlog, passwd_req; char *domain, *ttyn; char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10]; char *termenv; char *childArgv[10]; char *buff; int childArgc = 0; #ifdef HAVE_SECURITY_PAM_MISC_H int retcode; pam_handle_t *pamh = NULL; struct pam_conv conv = { misc_conv, NULL }; pid_t childPid; #else char *salt, *pp; #endif #ifdef LOGIN_CHOWN_VCS char vcsn[20], vcsan[20]; #endif pid = getpid(); signal(SIGALRM, timedout); alarm((unsigned int)timeout); signal(SIGQUIT, SIG_IGN); signal(SIGINT, SIG_IGN); setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); setpriority(PRIO_PROCESS, 0, 0); initproctitle(argc, argv); /* * -p is used by getty to tell login not to destroy the environment * -f is used to skip a second login authentication * -h is used by other servers to pass the name of the remote * host to login so that it may be placed in utmp and wtmp */ gethostname(tbuf, sizeof(tbuf)); xstrncpy(thishost, tbuf, sizeof(thishost)); domain = index(tbuf, '.'); username = tty_name = hostname = NULL; fflag = hflag = pflag = 0; passwd_req = 1; while ((ch = getopt(argc, argv, "fh:p")) != -1) switch (ch) { case 'f': fflag = 1; break; case 'h': if (getuid()) { fprintf(stderr, _("login: -h for super-user only.\n")); exit(1); } hflag = 1; if (domain && (p = index(optarg, '.')) && strcasecmp(p, domain) == 0) *p = 0; hostname = strdup(optarg); /* strdup: Ambrose C. Li */ { struct hostent *he = gethostbyname(hostname); /* he points to static storage; copy the part we use */ hostaddress[0] = 0; if (he && he->h_addr_list && he->h_addr_list[0]) memcpy(hostaddress, he->h_addr_list[0], sizeof(hostaddress)); } break; case 'p': pflag = 1; break; case '?': default: fprintf(stderr, _("usage: login [-fp] [username]\n")); exit(1); } argc -= optind; argv += optind; if (*argv) { char *p = *argv; username = strdup(p); ask = 0; /* wipe name - some people mistype their password here */ /* (of course we are too late, but perhaps this helps a little ..) */ while(*p) *p++ = ' '; } else ask = 1; for (cnt = getdtablesize(); cnt > 2; cnt--) close(cnt); ttyn = ttyname(0); if (ttyn == NULL || *ttyn == '\0') { /* no snprintf required - see definition of tname */ sprintf(tname, "%s??", _PATH_TTY); ttyn = tname; } check_ttyname(ttyn); if (strncmp(ttyn, "/dev/", 5) == 0) tty_name = ttyn+5; else tty_name = ttyn; if (strncmp(ttyn, "/dev/tty", 8) == 0) tty_number = ttyn+8; else { char *p = ttyn; while (*p && !isdigit(*p)) p++; tty_number = p; } #ifdef LOGIN_CHOWN_VCS /* find names of Virtual Console devices, for later mode change */ snprintf(vcsn, sizeof(vcsn), "/dev/vcs%s", tty_number); snprintf(vcsan, sizeof(vcsan), "/dev/vcsa%s", tty_number); #endif /* set pgid to pid */ setpgrp(); /* this means that setsid() will fail */ { struct termios tt, ttt; tcgetattr(0, &tt); ttt = tt; ttt.c_cflag &= ~HUPCL; /* These can fail, e.g. with ttyn on a read-only filesystem */ chown(ttyn, 0, 0); chmod(ttyn, TTY_MODE); /* Kill processes left on this tty */ tcsetattr(0,TCSAFLUSH,&ttt); signal(SIGHUP, SIG_IGN); /* so vhangup() wont kill us */ vhangup(); signal(SIGHUP, SIG_DFL); /* open stdin,stdout,stderr to the tty */ opentty(ttyn); /* restore tty modes */ tcsetattr(0,TCSAFLUSH,&tt); } openlog("login", LOG_ODELAY, LOG_AUTHPRIV); #if 0 /* other than iso-8859-1 */ printf("\033(K"); fprintf(stderr,"\033(K"); #endif #ifdef HAVE_SECURITY_PAM_MISC_H /* * username is initialized to NULL * and if specified on the command line it is set. * Therefore, we are safe not setting it to anything */ retcode = pam_start("login",username, &conv, &pamh); if(retcode != PAM_SUCCESS) { fprintf(stderr, _("login: PAM Failure, aborting: %s\n"), pam_strerror(pamh, retcode)); syslog(LOG_ERR, _("Couldn't initialize PAM: %s"), pam_strerror(pamh, retcode)); exit(99); } /* hostname & tty are either set to NULL or their correct values, depending on how much we know */ retcode = pam_set_item(pamh, PAM_RHOST, hostname); PAM_FAIL_CHECK; retcode = pam_set_item(pamh, PAM_TTY, tty_name); PAM_FAIL_CHECK; /* * [email protected]: Provide a user prompt to PAM * so that the "login: "******"Password: "******"login: "******"\033(K"); fprintf(stderr,"\033(K"); #endif /* if fflag == 1, then the user has already been authenticated */ if (fflag && (getuid() == 0)) passwd_req = 0; else passwd_req = 1; if(passwd_req == 1) { int failcount=0; /* if we didn't get a user on the command line, set it to NULL */ pam_get_item(pamh, PAM_USER, (const void **) &username); if (!username) pam_set_item(pamh, PAM_USER, NULL); /* there may be better ways to deal with some of these conditions, but at least this way I don't think we'll be giving away information... */ /* Perhaps someday we can trust that all PAM modules will pay attention to failure count and get rid of MAX_LOGIN_TRIES? */ retcode = pam_authenticate(pamh, 0); while((failcount++ < PAM_MAX_LOGIN_TRIES) && ((retcode == PAM_AUTH_ERR) || (retcode == PAM_USER_UNKNOWN) || (retcode == PAM_CRED_INSUFFICIENT) || (retcode == PAM_AUTHINFO_UNAVAIL))) { pam_get_item(pamh, PAM_USER, (const void **) &username); syslog(LOG_NOTICE,_("FAILED LOGIN %d FROM %s FOR %s, %s"), failcount, hostname, username, pam_strerror(pamh, retcode)); logbtmp(tty_name, username, hostname); fprintf(stderr,_("Login incorrect\n\n")); pam_set_item(pamh,PAM_USER,NULL); retcode = pam_authenticate(pamh, 0); } if (retcode != PAM_SUCCESS) { pam_get_item(pamh, PAM_USER, (const void **) &username); if (retcode == PAM_MAXTRIES) syslog(LOG_NOTICE,_("TOO MANY LOGIN TRIES (%d) FROM %s FOR " "%s, %s"), failcount, hostname, username, pam_strerror(pamh, retcode)); else syslog(LOG_NOTICE,_("FAILED LOGIN SESSION FROM %s FOR %s, %s"), hostname, username, pam_strerror(pamh, retcode)); logbtmp(tty_name, username, hostname); fprintf(stderr,_("\nLogin incorrect\n")); pam_end(pamh, retcode); exit(0); } retcode = pam_acct_mgmt(pamh, 0); if(retcode == PAM_NEW_AUTHTOK_REQD) { retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); } PAM_FAIL_CHECK; } /* * Grab the user information out of the password file for future usage * First get the username that we are actually using, though. */ retcode = pam_get_item(pamh, PAM_USER, (const void **) &username); PAM_FAIL_CHECK; if (!username || !*username) { fprintf(stderr, _("\nSession setup problem, abort.\n")); syslog(LOG_ERR, _("NULL user name in %s:%d. Abort."), __FUNCTION__, __LINE__); pam_end(pamh, PAM_SYSTEM_ERR); exit(1); } if (!(pwd = getpwnam(username))) { fprintf(stderr, _("\nSession setup problem, abort.\n")); syslog(LOG_ERR, _("Invalid user name \"%s\" in %s:%d. Abort."), username, __FUNCTION__, __LINE__); pam_end(pamh, PAM_SYSTEM_ERR); exit(1); } /* * Create a copy of the pwd struct - otherwise it may get * clobbered by PAM */ memcpy(&pwdcopy, pwd, sizeof(*pwd)); pwd = &pwdcopy; pwd->pw_name = strdup(pwd->pw_name); pwd->pw_passwd = strdup(pwd->pw_passwd); pwd->pw_gecos = strdup(pwd->pw_gecos); pwd->pw_dir = strdup(pwd->pw_dir); pwd->pw_shell = strdup(pwd->pw_shell); if (!pwd->pw_name || !pwd->pw_passwd || !pwd->pw_gecos || !pwd->pw_dir || !pwd->pw_shell) { fprintf(stderr, _("login: Out of memory\n")); syslog(LOG_ERR, "Out of memory"); pam_end(pamh, PAM_SYSTEM_ERR); exit(1); } username = pwd->pw_name; /* * Initialize the supplementary group list. * This should be done before pam_setcred because * the PAM modules might add groups during pam_setcred. */ if (initgroups(username, pwd->pw_gid) < 0) { syslog(LOG_ERR, "initgroups: %m"); fprintf(stderr, _("\nSession setup problem, abort.\n")); pam_end(pamh, PAM_SYSTEM_ERR); exit(1); } retcode = pam_open_session(pamh, 0); PAM_FAIL_CHECK; retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED); PAM_FAIL_CHECK; #else /* ! HAVE_SECURITY_PAM_MISC_H */ for (cnt = 0;; ask = 1) { if (ask) { fflag = 0; getloginname(); } /* Dirty patch to fix a gigantic security hole when using yellow pages. This problem should be solved by the libraries, and not by programs, but this must be fixed urgently! If the first char of the username is '+', we avoid login success. Feb 95 <*****@*****.**> */ if (username[0] == '+') { puts(_("Illegal username")); badlogin(username); sleepexit(1); } /* (void)strcpy(tbuf, username); why was this here? */ if ((pwd = getpwnam(username))) { # ifdef SHADOW_PWD struct spwd *sp; if ((sp = getspnam(username))) pwd->pw_passwd = sp->sp_pwdp; # endif salt = pwd->pw_passwd; } else salt = "xx"; if (pwd) { initgroups(username, pwd->pw_gid); checktty(username, tty_name, pwd); /* in checktty.c */ } /* if user not super-user, check for disabled logins */ if (pwd == NULL || pwd->pw_uid) checknologin(); /* * Disallow automatic login to root; if not invoked by * root, disallow if the uid's differ. */ if (fflag && pwd) { int uid = getuid(); passwd_req = pwd->pw_uid == 0 || (uid && uid != pwd->pw_uid); } /* * If trying to log in as root, but with insecure terminal, * refuse the login attempt. */ if (pwd && pwd->pw_uid == 0 && !rootterm(tty_name)) { fprintf(stderr, _("%s login refused on this terminal.\n"), pwd->pw_name); if (hostname) syslog(LOG_NOTICE, _("LOGIN %s REFUSED FROM %s ON TTY %s"), pwd->pw_name, hostname, tty_name); else syslog(LOG_NOTICE, _("LOGIN %s REFUSED ON TTY %s"), pwd->pw_name, tty_name); continue; } /* * If no pre-authentication and a password exists * for this user, prompt for one and verify it. */ if (!passwd_req || (pwd && !*pwd->pw_passwd)) break; setpriority(PRIO_PROCESS, 0, -4); pp = getpass(_("Password: "******"CRYPTO", 6) == 0) { if (pwd && cryptocard()) break; } # endif /* CRYPTOCARD */ p = crypt(pp, salt); setpriority(PRIO_PROCESS, 0, 0); # ifdef KERBEROS /* * If not present in pw file, act as we normally would. * If we aren't Kerberos-authenticated, try the normal * pw file for a password. If that's ok, log the user * in without issueing any tickets. */ if (pwd && !krb_get_lrealm(realm,1)) { /* * get TGT for local realm; be careful about uid's * here for ticket file ownership */ setreuid(geteuid(),pwd->pw_uid); kerror = krb_get_pw_in_tkt(pwd->pw_name, "", realm, "krbtgt", realm, DEFAULT_TKT_LIFE, pp); setuid(0); if (kerror == INTK_OK) { memset(pp, 0, strlen(pp)); notickets = 0; /* user got ticket */ break; } } # endif /* KERBEROS */ memset(pp, 0, strlen(pp)); if (pwd && !strcmp(p, pwd->pw_passwd)) break; printf(_("Login incorrect\n")); badlogin(username); /* log ALL bad logins */ failures++; /* we allow 10 tries, but after 3 we start backing off */ if (++cnt > 3) { if (cnt >= 10) { sleepexit(1); } sleep((unsigned int)((cnt - 3) * 5)); } } #endif /* !HAVE_SECURITY_PAM_MISC_H */ /* committed to login -- turn off timeout */ alarm((unsigned int)0); endpwent(); /* This requires some explanation: As root we may not be able to read the directory of the user if it is on an NFS mounted filesystem. We temporarily set our effective uid to the user-uid making sure that we keep root privs. in the real uid. A portable solution would require a fork(), but we rely on Linux having the BSD setreuid() */ { char tmpstr[MAXPATHLEN]; uid_t ruid = getuid(); gid_t egid = getegid(); /* avoid snprintf - old systems do not have it, or worse, have a libc in which snprintf is the same as sprintf */ if (strlen(pwd->pw_dir) + sizeof(_PATH_HUSHLOGIN) + 2 > MAXPATHLEN) quietlog = 0; else { sprintf(tmpstr, "%s/%s", pwd->pw_dir, _PATH_HUSHLOGIN); setregid(-1, pwd->pw_gid); setreuid(0, pwd->pw_uid); quietlog = (access(tmpstr, R_OK) == 0); setuid(0); /* setreuid doesn't do it alone! */ setreuid(ruid, 0); setregid(-1, egid); } } /* for linux, write entries in utmp and wtmp */ { struct utmp ut; struct utmp *utp; utmpname(_PATH_UTMP); setutent(); /* Find pid in utmp. login sometimes overwrites the runlevel entry in /var/run/utmp, confusing sysvinit. I added a test for the entry type, and the problem was gone. (In a runlevel entry, st_pid is not really a pid but some number calculated from the previous and current runlevel). Michael Riepe <*****@*****.**> */ while ((utp = getutent())) if (utp->ut_pid == pid && utp->ut_type >= INIT_PROCESS && utp->ut_type <= DEAD_PROCESS) break; /* If we can't find a pre-existing entry by pid, try by line. BSD network daemons may rely on this. (anonymous) */ if (utp == NULL) { setutent(); ut.ut_type = LOGIN_PROCESS; strncpy(ut.ut_line, tty_name, sizeof(ut.ut_line)); utp = getutline(&ut); } if (utp) { memcpy(&ut, utp, sizeof(ut)); } else { /* some gettys/telnetds don't initialize utmp... */ memset(&ut, 0, sizeof(ut)); } if (ut.ut_id[0] == 0) strncpy(ut.ut_id, tty_number, sizeof(ut.ut_id)); strncpy(ut.ut_user, username, sizeof(ut.ut_user)); xstrncpy(ut.ut_line, tty_name, sizeof(ut.ut_line)); #ifdef _HAVE_UT_TV /* in <utmpbits.h> included by <utmp.h> */ gettimeofday(&ut.ut_tv, NULL); #else { time_t t; time(&t); ut.ut_time = t; /* ut_time is not always a time_t */ /* glibc2 #defines it as ut_tv.tv_sec */ } #endif ut.ut_type = USER_PROCESS; ut.ut_pid = pid; if (hostname) { xstrncpy(ut.ut_host, hostname, sizeof(ut.ut_host)); if (hostaddress[0]) memcpy(&ut.ut_addr, hostaddress, sizeof(ut.ut_addr)); } pututline(&ut); endutent(); #if HAVE_UPDWTMP updwtmp(_PATH_WTMP, &ut); #else #if 0 /* The O_APPEND open() flag should be enough to guarantee atomic writes at end of file. */ { int wtmp; if((wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) { write(wtmp, (char *)&ut, sizeof(ut)); close(wtmp); } } #else /* Probably all this locking below is just nonsense, and the short version is OK as well. */ { int lf, wtmp; if ((lf = open(_PATH_WTMPLOCK, O_CREAT|O_WRONLY, 0660)) >= 0) { flock(lf, LOCK_EX); if ((wtmp = open(_PATH_WTMP, O_APPEND|O_WRONLY)) >= 0) { write(wtmp, (char *)&ut, sizeof(ut)); close(wtmp); } flock(lf, LOCK_UN); close(lf); } } #endif #endif } dolastlog(quietlog); chown(ttyn, pwd->pw_uid, (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid); chmod(ttyn, TTY_MODE); #ifdef LOGIN_CHOWN_VCS /* if tty is one of the VC's then change owner and mode of the special /dev/vcs devices as well */ if (consoletty(0)) { chown(vcsn, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid)); chown(vcsan, pwd->pw_uid, (gr ? gr->gr_gid : pwd->pw_gid)); chmod(vcsn, TTY_MODE); chmod(vcsan, TTY_MODE); } #endif setgid(pwd->pw_gid); if (*pwd->pw_shell == '\0') pwd->pw_shell = _PATH_BSHELL; /* preserve TERM even without -p flag */ { char *ep; if(!((ep = getenv("TERM")) && (termenv = strdup(ep)))) termenv = "dumb"; } /* destroy environment unless user has requested preservation */ if (!pflag) { environ = (char**)malloc(sizeof(char*)); memset(environ, 0, sizeof(char*)); } setenv("HOME", pwd->pw_dir, 0); /* legal to override */ if(pwd->pw_uid) setenv("PATH", _PATH_DEFPATH, 1); else setenv("PATH", _PATH_DEFPATH_ROOT, 1); setenv("SHELL", pwd->pw_shell, 1); setenv("TERM", termenv, 1); /* mailx will give a funny error msg if you forget this one */ { char tmp[MAXPATHLEN]; /* avoid snprintf */ if (sizeof(_PATH_MAILDIR) + strlen(pwd->pw_name) + 1 < MAXPATHLEN) { sprintf(tmp, "%s/%s", _PATH_MAILDIR, pwd->pw_name); setenv("MAIL",tmp,0); } } /* LOGNAME is not documented in login(1) but HP-UX 6.5 does it. We'll not allow modifying it. */ setenv("LOGNAME", pwd->pw_name, 1); #ifdef HAVE_SECURITY_PAM_MISC_H { int i; char ** env = pam_getenvlist(pamh); if (env != NULL) { for (i=0; env[i]; i++) { putenv(env[i]); /* D(("env[%d] = %s", i,env[i])); */ } } } #endif setproctitle("login", username); if (!strncmp(tty_name, "ttyS", 4)) syslog(LOG_INFO, _("DIALUP AT %s BY %s"), tty_name, pwd->pw_name); /* allow tracking of good logins. -steve philp ([email protected]) */ if (pwd->pw_uid == 0) { if (hostname) syslog(LOG_NOTICE, _("ROOT LOGIN ON %s FROM %s"), tty_name, hostname); else syslog(LOG_NOTICE, _("ROOT LOGIN ON %s"), tty_name); } else { if (hostname) syslog(LOG_INFO, _("LOGIN ON %s BY %s FROM %s"), tty_name, pwd->pw_name, hostname); else syslog(LOG_INFO, _("LOGIN ON %s BY %s"), tty_name, pwd->pw_name); } if (!quietlog) { motd(); #ifdef LOGIN_STAT_MAIL /* * This turns out to be a bad idea: when the mail spool * is NFS mounted, and the NFS connection hangs, the * login hangs, even root cannot login. * Checking for mail should be done from the shell. */ { struct stat st; char *mail; mail = getenv("MAIL"); if (mail && stat(mail, &st) == 0 && st.st_size != 0) { if (st.st_mtime > st.st_atime) printf(_("You have new mail.\n")); else printf(_("You have mail.\n")); } } #endif } signal(SIGALRM, SIG_DFL); signal(SIGQUIT, SIG_DFL); signal(SIGTSTP, SIG_IGN); #ifdef HAVE_SECURITY_PAM_MISC_H /* * We must fork before setuid() because we need to call * pam_close_session() as root. */ childPid = fork(); if (childPid < 0) { int errsv = errno; /* error in fork() */ fprintf(stderr, _("login: failure forking: %s"), strerror(errsv)); PAM_END; exit(0); } if (childPid) { /* parent - wait for child to finish, then cleanup session */ signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTTOU, SIG_IGN); wait(NULL); PAM_END; exit(0); } /* child */ /* * Problem: if the user's shell is a shell like ash that doesnt do * setsid() or setpgrp(), then a ctrl-\, sending SIGQUIT to every * process in the pgrp, will kill us. */ /* start new session */ setsid(); /* make sure we have a controlling tty */ opentty(ttyn); openlog("login", LOG_ODELAY, LOG_AUTHPRIV); /* reopen */ /* * TIOCSCTTY: steal tty from other process group. */ if (ioctl(0, TIOCSCTTY, 1)) syslog(LOG_ERR, _("TIOCSCTTY failed: %m")); #endif signal(SIGINT, SIG_DFL); /* discard permissions last so can't get killed and drop core */ if(setuid(pwd->pw_uid) < 0 && pwd->pw_uid) { syslog(LOG_ALERT, _("setuid() failed")); exit(1); } /* wait until here to change directory! */ if (chdir(pwd->pw_dir) < 0) { printf(_("No directory %s!\n"), pwd->pw_dir); if (chdir("/")) exit(0); pwd->pw_dir = "/"; printf(_("Logging in with home = \"/\".\n")); } /* if the shell field has a space: treat it like a shell script */ if (strchr(pwd->pw_shell, ' ')) { buff = malloc(strlen(pwd->pw_shell) + 6); if (!buff) { fprintf(stderr, _("login: no memory for shell script.\n")); exit(0); } strcpy(buff, "exec "); strcat(buff, pwd->pw_shell); childArgv[childArgc++] = "/bin/sh"; childArgv[childArgc++] = "-sh"; childArgv[childArgc++] = "-c"; childArgv[childArgc++] = buff; } else { tbuf[0] = '-'; xstrncpy(tbuf + 1, ((p = rindex(pwd->pw_shell, '/')) ? p + 1 : pwd->pw_shell), sizeof(tbuf)-1); childArgv[childArgc++] = pwd->pw_shell; childArgv[childArgc++] = tbuf; } childArgv[childArgc++] = NULL; execvp(childArgv[0], childArgv + 1); errsv = errno; if (!strcmp(childArgv[0], "/bin/sh")) fprintf(stderr, _("login: couldn't exec shell script: %s.\n"), strerror(errsv)); else fprintf(stderr, _("login: no shell: %s.\n"), strerror(errsv)); exit(0); }
int seteuid(uid_t euid) { return (setreuid(-1, euid)); }
int main(int argc, char *argv[]) { int tdcount, tlimit, mlimit; char exename[1024], inputfile[1024]; struct rlimit r; if (argc < 6) { printf("Usage: [id] [probid] [input] [time limit] [memory limit]\n"); exit(RET_SE); } tlimit = atoi(argv[4]); mlimit = atoi(argv[5]); sprintf(exename, "./%s", argv[1]); strcpy(inputfile, argv[3]); if ((pid = fork()) == 0) { freopen("input.txt", "r", stdin); chdir("sandbox"); chroot("."); freopen("output.txt", "w", stdout); setregid(99, 99); setreuid(99, 99); ptrace(PTRACE_TRACEME, 0, NULL, NULL); execl(exename, exename, NULL); exit(0); } signal(SIGALRM, timer); alarm(1); int stat, tmpmem, sig; for (;;) { wait4(pid, &stat, 0, &rinfo); if (WIFEXITED(stat)) { puts("exited!\n"); break; } else if (WIFSTOPPED(stat)) { sig = WSTOPSIG(stat); if (sig == SIGTRAP) { if (checkSyscall() == RET_RF) { ptrace(PTRACE_KILL, pid, NULL, NULL); final_result(RET_RF); } } else if (sig == SIGUSR1) { } else printf("Stopped due to signal: %d\n", sig); } else if (WIFSIGNALED(stat)) { //Runtime Error printf("Runtime Error. Received signal: %d\n", WTERMSIG(stat)); final_result(RET_RE); break; } tmpmem = getMemory(); if (tmpmem > maxmem) maxmem = tmpmem; if (maxmem > mlimit) final_result(RET_MLE); if (getRuntime() > tlimit) { ptrace(PTRACE_KILL, pid, NULL, NULL); final_result(RET_TLE); } ptrace(PTRACE_SYSCALL, pid, NULL, NULL); } final_result(RET_AC); return 0; }
void xsetreuid(uid_t ruid, uid_t euid) { if (setreuid(ruid, euid) != 0) perror_msg_and_die("Can't set %cid %lu", 'u', (long)ruid); }
int main(int argc, char *argv[]) { chdir(BBSHOME); setuid(BBSUID); setgid(BBSGID); setreuid(BBSUID, BBSUID); setregid(BBSGID, BBSGID); #ifndef CYGWIN #undef time bbssettime(time(0)); sleep(1); #define time(x) bbstime(x) #endif setpublicshmreadonly(0); #ifndef CYGWIN setpublicshmreadonly(1); #endif init_bbslog(); if (argc > 1) { if (strcasecmp(argv[1], "killuser") == 0) { if (resolve_ucache() != 0) return -1; resolve_utmp(); return dokilluser(); } if (strcasecmp(argv[1], "giveup") == 0) { if (resolve_ucache() != 0) return -1; return doupdategiveupuser(); } if (strcasecmp(argv[1], "allboards") == 0) return dokillalldir(); if (strcasecmp(argv[1], "daemon") == 0) return miscd_dodaemon(argv[1], argv[2]); if (strcasecmp(argv[1], "killdir") == 0) return dokilldir(argv[2]); if (strcasecmp(argv[1], "flush") == 0) { if (resolve_ucache() != 0) return -1; resolve_boards(); flushdata(0); return 0; } if (strcasecmp(argv[1], "flush-u") == 0) { if (resolve_ucache() != 0) return -1; strcpy(specfname, argv[2]); specfname[511] = 0; flushdata(1); return 0; } return miscd_dodaemon(NULL, argv[1]); } printf("Usage : %s daemon: to run as a daemon (this is the most common use)\n", argv[0]); printf(" %s killuser: to kill old users\n", argv[0]); printf(" %s giveup: to unlock given-up users\n", argv[0]); printf(" %s killdir <BOARDNAME>: to delete old file in <BOARDNAME>\n", argv[0]); printf(" %s allboards: to delete old files in all boards\n", argv[0]); printf(" %s flush: to synchronize .PASSWDS and .BOARDS to disk\n", argv[0]); printf(" %s flush-u <FILENAME>: to write ucache in shm to <FILENAME>\n", argv[0]); printf("That's all, folks. See doc/README.SYSOP for more details\n"); return 0; }
int main ( int argc, char *argv[] ) { pwr_tStatus sts; int event; plc_sProcess *pp; uid_t ruid; struct passwd *pwd; /* struct rlimit rlim; int i; */ /* Set core dump file size limit to infinite */ /* rlim.rlim_cur = RLIM_INFINITY; rlim.rlim_max = RLIM_INFINITY; sts = setrlimit(RLIMIT_CORE, &rlim); printf("%d\n", sts); i = 1/0; printf("%d\n", i); */ pp = init_process(); qcom_WaitAnd(&sts, &pp->eventQ, &qcom_cQini, ini_mEvent_newPlcInit, qcom_cTmoEternal); init_plc(pp); create_threads(pp); init_threads(pp); /* Once threads has set their priority don't run as root */ #if 0 ruid = getuid(); if (ruid == 0) { pwd = getpwnam("pwrp"); if (pwd != NULL) { setreuid(pwd->pw_uid, pwd->pw_uid); } } else setreuid(ruid, ruid); #endif qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_newPlcInitDone); qcom_WaitAnd(&sts, &pp->eventQ, &qcom_cQini, ini_mEvent_newPlcStart, qcom_cTmoEternal); // proc_SetPriority(pp->PlcProcess->Prio); set_values(pp); start_threads(pp); run_threads(pp); time_Uptime(&sts, &pp->PlcProcess->StartTime, NULL); qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_newPlcStartDone); #if 0 /* Force the backup to take care initialized backup objects. */ bck_ForceBackup(NULL); #endif errh_SetStatus( PWR__SRUN); qcom_WaitOr(&sts, &pp->eventQ, &qcom_cQini, ini_mEvent_terminate | ini_mEvent_oldPlcStop, qcom_cTmoEternal, &event); switch ( event) { case ini_mEvent_terminate: errh_SetStatus( PWR__SRVTERM); stop_threads(pp); clean_all(pp); nmps_delete_lock( &sts); break; case ini_mEvent_oldPlcStop: errh_SetStatus( PWR__SRVTERM); time_Uptime(&sts, &pp->PlcProcess->StopTime, NULL); stop_threads(pp); save_values(pp); qcom_SignalOr(&sts, &qcom_cQini, ini_mEvent_oldPlcStopDone); #if defined OS_ELN sts = proc_SetPriority(31); #endif clean_all(pp); break; default: ; } exit(0); }
/* * setup(void) - performs all ONE TIME setup for this test. * Exit the test program on receipt of unexpected signals. * Create a temporary directory used to hold test directories created * and change the directory to it. * Verify that pid of process executing the test is root. * Create a test directory on temporary directory and set the ownership * of test directory to guest user and process, change mode permissions * to set group id bit on it. * Set the effective uid/gid of the process to that of guest user. */ void setup(void) { tst_require_root(NULL); /* Capture unexpected signals */ tst_sig(NOFORK, DEF_HANDLER, cleanup); TEST_PAUSE; /* Make a temp dir and cd to it */ tst_tmpdir(); /* fix permissions on the tmpdir */ if (chmod(".", 0711) != 0) { tst_brkm(TBROK, cleanup, "chmod() failed"); } /* Save the real user id of the current test process */ save_myuid = getuid(); /* Save the process id of the current test process */ mypid = getpid(); /* Get the node name to be created in the test */ sprintf(node_name, TNODE, mypid); /* Get the uid/gid of ltpuser user */ if ((user1 = getpwnam(LTPUSER)) == NULL) { tst_brkm(TBROK, cleanup, "%s not in /etc/passwd", LTPUSER); } user1_uid = user1->pw_uid; group1_gid = user1->pw_gid; /* Get the effective group id of the test process */ group2_gid = getegid(); /* * Create a test directory under temporary directory with the * specified mode permissions, with uid/gid set to that of guest * user and the test process. */ if (mkdir(DIR_TEMP, MODE_RWX) < 0) { tst_brkm(TBROK, cleanup, "mkdir(2) of %s failed", DIR_TEMP); } if (chown(DIR_TEMP, user1_uid, group2_gid) < 0) { tst_brkm(TBROK, cleanup, "chown(2) of %s failed", DIR_TEMP); } if (chmod(DIR_TEMP, MODE_SGID) < 0) { tst_brkm(TBROK, cleanup, "chmod(2) of %s failed", DIR_TEMP); } /* * Verify that test directory created with expected permission modes * and ownerships. */ if (stat(DIR_TEMP, &buf) < 0) { tst_brkm(TBROK, cleanup, "stat(2) of %s failed", DIR_TEMP); } /* Verify modes of test directory */ if (!(buf.st_mode & S_ISGID)) { tst_brkm(TBROK, cleanup, "%s: Incorrect modes, setgid bit not set", DIR_TEMP); } /* Verify group ID of test directory */ if (buf.st_gid != group2_gid) { tst_brkm(TBROK, cleanup, "%s: Incorrect group", DIR_TEMP); } /* * Set the effective group id and user id of the test process * to that of guest user (nobody) */ if (setgid(group1_gid) < 0) { tst_brkm(TBROK, cleanup, "Unable to set process gid to that of ltp user"); } if (setreuid(-1, user1_uid) < 0) { tst_brkm(TBROK, cleanup, "Unable to set process uid to that of ltp user"); } /* Save the real group ID of the current process */ mygid = getgid(); /* Change directory to DIR_TEMP */ if (chdir(DIR_TEMP) < 0) { tst_brkm(TBROK, cleanup, "Unable to change to %s directory", DIR_TEMP); } }
int main(int argc, char * const argv[]) { int ch; uid_t uid = 0; gid_t gid = 0; gid_t gidset[1]; const char *cwd = NULL; const char *errstr; while ((ch = getopt(argc, argv, "+u:g:c:h")) != -1) { switch (ch) { case 'h': usage(); exit(EXIT_SUCCESS); break; case 'c': cwd = optarg; break; case 'u': uid = strtonum(optarg, 0, 65535, &errstr); if (errstr != NULL) { fprintf(stderr, "Provided UID `%s' is %s\n", optarg, errstr); usage(); exit(EXIT_FAILURE); } break; case 'g': gid = strtonum(optarg, 0, 65535, &errstr); gidset[0] = gid; if (errstr != NULL) { fprintf(stderr, "Provided GID `%s' is %s\n", optarg, errstr); usage(); exit(EXIT_FAILURE); } break; default: usage(); exit(EXIT_FAILURE); } } if (optind >= argc) { fprintf(stderr, "Missing command to execute\n"); usage(); exit(EXIT_FAILURE); } if (setregid(gid, gid) == -1 || setgroups(1, gidset) == -1 || setreuid(uid, uid) == -1) { fprintf(stderr, "unable to change UID %d/GID %d: %m\n", uid, gid); exit(EXIT_FAILURE); } if (cwd != NULL && chdir(cwd) == -1) { fprintf(stderr, "unable to change to `%s': %m\n", cwd); /* But continue */ } if (execvp(argv[optind], &argv[optind]) == -1) { fprintf(stderr, "unable to execute `%s': %m\n", argv[optind]); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
/** * Drop privileges. * */ ods_status privdrop(const char *username, const char *groupname, const char *newroot, uid_t* puid, gid_t* pgid) { int status; uid_t uid, olduid; gid_t gid; long ngroups_max; gid_t *final_groups; int final_group_len = -1; /* Save effective uid/gid */ uid = olduid = geteuid(); gid = getegid(); /* Check if we're going to drop uid */ if (username) { uid = privuid(username); if (uid == (uid_t)-1) { ods_log_error("[%s] user %s does not exist", privdrop_str, username); return ODS_STATUS_PRIVDROP_ERR; } } /* Check if we're going to drop gid */ if (groupname) { gid = privgid(groupname); if (gid == (gid_t)-1) { ods_log_error("[%s] group %s does not exist", privdrop_str, groupname); return ODS_STATUS_PRIVDROP_ERR; } } /* Change root if requested */ if (newroot) { #ifdef HAVE_CHROOT status = chroot(newroot); if (status != 0 || chdir("/") != 0) { ods_log_error("[%s] chroot to %s failed: %.100s", privdrop_str, newroot, strerror(errno)); return ODS_STATUS_CHROOT_ERR; } #else ods_log_error("[%s] chroot to %s failed: !HAVE_CHROOT", privdrop_str, newroot); return ODS_STATUS_CHROOT_ERR; #endif /* HAVE_CHROOT */ } /* Do additional groups first */ if (username != NULL && !olduid) { #ifdef HAVE_INITGROUPS if (initgroups(username, gid) < 0) { ods_log_error("[%s] initgroups failed: %s: %.100s", privdrop_str, username, strerror(errno)); return ODS_STATUS_PRIVDROP_ERR; } #else ods_log_error("initgroups failed: %s: !HAVE_INITGROUPS", username); return ODS_STATUS_PRIVDROP_ERR; #endif /* HAVE_INITGROUPS */ ngroups_max = sysconf(_SC_NGROUPS_MAX) + 1; final_groups = (gid_t *)malloc(ngroups_max *sizeof(gid_t)); if (!final_groups) { return ODS_STATUS_MALLOC_ERR; } #if defined(HAVE_GETGROUPS) && defined(HAVE_SETGROUPS) final_group_len = getgroups(ngroups_max, final_groups); /* If we are root then drop all groups other than the final one */ if (!olduid) { setgroups(final_group_len, final_groups); } #endif /* defined(HAVE_GETGROUPS) && defined(HAVE_SETGROUPS) */ free((void*)final_groups); } else { /* If we are root then drop all groups other than the final one */ #if defined(HAVE_SETGROUPS) if (!olduid) setgroups(1, &(gid)); #endif /* defined(HAVE_SETGROUPS) */ } /* Drop gid? */ if (groupname) { #if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID) status = setresgid(gid, gid, gid); #elif defined(HAVE_SETREGID) && !defined(BROKEN_SETREGID) status = setregid(gid, gid); #else # ifndef SETEUID_BREAKS_SETUID status = setegid(gid); if (status != 0) { ods_log_error("[%s] setegid() for %s (%lu) failed: %s", privdrop_str, groupname, (unsigned long) gid, strerror(errno)); return ODS_STATUS_PRIVDROP_ERR; } # endif /* SETEUID_BREAKS_SETUID */ status = setgid(gid); #endif if (status != 0) { ods_log_error("[%s] setgid() for %s (%lu) failed: %s", privdrop_str, groupname, (unsigned long) gid, strerror(errno)); return ODS_STATUS_PRIVDROP_ERR; } else { ods_log_debug("[%s] group set to %s (%lu)", privdrop_str, groupname, (unsigned long) gid); } } /* Drop uid? */ if (username) { /* Set the user to drop to if specified; else just set the uid as the real one */ #if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID) status = setresuid(uid, uid, uid); #elif defined(HAVE_SETREUID) && !defined(BROKEN_SETREUID) status = setreuid(uid, uid); #else # ifndef SETEUID_BREAKS_SETUID status = seteuid(uid); if (status != 0) { ods_log_error("[%s] seteuid() for %s (%lu) failed: %s", privdrop_str, username, (unsigned long) uid, strerror(errno)); return ODS_STATUS_PRIVDROP_ERR; } # endif /* SETEUID_BREAKS_SETUID */ status = setuid(uid); #endif if (status != 0) { ods_log_error("[%s] setuid() for %s (%lu) failed: %s", privdrop_str, username, (unsigned long) uid, strerror(errno)); return ODS_STATUS_PRIVDROP_ERR; } else { ods_log_debug("[%s] user set to %s (%lu)", privdrop_str, username, (unsigned long) uid); } } *puid = uid; *pgid = gid; return ODS_STATUS_OK; }
void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, int up) { //************************ // verify sandbox //************************ char *comm = pid_proc_comm(pid); if (!comm) { fprintf(stderr, "Error: cannot find sandbox\n"); exit(1); } // remove \n and check for firejail sandbox char *ptr = strchr(comm, '\n'); if (ptr) *ptr = '\0'; if (strcmp(comm, "firejail") != 0) { fprintf(stderr, "Error: cannot find sandbox\n"); exit(1); } free(comm); // check network namespace char *cmd = pid_proc_cmdline(pid); if (!cmd || strstr(cmd, "--net") == NULL) { fprintf(stderr, "Error: the sandbox doesn't use a new network namespace\n"); exit(1); } free(cmd); //************************ // join the network namespace //************************ pid_t child; if (find_child(pid, &child) == -1) { fprintf(stderr, "Error: cannot join the network namespace\n"); exit(1); } if (join_namespace(child, "net")) { fprintf(stderr, "Error: cannot join the network namespace\n"); exit(1); } // set shm file if (strcmp(command, "set") == 0) bandwidth_shm_set(pid, dev, down, up); else if (strcmp(command, "clear") == 0) bandwidth_shm_remove(pid, dev); //************************ // build command //************************ char *devname = NULL; if (dev) { // read shm network map file char *fname; if (asprintf(&fname, "/dev/shm/firejail/%d-netmap", (int) pid) == -1) errExit("asprintf"); FILE *fp = fopen(fname, "r"); if (!fp) { fprintf(stderr, "Error: cannot read netowk map filel %s\n", fname); exit(1); } char buf[1024]; int len = strlen(dev); while (fgets(buf, 1024, fp)) { // remove '\n' char *ptr = strchr(buf, '\n'); if (ptr) *ptr = '\0'; if (*buf == '\0') break; if (strncmp(buf, dev, len) == 0 && buf[len] == ':') { devname = strdup(buf + len + 1); if (!devname) errExit("strdup"); // check device in namespace if (if_nametoindex(devname) == 0) { fprintf(stderr, "Error: cannot find network device %s\n", devname); exit(1); } break; } } free(fname); fclose(fp); } // build fshaper.sh command cmd = NULL; if (devname) { if (strcmp(command, "set") == 0) { if (asprintf(&cmd, "%s/lib/firejail/fshaper.sh --%s %s %d %d", PREFIX, command, devname, down, up) == -1) errExit("asprintf"); } else { if (asprintf(&cmd, "%s/lib/firejail/fshaper.sh --%s %s", PREFIX, command, devname) == -1) errExit("asprintf"); } } else { if (asprintf(&cmd, "%s/lib/firejail/fshaper.sh --%s", PREFIX, command) == -1) errExit("asprintf"); } assert(cmd); // wipe out environment variables environ = NULL; //************************ // build command //************************ // elevate privileges if (setreuid(0, 0)) errExit("setreuid"); if (setregid(0, 0)) errExit("setregid"); char *arg[4]; arg[0] = "/bin/bash"; arg[1] = "-c"; arg[2] = cmd; arg[3] = NULL; execvp("/bin/bash", arg); // it will never get here exit(0); }
/* ================= Sys_GetGameAPI Loads the game dll ================= */ void *Sys_GetGameAPI (void *parms) { void *(*GetGameAPI) (void *); char name[MAX_OSPATH]; char curpath[MAX_OSPATH]; char *path; // Knightmare- changed game library name for better cohabitation #ifdef __i386__ const char *gamename = "kmq2gamei386.so"; #elif defined __alpha__ const char *gamename = "kmq2gameaxp.so"; #elif defined __x86_64__ const char *gamename = "kmq2gamex86_64.so"; #elif defined __powerpc__ const char *gamename = "kmq2gameppc.so"; #elif defined __sparc__ const char *gamename = "kmq2gamesparc.so"; #elif defined __arm__ const char *gamename = "kmq2gamearm.so"; #else #error Unknown arch #endif setreuid(getuid(), getuid()); setegid(getgid()); if (game_library) Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame"); getcwd(curpath, sizeof(curpath)); Com_Printf("------- Loading %s -------\n", gamename); // now run through the search paths path = NULL; /* while (1) { path = FS_NextPath (path); if (!path) return NULL; // couldn't find one anywhere sprintf (name, "%s/%s/%s", curpath, path, gamename); game_library = dlopen (name, RTLD_LAZY ); if (game_library) { Com_Printf ("LoadLibrary (%s)\n",name); break; } } if (!game_library)*/ { sprintf (name, "%s/%s", curpath, gamename); game_library = dlopen (name, RTLD_LAZY ); if (game_library) { Com_Printf ("LoadLibrary (%s)\n",name); } } GetGameAPI = (void *)dlsym (game_library, "GetGameAPI"); if (!GetGameAPI) { Sys_UnloadGame (); return NULL; } return GetGameAPI (parms); }
static void swapUserAndEffectiveUser() { (void) setreuid (geteuid(), getuid()); (void) setregid (getegid(), getgid()); }
/* Switch to the given UID/GID */ int mu_switch_to_privs (uid_t uid, gid_t gid, mu_list_t retain_groups) { int rc = 0; gid_t *emptygidset; size_t size = 1, j = 1; mu_iterator_t itr; if (uid == 0) return 0; /* Create a list of supplementary groups */ mu_list_count (retain_groups, &size); size++; emptygidset = xmalloc (size * sizeof emptygidset[0]); emptygidset[0] = gid ? gid : getegid (); if (mu_list_get_iterator (retain_groups, &itr) == 0) { for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) mu_iterator_current (itr, (void **)(emptygidset + j++)); mu_iterator_destroy (&itr); } /* Reset group permissions */ if (geteuid () == 0 && setgroups (j, emptygidset)) { mu_error(_("setgroups(1, %lu) failed: %s"), (unsigned long) emptygidset[0], mu_strerror (errno)); rc = 1; } free (emptygidset); /* Switch to the user's gid. On some OSes the effective gid must be reset first */ #if defined(HAVE_SETEGID) if ((rc = setegid (gid)) < 0) mu_error (_("setegid(%lu) failed: %s"), (unsigned long) gid, mu_strerror (errno)); #elif defined(HAVE_SETREGID) if ((rc = setregid (gid, gid)) < 0) mu_error (_("setregid(%lu,%lu) failed: %s"), (unsigned long) gid, (unsigned long) gid, mu_strerror (errno)); #elif defined(HAVE_SETRESGID) if ((rc = setresgid (gid, gid, gid)) < 0) mu_error (_("setresgid(%lu,%lu,%lu) failed: %s"), (unsigned long) gid, (unsigned long) gid, (unsigned long) gid, mu_strerror (errno)); #endif if (rc == 0 && gid != 0) { if ((rc = setgid (gid)) < 0 && getegid () != gid) mu_error (_("setgid(%lu) failed: %s"), (unsigned long) gid, mu_strerror (errno)); if (rc == 0 && getegid () != gid) { mu_error (_("Cannot set effective gid to %lu"), (unsigned long) gid); rc = 1; } } /* Now reset uid */ if (rc == 0 && uid != 0) { uid_t euid; if (setuid (uid) || geteuid () != uid || (getuid () != uid && (geteuid () == 0 || getuid () == 0))) { #if defined(HAVE_SETREUID) if (geteuid () != uid) { if (setreuid (uid, -1) < 0) { mu_error (_("setreuid(%lu,-1) failed: %s"), (unsigned long) uid, mu_strerror (errno)); rc = 1; } if (setuid (uid) < 0) { mu_error (_("second setuid(%lu) failed: %s"), (unsigned long) uid, mu_strerror (errno)); rc = 1; } } else #endif { mu_error (_("setuid(%lu) failed: %s"), (unsigned long) uid, mu_strerror (errno)); rc = 1; } } euid = geteuid (); if (uid != 0 && setuid (0) == 0) { mu_error (_("seteuid(0) succeeded when it should not")); rc = 1; } else if (uid != euid && setuid (euid) == 0) { mu_error (_("Cannot drop non-root setuid privileges")); rc = 1; } } return rc; }
/* * test_rwflag(int i, int cnt) * Validate the mount system call for rwflags. */ int test_rwflag(int i, int cnt) { int ret, fd, pid, status; char nobody_uid[] = "nobody"; time_t atime; struct passwd *ltpuser; struct stat file_stat; char readbuf[20]; switch (i) { case 0: /* Validate MS_RDONLY flag of mount call */ snprintf(file, PATH_MAX, "%stmp", path_name); fd = open(file, O_CREAT | O_RDWR, S_IRWXU); if (fd == -1) { if (errno == EROFS) { return 0; } else { tst_resm(TWARN | TERRNO, "open didn't fail with EROFS"); return 1; } } close(fd); return 1; case 1: /* Validate MS_NODEV flag of mount call */ snprintf(file, PATH_MAX, "%smynod_%d_%d", path_name, getpid(), cnt); if (mknod(file, S_IFBLK | 0777, 0) == 0) { fd = open(file, O_RDWR, S_IRWXU); if (fd == -1) { if (errno == EACCES) { return 0; } else { tst_resm(TWARN | TERRNO, "open didn't fail with EACCES"); return 1; } } close(fd); } else { tst_resm(TWARN | TERRNO, "mknod(2) failed to create %s", file); return 1; } return 1; case 2: /* Validate MS_NOEXEC flag of mount call */ snprintf(file, PATH_MAX, "%stmp1", path_name); fd = open(file, O_CREAT | O_RDWR, S_IRWXU); if (fd == -1) { tst_resm(TWARN | TERRNO, "opening %s failed", file); } else { close(fd); ret = execlp(file, basename(file), NULL); if ((ret == -1) && (errno == EACCES)) return 0; } return 1; case 3: /* * Validate MS_SYNCHRONOUS flag of mount call. * Copy some data into data buffer. */ strcpy(write_buffer, "abcdefghijklmnopqrstuvwxyz"); /* Creat a temporary file under above directory */ snprintf(file, PATH_MAX, "%s%s", path_name, TEMP_FILE); fildes = open(file, O_RDWR | O_CREAT, FILE_MODE); if (fildes == -1) { tst_resm(TWARN | TERRNO, "open(%s, O_RDWR|O_CREAT, %#o) failed", file, FILE_MODE); return 1; } /* Write the buffer data into file */ if (write(fildes, write_buffer, strlen(write_buffer)) != strlen(write_buffer)) { tst_resm(TWARN | TERRNO, "writing to %s failed", file); close(fildes); return 1; } /* Set the file ptr to b'nning of file */ if (lseek(fildes, 0, SEEK_SET) < 0) { tst_resm(TWARN, "lseek() failed on %s, error=" " %d", file, errno); close(fildes); return 1; } /* Read the contents of file */ if (read(fildes, read_buffer, sizeof(read_buffer)) > 0) { if (strcmp(read_buffer, write_buffer)) { tst_resm(TWARN, "Data read from %s and written " "mismatch", file); close(fildes); return 1; } else { close(fildes); return 0; } } else { tst_resm(TWARN | TERRNO, "read() Fails on %s", file); close(fildes); return 1; } case 4: /* Validate MS_REMOUNT flag of mount call */ TEST(mount(device, mntpoint, fs_type, MS_REMOUNT, NULL)); if (TEST_RETURN != 0) { tst_resm(TWARN | TTERRNO, "mount(2) failed to remount"); return 1; } else { snprintf(file, PATH_MAX, "%stmp2", path_name); fd = open(file, O_CREAT | O_RDWR, S_IRWXU); if (fd == -1) { tst_resm(TWARN, "open(%s) on readonly " "filesystem passed", file); return 1; } else { close(fd); return 0; } } case 5: /* Validate MS_NOSUID flag of mount call */ snprintf(file, PATH_MAX, "%ssetuid_test", path_name); SAFE_FILE_PRINTF(cleanup, file, "TEST FILE"); if (stat(file, &file_stat) < 0) tst_brkm(TBROK, cleanup, "stat for setuid_test failed"); if (file_stat.st_mode != SUID_MODE && chmod(file, SUID_MODE) < 0) tst_brkm(TBROK, cleanup, "setuid for setuid_test failed"); pid = fork(); switch (pid) { case -1: tst_resm(TBROK | TERRNO, "fork failed"); return 1; case 0: ltpuser = getpwnam(nobody_uid); if (setreuid(ltpuser->pw_uid, ltpuser->pw_uid) == -1) tst_resm(TWARN | TERRNO, "seteuid() failed to change euid to %d", ltpuser->pw_uid); execlp(file, basename(file), NULL); exit(1); default: waitpid(pid, &status, 0); if (WIFEXITED(status)) { /* reset the setup_uid */ if (status) return 0; else return 1; } } case 6: /* Validate MS_NOATIME flag of mount call */ snprintf(file, PATH_MAX, "%satime", path_name); fd = open(file, O_CREAT | O_RDWR, S_IRWXU); if (fd == -1) { tst_resm(TWARN | TERRNO, "opening %s failed", file); return 1; } if (write(fd, "TEST_MS_NOATIME", 15) != 15) { tst_resm(TWARN | TERRNO, "write %s failed", file); return 1; } if (fstat(fd, &file_stat) == -1) { tst_resm(TWARN | TERRNO, "stat %s failed #1", file); return 1; } atime = file_stat.st_atime; sleep(1); if (read(fd, readbuf, sizeof(readbuf)) == -1) { tst_resm(TWARN | TERRNO, "read %s failed", file); return 1; } if (fstat(fd, &file_stat) == -1) { tst_resm(TWARN | TERRNO, "stat %s failed #2", file); return 1; } close(fd); if (file_stat.st_atime != atime) { tst_resm(TWARN, "access time is updated"); return 1; } return 0; } return 0; }
int main(int ac, char **av) { int lc; char *msg; /* message returned from parse_opts */ /* parse standard options */ if ((msg = parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *)NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); tst_exit(); /*NOTREACHED*/} /* Perform global setup for test */ setup(); /* check looping state if -i option is given */ for (lc = 0; TEST_LOOPING(lc); lc++) { int i; /* reset Tst_count in case we are looping */ Tst_count = 0; for (i = 0; i < TST_TOTAL; i++) { /* Set the real or effective user id */ TEST(setreuid(*test_data[i].real_uid, *test_data[i].eff_uid)); if (TEST_RETURN == *test_data[i].exp_ret) { if (TEST_RETURN == neg_one) { if (TEST_ERRNO != EPERM) { tst_resm(TFAIL, "setreuid(%d, %d) " "did not set errno " "value as expected.", *test_data[i].real_uid, *test_data[i].eff_uid); continue; } tst_resm(TPASS, "setreuid(%d, %d) " "failed as expected.", *test_data[i].real_uid, *test_data[i].eff_uid); } else { tst_resm(TPASS, "setreuid(%d, %d) " "succeeded as expected.", *test_data[i].real_uid, *test_data[i].eff_uid); } } else { tst_resm(TFAIL, "setreuid(%d, %d) " "did not return as expected.", *test_data[i].real_uid, *test_data[i].eff_uid); } if (TEST_RETURN == -1) { TEST_ERROR_LOG(TEST_ERRNO); } /* * Perform functional verification if test * executed without (-f) option. */ if (STD_FUNCTIONAL_TEST) { uid_verify(test_data[i].exp_real_usr, test_data[i].exp_eff_usr, test_data[i].test_msg); } } } cleanup(); /*NOTREACHED*/ return 0; }
void ppp_start(struct device_list *entry) { int pgrpid; /* Run pppd directly here and set up to wait for the iface */ entry->status = 1; entry->link_pid = fork(); if (entry->link_pid < 0) { syslog(LOG_ERR, "failed to fork pppd: %m"); exit(EXIT_FAILURE); } #define ADD_ARG(arg) { argv[i] = arg; argv_len += strlen(argv[i++]) + 1; } if (entry->link_pid == 0) { char **argv = (char **)malloc(sizeof(char *)*(pppd_argc+12)); int argv_len = 0; char buf[24], tmpbuf[50], *argv_buf, connect[70]; int i = 0, j; ADD_ARG(path_pppd); ADD_ARG(entry->device); ADD_ARG("-defaultroute"); ADD_ARG("-detach"); if (modem){ ADD_ARG("modem"); ADD_ARG("connect"); sprintf(connect, // should add ABORT 'BLACKLISTED' here // pppd dies when it is set "/usr/sbin/chat -v ABORT 'BUSY' ABORT " "'NO CARRIER' '' ATZ OK ATDT%s CONNECT", iptotel((char *)inet_ntoa(*entry->raddr))); ADD_ARG(connect); } else{ ADD_ARG("local"); } ADD_ARG("115200"); sprintf(buf, "%s:", inet_ntoa(*entry->laddr)); sprintf(tmpbuf, "%s%s", buf, inet_ntoa(*entry->raddr)); ADD_ARG(tmpbuf); // if (crtscts) ADD_ARG("crtscts"); // ADD_ARG("mtu"); // sprintf(buf,"%d",mtu); // ADD_ARG(strdup(buf)); // ADD_ARG("mru"); // sprintf(buf,"%d",mru); // ADD_ARG(strdup(buf)); // if (netmask) { // ADD_ARG("netmask"); // ADD_ARG(netmask); // } for (j = 0; j < pppd_argc; j++) { ADD_ARG(pppd_argv[j]); } argv[i++] = 0; if ((argv_buf = (char *)malloc(argv_len + 1))) { argv_len = i - 1; *argv_buf = '\0'; for (i = 0; i < argv_len; i++) { strcat(argv_buf, argv[i]); strcat(argv_buf, " "); } syslog(LOG_DEBUG, "Running pppd: %s", argv_buf); } /* make sure pppd is the session leader and has the controlling * terminal so it gets the SIGHUP's */ pgrpid = setsid(); ioctl(modem_fd, TIOCSCTTY, 1); tcsetpgrp(modem_fd, pgrpid); setreuid(getuid(), getuid()); setregid(getgid(), getgid()); if (modem_fd != 0) dup2(modem_fd, 0); else fcntl(modem_fd, F_SETFD, 0); dup2(0, 1); execv(path_pppd,argv); syslog(LOG_ERR, "could not exec %s: %m",path_pppd); _exit(99); /* NOTREACHED */ } syslog(LOG_INFO,"Running pppd (pid = %d).",entry->link_pid); }
int setruid(uid_t ruid) { return (setreuid(ruid, -1)); }