static void set_color_select(struct video *v, u_char byte) { if(byte != v->data.cga.color_select) { v->vga.regs[VGA_ATTR_REGS+0x11] = byte & 15; if(byte & 0x20) { /* Cyan, Magenta & White. */ v->vga.regs[VGA_ATTR_REGS+0] = 0x00; v->vga.regs[VGA_ATTR_REGS+1] = 0x03; v->vga.regs[VGA_ATTR_REGS+2] = 0x05; v->vga.regs[VGA_ATTR_REGS+3] = 0x07; } else { /* Green, Red & Yellow. */ v->vga.regs[VGA_ATTR_REGS+0] = 0x00; v->vga.regs[VGA_ATTR_REGS+1] = 0x02; v->vga.regs[VGA_ATTR_REGS+2] = 0x04; v->vga.regs[VGA_ATTR_REGS+3] = 0x0e; } /* Need to do background intensity bit as well. */ v->data.cga.color_select = byte; if(v->in_view) { forbid(); video_module.vga_load_regs(&v->vga); permit(); } } }
/* Suspend the current task immediately, note that this *may not* be called from an interrupt handler. */ void suspend_current_task(void) { forbid(); suspend_task(current_task); schedule(); permit(); }
static inline void map_cga_buffer(struct video *v, bool phys_buf) { int i; DB(("map_cga_buffer: v=%p phys_buf=%#d\n", v, phys_buf)); forbid(); for(i = 0; i < 4; i++) { kernel->set_pte(v->task->page_dir, CGA_VIDEO_MEM + (i * PAGE_SIZE), (phys_buf ? (CGA_VIDEO_MEM + (i * PAGE_SIZE)) : TO_PHYSICAL(v->data.cga.video_buffer[i])) | PTE_USER | PTE_READ_WRITE | PTE_PRESENT); } permit(); }
/* Allocate memory from the heap. */ void * malloc(size_t size) { void *result; int log, block, blocks, i, lastblocks, start; struct list *next; forbid(); if ((!initialized && !initialize()) || (size == 0)) { permit(); return NULL; } if (size < sizeof (struct list)) size = sizeof (struct list); /* Determine the allocation policy based on the request size. */ if (size <= BLOCKSIZE / 2) { /* Small allocation to receive a fragment of a block. Determine the logarithm to base two of the fragment size. */ --size; for (log = 1; (size >>= 1) != 0; ++log) ; /* Look in the fragment lists for a free fragment of the desired size. */ if ((next = _fraghead[log].next) != 0) { /* There are free fragments of this size. Pop a fragment out of the fragment list and return it. Update the block's nfree and first counters. */ result = next; next->prev->next = next->next; if (next->next) next->next->prev = next->prev; block = BLOCK(result); if (--_heapinfo[block].busy.info.frag.nfree) _heapinfo[block].busy.info.frag.first = (unsigned int) ((char *) next->next - (char *) NULL) % BLOCKSIZE >> log; } else {
static void __dead checkconfig(const char *confpath, int argc, char **argv, uid_t uid, gid_t *groups, int ngroups, uid_t target) { struct rule *rule; setresuid(uid, uid, uid); parseconfig(confpath, 0); if (!argc) exit(0); if (permit(uid, groups, ngroups, &rule, target, argv[0], (const char **)argv + 1)) { printf("permit%s\n", (rule->options & NOPASS) ? " nopass" : ""); exit(0); } else { printf("deny\n"); exit(1); } }
void blockAlign3( int *cut1, int *cut2, Segment **seg1, Segment **seg2, double **ocrossscore, int *ncut ) // memory complexity = O(n^3), time complexity = O(n^2) { int i, j, shift, cur1, cur2, count; static TLS int crossscoresize = 0; static TLS int jumpposi, *jumppos; static TLS double jumpscorei, *jumpscore; static TLS int *result1 = NULL; static TLS int *result2 = NULL; static TLS int *ocut1 = NULL; static TLS int *ocut2 = NULL; double maximum; static TLS double **crossscore = NULL; static TLS int **track = NULL; if( result1 == NULL ) { result1 = AllocateIntVec( MAXSEG ); result2 = AllocateIntVec( MAXSEG ); ocut1 = AllocateIntVec( MAXSEG ); ocut2 = AllocateIntVec( MAXSEG ); } if( crossscoresize < *ncut+2 ) { crossscoresize = *ncut+2; if( fftkeika ) fprintf( stderr, "allocating crossscore and track, size = %d\n", crossscoresize ); if( track ) FreeIntMtx( track ); if( crossscore ) FreeDoubleMtx( crossscore ); if( jumppos ) FreeIntVec( jumppos ); if( jumpscore ) FreeDoubleVec( jumpscore ); track = AllocateIntMtx( crossscoresize, crossscoresize ); crossscore = AllocateDoubleMtx( crossscoresize, crossscoresize ); jumppos = AllocateIntVec( crossscoresize ); jumpscore = AllocateDoubleVec( crossscoresize ); } #if 0 for( i=0; i<*ncut-2; i++ ) fprintf( stderr, "%d.start = %d, score = %f\n", i, seg1[i]->start, seg1[i]->score ); for( i=0; i<*ncut; i++ ) fprintf( stderr, "i=%d, cut1 = %d, cut2 = %d\n", i, cut1[i], cut2[i] ); for( i=0; i<*ncut; i++ ) { for( j=0; j<*ncut; j++ ) fprintf( stderr, "%#4.0f ", ocrossscore[i][j] ); fprintf( stderr, "\n" ); } #endif for( i=0; i<*ncut; i++ ) for( j=0; j<*ncut; j++ ) /* mudadanaa */ crossscore[i][j] = ocrossscore[i][j]; for( i=0; i<*ncut; i++ ) { ocut1[i] = cut1[i]; ocut2[i] = cut2[i]; } for( j=0; j<*ncut; j++ ) { jumpscore[j] = -999.999; jumppos[j] = -1; } for( i=1; i<*ncut; i++ ) { jumpscorei = -999.999; jumpposi = -1; for( j=1; j<*ncut; j++ ) { #if 1 fprintf( stderr, "in blockalign3, ### i=%d, j=%d\n", i, j ); #endif #if 0 for( k=0; k<j-2; k++ ) { /* fprintf( stderr, "k=%d, i=%d\n", k, i ); */ if( k && k<*ncut-1 && j<*ncut-1 && !permit( seg1[k-1], seg1[j-1] ) ) continue; if( crossscore[i-1][k] > maxj ) { pointi = k; maxi = crossscore[i-1][k]; } } pointj = 0; maxj = 0.0; for( k=0; k<i-2; k++ ) { if( k && k<*ncut-1 && i<*ncut-1 && !permit( seg2[k-1], seg2[i-1] ) ) continue; if( crossscore[k][j-1] > maxj ) { pointj = k; maxj = crossscore[k][j-1]; } } maxi += penalty; maxj += penalty; #endif maximum = crossscore[i-1][j-1]; track[i][j] = 0; if( maximum < jumpscorei && permit( seg1[jumpposi], seg1[i] ) ) { maximum = jumpscorei; track[i][j] = j - jumpposi; } if( maximum < jumpscore[j] && permit( seg2[jumppos[j]], seg2[j] ) ) { maximum = jumpscore[j]; track[i][j] = jumpscore[j] - i; } crossscore[i][j] += maximum; if( jumpscorei < crossscore[i-1][j] ) { jumpscorei = crossscore[i-1][j]; jumpposi = j; } if( jumpscore[j] < crossscore[i][j-1] ) { jumpscore[j] = crossscore[i][j-1]; jumppos[j] = i; } } } #if 0 for( i=0; i<*ncut; i++ ) { for( j=0; j<*ncut; j++ ) fprintf( stderr, "%3d ", track[i][j] ); fprintf( stderr, "\n" ); } #endif result1[MAXSEG-1] = *ncut-1; result2[MAXSEG-1] = *ncut-1; for( i=MAXSEG-1; i>=1; i-- ) { cur1 = result1[i]; cur2 = result2[i]; if( cur1 == 0 || cur2 == 0 ) break; shift = track[cur1][cur2]; if( shift == 0 ) { result1[i-1] = cur1 - 1; result2[i-1] = cur2 - 1; continue; } else if( shift > 0 ) { result1[i-1] = cur1 - 1; result2[i-1] = cur2 - shift; } else if( shift < 0 ) { result1[i-1] = cur1 + shift; result2[i-1] = cur2 - 1; } } count = 0; for( j=i; j<MAXSEG; j++ ) { if( ocrossscore[result1[j]][result2[j]] == 0.0 ) continue; if( result1[j] == result1[j-1] || result2[j] == result2[j-1] ) if( ocrossscore[result1[j]][result2[j]] > ocrossscore[result1[j-1]][result2[j-1]] ) count--; cut1[count] = ocut1[result1[j]]; cut2[count] = ocut2[result2[j]]; count++; } *ncut = count; #if 0 for( i=0; i<*ncut; i++ ) fprintf( stderr, "i=%d, cut1 = %d, cut2 = %d\n", i, cut1[i], cut2[i] ); #endif }
void blockAlign2( int *cut1, int *cut2, Segment **seg1, Segment **seg2, double **ocrossscore, int *ncut ) { int i, j, k, shift, cur1, cur2, count, klim; static TLS int crossscoresize = 0; static TLS int *result1 = NULL; static TLS int *result2 = NULL; static TLS int *ocut1 = NULL; static TLS int *ocut2 = NULL; double maximum; static TLS double **crossscore = NULL; static TLS int **track = NULL; static TLS double maxj, maxi; static TLS int pointj, pointi; if( cut1 == NULL) { if( result1 ) { if( result1 ) free( result1 ); result1 = NULL; if( result2 ) free( result2 ); result2 = NULL; if( ocut1 ) free( ocut1 ); ocut1 = NULL; if( ocut2 ) free( ocut2 ); ocut2 = NULL; if( track ) FreeIntMtx( track ); track = NULL; if( crossscore ) FreeDoubleMtx( crossscore ); crossscore = NULL; } crossscoresize = 0; return; } if( result1 == NULL ) { result1 = AllocateIntVec( MAXSEG ); result2 = AllocateIntVec( MAXSEG ); ocut1 = AllocateIntVec( MAXSEG ); ocut2 = AllocateIntVec( MAXSEG ); } if( crossscoresize < *ncut+2 ) { crossscoresize = *ncut+2; if( fftkeika ) fprintf( stderr, "allocating crossscore and track, size = %d\n", crossscoresize ); if( track ) FreeIntMtx( track ); if( crossscore ) FreeDoubleMtx( crossscore ); track = AllocateIntMtx( crossscoresize, crossscoresize ); crossscore = AllocateDoubleMtx( crossscoresize, crossscoresize ); } #if 0 for( i=0; i<*ncut-2; i++ ) fprintf( stderr, "%d.start = %d, score = %f\n", i, seg1[i]->start, seg1[i]->score ); for( i=0; i<*ncut; i++ ) fprintf( stderr, "i=%d, cut1 = %d, cut2 = %d\n", i, cut1[i], cut2[i] ); for( i=0; i<*ncut; i++ ) { for( j=0; j<*ncut; j++ ) fprintf( stderr, "%#4.0f ", ocrossscore[i][j] ); fprintf( stderr, "\n" ); } #endif for( i=0; i<*ncut; i++ ) for( j=0; j<*ncut; j++ ) /* mudadanaa */ crossscore[i][j] = ocrossscore[i][j]; for( i=0; i<*ncut; i++ ) { ocut1[i] = cut1[i]; ocut2[i] = cut2[i]; } for( i=1; i<*ncut; i++ ) { #if 0 fprintf( stderr, "### i=%d/%d\n", i,*ncut ); #endif for( j=1; j<*ncut; j++ ) { pointi = 0; maxi = 0.0; klim = j-2; for( k=0; k<klim; k++ ) { /* fprintf( stderr, "k=%d, i=%d\n", k, i ); */ if( k && k<*ncut-1 && j<*ncut-1 && !permit( seg1[k-1], seg1[j-1] ) ) continue; if( crossscore[i-1][k] > maxj ) { pointi = k; maxi = crossscore[i-1][k]; } } pointj = 0; maxj = 0.0; klim = i-2; for( k=0; k<klim; k++ ) { if( k && k<*ncut-1 && i<*ncut-1 && !permit( seg2[k-1], seg2[i-1] ) ) continue; if( crossscore[k][j-1] > maxj ) { pointj = k; maxj = crossscore[k][j-1]; } } maxi += penalty; maxj += penalty; maximum = crossscore[i-1][j-1]; track[i][j] = 0; if( maximum < maxi ) { maximum = maxi ; track[i][j] = j - pointi; } if( maximum < maxj ) { maximum = maxj ; track[i][j] = pointj - i; } crossscore[i][j] += maximum; } } #if 0 for( i=0; i<*ncut; i++ ) { for( j=0; j<*ncut; j++ ) fprintf( stderr, "%3d ", track[i][j] ); fprintf( stderr, "\n" ); } #endif result1[MAXSEG-1] = *ncut-1; result2[MAXSEG-1] = *ncut-1; for( i=MAXSEG-1; i>=1; i-- ) { cur1 = result1[i]; cur2 = result2[i]; if( cur1 == 0 || cur2 == 0 ) break; shift = track[cur1][cur2]; if( shift == 0 ) { result1[i-1] = cur1 - 1; result2[i-1] = cur2 - 1; continue; } else if( shift > 0 ) { result1[i-1] = cur1 - 1; result2[i-1] = cur2 - shift; } else if( shift < 0 ) { result1[i-1] = cur1 + shift; result2[i-1] = cur2 - 1; } } count = 0; for( j=i; j<MAXSEG; j++ ) { if( ocrossscore[result1[j]][result2[j]] == 0.0 ) continue; if( result1[j] == result1[j-1] || result2[j] == result2[j-1] ) if( ocrossscore[result1[j]][result2[j]] > ocrossscore[result1[j-1]][result2[j-1]] ) count--; cut1[count] = ocut1[result1[j]]; cut2[count] = ocut2[result2[j]]; count++; } *ncut = count; #if 0 for( i=0; i<*ncut; i++ ) fprintf( stderr, "i=%d, cut1 = %d, cut2 = %d\n", i, cut1[i], cut2[i] ); #endif }
int main(int argc, char **argv, char **envp) { const char *safepath = "/bin:/sbin:/usr/bin:/usr/sbin:" "/usr/local/bin:/usr/local/sbin"; const char *confpath = NULL; char *shargv[] = { NULL, NULL }; char *sh; const char *cmd; char cmdline[LINE_MAX]; char myname[_PW_NAME_LEN + 1]; struct passwd *pw; struct rule *rule; uid_t uid; uid_t target = 0; gid_t groups[NGROUPS_MAX + 1]; int ngroups; int i, ch; int sflag = 0; int nflag = 0; char cwdpath[PATH_MAX]; const char *cwd; closefrom(STDERR_FILENO + 1); uid = getuid(); while ((ch = getopt(argc, argv, "C:nsu:")) != -1) { switch (ch) { case 'C': confpath = optarg; break; case 'u': if (parseuid(optarg, &target) != 0) errx(1, "unknown user"); break; case 'n': nflag = 1; break; case 's': sflag = 1; break; default: usage(); break; } } argv += optind; argc -= optind; if (confpath) { if (sflag) usage(); } else if ((!sflag && !argc) || (sflag && argc)) usage(); pw = getpwuid(uid); if (!pw) err(1, "getpwuid failed"); if (strlcpy(myname, pw->pw_name, sizeof(myname)) >= sizeof(myname)) errx(1, "pw_name too long"); ngroups = getgroups(NGROUPS_MAX, groups); if (ngroups == -1) err(1, "can't get groups"); groups[ngroups++] = getgid(); if (sflag) { sh = getenv("SHELL"); if (sh == NULL || *sh == '\0') shargv[0] = pw->pw_shell; else shargv[0] = sh; argv = shargv; argc = 1; } if (confpath) { checkconfig(confpath, argc, argv, uid, groups, ngroups, target); exit(1); /* fail safe */ } parseconfig("/etc/doas.conf", 1); /* cmdline is used only for logging, no need to abort on truncate */ (void) strlcpy(cmdline, argv[0], sizeof(cmdline)); for (i = 1; i < argc; i++) { if (strlcat(cmdline, " ", sizeof(cmdline)) >= sizeof(cmdline)) break; if (strlcat(cmdline, argv[i], sizeof(cmdline)) >= sizeof(cmdline)) break; } cmd = argv[0]; if (!permit(uid, groups, ngroups, &rule, target, cmd, (const char**)argv + 1)) { syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed command for %s: %s", myname, cmdline); errc(1, EPERM, NULL); } if (!(rule->options & NOPASS)) { if (nflag) errx(1, "Authorization required"); if (!auth_userokay(myname, NULL, "auth-doas", NULL)) { syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed password for %s", myname); errc(1, EPERM, NULL); } } envp = copyenv((const char **)envp, rule); pw = getpwuid(target); if (!pw) errx(1, "no passwd entry for target"); if (setusercontext(NULL, pw, target, LOGIN_SETGROUP | LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK | LOGIN_SETUSER) != 0) errx(1, "failed to set user context for target"); if (getcwd(cwdpath, sizeof(cwdpath)) == NULL) cwd = "(failed)"; else cwd = cwdpath; syslog(LOG_AUTHPRIV | LOG_INFO, "%s ran command %s as %s from %s", myname, cmdline, pw->pw_name, cwd); if (rule->cmd) { if (setenv("PATH", safepath, 1) == -1) err(1, "failed to set PATH '%s'", safepath); } execvpe(cmd, argv, envp); if (errno == ENOENT) errx(1, "%s: command not found", cmd); err(1, "%s", cmd); }
int main(int argc, char **argv) { const char *safepath = "/bin:/sbin:/usr/bin:/usr/sbin:" "/usr/local/bin:/usr/local/sbin"; const char *confpath = NULL; char *shargv[] = { NULL, NULL }; char *sh; const char *cmd; char cmdline[LINE_MAX]; char myname[_PW_NAME_LEN + 1]; struct passwd *pw; struct rule *rule; uid_t uid; uid_t target = 0; gid_t groups[NGROUPS_MAX + 1]; int ngroups; int i, ch; int sflag = 0; int nflag = 0; char cwdpath[PATH_MAX]; const char *cwd; char *login_style = NULL; char **envp; #ifndef linux setprogname("doas"); #endif #ifndef linux closefrom(STDERR_FILENO + 1); #endif uid = getuid(); while ((ch = getopt(argc, argv, "a:C:nsu:")) != -1) { /* while ((ch = getopt(argc, argv, "a:C:Lnsu:")) != -1) { */ switch (ch) { case 'a': login_style = optarg; break; case 'C': confpath = optarg; break; /* case 'L': i = open("/dev/tty", O_RDWR); if (i != -1) ioctl(i, TIOCCLRVERAUTH); exit(i != -1); */ case 'u': if (parseuid(optarg, &target) != 0) errx(1, "unknown user"); break; case 'n': nflag = 1; break; case 's': sflag = 1; break; default: usage(); break; } } argv += optind; argc -= optind; if (confpath) { if (sflag) usage(); } else if ((!sflag && !argc) || (sflag && argc)) usage(); pw = getpwuid(uid); if (!pw) err(1, "getpwuid failed"); if (strlcpy(myname, pw->pw_name, sizeof(myname)) >= sizeof(myname)) errx(1, "pw_name too long"); ngroups = getgroups(NGROUPS_MAX, groups); if (ngroups == -1) err(1, "can't get groups"); groups[ngroups++] = getgid(); if (sflag) { sh = getenv("SHELL"); if (sh == NULL || *sh == '\0') { shargv[0] = strdup(pw->pw_shell); if (shargv[0] == NULL) err(1, NULL); } else shargv[0] = sh; argv = shargv; argc = 1; } if (confpath) { checkconfig(confpath, argc, argv, uid, groups, ngroups, target); exit(1); /* fail safe */ } if (geteuid()) errx(1, "not installed setuid"); parseconfig(DOAS_CONF, 1); /* cmdline is used only for logging, no need to abort on truncate */ (void)strlcpy(cmdline, argv[0], sizeof(cmdline)); for (i = 1; i < argc; i++) { if (strlcat(cmdline, " ", sizeof(cmdline)) >= sizeof(cmdline)) break; if (strlcat(cmdline, argv[i], sizeof(cmdline)) >= sizeof(cmdline)) break; } cmd = argv[0]; if (!permit(uid, groups, ngroups, &rule, target, cmd, (const char **)argv + 1)) { syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed command for %s: %s", myname, cmdline); errc(1, EPERM, NULL); } if (!(rule->options & NOPASS)) { if (nflag) errx(1, "Authorization required"); #if defined(USE_BSD_AUTH) authuser(myname, login_style, rule->options & PERSIST); #elif defined(USE_PAM) #define PAM_END(msg) do { \ syslog(LOG_ERR, "%s: %s", msg, pam_strerror(pamh, pam_err)); \ warnx("%s: %s", msg, pam_strerror(pamh, pam_err)); \ pam_end(pamh, pam_err); \ exit(EXIT_FAILURE); \ } while (/*CONSTCOND*/0) pam_handle_t *pamh = NULL; int pam_err; /* #ifndef linux */ int temp_stdin; /* openpam_ttyconv checks if stdin is a terminal and * if it is then does not bother to open /dev/tty. * The result is that PAM writes the password prompt * directly to stdout. In scenarios where stdin is a * terminal, but stdout is redirected to a file * e.g. by running doas ls &> ls.out interactively, * the password prompt gets written to ls.out as well. * By closing stdin first we forces PAM to read/write * to/from the terminal directly. We restore stdin * after authenticating. */ temp_stdin = dup(STDIN_FILENO); if (temp_stdin == -1) err(1, "dup"); close(STDIN_FILENO); /* #else */ /* force password prompt to display on stderr, not stdout */ int temp_stdout = dup(1); if (temp_stdout == -1) err(1, "dup"); close(1); if (dup2(2, 1) == -1) err(1, "dup2"); /* #endif */ pam_err = pam_start("doas", myname, &pamc, &pamh); if (pam_err != PAM_SUCCESS) { if (pamh != NULL) PAM_END("pam_start"); syslog(LOG_ERR, "pam_start failed: %s", pam_strerror(pamh, pam_err)); errx(EXIT_FAILURE, "pam_start failed"); } switch (pam_err = pam_authenticate(pamh, PAM_SILENT)) { case PAM_SUCCESS: switch (pam_err = pam_acct_mgmt(pamh, PAM_SILENT)) { case PAM_SUCCESS: break; case PAM_NEW_AUTHTOK_REQD: pam_err = pam_chauthtok(pamh, PAM_SILENT|PAM_CHANGE_EXPIRED_AUTHTOK); if (pam_err != PAM_SUCCESS) PAM_END("pam_chauthtok"); break; case PAM_AUTH_ERR: case PAM_USER_UNKNOWN: case PAM_MAXTRIES: syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname); errx(EXIT_FAILURE, "second authentication failed"); break; default: PAM_END("pam_acct_mgmt"); break; } break; case PAM_AUTH_ERR: case PAM_USER_UNKNOWN: case PAM_MAXTRIES: syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed auth for %s", myname); errx(EXIT_FAILURE, "authentication failed"); break; default: PAM_END("pam_authenticate"); break; } pam_end(pamh, pam_err); #ifndef linux /* Re-establish stdin */ if (dup2(temp_stdin, STDIN_FILENO) == -1) err(1, "dup2"); close(temp_stdin); #else /* Re-establish stdout */ close(1); if (dup2(temp_stdout, 1) == -1) err(1, "dup2"); #endif #else #error No auth module! #endif } /* if (pledge("stdio rpath getpw exec id", NULL) == -1) err(1, "pledge"); */ pw = getpwuid(target); if (!pw) errx(1, "no passwd entry for target"); #if defined(HAVE_LOGIN_CAP_H) if (setusercontext(NULL, pw, target, LOGIN_SETGROUP | LOGIN_SETPRIORITY | LOGIN_SETRESOURCES | LOGIN_SETUMASK | LOGIN_SETUSER) != 0) errx(1, "failed to set user context for target"); #endif /* if (pledge("stdio rpath exec", NULL) == -1) err(1, "pledge"); */ if (getcwd(cwdpath, sizeof(cwdpath)) == NULL) cwd = "(failed)"; else cwd = cwdpath; /* if (pledge("stdio exec", NULL) == -1) err(1, "pledge"); */ #ifndef HAVE_LOGIN_CAP_H /* If we effectively are root, set the UID to actually be root to avoid permission errors. */ if (target != 0) setuid(target); if ( geteuid() == ROOT_UID ) setuid(ROOT_UID); #endif syslog(LOG_AUTHPRIV | LOG_INFO, "%s ran command %s as %s from %s", myname, cmdline, pw->pw_name, cwd); envp = prepenv(rule); if (rule->cmd) { if (setenv("PATH", safepath, 1) == -1) err(1, "failed to set PATH '%s'", safepath); } execvpe(cmd, argv, envp); if (errno == ENOENT) errx(1, "%s: command not found", cmd); err(1, "%s", cmd); }