version 1.13, 2007/07/26 16:10:16 |
version 1.14, 2008/11/14 11:58:08 |
|
|
/* |
/* |
* Copyright (c) 1999-2005 Todd C. Miller <Todd.Miller@courtesan.com> |
* Copyright (c) 1999-2005, 2007-2008 |
|
* Todd C. Miller <Todd.Miller@courtesan.com> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
|
|
#include <unistd.h> |
#include <unistd.h> |
#endif /* HAVE_UNISTD_H */ |
#endif /* HAVE_UNISTD_H */ |
#include <pwd.h> |
#include <pwd.h> |
#ifdef HAVE_ERR_H |
|
# include <err.h> |
|
#else |
|
# include "emul/err.h" |
|
#endif /* HAVE_ERR_H */ |
|
#include <ctype.h> |
#include <ctype.h> |
|
|
#include "sudo.h" |
#include "sudo.h" |
|
#include "parse.h" |
|
#include <gram.h> |
|
|
#ifndef lint |
#ifndef lint |
__unused static const char rcsid[] = "$Sudo: defaults.c,v 1.48.2.5 2007/06/18 15:51:35 millert Exp $"; |
__unused static const char rcsid[] = "$Sudo: defaults.c,v 1.73 2008/11/09 14:13:12 millert Exp $"; |
#endif /* lint */ |
#endif /* lint */ |
|
|
/* |
/* |
|
|
{ NULL, -1 } |
{ NULL, -1 } |
}; |
}; |
|
|
extern int sudolineno; |
|
|
|
/* |
/* |
* Local prototypes. |
* Local prototypes. |
*/ |
*/ |
|
|
break; |
break; |
} |
} |
if (!cur->name) { |
if (!cur->name) { |
warnx("unknown defaults entry `%s' referenced near line %d", |
warningx("unknown defaults entry `%s'", var); |
var, sudolineno); |
|
return(FALSE); |
return(FALSE); |
} |
} |
|
|
|
|
case T_LOGFAC: |
case T_LOGFAC: |
if (!store_syslogfac(val, cur, op)) { |
if (!store_syslogfac(val, cur, op)) { |
if (val) |
if (val) |
warnx("value `%s' is invalid for option `%s'", val, var); |
warningx("value `%s' is invalid for option `%s'", val, var); |
else |
else |
warnx("no value specified for `%s' on line %d", |
warningx("no value specified for `%s'", var); |
var, sudolineno); |
|
return(FALSE); |
return(FALSE); |
} |
} |
break; |
break; |
case T_LOGPRI: |
case T_LOGPRI: |
if (!store_syslogpri(val, cur, op)) { |
if (!store_syslogpri(val, cur, op)) { |
if (val) |
if (val) |
warnx("value `%s' is invalid for option `%s'", val, var); |
warningx("value `%s' is invalid for option `%s'", val, var); |
else |
else |
warnx("no value specified for `%s' on line %d", |
warningx("no value specified for `%s'", var); |
var, sudolineno); |
|
return(FALSE); |
return(FALSE); |
} |
} |
break; |
break; |
|
|
if (!val) { |
if (!val) { |
/* Check for bogus boolean usage or lack of a value. */ |
/* Check for bogus boolean usage or lack of a value. */ |
if (!ISSET(cur->type, T_BOOL) || op != FALSE) { |
if (!ISSET(cur->type, T_BOOL) || op != FALSE) { |
warnx("no value specified for `%s' on line %d", |
warningx("no value specified for `%s'", var); |
var, sudolineno); |
|
return(FALSE); |
return(FALSE); |
} |
} |
} |
} |
if (ISSET(cur->type, T_PATH) && val && *val != '/') { |
if (ISSET(cur->type, T_PATH) && val && *val != '/') { |
warnx("values for `%s' must start with a '/'", var); |
warningx("values for `%s' must start with a '/'", var); |
return(FALSE); |
return(FALSE); |
} |
} |
if (!store_str(val, cur, op)) { |
if (!store_str(val, cur, op)) { |
warnx("value `%s' is invalid for option `%s'", val, var); |
warningx("value `%s' is invalid for option `%s'", val, var); |
return(FALSE); |
return(FALSE); |
} |
} |
break; |
break; |
|
|
if (!val) { |
if (!val) { |
/* Check for bogus boolean usage or lack of a value. */ |
/* Check for bogus boolean usage or lack of a value. */ |
if (!ISSET(cur->type, T_BOOL) || op != FALSE) { |
if (!ISSET(cur->type, T_BOOL) || op != FALSE) { |
warnx("no value specified for `%s' on line %d", |
warningx("no value specified for `%s'", var); |
var, sudolineno); |
|
return(FALSE); |
return(FALSE); |
} |
} |
} |
} |
if (!store_int(val, cur, op)) { |
if (!store_int(val, cur, op)) { |
warnx("value `%s' is invalid for option `%s'", val, var); |
warningx("value `%s' is invalid for option `%s'", val, var); |
return(FALSE); |
return(FALSE); |
} |
} |
break; |
break; |
|
|
if (!val) { |
if (!val) { |
/* Check for bogus boolean usage or lack of a value. */ |
/* Check for bogus boolean usage or lack of a value. */ |
if (!ISSET(cur->type, T_BOOL) || op != FALSE) { |
if (!ISSET(cur->type, T_BOOL) || op != FALSE) { |
warnx("no value specified for `%s' on line %d", |
warningx("no value specified for `%s'", var); |
var, sudolineno); |
|
return(FALSE); |
return(FALSE); |
} |
} |
} |
} |
if (!store_uint(val, cur, op)) { |
if (!store_uint(val, cur, op)) { |
warnx("value `%s' is invalid for option `%s'", val, var); |
warningx("value `%s' is invalid for option `%s'", val, var); |
return(FALSE); |
return(FALSE); |
} |
} |
break; |
break; |
|
|
if (!val) { |
if (!val) { |
/* Check for bogus boolean usage or lack of a value. */ |
/* Check for bogus boolean usage or lack of a value. */ |
if (!ISSET(cur->type, T_BOOL) || op != FALSE) { |
if (!ISSET(cur->type, T_BOOL) || op != FALSE) { |
warnx("no value specified for `%s' on line %d", |
warningx("no value specified for `%s'", var); |
var, sudolineno); |
|
return(FALSE); |
return(FALSE); |
} |
} |
} |
} |
if (!store_mode(val, cur, op)) { |
if (!store_mode(val, cur, op)) { |
warnx("value `%s' is invalid for option `%s'", val, var); |
warningx("value `%s' is invalid for option `%s'", val, var); |
return(FALSE); |
return(FALSE); |
} |
} |
break; |
break; |
case T_FLAG: |
case T_FLAG: |
if (val) { |
if (val) { |
warnx("option `%s' does not take a value on line %d", |
warningx("option `%s' does not take a value", var); |
var, sudolineno); |
|
return(FALSE); |
return(FALSE); |
} |
} |
cur->sd_un.flag = op; |
cur->sd_un.flag = op; |
|
|
if (!val) { |
if (!val) { |
/* Check for bogus boolean usage or lack of a value. */ |
/* Check for bogus boolean usage or lack of a value. */ |
if (!ISSET(cur->type, T_BOOL) || op != FALSE) { |
if (!ISSET(cur->type, T_BOOL) || op != FALSE) { |
warnx("no value specified for `%s' on line %d", |
warningx("no value specified for `%s'", var); |
var, sudolineno); |
|
return(FALSE); |
return(FALSE); |
} |
} |
} |
} |
if (!store_list(val, cur, op)) { |
if (!store_list(val, cur, op)) { |
warnx("value `%s' is invalid for option `%s'", val, var); |
warningx("value `%s' is invalid for option `%s'", val, var); |
return(FALSE); |
return(FALSE); |
} |
} |
break; |
break; |
case T_TUPLE: |
case T_TUPLE: |
if (!val && !ISSET(cur->type, T_BOOL)) { |
if (!val && !ISSET(cur->type, T_BOOL)) { |
warnx("no value specified for `%s' on line %d", |
warningx("no value specified for `%s'", var); |
var, sudolineno); |
|
return(FALSE); |
return(FALSE); |
} |
} |
if (!store_tuple(val, cur, op)) { |
if (!store_tuple(val, cur, op)) { |
warnx("value `%s' is invalid for option `%s'", val, var); |
warningx("value `%s' is invalid for option `%s'", val, var); |
return(FALSE); |
return(FALSE); |
} |
} |
break; |
break; |
|
|
static int firsttime = 1; |
static int firsttime = 1; |
struct sudo_defs_types *def; |
struct sudo_defs_types *def; |
|
|
/* Free any strings that were set. */ |
/* Clear any old settings. */ |
if (!firsttime) { |
if (!firsttime) { |
for (def = sudo_defs_table; def->name; def++) |
for (def = sudo_defs_table; def->name; def++) { |
switch (def->type & T_MASK) { |
switch (def->type & T_MASK) { |
case T_STR: |
case T_STR: |
efree(def->sd_un.str); |
efree(def->sd_un.str); |
|
|
list_op(NULL, 0, def, freeall); |
list_op(NULL, 0, def, freeall); |
break; |
break; |
} |
} |
|
zero_bytes(&def->sd_un, sizeof(def->sd_un)); |
|
} |
} |
} |
|
|
/* First initialize the flags. */ |
/* First initialize the flags. */ |
|
|
#ifdef ENV_EDITOR |
#ifdef ENV_EDITOR |
def_env_editor = TRUE; |
def_env_editor = TRUE; |
#endif |
#endif |
|
#ifdef _PATH_SUDO_ASKPASS |
|
def_askpass = estrdup(_PATH_SUDO_ASKPASS); |
|
#endif |
|
def_sudoers_locale = estrdup("C"); |
def_env_reset = TRUE; |
def_env_reset = TRUE; |
def_set_logname = TRUE; |
def_set_logname = TRUE; |
|
def_closefrom = STDERR_FILENO + 1; |
|
|
/* Syslog options need special care since they both strings and ints */ |
/* Syslog options need special care since they both strings and ints */ |
#if (LOGGING & SLOG_SYSLOG) |
#if (LOGGING & SLOG_SYSLOG) |
|
|
#ifdef EXEMPTGROUP |
#ifdef EXEMPTGROUP |
def_exempt_group = estrdup(EXEMPTGROUP); |
def_exempt_group = estrdup(EXEMPTGROUP); |
#endif |
#endif |
|
#ifdef SECURE_PATH |
|
def_secure_path = estrdup(SECURE_PATH); |
|
#endif |
def_editor = estrdup(EDITOR); |
def_editor = estrdup(EDITOR); |
#ifdef _PATH_SUDO_NOEXEC |
#ifdef _PATH_SUDO_NOEXEC |
def_noexec_file = estrdup(_PATH_SUDO_NOEXEC); |
def_noexec_file = estrdup(_PATH_SUDO_NOEXEC); |
|
|
/* Finally do the lists (currently just environment tables). */ |
/* Finally do the lists (currently just environment tables). */ |
init_envtables(); |
init_envtables(); |
|
|
/* |
|
* The following depend on the above values. |
|
* We use a pointer to the string so that if its |
|
* value changes we get the change. |
|
*/ |
|
if (user_runas == NULL) |
|
user_runas = &def_runas_default; |
|
|
|
firsttime = 0; |
firsttime = 0; |
} |
} |
|
|
|
/* |
|
* Update the defaults based on what was set by sudoers. |
|
* Pass in a an OR'd list of which default types to update. |
|
*/ |
|
int |
|
update_defaults(what) |
|
int what; |
|
{ |
|
struct defaults *def; |
|
|
|
tq_foreach_fwd(&defaults, def) { |
|
switch (def->type) { |
|
case DEFAULTS: |
|
if (ISSET(what, SETDEF_GENERIC) && |
|
!set_default(def->var, def->val, def->op)) |
|
return(FALSE); |
|
break; |
|
case DEFAULTS_USER: |
|
if (ISSET(what, SETDEF_USER) && |
|
userlist_matches(sudo_user.pw, &def->binding) == ALLOW && |
|
!set_default(def->var, def->val, def->op)) |
|
return(FALSE); |
|
break; |
|
case DEFAULTS_RUNAS: |
|
if (ISSET(what, SETDEF_RUNAS) && |
|
runaslist_matches(&def->binding, NULL) == ALLOW && |
|
!set_default(def->var, def->val, def->op)) |
|
return(FALSE); |
|
break; |
|
case DEFAULTS_HOST: |
|
if (ISSET(what, SETDEF_HOST) && |
|
hostlist_matches(&def->binding) == ALLOW && |
|
!set_default(def->var, def->val, def->op)) |
|
return(FALSE); |
|
break; |
|
case DEFAULTS_CMND: |
|
if (ISSET(what, SETDEF_CMND) && |
|
cmndlist_matches(&def->binding) == ALLOW && |
|
!set_default(def->var, def->val, def->op)) |
|
return(FALSE); |
|
break; |
|
} |
|
} |
|
return(TRUE); |
|
} |
|
|
static int |
static int |
store_int(val, def, op) |
store_int(val, def, op) |
char *val; |
char *val; |
|
|
|
|
for (fac = facilities; fac->name && fac->num != n; fac++) |
for (fac = facilities; fac->name && fac->num != n; fac++) |
; |
; |
return (fac->name); |
return(fac->name); |
#else |
#else |
return ("default"); |
return("default"); |
#endif /* LOG_NFACILITIES */ |
#endif /* LOG_NFACILITIES */ |
} |
} |
|
|
|
|
|
|
for (pri = priorities; pri->name && pri->num != n; pri++) |
for (pri = priorities; pri->name && pri->num != n; pri++) |
; |
; |
return (pri->name); |
return(pri->name); |
} |
} |
|
|
static int |
static int |