version 1.1, 1999/11/18 16:29:01 |
version 1.2, 1999/12/10 06:45:11 |
|
|
#endif /* STDC_HEADERS */ |
#endif /* STDC_HEADERS */ |
|
|
#ifndef lint |
#ifndef lint |
static const char rcsid[] = "$Sudo: sudo.c,v 1.258 1999/11/16 06:09:23 millert Exp $"; |
static const char rcsid[] = "$Sudo: sudo.c,v 1.262 1999/12/09 04:04:47 millert Exp $"; |
#endif /* lint */ |
#endif /* lint */ |
|
|
/* |
/* |
|
|
int fd; |
int fd; |
int cmnd_status; |
int cmnd_status; |
int sudo_mode; |
int sudo_mode; |
|
int check_cmnd; |
#ifdef POSIX_SIGNALS |
#ifdef POSIX_SIGNALS |
sigset_t set, oset; |
sigset_t set, oset; |
#else |
#else |
|
|
/* Setup defaults data structures. */ |
/* Setup defaults data structures. */ |
init_defaults(); |
init_defaults(); |
|
|
/* Initialize syslog(3) if we are using it. */ |
check_cmnd = 1; |
if (def_str(I_LOGFACSTR)) { |
|
#ifdef LOG_NFACILITIES |
|
openlog("sudo", 0, def_ival(I_LOGFAC)); |
|
#else |
|
openlog("sudo", 0); |
|
#endif /* LOG_NFACILITIES */ |
|
} |
|
|
|
if (sudo_mode & MODE_SHELL) |
if (sudo_mode & MODE_SHELL) |
user_cmnd = "shell"; |
user_cmnd = "shell"; |
else |
else |
|
|
break; |
break; |
case MODE_VALIDATE: |
case MODE_VALIDATE: |
user_cmnd = "validate"; |
user_cmnd = "validate"; |
|
check_cmnd = 0; |
break; |
break; |
case MODE_KILL: |
case MODE_KILL: |
case MODE_INVALIDATE: |
case MODE_INVALIDATE: |
user_cmnd = "kill"; |
user_cmnd = "kill"; |
|
check_cmnd = 0; |
break; |
break; |
case MODE_LISTDEFS: |
case MODE_LISTDEFS: |
list_options(); |
list_options(); |
|
|
case MODE_LIST: |
case MODE_LIST: |
user_cmnd = "list"; |
user_cmnd = "list"; |
printmatches = 1; |
printmatches = 1; |
|
check_cmnd = 0; |
break; |
break; |
} |
} |
|
|
|
|
|
|
check_sudoers(); /* check mode/owner on _PATH_SUDOERS */ |
check_sudoers(); /* check mode/owner on _PATH_SUDOERS */ |
|
|
|
add_env(!(sudo_mode & MODE_SHELL)); /* add in SUDO_* envariables */ |
|
|
|
/* Validate the user but don't search for pseudo-commands. */ |
|
validated = sudoers_lookup(check_cmnd); |
|
|
|
/* This goes after the sudoers parse since we honor sudoers options. */ |
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) { |
if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) { |
remove_timestamp((sudo_mode == MODE_KILL)); |
remove_timestamp((sudo_mode == MODE_KILL)); |
exit(0); |
exit(0); |
} |
} |
|
|
add_env(!(sudo_mode & MODE_SHELL)); /* add in SUDO_* envariables */ |
|
|
|
/* Validate the user but don't search for pseudo-commands. */ |
|
validated = |
|
sudoers_lookup((sudo_mode != MODE_VALIDATE && sudo_mode != MODE_LIST)); |
|
|
|
if (validated & VALIDATE_ERROR) |
if (validated & VALIDATE_ERROR) |
log_error(0, "parse error in %s near line %d", _PATH_SUDOERS, |
log_error(0, "parse error in %s near line %d", _PATH_SUDOERS, |
errorlineno); |
errorlineno); |
|
|
exit(1); |
exit(1); |
} |
} |
|
|
|
/* May need to set $HOME to target user. */ |
|
if ((sudo_mode & MODE_SHELL) && def_flag(I_SET_HOME)) |
|
sudo_mode |= MODE_RESET_HOME; |
|
|
/* Bail if a tty is required and we don't have one. */ |
/* Bail if a tty is required and we don't have one. */ |
if (def_flag(I_REQUIRETTY)) { |
if (def_flag(I_REQUIRETTY)) { |
if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) |
if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) |
|
|
int sudo_mode; |
int sudo_mode; |
{ |
{ |
char *p, thost[MAXHOSTNAMELEN]; |
char *p, thost[MAXHOSTNAMELEN]; |
struct hostent *hp; |
|
|
|
/* Sanity check command from user. */ |
/* Sanity check command from user. */ |
if (user_cmnd == NULL && strlen(NewArgv[0]) >= MAXPATHLEN) { |
if (user_cmnd == NULL && strlen(NewArgv[0]) >= MAXPATHLEN) { |
|
|
log_error(USE_ERRNO|MSG_ONLY, "can't get hostname"); |
log_error(USE_ERRNO|MSG_ONLY, "can't get hostname"); |
} else |
} else |
user_host = estrdup(thost); |
user_host = estrdup(thost); |
if (def_flag(I_FQDN)) { |
if (def_flag(I_FQDN)) |
if (!(hp = gethostbyname(user_host))) { |
set_fqdn(); |
log_error(USE_ERRNO|MSG_ONLY|NO_EXIT, |
else { |
"unable to lookup %s via gethostbyname()", user_host); |
if ((p = strchr(user_host, '.'))) { |
|
*p = '\0'; |
|
user_shost = estrdup(user_host); |
|
*p = '.'; |
} else { |
} else { |
free(user_host); |
user_shost = user_host; |
user_host = estrdup(hp->h_name); |
|
} |
} |
} |
} |
if ((p = strchr(user_host, '.'))) { |
|
*p = '\0'; |
|
user_shost = estrdup(user_host); |
|
*p = '.'; |
|
} else { |
|
user_shost = user_host; |
|
} |
|
|
|
if ((p = ttyname(STDIN_FILENO)) || (p = ttyname(STDOUT_FILENO))) { |
if ((p = ttyname(STDIN_FILENO)) || (p = ttyname(STDOUT_FILENO))) { |
if (strncmp(p, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) |
if (strncmp(p, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) |
|
|
NewArgv = Argv + 1; |
NewArgv = Argv + 1; |
NewArgc = Argc - 1; |
NewArgc = Argc - 1; |
|
|
if (Argc < 2) { /* no options and no command */ |
#ifdef SHELL_IF_NO_ARGS |
if (!def_flag(I_SHELL_NOARGS)) |
if (NewArgc == 0) { /* no options and no command */ |
usage(1); |
|
rval |= MODE_SHELL; |
rval |= MODE_SHELL; |
return(rval); |
return(rval); |
} |
} |
|
#endif |
|
|
while (NewArgc > 0 && NewArgv[0][0] == '-') { |
while (NewArgc > 0 && NewArgv[0][0] == '-') { |
if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0') { |
if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0') { |
|
|
break; |
break; |
case 's': |
case 's': |
rval |= MODE_SHELL; |
rval |= MODE_SHELL; |
if (def_flag(I_SET_HOME)) |
if (excl && excl != 's') |
rval |= MODE_RESET_HOME; |
usage_excl(1); |
|
excl = 's'; |
break; |
break; |
case 'H': |
case 'H': |
rval |= MODE_RESET_HOME; |
rval |= MODE_RESET_HOME; |
|
|
case '-': |
case '-': |
NewArgc--; |
NewArgc--; |
NewArgv++; |
NewArgv++; |
if (def_flag(I_SHELL_NOARGS) && rval == MODE_RUN) |
#ifdef SHELL_IF_NO_ARGS |
|
if (rval == MODE_RUN) |
rval |= MODE_SHELL; |
rval |= MODE_SHELL; |
|
#endif |
return(rval); |
return(rval); |
case '\0': |
case '\0': |
(void) fprintf(stderr, "%s: '-' requires an argument\n", |
(void) fprintf(stderr, "%s: '-' requires an argument\n", |
|
|
strerror(errno)); |
strerror(errno)); |
exit(1); |
exit(1); |
} |
} |
|
#ifdef HAVE_INITGROUPS |
/* |
/* |
* Initialize group vector only if are |
* Initialize group vector only if are |
* going to run as a non-root user. |
* going to run as a non-root user. |
|
|
Argv[0], strerror(errno)); |
Argv[0], strerror(errno)); |
exit(1); |
exit(1); |
} |
} |
|
#endif /* HAVE_INITGROUPS */ |
if (setuid(pw->pw_uid)) { |
if (setuid(pw->pw_uid)) { |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"%s: cannot set uid to %ld: %s\n", |
"%s: cannot set uid to %ld: %s\n", |
|
|
} |
} |
|
|
/* |
/* |
|
* Look up the fully qualified domain name and set user_host and user_shost. |
|
*/ |
|
void |
|
set_fqdn() |
|
{ |
|
struct hostent *hp; |
|
char *p; |
|
|
|
if (def_flag(I_FQDN)) { |
|
if (!(hp = gethostbyname(user_host))) { |
|
log_error(USE_ERRNO|MSG_ONLY|NO_EXIT, |
|
"unable to lookup %s via gethostbyname()", user_host); |
|
} else { |
|
free(user_host); |
|
user_host = estrdup(hp->h_name); |
|
} |
|
} |
|
if (user_shost != user_host) |
|
free(user_shost); |
|
if ((p = strchr(user_host, '.'))) { |
|
*p = '\0'; |
|
user_shost = estrdup(user_host); |
|
*p = '.'; |
|
} else { |
|
user_shost = user_host; |
|
} |
|
} |
|
|
|
/* |
* Tell which options are mutually exclusive and exit. |
* Tell which options are mutually exclusive and exit. |
*/ |
*/ |
static void |
static void |
|
|
int exit_val; |
int exit_val; |
{ |
{ |
(void) fprintf(stderr, |
(void) fprintf(stderr, |
"Only one of the -v, -k, -K, -l, -V and -h options may be used\n"); |
"Only one of the -h, -k, -K, -l, -s, -v or -V options may be used\n"); |
usage(exit_val); |
usage(exit_val); |
} |
} |
|
|