used indent to "fix" coding style

This commit is contained in:
Todd C. Miller
1993-10-04 19:10:33 +00:00
parent 847ce91e0f
commit e75a6d3b54
7 changed files with 1030 additions and 979 deletions

69
check.c
View File

@@ -74,13 +74,13 @@ if ( setuid (0) ) { /* have to be root to see timestamps */
exit(1); exit(1);
} }
rtn = check_timestamp(); rtn = check_timestamp();
if ( setruid (uid) ) { /* don't want to be root longer than necessary */ if (setruid(uid)) { /* don't want to be root longer than
* necessary */
#ifndef _AIX #ifndef _AIX
perror("setruid(uid)"); perror("setruid(uid)");
exit(1); exit(1);
#endif #endif
} }
if (rtn && uid) /* if timestamp is not current... */ if (rtn && uid) /* if timestamp is not current... */
check_passwd(); check_passwd();
@@ -89,13 +89,13 @@ if ( setuid (0) ) { /* have to be root to play with timestamps */
exit(1); exit(1);
} }
update_timestamp(); update_timestamp();
if ( setruid (uid) ) { /* don't want to be root longer than necessary */ if (setruid(uid)) { /* don't want to be root longer than
* necessary */
#ifndef _AIX #ifndef _AIX
perror("setruid(uid)"); perror("setruid(uid)");
exit(1); exit(1);
#endif #endif
} }
umask(022); /* want a real umask to exec() the command */ umask(022); /* want a real umask to exec() the command */
} }
@@ -119,33 +119,35 @@ struct stat statbuf;
register int timestamp_is_old = -1; register int timestamp_is_old = -1;
time_t now; time_t now;
(void) sprintf(timestampfile, "%s/%s", TIMEDIR, user);
sprintf ( timestampfile, "%s/%s", TIMEDIR, user );
timestampfile_p = timestampfile; timestampfile_p = timestampfile;
timedir_is_good = 1; /* now there's an assumption for ya... */ timedir_is_good = 1; /* now there's an assumption for ya... */
/* walk through the path one directory at a time */ /*
* walk through the path one directory at a time
*/
for (p = timestampfile + 1; p = index(p, '/'); *p++ = '/') { for (p = timestampfile + 1; p = index(p, '/'); *p++ = '/') {
*p = '\0'; *p = '\0';
if (stat(timestampfile, &statbuf) < 0) { if (stat(timestampfile, &statbuf) < 0) {
if (strcmp(timestampfile, TIMEDIR)) if (strcmp(timestampfile, TIMEDIR))
fprintf ( stderr, "Cannot stat() %s\n", timestampfile ); (void) fprintf(stderr, "Cannot stat() %s\n", timestampfile);
timedir_is_good = 0; timedir_is_good = 0;
*p = '/'; *p = '/';
break; break;
} }
} }
/*
if ( timedir_is_good ) { /* if all the directories are stat()able */ * if all the directories are stat()able
*/
if (timedir_is_good) {
if (stat(timestampfile, &statbuf)) { /* does the file exist? */ if (stat(timestampfile, &statbuf)) { /* does the file exist? */
if ( uid ) reminder(); /* if not, do the reminder */ if (uid)
reminder(); /* if not, do the reminder */
timestamp_is_old = 1; /* and return (1) */ timestamp_is_old = 1; /* and return (1) */
} } else { /* otherwise, check the time */
else { /* otherwise, check the time */
now = time((time_t *) NULL); now = time((time_t *) NULL);
if (now - statbuf.st_mtime < 60 * TIMEOUT) if (now - statbuf.st_mtime < 60 * TIMEOUT)
timestamp_is_old = 0; /* if file is recent, return(0) */ timestamp_is_old = 0; /* if file is recent, return(0) */
@@ -153,29 +155,25 @@ if ( timedir_is_good ) { /* if all the directories are stat()able */
timestamp_is_old = 1; /* else make 'em enter password */ timestamp_is_old = 1; /* else make 'em enter password */
} }
} }
/*
/* there was a problem stat()ing a directory */ * there was a problem stat()ing a directory
*/
else { else {
timestamp_is_old = 1; /* user has to enter password */ timestamp_is_old = 1; /* user has to enter password */
if (mkdir(TIMEDIR, 0700)) { /* make the TIMEDIR directory */ if (mkdir(TIMEDIR, 0700)) { /* make the TIMEDIR directory */
perror("check_timestamp: mkdir"); perror("check_timestamp: mkdir");
timedir_is_good = 0; timedir_is_good = 0;
} } else {
else {
timedir_is_good = 1;/* TIMEDIR now exists */ timedir_is_good = 1;/* TIMEDIR now exists */
reminder(); reminder();
} }
} }
return (timestamp_is_old); return (timestamp_is_old);
} }
/******************************************************************** /********************************************************************
* *
* update_timestamp() * update_timestamp()
@@ -197,8 +195,6 @@ if ( timedir_is_good ) {
/******************************************************************** /********************************************************************
* *
* check_passwd() * check_passwd()
@@ -215,38 +211,35 @@ char *encrypted; /* this comes from /etc/passwd */
char *pass; /* this is what gets entered */ char *pass; /* this is what gets entered */
register int counter = TRIES_FOR_PASSWORD; register int counter = TRIES_FOR_PASSWORD;
if ((pw_ent = getpwuid(uid)) == NULL) { if ((pw_ent = getpwuid(uid)) == NULL) {
sprintf ( user, "%u", uid ); (void) sprintf(user, "%u", uid);
log_error(GLOBAL_NO_PW_ENT); log_error(GLOBAL_NO_PW_ENT);
inform_user(GLOBAL_NO_PW_ENT); inform_user(GLOBAL_NO_PW_ENT);
exit(1); exit(1);
} }
encrypted = pw_ent -> pw_passwd; encrypted = pw_ent -> pw_passwd;
/* you get TRIES_FOR_PASSWORD times to guess your password */ /*
* you get TRIES_FOR_PASSWORD times to guess your password
*/
while (counter > 0) { while (counter > 0) {
pass = getpass("Password:"); pass = getpass("Password:");
if ( *pass == (char)NULL ) exit(0); if (*pass == (char) NULL)
exit(0);
if (!strcmp(encrypted, crypt(pass, encrypted))) if (!strcmp(encrypted, crypt(pass, encrypted)))
return; /* if the passwd is correct return() */ return; /* if the passwd is correct return() */
--counter; /* otherwise, try again */ --counter; /* otherwise, try again */
fprintf ( stderr, "%s\n", INCORRECT_PASSWORD ); (void) fprintf(stderr, "%s\n", INCORRECT_PASSWORD);
} }
log_error(PASSWORD_NOT_CORRECT); log_error(PASSWORD_NOT_CORRECT);
inform_user(PASSWORD_NOT_CORRECT); inform_user(PASSWORD_NOT_CORRECT);
exit(1); exit(1);
} }
/******************************************************************** /********************************************************************
* *
* reminder() * reminder()
@@ -256,20 +249,16 @@ exit (1);
static void reminder() static void reminder()
{ {
#ifdef SHORT_MESSAGE #ifdef SHORT_MESSAGE
fprintf(stderr,"\n%s\n%s\n\n%s\n%s\n\n", (void) fprintf(stderr, "\n%s\n%s\n\n%s\n%s\n\n",
#else #else
fprintf(stderr,"\n%s\n%s\n%s\n\n%s\n%s\n\n%s\n%s\n\n", (void) fprintf(stderr, "\n%s\n%s\n%s\n\n%s\n%s\n\n%s\n%s\n\n",
" sudo version 1.1, Copyright (C) 1991 The Root Group, Inc.", " sudo version 1.1, Copyright (C) 1991 The Root Group, Inc.",
" sudo comes with ABSOLUTELY NO WARRANTY. This is free software,", " sudo comes with ABSOLUTELY NO WARRANTY. This is free software,",
" and you are welcome to redistribute it under certain conditions.", " and you are welcome to redistribute it under certain conditions.",
#endif #endif
"We trust you have received the usual lecture from the local Systems", "We trust you have received the usual lecture from the local Systems",
"Administrator. It usually boils down to these two things:", "Administrator. It usually boils down to these two things:",
" #1) Respect the privacy of others.", " #1) Respect the privacy of others.",
" #2) Think before you type." " #2) Think before you type."
); );

View File

@@ -36,8 +36,7 @@
/* /*
* Most of this code has been rewritten to fix bugs and bears little * Most of this code has been rewritten to fix bugs and bears little
* resemblence to the original. As such, this file conforms to my * resemblence to the original.
* personal coding style.
* *
* Todd C. Miller (millert@colorado.edu) Sat Sep 4 12:22:04 MDT 1993 * Todd C. Miller (millert@colorado.edu) Sat Sep 4 12:22:04 MDT 1993
*/ */
@@ -83,15 +82,19 @@ char *find_path(file)
char *qualify(); char *qualify();
if (strlen(file) > MAXPATHLEN) { if (strlen(file) > MAXPATHLEN) {
fprintf(stderr, "%s: path too long: %s\n", Argv[0], file); (void) fprintf(stderr, "%s: path too long: %s\n", Argv[0], file);
exit(1); exit(1);
} }
/* do we need to search the path? */ /*
* do we need to search the path?
*/
if (index(file, '/')) if (index(file, '/'))
return (qualify(file)); return (qualify(file));
/* grab PATH out of environment and make a local copy */ /*
* grab PATH out of environment and make a local copy
*/
if ((path = getenv("PATH")) == NULL) if ((path = getenv("PATH")) == NULL)
return (NULL); return (NULL);
@@ -101,13 +104,12 @@ char *find_path(file)
} }
do { do {
/* cheap strtok() */
if ((n = index(path, ':'))) if ((n = index(path, ':')))
*n = '\0'; *n = '\0';
/* /*
* search current dir last if it is in PATH * search current dir last if it is in PATH This will miss sneaky
* This will miss sneaky things like using './' or './/' * things like using './' or './/'
*/ */
if (*path == NULL || (*path == '.' && *(path + 1) == NULL)) { if (*path == NULL || (*path == '.' && *(path + 1) == NULL)) {
checkdot = 1; checkdot = 1;
@@ -115,10 +117,11 @@ char *find_path(file)
continue; continue;
} }
/* filename to try */
(void) sprintf(fn, "%s/%s", path, file); (void) sprintf(fn, "%s/%s", path, file);
/* stat the file to make sure it exists and is executable */ /*
* stat the file to make sure it exists and is executable
*/
statfailed = stat(fn, &statbuf); statfailed = stat(fn, &statbuf);
if (!statfailed && (statbuf.st_mode & 0000111)) if (!statfailed && (statbuf.st_mode & 0000111))
return (qualify(fn)); return (qualify(fn));
@@ -130,11 +133,15 @@ char *find_path(file)
} while (n); } while (n);
/* check current dir if dot was in the PATH */ /*
* check current dir if dot was in the PATH
*/
if (checkdot) { if (checkdot) {
(void) sprintf(fn, "./%s", file); (void) sprintf(fn, "./%s", file);
/* stat the file to make sure it exists and is executable */ /*
* stat the file to make sure it exists and is executable
*/
statfailed = stat(fn, &statbuf); statfailed = stat(fn, &statbuf);
if (!statfailed && (statbuf.st_mode & 0000111)) if (!statfailed && (statbuf.st_mode & 0000111))
return (qualify(fn)); return (qualify(fn));
@@ -165,7 +172,9 @@ char *qualify(n)
struct stat statbuf; /* for lstat() */ struct stat statbuf; /* for lstat() */
char *tmp; /* temporary pointer */ char *tmp; /* temporary pointer */
/* is it a bogus path? */ /*
* is it a bogus path?
*/
if (stat(n, &statbuf)) { if (stat(n, &statbuf)) {
if (errno == ENOENT) if (errno == ENOENT)
return (NULL); return (NULL);
@@ -175,14 +184,17 @@ char *qualify(n)
} }
} }
/* if n is relative, fill full with working dir */ /*
* if n is relative, fill full with working dir
*/
if (*n != '/') { if (*n != '/') {
#ifdef USE_CWD #ifdef USE_CWD
if (!getcwd(full, (size_t) (MAXPATHLEN + 1))) { if (!getcwd(full, (size_t) (MAXPATHLEN + 1))) {
#else #else
if (!getwd(full)) { if (!getwd(full)) {
#endif #endif
fprintf(stderr, "%s: Can't get working directory!\n", Argv[0]); (void) fprintf(stderr, "%s: Can't get working directory!\n",
Argv[0]);
exit(1); exit(1);
} }
} else } else
@@ -196,14 +208,15 @@ char *qualify(n)
else else
beg = name; /* just starting out... */ beg = name; /* just starting out... */
/* find and terminate end of path component */ /*
* find and terminate end of path component
*/
if ((end = index(beg, '/'))) if ((end = index(beg, '/')))
*end = '\0'; *end = '\0';
if (beg == end) if (beg == end)
continue; continue;
else if (!strcmp(beg, ".")) else if (!strcmp(beg, ".")); /* ignore "." */
; /* ignore "." */
else if (!strcmp(beg, "..")) { else if (!strcmp(beg, "..")) {
if ((tmp = rindex(full, '/'))) if ((tmp = rindex(full, '/')))
*tmp = '\0'; *tmp = '\0';
@@ -212,11 +225,15 @@ char *qualify(n)
strcat(full, beg); /* copy in new component */ strcat(full, beg); /* copy in new component */
} }
/* if we used ../.. to go past the root dir just continue */ /*
* if we used ../.. to go past the root dir just continue
*/
if (!full[0]) if (!full[0])
continue; continue;
/* check for symbolic links */ /*
* check for symbolic links
*/
if (lstat(full, &statbuf)) { if (lstat(full, &statbuf)) {
perror("qualify: lstat"); perror("qualify: lstat");
exit(1); exit(1);
@@ -224,7 +241,8 @@ char *qualify(n)
if ((statbuf.st_mode & S_IFMT) == S_IFLNK) { if ((statbuf.st_mode & S_IFMT) == S_IFLNK) {
int linklen; /* length of link contents */ int linklen; /* length of link contents */
char newname[MAXPATHLEN+1]; /* temp storage to build new name */ char newname[MAXPATHLEN + 1]; /* temp storage to build new
* name */
linklen = readlink(full, newname, sizeof(newname)); linklen = readlink(full, newname, sizeof(newname));
newname[linklen] = '\0'; newname[linklen] = '\0';
@@ -233,19 +251,16 @@ char *qualify(n)
++end; ++end;
if (end != (char *) 1) { if (end != (char *) 1) {
if (linklen + strlen(end) >= MAXPATHLEN) { if (linklen + strlen(end) >= MAXPATHLEN) {
fprintf(stderr, "%s: path too long: %s/%s\n", Argv[0], (void )fprintf(stderr, "%s: path too long: %s/%s\n",
newname, end); Argv[0], newname, end);
exit(1); exit(1);
} }
strcat(newname, "/"); strcat(newname, "/");
strcat(newname, end); /* copy what's left of end */ strcat(newname, end); /* copy what's left of end */
} }
if (newname[0] == '/') /* reset full if necesary */ if (newname[0] == '/') /* reset full if necesary */
full[0] = '\0'; full[0] = '\0';
else else if ((tmp = rindex(full, '/'))) /* remove component from full */
if ((tmp = rindex(full, '/'))) /* remove component from full */
*tmp = '\0'; *tmp = '\0';
strcpy(name, newname); /* reset name with new path */ strcpy(name, newname); /* reset name with new path */
@@ -253,7 +268,9 @@ char *qualify(n)
} }
} while (end); } while (end);
/* if we resolved to "/" full[0] will be NULL */ /*
* if we resolved to "/" full[0] will be NULL
*/
if (!full[0]) if (!full[0])
strcpy(full, "/"); strcpy(full, "/");

View File

@@ -55,15 +55,14 @@ getpass(prompt)
static char buf[PASSWD_LEN + 1]; static char buf[PASSWD_LEN + 1];
/* /*
* read and write to /dev/tty if possible; else read from * read and write to /dev/tty if possible; else read from stdin and write
* stdin and write to stderr. * to stderr.
*/ */
fd_tmp = open("/dev/tty", O_RDWR); fd_tmp = open("/dev/tty", O_RDWR);
if (fd_tmp < 0 || (outfp = fp = fdopen(fd_tmp, "r+")) == NULL) { if (fd_tmp < 0 || (outfp = fp = fdopen(fd_tmp, "r+")) == NULL) {
outfp = stderr; outfp = stderr;
fp = stdin; fp = stdin;
} }
#if defined(sgi) #if defined(sgi)
(void) ioctl(fileno(fp), TCGETA, &ttyb); (void) ioctl(fileno(fp), TCGETA, &ttyb);
svflagval = ttyb.c_lflag; svflagval = ttyb.c_lflag;
@@ -78,7 +77,7 @@ getpass(prompt)
(void) ioctl(fileno(fp), TIOCSETP, &ttyb); (void) ioctl(fileno(fp), TIOCSETP, &ttyb);
#endif #endif
fprintf(outfp, "%s", prompt); (void) fprintf(outfp, "%s", prompt);
rewind(outfp); /* implied flush */ rewind(outfp); /* implied flush */
for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';) for (p = buf; (ch = getc(fp)) != EOF && ch != '\n';)
if (p < buf + PASSWD_LEN) if (p < buf + PASSWD_LEN)

150
logging.c
View File

@@ -74,63 +74,70 @@ time_t now;
register int pri; /* syslog priority */ register int pri; /* syslog priority */
#endif #endif
/*
* there is no need to log the date and time twice if using syslog
/* there is no need to log the date and time twice if using syslog */ */
#ifndef SYSLOG #ifndef SYSLOG
now = time((time_t) 0); now = time((time_t) 0);
sprintf( logline, "%19.19s : %8.8s : ", ctime (&now), user ); (void) sprintf(logline, "%19.19s : %8.8s : ", ctime(&now), user);
#else #else
sprintf( logline, "%8.8s : ", user ); (void) sprintf(logline, "%8.8s : ", user);
#endif #endif
p = logline + strlen(logline); /* we need a pointer to the end of logline */ /*
* we need a pointer to the end of logline
*/
p = logline + strlen(logline);
/*
* so we know where we are...
*/
#ifdef USE_CWD #ifdef USE_CWD
getcwd(cwd, (size_t)(MAXPATHLEN+1)); /* so we know where we are... */ getcwd(cwd, (size_t) (MAXPATHLEN + 1));
#else #else
getwd(cwd); /* so we know where we are... */ getwd(cwd);
#endif #endif
switch (code) { switch (code) {
case ALL_SYSTEMS_GO: case ALL_SYSTEMS_GO:
sprintf ( p, "PWD=%s ; COMMAND=", cwd ); (void) sprintf(p, "PWD=%s ; COMMAND=", cwd);
#ifdef SYSLOG #ifdef SYSLOG
pri = Syslog_priority_OK; pri = Syslog_priority_OK;
#endif #endif
break; break;
case VALIDATE_NO_USER: case VALIDATE_NO_USER:
sprintf ( p, "user NOT in sudoers ; PWD=%s ; COMMAND=", cwd ); (void) sprintf(p, "user NOT in sudoers ; PWD=%s ; COMMAND=", cwd);
#ifdef SYSLOG #ifdef SYSLOG
pri = Syslog_priority_NO; pri = Syslog_priority_NO;
#endif #endif
break; break;
case VALIDATE_NOT_OK: case VALIDATE_NOT_OK:
sprintf ( p, "command not allowed ; PWD=%s ; COMMAND=", cwd ); (void) sprintf(p, "command not allowed ; PWD=%s ; COMMAND=", cwd);
#ifdef SYSLOG #ifdef SYSLOG
pri = Syslog_priority_NO; pri = Syslog_priority_NO;
#endif #endif
break; break;
case VALIDATE_ERROR: case VALIDATE_ERROR:
sprintf ( p, "error in %s ; PWD=%s ; command: ", SUDOERS, cwd ); (void) sprintf(p, "error in %s ; PWD=%s ; command: ", SUDOERS, cwd);
#ifdef SYSLOG #ifdef SYSLOG
pri = Syslog_priority_NO; pri = Syslog_priority_NO;
#endif #endif
break; break;
case GLOBAL_NO_PW_ENT: case GLOBAL_NO_PW_ENT:
sprintf ( p, "There is no /etc/passwd entry for uid %d. ", uid ); (void) sprintf(p, "There is no /etc/passwd entry for uid %d. ",
uid);
#ifdef SYSLOG #ifdef SYSLOG
pri = Syslog_priority_NO; pri = Syslog_priority_NO;
#endif #endif
break; break;
case PASSWORD_NOT_CORRECT: case PASSWORD_NOT_CORRECT:
sprintf ( p, "%d incorrect passwords ; PWD=%s ; COMMAND=", (void) sprintf(p, "%d incorrect passwords ; PWD=%s ; COMMAND=",
TRIES_FOR_PASSWORD, cwd); TRIES_FOR_PASSWORD, cwd);
#ifdef SYSLOG #ifdef SYSLOG
pri = Syslog_priority_NO; pri = Syslog_priority_NO;
@@ -147,13 +154,15 @@ switch ( code ) {
case NO_SUDOERS_FILE: case NO_SUDOERS_FILE:
switch (errno) { switch (errno) {
case ENOENT: case ENOENT:
sprintf ( p, "There is no %s file. ", SUDOERS ); (void) sprintf(p, "There is no %s file. ", SUDOERS);
break; break;
case EACCES: case EACCES:
sprintf ( p, "%s needs to run setuid root. ", Argv[0] ); (void) sprintf(p, "%s needs to run setuid root. ",
Argv[0]);
break; break;
default: default:
sprintf ( p, "There is a problem opening %s ", SUDOERS ); (void) sprintf(p, "There is a problem opening %s ",
SUDOERS);
break; break;
} }
#ifdef SYSLOG #ifdef SYSLOG
@@ -162,7 +171,7 @@ switch ( code ) {
break; break;
case GLOBAL_HOST_UNREGISTERED: case GLOBAL_HOST_UNREGISTERED:
sprintf ( p, "gethostbyname() cannot find host %s ", host ); (void) sprintf(p, "gethostbyname() cannot find host %s ", host);
#ifdef SYSLOG #ifdef SYSLOG
pri = Syslog_priority_NO; pri = Syslog_priority_NO;
#endif #endif
@@ -174,22 +183,26 @@ switch ( code ) {
pri = Syslog_priority_NO; pri = Syslog_priority_NO;
#endif #endif
break; break;
} }
/* if this error is from load_globals() don't put argv in the message */ /*
* if this error is from load_globals() don't put argv in the message
*/
if (!(code & GLOBAL_PROBLEM)) { if (!(code & GLOBAL_PROBLEM)) {
strcat(logline, cmnd); /* stuff the command into the logline */ strcat(logline, cmnd); /* stuff the command into the logline */
strcat(logline, " "); strcat(logline, " ");
argc = Argc - 2; argc = Argc - 2;
argv = Argv; argv++; argv = Argv;
argv++;
p = logline + strlen(logline); p = logline + strlen(logline);
count = (int) (logline + MAXLOGLEN - p); count = (int) (logline + MAXLOGLEN - p);
/* now stuff as much of the rest of the line as will fit */ /*
* now stuff as much of the rest of the line as will fit
*/
while (count > 0 && argc--) { while (count > 0 && argc--) {
strncpy(p, *++argv, count); strncpy(p, *++argv, count);
strcat(p, " "); strcat(p, " ");
@@ -200,35 +213,26 @@ if ( ! ( code & GLOBAL_PROBLEM ) ) {
strcat(p, " ... "); /* add an elipsis to the end */ strcat(p, " ... "); /* add an elipsis to the end */
} }
if (appropriate(code)) if (appropriate(code))
send_mail(); send_mail();
#ifdef SYSLOG #ifdef SYSLOG
openlog(Syslog_ident, Syslog_options, Syslog_facility); openlog(Syslog_ident, Syslog_options, Syslog_facility);
syslog(pri, logline); syslog(pri, logline);
closelog(); closelog();
#else #else
if ((fp = fopen(LOGFILE, "a")) == NULL) { if ((fp = fopen(LOGFILE, "a")) == NULL) {
sprintf ( logline, "Can\'t open log file: %s", LOGFILE ); (void) sprintf(logline, "Can\'t open log file: %s", LOGFILE);
send_mail(); send_mail();
} } else {
else { (void) fprintf(fp, "%s\n", logline);
fprintf ( fp, "%s\n", logline );
(void) fclose(fp); (void) fclose(fp);
} }
#endif #endif
} }
/********************************************************************** /**********************************************************************
* *
* send_mail() * send_mail()
@@ -242,7 +246,6 @@ char *exec_argv[]= { "sendmail" ,
ALERTMAIL, ALERTMAIL,
(char *) NULL}; (char *) NULL};
static void send_mail() static void send_mail()
{ {
char *mailer = MAILER; char *mailer = MAILER;
@@ -251,66 +254,56 @@ int fd[2];
char buf[MAXLOGLEN + 1024]; char buf[MAXLOGLEN + 1024];
if ((mailer = find_path(mailer)) == NULL) { if ((mailer = find_path(mailer)) == NULL) {
fprintf (stderr, "%s not found\n", mailer ); (void) fprintf(stderr, "%s not found\n", mailer);
exit(1); exit(1);
} }
(void) signal(SIGCHLD, reapchild);
signal ( SIGCHLD, reapchild ); if (fork())
return;
if ( fork () ) return; /*
* we don't want any security problems ...
/* we don't want any security problems ... */ */
if (setuid(uid)) { if (setuid(uid)) {
perror("setuid(uid)"); perror("setuid(uid)");
exit(1); exit(1);
} }
(void) signal(SIGHUP, SIG_IGN);
signal ( SIGHUP, SIG_IGN ); (void) signal(SIGINT, SIG_IGN);
signal ( SIGINT, SIG_IGN ); (void) signal(SIGQUIT, SIG_IGN);
signal ( SIGQUIT, SIG_IGN );
if (pipe(fd)) { if (pipe(fd)) {
perror("send_mail: pipe"); perror("send_mail: pipe");
exit(1); exit(1);
} }
(void) dup2(fd[0], 0); (void) dup2(fd[0], 0);
(void) dup2(fd[1], 1); (void) dup2(fd[1], 1);
(void) close(fd[0]); (void) close(fd[0]);
(void) close(fd[1]); (void) close(fd[1]);
if ( ! fork () ) { if (!fork()) { /* child */
/* child parent */
(void) close(1); (void) close(1);
execv ( mailer, exec_argv ); execve(mailer, exec_argv, Envp);
/* this should not happen */ /* this should not happen */
perror( "execv"); perror("execve");
exit(1); exit(1);
} else { /* parent */
}
else {
(void) close(0); (void) close(0);
/* feed the data to sendmail */ /* feed the data to sendmail */
sprintf (buf, "To: %s\nSubject: %s\n\n%s\n\n", (void) sprintf(buf, "To: %s\nSubject: %s\n\n%s\n\n",
ALERTMAIL, subject, logline); ALERTMAIL, subject, logline);
write(1, buf, strlen(buf)); write(1, buf, strlen(buf));
close(1); close(1);
exit(0); exit(0);
} }
} }
/**************************************************************** /****************************************************************
* *
* reapchild() * reapchild()
@@ -325,8 +318,6 @@ static void reapchild ()
/********************************************************************** /**********************************************************************
* *
* inform_user () * inform_user ()
@@ -340,57 +331,52 @@ int code;
{ {
switch (code) { switch (code) {
case VALIDATE_NO_USER: case VALIDATE_NO_USER:
fprintf( stderr, (void) fprintf(stderr,
"%s is not in the sudoers file. This incident will be reported.\n\n", "%s is not in the sudoers file. This incident will be reported.\n\n",
user); user);
break; break;
case VALIDATE_NOT_OK: case VALIDATE_NOT_OK:
fprintf( stderr, (void) fprintf(stderr,
"Sorry, user %s is not allowed to execute %s\n\n", "Sorry, user %s is not allowed to execute %s\n\n",
user, cmnd); user, cmnd);
break; break;
case VALIDATE_ERROR: case VALIDATE_ERROR:
fprintf( stderr, (void) fprintf(stderr,
"Sorry, there is a fatal error in the sudoers file.\n\n"); "Sorry, there is a fatal error in the sudoers file.\n\n");
break; break;
case GLOBAL_NO_PW_ENT: case GLOBAL_NO_PW_ENT:
fprintf ( stderr, (void) fprintf(stderr,
"Intruder Alert! You don\'t exist in the passwd file\n\n"); "Intruder Alert! You don\'t exist in the passwd file\n\n");
break; break;
case GLOBAL_NO_HOSTNAME: case GLOBAL_NO_HOSTNAME:
fprintf ( stderr, (void) fprintf(stderr,
"This machine does not have a hostname\n\n"); "This machine does not have a hostname\n\n");
break; break;
case GLOBAL_HOST_UNREGISTERED: case GLOBAL_HOST_UNREGISTERED:
fprintf ( stderr, (void) fprintf(stderr,
"This machine is not available via gethostbyname()\n\n"); "This machine is not available via gethostbyname()\n\n");
break; break;
case PASSWORD_NOT_CORRECT: case PASSWORD_NOT_CORRECT:
fprintf ( stderr, "Password not entered correctly after %d tries\n\n", (void) fprintf(stderr, "Password not entered correctly after %d tries\n\n",
TRIES_FOR_PASSWORD); TRIES_FOR_PASSWORD);
break; break;
default: default:
fprintf ( stderr, (void) fprintf(stderr,
"Something wierd happened.\n\n"); "Something wierd happened.\n\n");
break; break;
} }
} }
/**************************************************************** /****************************************************************
* *
* appropriate() * appropriate()
@@ -404,8 +390,9 @@ int code;
switch (code) { switch (code) {
/* these will NOT send mail */ /*
* these will NOT send mail
*/
case VALIDATE_OK: case VALIDATE_OK:
case PASSWORD_NOT_CORRECT: case PASSWORD_NOT_CORRECT:
/* case ALL_SYSTEMS_GO: this is the same as OK */ /* case ALL_SYSTEMS_GO: this is the same as OK */
@@ -428,8 +415,9 @@ switch ( code ) {
#endif #endif
break; break;
/* these WILL send mail */ /*
* these WILL send mail
*/
case VALIDATE_ERROR: case VALIDATE_ERROR:
case NO_SUDOERS_FILE: case NO_SUDOERS_FILE:
default: default:

174
parse.c
View File

@@ -22,13 +22,15 @@
* 3959 Arbol CT (303) 447-8093 * 3959 Arbol CT (303) 447-8093
* Boulder, CO 80301-1752 * Boulder, CO 80301-1752
* *
******************************************************************************** **************************************************************************
*
* parse.c, sudo project * parse.c, sudo project
* David R. Hieb * David R. Hieb
* March 18, 1991 * March 18, 1991
* *
* routines to implement and maintain the parsing and list management. * routines to implement and maintain the parsing and list management.
*******************************************************************************/ */
#include <stdio.h> #include <stdio.h>
#include <strings.h> #include <strings.h>
#include <ctype.h> #include <ctype.h>
@@ -37,7 +39,9 @@
#include "sudo.h" #include "sudo.h"
/* there are 3 main lists (User, Host_Alias, Cmnd_Alias) and 1 extra list */ /*
* there are 3 main lists (User, Host_Alias, Cmnd_Alias) and 1 extra list
*/
#define NUM_LISTS 3+1 #define NUM_LISTS 3+1
extern char *user, *host, *cmnd; extern char *user, *host, *cmnd;
@@ -49,9 +53,11 @@ int parse_error = FALSE, found_user = FALSE;
int next_type, num_host_alias = 0, num_cmnd_alias = 0; int next_type, num_host_alias = 0, num_cmnd_alias = 0;
LINK tmp_ptr, reset_ptr, save_ptr, list_ptr[NUM_LISTS]; LINK tmp_ptr, reset_ptr, save_ptr, list_ptr[NUM_LISTS];
/*******************************************************************************
/*
* inserts a node into list 'list_num' and updates list_ptr[list_num] * inserts a node into list 'list_num' and updates list_ptr[list_num]
*******************************************************************************/ */
void insert_member(list_num, token_type, op_type, data_string) void insert_member(list_num, token_type, op_type, data_string)
int token_type, list_num; int token_type, list_num;
char op_type; char op_type;
@@ -67,9 +73,12 @@ char *data_string;
list_ptr[list_num] = list_ptr[EXTRA_LIST] = tmp_ptr; list_ptr[list_num] = list_ptr[EXTRA_LIST] = tmp_ptr;
} }
/*******************************************************************************
/*
* diagnostic list printing utility that prints list 'list_num' * diagnostic list printing utility that prints list 'list_num'
*******************************************************************************/ */
void print_list(list_num) void print_list(list_num)
int list_num; int list_num;
{ {
@@ -78,7 +87,8 @@ LINK tmptmp_ptr;
tmptmp_ptr = list_ptr[list_num]; tmptmp_ptr = list_ptr[list_num];
while (list_ptr[list_num] != NULL) { while (list_ptr[list_num] != NULL) {
printf("type = %d, op = %c, data = %s\n", list_ptr[list_num]->type, (void) printf("type = %d, op = %c, data = %s\n",
list_ptr[list_num] -> type,
list_ptr[list_num] -> op, list_ptr[list_num] -> data); list_ptr[list_num] -> op, list_ptr[list_num] -> data);
tmp_ptr = list_ptr[list_num]; tmp_ptr = list_ptr[list_num];
list_ptr[list_num] = tmp_ptr -> next; list_ptr[list_num] = tmp_ptr -> next;
@@ -86,9 +96,12 @@ while (list_ptr[list_num] != NULL) {
list_ptr[list_num] = tmptmp_ptr; list_ptr[list_num] = tmptmp_ptr;
} }
/*******************************************************************************
/*
* delete list utility that deletes list 'list_num' * delete list utility that deletes list 'list_num'
*******************************************************************************/ */
void delete_list(list_num) void delete_list(list_num)
int list_num; int list_num;
{ {
@@ -99,16 +112,22 @@ while (list_ptr[list_num] != NULL) {
} }
} }
/*******************************************************************************
/*
* this routine is what the lex/yacc code calls to build the different lists. * this routine is what the lex/yacc code calls to build the different lists.
* once the lists are all built, control eventually returns to validate(). * once the lists are all built, control eventually returns to validate().
*******************************************************************************/ */
int call_back(token_type, op_type, data_string) int call_back(token_type, op_type, data_string)
int token_type; int token_type;
char op_type; char op_type;
char *data_string; char *data_string;
{ {
/* all nodes start out in the extra list since the node name is received last */ /*
* all nodes start out in the extra list since the node name
* is received last
*/
list_num = EXTRA_LIST; list_num = EXTRA_LIST;
/* /*
@@ -116,7 +135,9 @@ list_num = EXTRA_LIST;
* and effectively transfer the extra list to the correct list type. * and effectively transfer the extra list to the correct list type.
*/ */
if (token_type == TYPE1) { if (token_type == TYPE1) {
/* we have just build a "Host_Alias" list */ /*
* we have just build a "Host_Alias" list
*/
if (strcmp(data_string, "Host_Alias") == 0) { if (strcmp(data_string, "Host_Alias") == 0) {
list_num = HOST_LIST; list_num = HOST_LIST;
if (num_host_alias > 0) { if (num_host_alias > 0) {
@@ -124,7 +145,9 @@ if (token_type == TYPE1) {
} }
num_host_alias++; num_host_alias++;
} }
/* we have just build a "Cmnd_Alias" list */ /*
* we have just build a "Cmnd_Alias" list
*/
else if (strcmp(data_string, "Cmnd_Alias") == 0) { else if (strcmp(data_string, "Cmnd_Alias") == 0) {
list_num = CMND_LIST; list_num = CMND_LIST;
if (num_cmnd_alias > 0) { if (num_cmnd_alias > 0) {
@@ -132,7 +155,9 @@ if (token_type == TYPE1) {
} }
num_cmnd_alias++; num_cmnd_alias++;
} }
/* we have just build a "User" list */ /*
* we have just build a "User" list
*/
else { else {
list_num = USER_LIST; list_num = USER_LIST;
user_list_found = TRUE; user_list_found = TRUE;
@@ -141,15 +166,15 @@ if (token_type == TYPE1) {
new_list[list_num] = FALSE; new_list[list_num] = FALSE;
list_ptr[list_num] = list_ptr[EXTRA_LIST]; list_ptr[list_num] = list_ptr[EXTRA_LIST];
} }
/*
/* actually link the new node into list 'list_num' */ * actually link the new node into list 'list_num'
*/
insert_member(list_num, token_type, op_type, data_string); insert_member(list_num, token_type, op_type, data_string);
if (new_list[list_num] == TRUE) { if (new_list[list_num] == TRUE) {
reset_ptr = list_ptr[list_num]; reset_ptr = list_ptr[list_num];
new_list[list_num] = FALSE; new_list[list_num] = FALSE;
} }
/* /*
* we process one user record at a time from the sudoers file. if we * we process one user record at a time from the sudoers file. if we
* find the user were looking for, we return to lex/yacc declaring * find the user were looking for, we return to lex/yacc declaring
@@ -160,8 +185,7 @@ if (user_list_found == TRUE) {
if (list_ptr[list_num] -> type == TYPE1 && if (list_ptr[list_num] -> type == TYPE1 &&
strcmp(list_ptr[list_num] -> data, user) == 0) { strcmp(list_ptr[list_num] -> data, user) == 0) {
return (FOUND_USER); return (FOUND_USER);
} } else {
else {
new_list[list_num] = TRUE; new_list[list_num] = TRUE;
user_list_found = FALSE; user_list_found = FALSE;
delete_list(list_num); delete_list(list_num);
@@ -170,22 +194,31 @@ if (user_list_found == TRUE) {
return (NOT_FOUND_USER); return (NOT_FOUND_USER);
} }
/*******************************************************************************
/*
* this routine is called from cmnd_check() to resolve whether or not * this routine is called from cmnd_check() to resolve whether or not
* a user is permitted to perform a to-yet-be-determined command for * a user is permitted to perform a to-yet-be-determined command for
* a certain host name. * a certain host name.
*******************************************************************************/ */
int host_type_ok() int host_type_ok()
{ {
/* check for the reserved keyword 'ALL'. if so, don't check the host name */ /*
* check for the reserved keyword 'ALL'. if so, don't check the host name
*/
if (strcmp(list_ptr[USER_LIST] -> data, "ALL") == 0) { if (strcmp(list_ptr[USER_LIST] -> data, "ALL") == 0) {
return (TRUE); return (TRUE);
} }
/* this case is the normal lowercase hostname */ /*
* this case is the normal lowercase hostname
*/
else if (isupper(list_ptr[USER_LIST] -> data[0]) == FALSE) { else if (isupper(list_ptr[USER_LIST] -> data[0]) == FALSE) {
return (strcmp(list_ptr[USER_LIST] -> data, host) == 0); return (strcmp(list_ptr[USER_LIST] -> data, host) == 0);
} }
/* by now we have a Host_Alias that will have to be expanded */ /*
* by now we have a Host_Alias that will have to be expanded
*/
else { else {
save_ptr = list_ptr[HOST_LIST]; save_ptr = list_ptr[HOST_LIST];
while (list_ptr[HOST_LIST] != NULL) { while (list_ptr[HOST_LIST] != NULL) {
@@ -204,13 +237,11 @@ else {
next_type = list_ptr[HOST_LIST] -> next -> type; next_type = list_ptr[HOST_LIST] -> next -> type;
tmp_ptr = list_ptr[HOST_LIST]; tmp_ptr = list_ptr[HOST_LIST];
list_ptr[HOST_LIST] = tmp_ptr -> next; list_ptr[HOST_LIST] = tmp_ptr -> next;
} } else {
else {
next_type = ~TYPE3; next_type = ~TYPE3;
} }
} }
} } else {
else {
tmp_ptr = list_ptr[HOST_LIST]; tmp_ptr = list_ptr[HOST_LIST];
list_ptr[HOST_LIST] = tmp_ptr -> next; list_ptr[HOST_LIST] = tmp_ptr -> next;
} }
@@ -220,14 +251,19 @@ else {
} }
} }
/*******************************************************************************
/*
* this routine is called from cmnd_check() to resolve whether or not * this routine is called from cmnd_check() to resolve whether or not
* a user is permitted to perform a certain command on the already * a user is permitted to perform a certain command on the already
* established host. * established host.
*******************************************************************************/ */
int cmnd_type_ok() int cmnd_type_ok()
{ {
/* check for the reserved keyword 'ALL'. */ /*
* check for the reserved keyword 'ALL'.
*/
if (strcmp(list_ptr[USER_LIST] -> data, "ALL") == 0) { if (strcmp(list_ptr[USER_LIST] -> data, "ALL") == 0) {
/* if the command has an absolute path, let them do it */ /* if the command has an absolute path, let them do it */
if (cmnd[0] == '/') { if (cmnd[0] == '/') {
@@ -238,32 +274,35 @@ if (strcmp(list_ptr[USER_LIST]->data, "ALL") == 0) {
return (NO_MATCH); return (NO_MATCH);
} }
} }
/* if the command has an absolute path, check it out */ /*
* if the command has an absolute path, check it out
*/
else if (list_ptr[USER_LIST] -> data[0] == '/') { else if (list_ptr[USER_LIST] -> data[0] == '/') {
/* op | data | return value /*
* op | data | return value
* --------------------------------- * ---------------------------------
* ' ' | No Match | return(NO_MATCH) * ' ' | No Match | return(NO_MATCH)
* '!' | No Match | return(NO_MATCH) * '!' | No Match | return(NO_MATCH)
* ' ' | A Match | return(MATCH) * ' ' | A Match | return(MATCH)
* '!' | A Match | return(QUIT_NOW) * '!' | A Match | return(QUIT_NOW)
* *
* these special cases are important in subtracting from the * these special cases are important in subtracting from the Universe
* Universe of commands in something like: * of commands in something like:
* user machine=ALL,!/bin/rm,!/etc/named ... * user machine=ALL,!/bin/rm,!/etc/named ...
*/ */
if (strcmp(list_ptr[USER_LIST] -> data, cmnd) == 0) { if (strcmp(list_ptr[USER_LIST] -> data, cmnd) == 0) {
if (list_ptr[USER_LIST] -> op == '!') { if (list_ptr[USER_LIST] -> op == '!') {
return (QUIT_NOW); return (QUIT_NOW);
} } else {
else {
return (MATCH); return (MATCH);
} }
} } else {
else {
return (NO_MATCH); return (NO_MATCH);
} }
} }
/* by now we have a Cmnd_Alias that will have to be expanded */ /*
* by now we have a Cmnd_Alias that will have to be expanded
*/
else { else {
save_ptr = list_ptr[CMND_LIST]; save_ptr = list_ptr[CMND_LIST];
while (list_ptr[CMND_LIST] != NULL) { while (list_ptr[CMND_LIST] != NULL) {
@@ -278,8 +317,7 @@ else {
if (list_ptr[USER_LIST] -> op == '!') { if (list_ptr[USER_LIST] -> op == '!') {
list_ptr[CMND_LIST] = save_ptr; list_ptr[CMND_LIST] = save_ptr;
return (QUIT_NOW); return (QUIT_NOW);
} } else {
else {
list_ptr[CMND_LIST] = save_ptr; list_ptr[CMND_LIST] = save_ptr;
return (MATCH); return (MATCH);
} }
@@ -288,13 +326,11 @@ else {
next_type = list_ptr[CMND_LIST] -> next -> type; next_type = list_ptr[CMND_LIST] -> next -> type;
tmp_ptr = list_ptr[CMND_LIST]; tmp_ptr = list_ptr[CMND_LIST];
list_ptr[CMND_LIST] = tmp_ptr -> next; list_ptr[CMND_LIST] = tmp_ptr -> next;
} } else {
else {
next_type = ~TYPE3; next_type = ~TYPE3;
} }
} }
} } else {
else {
tmp_ptr = list_ptr[CMND_LIST]; tmp_ptr = list_ptr[CMND_LIST];
list_ptr[CMND_LIST] = tmp_ptr -> next; list_ptr[CMND_LIST] = tmp_ptr -> next;
} }
@@ -304,12 +340,15 @@ else {
} }
} }
/*******************************************************************************
/*
* this routine is called from validate() after the call_back() routine * this routine is called from validate() after the call_back() routine
* has built all the possible lists. this routine steps thru the user list * has built all the possible lists. this routine steps thru the user list
* calling on host_type_ok() and cmnd_type_ok() trying to resolve whether * calling on host_type_ok() and cmnd_type_ok() trying to resolve whether
* or not the user will be able to execute the command on the host. * or not the user will be able to execute the command on the host.
*******************************************************************************/ */
int cmnd_check() int cmnd_check()
{ {
int return_code; int return_code;
@@ -323,21 +362,18 @@ while (list_ptr[USER_LIST] != NULL) {
return_code = cmnd_type_ok(); return_code = cmnd_type_ok();
if (return_code == MATCH) { if (return_code == MATCH) {
return (VALIDATE_OK); return (VALIDATE_OK);
} } else if (return_code == QUIT_NOW) {
else if (return_code == QUIT_NOW) {
return (VALIDATE_NOT_OK); return (VALIDATE_NOT_OK);
} }
if (list_ptr[USER_LIST] -> next != NULL) { if (list_ptr[USER_LIST] -> next != NULL) {
next_type = list_ptr[USER_LIST] -> next -> type; next_type = list_ptr[USER_LIST] -> next -> type;
tmp_ptr = list_ptr[USER_LIST]; tmp_ptr = list_ptr[USER_LIST];
list_ptr[USER_LIST] = tmp_ptr -> next; list_ptr[USER_LIST] = tmp_ptr -> next;
} } else {
else {
next_type = ~TYPE3; next_type = ~TYPE3;
} }
} }
} } else {
else {
tmp_ptr = list_ptr[USER_LIST]; tmp_ptr = list_ptr[USER_LIST];
list_ptr[USER_LIST] = tmp_ptr -> next; list_ptr[USER_LIST] = tmp_ptr -> next;
} }
@@ -345,10 +381,13 @@ while (list_ptr[USER_LIST] != NULL) {
return (VALIDATE_NOT_OK); return (VALIDATE_NOT_OK);
} }
/*******************************************************************************
/*
* this routine is called from the sudo.c module and tries to validate * this routine is called from the sudo.c module and tries to validate
* the user, host and command triplet. * the user, host and command triplet.
*******************************************************************************/ */
int validate() int validate()
{ {
FILE *sudoers_fp; FILE *sudoers_fp;
@@ -359,7 +398,6 @@ if ((sudoers_fp = fopen(SUDOERS, "r")) == NULL ) {
log_error(NO_SUDOERS_FILE); log_error(NO_SUDOERS_FILE);
exit(1); exit(1);
} }
yyin = sudoers_fp; yyin = sudoers_fp;
yyout = stdout; yyout = stdout;
@@ -373,20 +411,26 @@ for (i = 0; i < NUM_LISTS; i++)
*/ */
return_code = yyparse(); return_code = yyparse();
/* don't need to keep this open... */ /*
* don't need to keep this open...
*/
(void) fclose(sudoers_fp); (void) fclose(sudoers_fp);
/* if a parsing error occurred, set return_code accordingly */ /*
* if a parsing error occurred, set return_code accordingly
*/
if (parse_error == TRUE) { if (parse_error == TRUE) {
return_code = PARSE_ERROR; return_code = PARSE_ERROR;
} }
/*
/* if the user was not found, set the return_code accordingly */ * if the user was not found, set the return_code accordingly
*/
if (found_user == FALSE) { if (found_user == FALSE) {
return_code = NOT_FOUND_USER; return_code = NOT_FOUND_USER;
} }
/*
/* handle the 3 cases individually &*/ * handle the 3 cases individually
*/
switch (return_code) { switch (return_code) {
case FOUND_USER: case FOUND_USER:
return_code = cmnd_check(); return_code = cmnd_check();

67
sudo.c
View File

@@ -78,7 +78,9 @@ uid_t uid;
*/ */
main(argc, argv, envp) main(argc, argv, envp)
int argc; char **argv; char **envp; int argc;
char **argv;
char **envp;
{ {
static void usage(); static void usage();
int rtn; int rtn;
@@ -86,10 +88,14 @@ int rtn;
Argv = argv; Argv = argv;
Argc = argc; Argc = argc;
/* if nothing is passed, we don't need to do anything... */ /*
if ( argc < 2 ) usage(); * if nothing is passed, we don't need to do anything...
*/
if (argc < 2)
usage();
/* close all file descriptors to make sure we have a nice /*
* close all file descriptors to make sure we have a nice
* clean slate from which to work. * clean slate from which to work.
*/ */
for (rtn = getdtablesize() - 1; rtn > 3; rtn--) for (rtn = getdtablesize() - 1; rtn > 3; rtn--)
@@ -110,7 +116,6 @@ if ( setruid(uid) ) {
exit(1); exit(1);
#endif #endif
} }
switch (rtn) { switch (rtn) {
case VALIDATE_OK: case VALIDATE_OK:
@@ -136,16 +141,16 @@ switch ( rtn ) {
inform_user(rtn); inform_user(rtn);
exit(1); exit(1);
break; break;
} }
return(-1); /* If we get here it's an error (execve failed) */ /*
* If we get here it's an error (execve failed)
*/
return (-1);
} }
/********************************************************************** /**********************************************************************
* *
* load_globals() * load_globals()
@@ -170,31 +175,32 @@ if ( (host=malloc(MAXHOSTNAMELEN+1)) == NULL ) {
perror("malloc"); perror("malloc");
exit(1); exit(1);
} }
uid = getuid(); /* we need to tuck this away for safe keeping */ uid = getuid(); /* we need to tuck this away for safe keeping */
/* loading the cmnd global variable from argv[1] */ /*
* loading the cmnd global variable from argv[1]
*/
strncpy(path, Argv[1], MAXPATHLEN)[MAXPATHLEN] = 0; strncpy(path, Argv[1], MAXPATHLEN)[MAXPATHLEN] = 0;
cmnd = find_path(path); /* get the absolute path */ cmnd = find_path(path); /* get the absolute path */
if (cmnd == NULL) { if (cmnd == NULL) {
fprintf ( stderr, "%s: %s: command not found\n", Argv[0], Argv[1] ); (void) fprintf(stderr, "%s: %s: command not found\n", Argv[0], Argv[1]);
exit(1); exit(1);
} }
cmnd = strdup(cmnd); cmnd = strdup(cmnd);
#ifdef NO_ROOT_SUDO #ifdef NO_ROOT_SUDO
if (uid == 0) { if (uid == 0) {
fprintf(stderr, "You are already root, you don\'t need to use sudo.\n"); (void) fprintf(stderr, "You are already root, you don\'t need to use sudo.\n");
exit(1); exit(1);
} }
#endif #endif
/* loading the user global variable from the passwd file */ /*
* loading the user global variable from the passwd file
*/
if ((pw_ent = getpwuid(uid)) == NULL) { if ((pw_ent = getpwuid(uid)) == NULL) {
sprintf ( user, "%u", uid ); (void) sprintf(user, "%u", uid);
log_error(GLOBAL_NO_PW_ENT); log_error(GLOBAL_NO_PW_ENT);
inform_user(GLOBAL_NO_PW_ENT); inform_user(GLOBAL_NO_PW_ENT);
exit(1); exit(1);
@@ -202,23 +208,25 @@ if ( (pw_ent = getpwuid( uid )) == NULL ) {
strncpy(user, pw_ent -> pw_name, 8)[8] = '\0'; strncpy(user, pw_ent -> pw_name, 8)[8] = '\0';
/* loading the host global variable from gethostname() & gethostbyname() */ /*
* loading the host global variable from gethostname() & gethostbyname()
*/
if ((gethostname(host, MAXHOSTNAMELEN))) { if ((gethostname(host, MAXHOSTNAMELEN))) {
strcpy(host, "amnesiac"); strcpy(host, "amnesiac");
log_error(GLOBAL_NO_HOSTNAME); log_error(GLOBAL_NO_HOSTNAME);
inform_user(GLOBAL_NO_HOSTNAME); inform_user(GLOBAL_NO_HOSTNAME);
} } else {
else {
if ((h_ent = gethostbyname(host)) == NULL) if ((h_ent = gethostbyname(host)) == NULL)
log_error(GLOBAL_HOST_UNREGISTERED); log_error(GLOBAL_HOST_UNREGISTERED);
else else
strcpy(host, h_ent -> h_name); strcpy(host, h_ent -> h_name);
/* We don't want to return the fully quallified name all the time... */ /*
* We don't want to return the fully quallified name all the time...
*/
#ifndef FQDN #ifndef FQDN
if ( (p = index ( host, '.' )) ) *p='\0'; if ((p = index(host, '.')))
*p = '\0';
#endif #endif
} }
@@ -226,7 +234,6 @@ else {
/********************************************************************** /**********************************************************************
* *
* usage() * usage()
@@ -236,13 +243,12 @@ else {
static void usage() static void usage()
{ {
fprintf( stderr, "usage: %s command\n", *Argv); (void) fprintf(stderr, "usage: %s command\n", *Argv);
exit(1); exit(1);
} }
/********************************************************************** /**********************************************************************
* *
* clean_envp() * clean_envp()
@@ -257,8 +263,7 @@ char **envp;
int envlen; int envlen;
char **tenvp; char **tenvp;
for ( envlen=0; envp[envlen]; envlen++ ) for (envlen = 0; envp[envlen]; envlen++); /* noop */
; /* noop */
++envlen; ++envlen;
Envp = (char **) malloc(sizeof(char **) * envlen); Envp = (char **) malloc(sizeof(char **) * envlen);
@@ -268,7 +273,9 @@ if ( Envp == NULL ) {
exit(1); exit(1);
} }
/* omit all LD_* environmental vars */ /*
* omit all LD_* environmental vars
*/
for (tenvp = Envp; *envp; envp++) for (tenvp = Envp; *envp; envp++)
if (strncmp("LD_", *envp, 3)) if (strncmp("LD_", *envp, 3))
*tenvp++ = *envp; *tenvp++ = *envp;

37
sudo.h
View File

@@ -120,7 +120,6 @@
#define MAXHOSTNAMELEN 64 #define MAXHOSTNAMELEN 64
#endif #endif
/* 48 chars is not enough */
#define MAXCOMMANDLENGTH MAXPATHLEN #define MAXCOMMANDLENGTH MAXPATHLEN
typedef union { typedef union {
@@ -141,10 +140,10 @@ YYSTYPE yylval, yyval;
YYSTYPE yylval; YYSTYPE yylval;
#endif #endif
/*
* SYSLOG should be defined in the makefile
*/
#ifdef SYSLOG /* SYSLOG should be defined in the makefile */ #ifdef SYSLOG
#include <syslog.h> #include <syslog.h>
#ifndef Syslog_ident #ifndef Syslog_ident
#define Syslog_ident "sudo" #define Syslog_ident "sudo"
@@ -171,12 +170,16 @@ YYSTYPE yylval;
#endif /* LOGFILE */ #endif /* LOGFILE */
#endif /* SYSLOG */ #endif /* SYSLOG */
/* Maximum number of characters to log per entry. */ /*
#ifndef MAXLOGLEN /* The syslogger will log this much, after that, */ * Maximum number of characters to log per entry.
#define MAXLOGLEN 990 /* it truncates the log line. We need this here */ * The syslogger will log this much, after that,
#endif /* to make sure that we get ellipses when the log */ * it truncates the log line. We need this here
/* line is longer than 990 characters. */ * to make sure that we get ellipses when the log
* line is longer than 990 characters.
*/
#ifndef MAXLOGLEN
#define MAXLOGLEN 990
#endif
#define VALIDATE_OK 0x00 #define VALIDATE_OK 0x00
#define VALIDATE_NO_USER 0x01 #define VALIDATE_NO_USER 0x01
@@ -226,6 +229,7 @@ void load_globals();
void log_error(); void log_error();
void inform_user(); void inform_user();
void check_user(); void check_user();
void clean_envp();
int validate(); int validate();
/* Most of these variables are declared in main() so they don't need /* Most of these variables are declared in main() so they don't need
@@ -240,16 +244,19 @@ extern uid_t uid;
extern char *host; extern char *host;
extern char *user; extern char *user;
extern char *cmnd; extern char *cmnd;
extern char **Argv;
extern int Argc; extern int Argc;
extern char **Argv;
extern char **Envp;
#endif #endif
extern int errno; extern int errno;
/* This is to placate hpux */ /*
* This is to placate hpux
*/
#ifdef hpux #ifdef hpux
#define setruid(__RUID) (setresuid((uid_t)(__RUID), (uid_t) -1, (uid_t) -1)) #define setruid(__RUID) (setresuid((uid_t)(__RUID), (uid_t) -1, (uid_t) -1))
#define getdtablesize() (sysconf(_SC_OPEN_MAX)) #define getdtablesize() (sysconf(_SC_OPEN_MAX))
#ifndef USE_CWD #ifndef USE_CWD
#define USE_CWD #define USE_CWD
#endif #endif /* USE_CWD */
#endif #endif /* hpux */