static void build_timestamp __P((char **, char **));
static int timestamp_status __P((char *, char *, char *, int));
static char *expand_prompt __P((char *, char *, char *));
-static void lecture __P((void));
+static void lecture __P((int));
static void update_timestamp __P((char *, char *));
/*
* verify who he/she is.
*/
void
-check_user()
+check_user(override)
+ int override;
{
char *timestampdir = NULL;
char *timestampfile = NULL;
build_timestamp(×tampdir, ×tampfile);
status = timestamp_status(timestampdir, timestampfile, user_name, TRUE);
- if (status != TS_CURRENT) {
- if (status == TS_MISSING || status == TS_ERROR)
- lecture(); /* first time through they get a lecture */
+ if (override || status != TS_CURRENT) {
+ lecture(status);
/* Expand any escapes in the prompt. */
prompt = expand_prompt(user_prompt ? user_prompt : def_passprompt,
* TODO: allow the user to specify a file name instead.
*/
static void
-lecture()
+lecture(status)
+ int status;
{
- if (def_lecture) {
- (void) fputs("\n\
+ if (def_lecture == never ||
+ (def_lecture == once && status != TS_MISSING && status != TS_ERROR))
+ return;
+
+ (void) fputs("\n\
We trust you have received the usual lecture from the local System\n\
Administrator. It usually boils down to these two things:\n\
\n\
- #1) Respect the privacy of others.\n\
- #2) Think before you type.\n\n",
- stderr);
- }
+ #1) Respect the privacy of others.\n\
+ #2) Think before you type.\n\n",
+ stderr);
}
/*
+static struct def_values def_data_lecture[] = {
+ { "never", never },
+ { "once", once },
+ { "always", always },
+ { NULL, 0 },
+};
+
+static struct def_values def_data_listpw[] = {
+ { "never", never },
+ { "any", any },
+ { "all", all },
+ { "always", always },
+ { NULL, 0 },
+};
+
+static struct def_values def_data_verifypw[] = {
+ { "never", never },
+ { "any", any },
+ { "all", all },
+ { "always", always },
+ { NULL, 0 },
+};
+
struct sudo_defs_types sudo_defs_table[] = {
{
- "syslog_ifac", T_UINT,
- NULL
- }, {
- "syslog_igoodpri", T_UINT,
- NULL
- }, {
- "syslog_ibadpri", T_UINT,
- NULL
- }, {
"syslog", T_LOGFAC|T_BOOL,
- "Syslog facility if syslog is being used for logging: %s"
+ "Syslog facility if syslog is being used for logging: %s",
}, {
"syslog_goodpri", T_LOGPRI,
- "Syslog priority to use when user authenticates successfully: %s"
+ "Syslog priority to use when user authenticates successfully: %s",
}, {
"syslog_badpri", T_LOGPRI,
- "Syslog priority to use when user authenticates unsuccessfully: %s"
+ "Syslog priority to use when user authenticates unsuccessfully: %s",
}, {
"long_otp_prompt", T_FLAG,
- "Put OTP prompt on its own line"
+ "Put OTP prompt on its own line",
}, {
"ignore_dot", T_FLAG,
- "Ignore '.' in $PATH"
+ "Ignore '.' in $PATH",
}, {
"mail_always", T_FLAG,
- "Always send mail when sudo is run"
+ "Always send mail when sudo is run",
}, {
"mail_badpass", T_FLAG,
- "Send mail if user authentication fails"
+ "Send mail if user authentication fails",
}, {
"mail_no_user", T_FLAG,
- "Send mail if the user is not in sudoers"
+ "Send mail if the user is not in sudoers",
}, {
"mail_no_host", T_FLAG,
- "Send mail if the user is not in sudoers for this host"
+ "Send mail if the user is not in sudoers for this host",
}, {
"mail_no_perms", T_FLAG,
- "Send mail if the user is not allowed to run a command"
+ "Send mail if the user is not allowed to run a command",
}, {
"tty_tickets", T_FLAG,
- "Use a separate timestamp for each user/tty combo"
+ "Use a separate timestamp for each user/tty combo",
}, {
- "lecture", T_FLAG,
- "Lecture user the first time they run sudo"
+ "lecture", T_TUPLE|T_BOOL,
+ "Lecture user the first time they run sudo",
+ def_data_lecture,
}, {
"authenticate", T_FLAG,
- "Require users to authenticate by default"
+ "Require users to authenticate by default",
}, {
"root_sudo", T_FLAG,
- "Root may run sudo"
+ "Root may run sudo",
}, {
"log_host", T_FLAG,
- "Log the hostname in the (non-syslog) log file"
+ "Log the hostname in the (non-syslog) log file",
}, {
"log_year", T_FLAG,
- "Log the year in the (non-syslog) log file"
+ "Log the year in the (non-syslog) log file",
}, {
"shell_noargs", T_FLAG,
- "If sudo is invoked with no arguments, start a shell"
+ "If sudo is invoked with no arguments, start a shell",
}, {
"set_home", T_FLAG,
- "Set $HOME to the target user when starting a shell with -s"
+ "Set $HOME to the target user when starting a shell with -s",
}, {
"always_set_home", T_FLAG,
- "Always set $HOME to the target user's home directory"
+ "Always set $HOME to the target user's home directory",
}, {
"path_info", T_FLAG,
- "Allow some information gathering to give useful error messages"
+ "Allow some information gathering to give useful error messages",
}, {
"fqdn", T_FLAG,
- "Require fully-qualified hostnames in the sudoers file"
+ "Require fully-qualified hostnames in the sudoers file",
}, {
"insults", T_FLAG,
- "Insult the user when they enter an incorrect password"
+ "Insult the user when they enter an incorrect password",
}, {
"requiretty", T_FLAG,
- "Only allow the user to run sudo if they have a tty"
+ "Only allow the user to run sudo if they have a tty",
}, {
"env_editor", T_FLAG,
- "Visudo will honor the EDITOR environment variable"
+ "Visudo will honor the EDITOR environment variable",
}, {
"rootpw", T_FLAG,
- "Prompt for root's password, not the users's"
+ "Prompt for root's password, not the users's",
}, {
"runaspw", T_FLAG,
- "Prompt for the runas_default user's password, not the users's"
+ "Prompt for the runas_default user's password, not the users's",
}, {
"targetpw", T_FLAG,
- "Prompt for the target user's password, not the users's"
+ "Prompt for the target user's password, not the users's",
}, {
"use_loginclass", T_FLAG,
- "Apply defaults in the target user's login class if there is one"
+ "Apply defaults in the target user's login class if there is one",
}, {
"set_logname", T_FLAG,
- "Set the LOGNAME and USER environment variables"
+ "Set the LOGNAME and USER environment variables",
}, {
"stay_setuid", T_FLAG,
- "Only set the effective uid to the target user, not the real uid"
+ "Only set the effective uid to the target user, not the real uid",
}, {
"env_reset", T_FLAG,
- "Reset the environment to a default set of variables"
+ "Reset the environment to a default set of variables",
}, {
"preserve_groups", T_FLAG,
- "Don't initialize the group vector to that of the target user"
+ "Don't initialize the group vector to that of the target user",
}, {
"loglinelen", T_UINT|T_BOOL,
- "Length at which to wrap log file lines (0 for no wrap): %d"
+ "Length at which to wrap log file lines (0 for no wrap): %d",
}, {
"timestamp_timeout", T_INT|T_BOOL,
- "Authentication timestamp timeout: %d minutes"
+ "Authentication timestamp timeout: %d minutes",
}, {
"passwd_timeout", T_UINT|T_BOOL,
- "Password prompt timeout: %d minutes"
+ "Password prompt timeout: %d minutes",
}, {
"passwd_tries", T_UINT,
- "Number of tries to enter a password: %d"
+ "Number of tries to enter a password: %d",
}, {
"umask", T_MODE|T_BOOL,
- "Umask to use or 0777 to use user's: 0%o"
+ "Umask to use or 0777 to use user's: 0%o",
}, {
"logfile", T_STR|T_BOOL|T_PATH,
- "Path to log file: %s"
+ "Path to log file: %s",
}, {
"mailerpath", T_STR|T_BOOL|T_PATH,
- "Path to mail program: %s"
+ "Path to mail program: %s",
}, {
"mailerflags", T_STR|T_BOOL,
- "Flags for mail program: %s"
+ "Flags for mail program: %s",
}, {
"mailto", T_STR|T_BOOL,
- "Address to send mail to: %s"
+ "Address to send mail to: %s",
}, {
"mailsub", T_STR,
- "Subject line for mail messages: %s"
+ "Subject line for mail messages: %s",
}, {
"badpass_message", T_STR,
- "Incorrect password message: %s"
+ "Incorrect password message: %s",
}, {
"timestampdir", T_STR|T_PATH,
- "Path to authentication timestamp dir: %s"
+ "Path to authentication timestamp dir: %s",
}, {
"timestampowner", T_STR,
- "Owner of the authentication timestamp dir: %s"
+ "Owner of the authentication timestamp dir: %s",
}, {
"exempt_group", T_STR|T_BOOL,
- "Users in this group are exempt from password and PATH requirements: %s"
+ "Users in this group are exempt from password and PATH requirements: %s",
}, {
"passprompt", T_STR,
- "Default password prompt: %s"
+ "Default password prompt: %s",
}, {
"runas_default", T_STR,
- "Default user to run commands as: %s"
+ "Default user to run commands as: %s",
}, {
"editor", T_STR|T_PATH,
- "Path to the editor for use by visudo: %s"
+ "Path to the editor for use by visudo: %s",
}, {
"env_check", T_LIST|T_BOOL,
- "Environment variables to check for sanity:"
+ "Environment variables to check for sanity:",
}, {
"env_delete", T_LIST|T_BOOL,
- "Environment variables to remove:"
+ "Environment variables to remove:",
}, {
"env_keep", T_LIST|T_BOOL,
- "Environment variables to preserve:"
- }, {
- "listpw_i", T_UINT,
- NULL
- }, {
- "verifypw_i", T_UINT,
- NULL
+ "Environment variables to preserve:",
}, {
- "listpw", T_PWFLAG,
- "When to require a password for 'list' pseudocommand: %s"
+ "listpw", T_TUPLE|T_BOOL,
+ "When to require a password for 'list' pseudocommand: %s",
+ def_data_listpw,
}, {
- "verifypw", T_PWFLAG,
- "When to require a password for 'verify' pseudocommand: %s"
+ "verifypw", T_TUPLE|T_BOOL,
+ "When to require a password for 'verify' pseudocommand: %s",
+ def_data_verifypw,
}, {
NULL, 0, NULL
}
-#define def_syslog_ifac (sudo_defs_table[0].sd_un.ival)
-#define I_SYSLOG_IFAC 0
-#define def_syslog_igoodpri (sudo_defs_table[1].sd_un.ival)
-#define I_SYSLOG_IGOODPRI 1
-#define def_syslog_ibadpri (sudo_defs_table[2].sd_un.ival)
-#define I_SYSLOG_IBADPRI 2
-#define def_syslog (sudo_defs_table[3].sd_un.str)
-#define I_SYSLOG 3
-#define def_syslog_goodpri (sudo_defs_table[4].sd_un.str)
-#define I_SYSLOG_GOODPRI 4
-#define def_syslog_badpri (sudo_defs_table[5].sd_un.str)
-#define I_SYSLOG_BADPRI 5
-#define def_long_otp_prompt (sudo_defs_table[6].sd_un.flag)
-#define I_LONG_OTP_PROMPT 6
-#define def_ignore_dot (sudo_defs_table[7].sd_un.flag)
-#define I_IGNORE_DOT 7
-#define def_mail_always (sudo_defs_table[8].sd_un.flag)
-#define I_MAIL_ALWAYS 8
-#define def_mail_badpass (sudo_defs_table[9].sd_un.flag)
-#define I_MAIL_BADPASS 9
-#define def_mail_no_user (sudo_defs_table[10].sd_un.flag)
-#define I_MAIL_NO_USER 10
-#define def_mail_no_host (sudo_defs_table[11].sd_un.flag)
-#define I_MAIL_NO_HOST 11
-#define def_mail_no_perms (sudo_defs_table[12].sd_un.flag)
-#define I_MAIL_NO_PERMS 12
-#define def_tty_tickets (sudo_defs_table[13].sd_un.flag)
-#define I_TTY_TICKETS 13
-#define def_lecture (sudo_defs_table[14].sd_un.flag)
-#define I_LECTURE 14
-#define def_authenticate (sudo_defs_table[15].sd_un.flag)
-#define I_AUTHENTICATE 15
-#define def_root_sudo (sudo_defs_table[16].sd_un.flag)
-#define I_ROOT_SUDO 16
-#define def_log_host (sudo_defs_table[17].sd_un.flag)
-#define I_LOG_HOST 17
-#define def_log_year (sudo_defs_table[18].sd_un.flag)
-#define I_LOG_YEAR 18
-#define def_shell_noargs (sudo_defs_table[19].sd_un.flag)
-#define I_SHELL_NOARGS 19
-#define def_set_home (sudo_defs_table[20].sd_un.flag)
-#define I_SET_HOME 20
-#define def_always_set_home (sudo_defs_table[21].sd_un.flag)
-#define I_ALWAYS_SET_HOME 21
-#define def_path_info (sudo_defs_table[22].sd_un.flag)
-#define I_PATH_INFO 22
-#define def_fqdn (sudo_defs_table[23].sd_un.flag)
-#define I_FQDN 23
-#define def_insults (sudo_defs_table[24].sd_un.flag)
-#define I_INSULTS 24
-#define def_requiretty (sudo_defs_table[25].sd_un.flag)
-#define I_REQUIRETTY 25
-#define def_env_editor (sudo_defs_table[26].sd_un.flag)
-#define I_ENV_EDITOR 26
-#define def_rootpw (sudo_defs_table[27].sd_un.flag)
-#define I_ROOTPW 27
-#define def_runaspw (sudo_defs_table[28].sd_un.flag)
-#define I_RUNASPW 28
-#define def_targetpw (sudo_defs_table[29].sd_un.flag)
-#define I_TARGETPW 29
-#define def_use_loginclass (sudo_defs_table[30].sd_un.flag)
-#define I_USE_LOGINCLASS 30
-#define def_set_logname (sudo_defs_table[31].sd_un.flag)
-#define I_SET_LOGNAME 31
-#define def_stay_setuid (sudo_defs_table[32].sd_un.flag)
-#define I_STAY_SETUID 32
-#define def_env_reset (sudo_defs_table[33].sd_un.flag)
-#define I_ENV_RESET 33
-#define def_preserve_groups (sudo_defs_table[34].sd_un.flag)
-#define I_PRESERVE_GROUPS 34
-#define def_loglinelen (sudo_defs_table[35].sd_un.ival)
-#define I_LOGLINELEN 35
-#define def_timestamp_timeout (sudo_defs_table[36].sd_un.ival)
-#define I_TIMESTAMP_TIMEOUT 36
-#define def_passwd_timeout (sudo_defs_table[37].sd_un.ival)
-#define I_PASSWD_TIMEOUT 37
-#define def_passwd_tries (sudo_defs_table[38].sd_un.ival)
-#define I_PASSWD_TRIES 38
-#define def_umask (sudo_defs_table[39].sd_un.mode)
-#define I_UMASK 39
-#define def_logfile (sudo_defs_table[40].sd_un.str)
-#define I_LOGFILE 40
-#define def_mailerpath (sudo_defs_table[41].sd_un.str)
-#define I_MAILERPATH 41
-#define def_mailerflags (sudo_defs_table[42].sd_un.str)
-#define I_MAILERFLAGS 42
-#define def_mailto (sudo_defs_table[43].sd_un.str)
-#define I_MAILTO 43
-#define def_mailsub (sudo_defs_table[44].sd_un.str)
-#define I_MAILSUB 44
-#define def_badpass_message (sudo_defs_table[45].sd_un.str)
-#define I_BADPASS_MESSAGE 45
-#define def_timestampdir (sudo_defs_table[46].sd_un.str)
-#define I_TIMESTAMPDIR 46
-#define def_timestampowner (sudo_defs_table[47].sd_un.str)
-#define I_TIMESTAMPOWNER 47
-#define def_exempt_group (sudo_defs_table[48].sd_un.str)
-#define I_EXEMPT_GROUP 48
-#define def_passprompt (sudo_defs_table[49].sd_un.str)
-#define I_PASSPROMPT 49
-#define def_runas_default (sudo_defs_table[50].sd_un.str)
-#define I_RUNAS_DEFAULT 50
-#define def_editor (sudo_defs_table[51].sd_un.str)
-#define I_EDITOR 51
-#define def_env_check (sudo_defs_table[52].sd_un.list)
-#define I_ENV_CHECK 52
-#define def_env_delete (sudo_defs_table[53].sd_un.list)
-#define I_ENV_DELETE 53
-#define def_env_keep (sudo_defs_table[54].sd_un.list)
-#define I_ENV_KEEP 54
-#define def_listpw_i (sudo_defs_table[55].sd_un.ival)
-#define I_LISTPW_I 55
-#define def_verifypw_i (sudo_defs_table[56].sd_un.ival)
-#define I_VERIFYPW_I 56
-#define def_listpw (sudo_defs_table[57].sd_un.str)
-#define I_LISTPW 57
-#define def_verifypw (sudo_defs_table[58].sd_un.str)
-#define I_VERIFYPW 58
+#define def_syslog (sudo_defs_table[0].sd_un.ival)
+#define I_SYSLOG 0
+#define def_syslog_goodpri (sudo_defs_table[1].sd_un.ival)
+#define I_SYSLOG_GOODPRI 1
+#define def_syslog_badpri (sudo_defs_table[2].sd_un.ival)
+#define I_SYSLOG_BADPRI 2
+#define def_long_otp_prompt (sudo_defs_table[3].sd_un.flag)
+#define I_LONG_OTP_PROMPT 3
+#define def_ignore_dot (sudo_defs_table[4].sd_un.flag)
+#define I_IGNORE_DOT 4
+#define def_mail_always (sudo_defs_table[5].sd_un.flag)
+#define I_MAIL_ALWAYS 5
+#define def_mail_badpass (sudo_defs_table[6].sd_un.flag)
+#define I_MAIL_BADPASS 6
+#define def_mail_no_user (sudo_defs_table[7].sd_un.flag)
+#define I_MAIL_NO_USER 7
+#define def_mail_no_host (sudo_defs_table[8].sd_un.flag)
+#define I_MAIL_NO_HOST 8
+#define def_mail_no_perms (sudo_defs_table[9].sd_un.flag)
+#define I_MAIL_NO_PERMS 9
+#define def_tty_tickets (sudo_defs_table[10].sd_un.flag)
+#define I_TTY_TICKETS 10
+#define def_lecture (sudo_defs_table[11].sd_un.tuple)
+#define I_LECTURE 11
+#define def_authenticate (sudo_defs_table[12].sd_un.flag)
+#define I_AUTHENTICATE 12
+#define def_root_sudo (sudo_defs_table[13].sd_un.flag)
+#define I_ROOT_SUDO 13
+#define def_log_host (sudo_defs_table[14].sd_un.flag)
+#define I_LOG_HOST 14
+#define def_log_year (sudo_defs_table[15].sd_un.flag)
+#define I_LOG_YEAR 15
+#define def_shell_noargs (sudo_defs_table[16].sd_un.flag)
+#define I_SHELL_NOARGS 16
+#define def_set_home (sudo_defs_table[17].sd_un.flag)
+#define I_SET_HOME 17
+#define def_always_set_home (sudo_defs_table[18].sd_un.flag)
+#define I_ALWAYS_SET_HOME 18
+#define def_path_info (sudo_defs_table[19].sd_un.flag)
+#define I_PATH_INFO 19
+#define def_fqdn (sudo_defs_table[20].sd_un.flag)
+#define I_FQDN 20
+#define def_insults (sudo_defs_table[21].sd_un.flag)
+#define I_INSULTS 21
+#define def_requiretty (sudo_defs_table[22].sd_un.flag)
+#define I_REQUIRETTY 22
+#define def_env_editor (sudo_defs_table[23].sd_un.flag)
+#define I_ENV_EDITOR 23
+#define def_rootpw (sudo_defs_table[24].sd_un.flag)
+#define I_ROOTPW 24
+#define def_runaspw (sudo_defs_table[25].sd_un.flag)
+#define I_RUNASPW 25
+#define def_targetpw (sudo_defs_table[26].sd_un.flag)
+#define I_TARGETPW 26
+#define def_use_loginclass (sudo_defs_table[27].sd_un.flag)
+#define I_USE_LOGINCLASS 27
+#define def_set_logname (sudo_defs_table[28].sd_un.flag)
+#define I_SET_LOGNAME 28
+#define def_stay_setuid (sudo_defs_table[29].sd_un.flag)
+#define I_STAY_SETUID 29
+#define def_env_reset (sudo_defs_table[30].sd_un.flag)
+#define I_ENV_RESET 30
+#define def_preserve_groups (sudo_defs_table[31].sd_un.flag)
+#define I_PRESERVE_GROUPS 31
+#define def_loglinelen (sudo_defs_table[32].sd_un.ival)
+#define I_LOGLINELEN 32
+#define def_timestamp_timeout (sudo_defs_table[33].sd_un.ival)
+#define I_TIMESTAMP_TIMEOUT 33
+#define def_passwd_timeout (sudo_defs_table[34].sd_un.ival)
+#define I_PASSWD_TIMEOUT 34
+#define def_passwd_tries (sudo_defs_table[35].sd_un.ival)
+#define I_PASSWD_TRIES 35
+#define def_umask (sudo_defs_table[36].sd_un.mode)
+#define I_UMASK 36
+#define def_logfile (sudo_defs_table[37].sd_un.str)
+#define I_LOGFILE 37
+#define def_mailerpath (sudo_defs_table[38].sd_un.str)
+#define I_MAILERPATH 38
+#define def_mailerflags (sudo_defs_table[39].sd_un.str)
+#define I_MAILERFLAGS 39
+#define def_mailto (sudo_defs_table[40].sd_un.str)
+#define I_MAILTO 40
+#define def_mailsub (sudo_defs_table[41].sd_un.str)
+#define I_MAILSUB 41
+#define def_badpass_message (sudo_defs_table[42].sd_un.str)
+#define I_BADPASS_MESSAGE 42
+#define def_timestampdir (sudo_defs_table[43].sd_un.str)
+#define I_TIMESTAMPDIR 43
+#define def_timestampowner (sudo_defs_table[44].sd_un.str)
+#define I_TIMESTAMPOWNER 44
+#define def_exempt_group (sudo_defs_table[45].sd_un.str)
+#define I_EXEMPT_GROUP 45
+#define def_passprompt (sudo_defs_table[46].sd_un.str)
+#define I_PASSPROMPT 46
+#define def_runas_default (sudo_defs_table[47].sd_un.str)
+#define I_RUNAS_DEFAULT 47
+#define def_editor (sudo_defs_table[48].sd_un.str)
+#define I_EDITOR 48
+#define def_env_check (sudo_defs_table[49].sd_un.list)
+#define I_ENV_CHECK 49
+#define def_env_delete (sudo_defs_table[50].sd_un.list)
+#define I_ENV_DELETE 50
+#define def_env_keep (sudo_defs_table[51].sd_un.list)
+#define I_ENV_KEEP 51
+#define def_listpw (sudo_defs_table[52].sd_un.tuple)
+#define I_LISTPW 52
+#define def_verifypw (sudo_defs_table[53].sd_un.tuple)
+#define I_VERIFYPW 53
+
+enum def_tupple {
+ never,
+ once,
+ always,
+ any,
+ all,
+};
# var_name
# TYPE
# description (or NULL)
+# array of struct def_values if TYPE == T_TUPLE
#
-syslog_ifac
- T_UINT
- NULL
-syslog_igoodpri
- T_UINT
- NULL
-syslog_ibadpri
- T_UINT
- NULL
syslog
T_LOGFAC|T_BOOL
"Syslog facility if syslog is being used for logging: %s"
T_FLAG
"Use a separate timestamp for each user/tty combo"
lecture
- T_FLAG
+ T_TUPLE|T_BOOL
"Lecture user the first time they run sudo"
+ never once always
authenticate
T_FLAG
"Require users to authenticate by default"
env_keep
T_LIST|T_BOOL
"Environment variables to preserve:"
-listpw_i
- T_UINT
- NULL
-verifypw_i
- T_UINT
- NULL
listpw
- T_PWFLAG
+ T_TUPLE|T_BOOL
"When to require a password for 'list' pseudocommand: %s"
+ never any all always
verifypw
- T_PWFLAG
+ T_TUPLE|T_BOOL
"When to require a password for 'verify' pseudocommand: %s"
+ never any all always
* Local prototypes.
*/
static int store_int __P((char *, struct sudo_defs_types *, int));
-static int store_uint __P((char *, struct sudo_defs_types *, int));
+static int store_list __P((char *, struct sudo_defs_types *, int));
+static int store_mode __P((char *, struct sudo_defs_types *, int));
static int store_str __P((char *, struct sudo_defs_types *, int));
static int store_syslogfac __P((char *, struct sudo_defs_types *, int));
static int store_syslogpri __P((char *, struct sudo_defs_types *, int));
-static int store_mode __P((char *, struct sudo_defs_types *, int));
-static int store_pwflag __P((char *, struct sudo_defs_types *, int));
-static int store_list __P((char *, struct sudo_defs_types *, int));
+static int store_tuple __P((char *, struct sudo_defs_types *, int));
+static int store_uint __P((char *, struct sudo_defs_types *, int));
static void list_op __P((char *, size_t, struct sudo_defs_types *, enum list_ops));
+static const char *logfac2str __P((int));
+static const char *logpri2str __P((int));
/*
* Table describing compile-time and run-time options.
{
struct sudo_defs_types *cur;
struct list_member *item;
+ struct def_values *def;
for (cur = sudo_defs_table; cur->name; cur++) {
if (cur->desc) {
puts(cur->desc);
break;
case T_STR:
- case T_LOGFAC:
- case T_LOGPRI:
- case T_PWFLAG:
if (cur->sd_un.str) {
(void) printf(cur->desc, cur->sd_un.str);
putchar('\n');
}
break;
+ case T_LOGFAC:
+ if (cur->sd_un.ival) {
+ (void) printf(cur->desc, logfac2str(cur->sd_un.ival));
+ putchar('\n');
+ }
+ break;
+ case T_LOGPRI:
+ if (cur->sd_un.ival) {
+ (void) printf(cur->desc, logpri2str(cur->sd_un.ival));
+ putchar('\n');
+ }
+ break;
case T_UINT:
case T_INT:
(void) printf(cur->desc, cur->sd_un.ival);
printf("\t%s\n", item->value);
}
break;
+ case T_TUPLE:
+ for (def = cur->values; def->sval; def++) {
+ if (cur->sd_un.ival == def->ival) {
+ (void) printf(cur->desc, def->sval);
+ break;
+ }
+ }
+ putchar('\n');
+ break;
}
}
}
return(FALSE);
}
break;
- case T_PWFLAG:
- if (!store_pwflag(val, cur, op)) {
- if (val)
- warnx("value `%s' is invalid for option `%s'", val, var);
- else
- warnx("no value specified for `%s' on line %d",
- var, sudolineno);
- return(FALSE);
- }
- break;
case T_STR:
if (!val) {
/* Check for bogus boolean usage or lack of a value. */
warnx("value `%s' is invalid for option `%s'", val, var);
return(FALSE);
}
+ break;
+ case T_TUPLE:
+ if (!val) {
+ /* Check for bogus boolean usage or lack of a value. */
+ if (!(cur->type & T_BOOL) || op != FALSE) {
+ warnx("no value specified for `%s' on line %d",
+ var, sudolineno);
+ return(FALSE);
+ }
+ }
+ if (!store_tuple(val, cur, op)) {
+ warnx("value `%s' is invalid for option `%s'", val, var);
+ return(FALSE);
+ }
+ break;
}
return(TRUE);
for (def = sudo_defs_table; def->name; def++)
switch (def->type & T_MASK) {
case T_STR:
- case T_LOGFAC:
- case T_LOGPRI:
- case T_PWFLAG:
if (def->sd_un.str) {
free(def->sd_un.str);
def->sd_un.str = NULL;
def_tty_tickets = TRUE;
#endif
#ifndef NO_LECTURE
- def_lecture = TRUE;
+ def_lecture = once;
#endif
#ifndef NO_AUTHENTICATION
def_authenticate = TRUE;
#endif
/* Password flags also have a string and integer component. */
- (void) store_pwflag("any", &sudo_defs_table[I_LISTPW], TRUE);
- (void) store_pwflag("all", &sudo_defs_table[I_VERIFYPW], TRUE);
+ (void) store_tuple("any", &sudo_defs_table[I_LISTPW], TRUE);
+ (void) store_tuple("all", &sudo_defs_table[I_VERIFYPW], TRUE);
/* Then initialize the int-like things. */
#ifdef SUDO_UMASK
return(TRUE);
}
+static int
+store_tuple(val, def, op)
+ char *val;
+ struct sudo_defs_types *def;
+ int op;
+{
+ struct def_values *v;
+
+ /*
+ * Since enums are really just ints we store the value as an ival.
+ * In the future, there may be multiple enums for different tuple
+ * types we want to avoid and special knowledge of the tuple type.
+ * This does assume that the first entry in the tuple enum will
+ * be the equivalent to a boolean "false".
+ */
+ if (op == FALSE) {
+ def->sd_un.ival = 0;
+ } else {
+ for (v = def->values; v != NULL; v++) {
+ if (strcmp(v->sval, val) == 0) {
+ def->sd_un.ival = v->ival;
+ break;
+ }
+ }
+ if (v == NULL)
+ return(FALSE);
+ }
+ return(TRUE);
+}
+
static int
store_str(val, def, op)
char *val;
struct strmap *fac;
if (op == FALSE) {
- if (def->sd_un.str) {
- free(def->sd_un.str);
- def->sd_un.str = NULL;
- }
+ def->sd_un.ival = FALSE;
return(TRUE);
}
#ifdef LOG_NFACILITIES
if (fac->name == NULL)
return(FALSE); /* not found */
- /* Store both name and number. */
- if (def->sd_un.str)
- free(def->sd_un.str);
- def->sd_un.str = estrdup(fac->name);
- sudo_defs_table[I_LOGFAC].sd_un.ival = fac->num;
+ def->sd_un.ival = fac->num;
#else
- if (def->sd_un.str)
- free(def->sd_un.str);
- def->sd_un.str = estrdup("default");
+ def->sd_un.ival = -1;
#endif /* LOG_NFACILITIES */
return(TRUE);
}
+static const char *
+logfac2str(n)
+ int n;
+{
+#ifdef LOG_NFACILITIES
+ struct strmap *fac;
+
+ for (fac = facilities; fac->name && fac->num != n; fac++)
+ ;
+ return (fac->name);
+#else
+ return ("default");
+#endif /* LOG_NFACILITIES */
+}
+
static int
store_syslogpri(val, def, op)
char *val;
int op;
{
struct strmap *pri;
- struct sudo_defs_types *idef;
if (op == FALSE || !val)
return(FALSE);
- if (def == &sudo_defs_table[I_SYSLOG_GOODPRI])
- idef = &sudo_defs_table[I_GOODPRI];
- else if (def == &sudo_defs_table[I_SYSLOG_BADPRI])
- idef = &sudo_defs_table[I_BADPRI];
- else
- return(FALSE);
for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
;
if (pri->name == NULL)
return(FALSE); /* not found */
- /* Store both name and number. */
- if (def->sd_un.str)
- free(def->sd_un.str);
- def->sd_un.str = estrdup(pri->name);
- idef->sd_un.ival = pri->num;
+ def->sd_un.ival = pri->num;
return(TRUE);
}
+static const char *
+logpri2str(n)
+ int n;
+{
+ struct strmap *pri;
+
+ for (pri = priorities; pri->name && pri->num != n; pri++)
+ ;
+ return (pri->name);
+}
+
static int
store_mode(val, def, op)
char *val;
return(TRUE);
}
-static int
-store_pwflag(val, def, op)
- char *val;
- struct sudo_defs_types *def;
- int op;
-{
- int isub, flags;
-
- if (strcmp(def->name, "verifypw") == 0)
- isub = I_VERIFYPW_I;
- else
- isub = I_LISTPW_I;
-
- /* Handle !foo. */
- if (op == FALSE) {
- if (def->sd_un.str) {
- free(def->sd_un.str);
- def->sd_un.str = NULL;
- }
- def->sd_un.str = estrdup("never");
- sudo_defs_table[isub].sd_un.ival = PWCHECK_NEVER;
- return(TRUE);
- }
- if (!val)
- return(FALSE);
-
- /* Convert strings to integer values. */
- if (strcmp(val, "all") == 0)
- flags = PWCHECK_ALL;
- else if (strcmp(val, "any") == 0)
- flags = PWCHECK_ANY;
- else if (strcmp(val, "never") == 0)
- flags = PWCHECK_NEVER;
- else if (strcmp(val, "always") == 0)
- flags = PWCHECK_ALWAYS;
- else
- return(FALSE);
-
- /* Store both name and number. */
- if (def->sd_un.str)
- free(def->sd_un.str);
- def->sd_un.str = estrdup(val);
- sudo_defs_table[isub].sd_un.ival = flags;
-
- return(TRUE);
-}
-
static void
list_op(val, len, def, op)
char *val;
#ifndef _SUDO_DEFAULTS_H
#define _SUDO_DEFAULTS_H
+#include <def_data.h>
+
struct list_member {
char *value;
struct list_member *next;
};
+struct def_values {
+ char *sval; /* string value */
+ int ival; /* actually an enum */
+};
+
enum list_ops {
add,
delete,
char *name;
int type;
char *desc;
+ struct def_values *values;
union {
int flag;
int ival;
+ enum def_tupple tuple;
char *str;
mode_t mode;
struct list_member *list;
#define T_LOGFAC 0x007
#undef T_LOGPRI
#define T_LOGPRI 0x008
-#undef T_PWFLAG
-#define T_PWFLAG 0x009
+#undef T_TUPLE
+#define T_TUPLE 0x009
#undef T_MASK
#define T_MASK 0x0FF
#undef T_BOOL
#undef T_PATH
#define T_PATH 0x200
-/*
- * Indexes into sudo_defs_table
- */
-#include <def_data.h>
-#define I_LOGFAC I_SYSLOG_IFAC
-#define I_GOODPRI I_SYSLOG_IGOODPRI
-#define I_BADPRI I_SYSLOG_IBADPRI
-
/*
* Prototypes
*/
va_start(ap);
#endif
#ifdef LOG_NFACILITIES
- openlog("sudo", 0, def_syslog_ifac);
+ openlog("sudo", 0, def_syslog);
#else
openlog("sudo", 0);
#endif
int pri;
if (status & VALIDATE_OK)
- pri = def_syslog_igoodpri;
+ pri = def_syslog_goodpri;
else
- pri = def_syslog_ibadpri;
+ pri = def_syslog_badpri;
/* Set error message, if any. */
if (status & VALIDATE_OK)
* Log to syslog and/or a file.
*/
if (def_syslog)
- do_syslog(def_syslog_ibadpri, logline);
+ do_syslog(def_syslog_badpri, logline);
if (def_logfile)
do_logfile(logline);
# var_name
# TYPE
# description (or NULL)
+# array of struct def_values if TYPE == T_TUPLE
# Deal with optional -o (output) argument
if ($#ARGV > 0 && $ARGV[0] eq "-o") {
open(HEADER, ">$header") || die "$0: can't open $header: $!\n";
open(CFILE, ">$cfile") || die "$0: can't open $cfile: $!\n";
-print CFILE "struct sudo_defs_types sudo_defs_table[] = {\n {\n";
-
-$count = -1;
+$count = 0;
+@tuple_values = ( "never" );
+@records = ();
while(<IN>) {
chomp;
+ s/\s*#.*$//;
next if /^\s*$/;
- next if /^\s*#/;
if (/^\S/) {
- # Print last record
- &print_record() if defined($var);
+ # Store previous record and begin new one
+ $records[$count++] = [$var, $type, $desc, $values] if defined($var);
$var = $_;
- ($type, $desc) = (undef, undef);
- $count++;
+ $type = '';
+ $desc = undef;
+ $values = undef;
+ $field = 0;
} else {
+ $field++;
s/^\s+//;
s/\s+$//;
die "$0: syntax error near line $.\n" if
- defined($type) && defined($desc);
- next if /^NULL$/;
- if (defined($type)) {
- # Strip leading and trailing double quote and escape the rest
- s/^"//;
- s/"$//;
- s/"/\\"/g;
- $desc = "\"$_\"";
- } else {
+ $field > 2 + ($type =~ /^T_TUPLE/);
+ if ($field == 1) {
+ # type
$type = $_;
+ } elsif ($field == 2) {
+ # description
+ if ($_ eq "NULL") {
+ $desc = "NULL";
+ } else {
+ # Strip leading and trailing double quote and escape the rest
+ s/^"//;
+ s/"$//;
+ s/"/\\"/g;
+ $desc = "\"$_\"";
+ }
+ } elsif ($field == 3) {
+ $values = [ split ];
+ foreach $v (@$values) {
+ push(@tuple_values, $v) unless grep(/^$v$/, @tuple_values);
+ }
}
}
}
-&print_record();
+$records[$count++] = [$var, $type, $desc, $values] if defined($var);
+
+# Print out value arrays
+for ($i = 0; $i < $count; $i++) {
+ if (defined($records[$i]->[3])) {
+ die "Values list specified for non-tupple\n" unless
+ $records[$i]->[1] =~ /^T_TUPLE/;
+ printf CFILE "static struct def_values def_data_%s[] = {\n", $records[$i]->[0];
+ foreach (@{$records[$i]->[3]}) {
+ print CFILE " { \"$_\", $_ },\n";
+ }
+ print CFILE " { NULL, 0 },\n";
+ print CFILE "};\n\n";
+ }
+}
+
+# Print each record
+print CFILE "struct sudo_defs_types sudo_defs_table[] = {\n {\n";
+for ($i = 0; $i < $count; $i++) {
+ &print_record($records[$i], $i);
+}
print CFILE "\tNULL, 0, NULL\n }\n};\n";
+# Print out def_tuple
+if (@tuple_values) {
+ print HEADER "\nenum def_tupple {\n";
+ foreach (@tuple_values) {
+ print HEADER "\t$_,\n";
+ }
+ print HEADER "};\n";
+}
+
close(IN);
close(HEADER);
close(CFILE);
sub print_record {
- my ($v, $defname);
+ my ($rec, $recnum) = @_;
+ my ($i, $v, $defname);
# each variable gets a macro to access its value
- for ($type) {
+ for ($rec->[1]) {
if (/^T_U?INT/) { $v = "ival"; }
- elsif (/^(T_STR|T_PWFLAG|T_LOG)/) { $v = "str"; }
+ elsif (/^T_STR/) { $v = "str"; }
elsif (/^T_FLAG/) { $v = "flag"; }
elsif (/^T_MODE/) { $v = "mode"; }
elsif (/^T_LIST/) { $v = "list"; }
+ elsif (/^T_LOGFAC/) { $v = "ival"; }
+ elsif (/^T_LOGPRI/) { $v = "ival"; }
+ elsif (/^T_TUPLE/) { $v = "tuple"; }
else { die "$0: unknown defaults type: $type\n"; }
}
- printf HEADER "#define %-24s(sudo_defs_table[$count].sd_un.${v})\n",
- "def_${var}";
+ printf HEADER "#define %-24s(sudo_defs_table[$recnum].sd_un.${v})\n",
+ "def_$rec->[0]";
- $defname = "I_" . uc($var);
- printf HEADER "#define %-24s%d", $defname, $count;
- #print HEADER "\t/* $desc */" if defined($desc);
+ $defname = "I_" . uc($rec->[0]);
+ printf HEADER "#define %-24s%d", $defname, $recnum;
+ #print HEADER "\t/* $rec->[2] */" if defined($rec->[2]);
print HEADER "\n";
- $desc = "NULL" unless defined($desc);
- print CFILE "\t\"$var\", $type,\n\t$desc\n }, {\n";
+ print CFILE "\t\"$rec->[0]\", $rec->[1],\n\t$rec->[2],\n";
+ if (defined($rec->[3])) {
+ printf CFILE "\tdef_data_$rec->[0],\n";
+ }
+ print CFILE " }, {\n";
}
sudoers_lookup(pwflag)
int pwflag;
{
- int error;
- int pwcheck;
- int nopass;
+ int error, nopass;
+ enum def_tupple pwcheck;
/* Become sudoers file owner */
set_perms(PERM_SUDOERS);
/* Allocate space for data structures in the parser. */
init_parser();
- /* If pwcheck *could* be PWCHECK_ALL or PWCHECK_ANY, keep more state. */
+ /* If pwcheck *could* be "all" or "any", keep more state. */
if (pwflag > 0)
keepall = TRUE;
* wait until now to set this.
*/
if (pwflag)
- pwcheck = (pwflag == -1) ? PWCHECK_NEVER : sudo_defs_table[pwflag].sd_un.ival;
+ pwcheck = (pwflag == -1) ? never : sudo_defs_table[pwflag].sd_un.tuple;
else
pwcheck = 0;
}
/*
- * Only check the actual command if pwcheck flag is not set.
+ * Only check the actual command if pwflag is not set.
* It is set for the "validate", "list" and "kill" pseudo-commands.
* Always check the host and user.
*/
nopass = -1;
- if (pwcheck) {
+ if (pwflag) {
int found;
- if (pwcheck == PWCHECK_NEVER || !def_authenticate)
+ if (pwcheck == always && def_authenticate)
+ nopass = FLAG_CHECK_USER;
+ else if (pwcheck == never || !def_authenticate)
nopass = FLAG_NOPASS;
found = 0;
while (top) {
if (host_matches == TRUE) {
found = 1;
- if (pwcheck == PWCHECK_ANY && no_passwd == TRUE)
+ if (pwcheck == any && no_passwd == TRUE)
nopass = FLAG_NOPASS;
- else if (pwcheck == PWCHECK_ALL && nopass != 0)
+ else if (pwcheck == all && nopass != 0)
nopass = (no_passwd == TRUE) ? FLAG_NOPASS : 0;
}
top--;
break;
case MODE_VALIDATE:
user_cmnd = "validate";
- pwflag = I_VERIFYPW_I;
+ pwflag = I_VERIFYPW;
break;
case MODE_KILL:
case MODE_INVALIDATE:
break;
case MODE_LIST:
user_cmnd = "list";
- pwflag = I_LISTPW_I;
+ pwflag = I_LISTPW;
printmatches = 1;
break;
}
/* Fill in passwd struct based on user we are authenticating as. */
auth_pw = get_authpw();
- /* Require a password unless the NOPASS tag was set. */
+ /* Require a password if sudoers says so. */
if (!(validated & FLAG_NOPASS))
- check_user();
+ check_user(validated & FLAG_CHECK_USER);
/* Build up custom environment that avoids any nasty bits. */
new_environ = rebuild_env(sudo_mode, envp);
* Note: cannot use '0' as a value here.
*/
/* XXX - VALIDATE_SUCCESS and VALIDATE_FAILURE instead? */
-#define VALIDATE_ERROR 0x01
-#define VALIDATE_OK 0x02
-#define VALIDATE_NOT_OK 0x04
-#define FLAG_NOPASS 0x10
-#define FLAG_NO_USER 0x20
-#define FLAG_NO_HOST 0x40
-#define FLAG_NO_CHECK 0x80
+#define VALIDATE_ERROR 0x001
+#define VALIDATE_OK 0x002
+#define VALIDATE_NOT_OK 0x004
+#define FLAG_CHECK_USER 0x010
+#define FLAG_NOPASS 0x020
+#define FLAG_NO_USER 0x040
+#define FLAG_NO_HOST 0x080
+#define FLAG_NO_CHECK 0x100
/*
* Boolean values
#define SUDO_TLOCK 2 /* test & lock a file (non-blocking) */
#define SUDO_UNLOCK 4 /* unlock a file */
-/*
- * Flags for sudoers_lookup:
- * PASSWD_NEVER: user never has to give a passwd
- * PASSWD_ALL: no passwd needed if all entries for host have NOPASSWD flag
- * PASSWD_ANY: no passwd needed if any entry for host has a NOPASSWD flag
- * PASSWD_ALWAYS: passwd always needed
- */
-#define PWCHECK_NEVER 0x01
-#define PWCHECK_ALL 0x02
-#define PWCHECK_ANY 0x04
-#define PWCHECK_ALWAYS 0x08
-
/*
* Flags for tgetpass()
*/
char *sudo_goodpath __P((const char *));
char *tgetpass __P((const char *, int, int));
int find_path __P((char *, char **, char *));
-void check_user __P((void));
+void check_user __P((int));
void verify_user __P((struct passwd *, char *));
int sudoers_lookup __P((int));
void set_perms_nosuid __P((int));