From 5ce1fa96f22dbafbf0e0d56babef57cd62ea67d2 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Thu, 23 Mar 2000 04:09:53 +0000 Subject: [PATCH] Add support for wildcards in the hostname. --- parse.c | 15 ++++ parse.h | 1 + parse.yacc | 6 +- sudo.tab.c | 6 +- sudoers.cat | 232 ++++++++++++++++++++++++------------------------- sudoers.man.in | 16 ++-- sudoers.pod | 12 ++- testsudoers.c | 12 +++ visudo.c | 8 ++ 9 files changed, 176 insertions(+), 132 deletions(-) diff --git a/parse.c b/parse.c index 77cacf662..915ca2c34 100644 --- a/parse.c +++ b/parse.c @@ -385,6 +385,21 @@ addr_matches(n) return(FALSE); } +/* + * Returns 0 if the hostname matches the pattern and non-zero otherwise. + */ +int +hostname_matches(host, pattern) + char *host; + char *pattern; +{ + + if (has_meta(pattern)) + return(fnmatch(pattern, host, FNM_CASEFOLD)); + else + return(strcasecmp(host, pattern)); +} + /* * Returns TRUE if the given user belongs to the named group, * else returns FALSE. diff --git a/parse.h b/parse.h index 2316fd66c..5e727185a 100644 --- a/parse.h +++ b/parse.h @@ -109,6 +109,7 @@ extern int top; */ int addr_matches __P((char *)); int command_matches __P((char *, char *, char *, char *)); +int hostname_matches __P((char *, char *)); int netgr_matches __P((char *, char *, char *, char *)); int usergr_matches __P((char *, char *)); diff --git a/parse.yacc b/parse.yacc index 655318902..4d756bdf4 100644 --- a/parse.yacc +++ b/parse.yacc @@ -361,14 +361,14 @@ host : ALL { free($1); } | WORD { - if (strcasecmp(user_shost, $1) == 0) + if (hostname_matches(user_shost, $1) == 0) $$ = TRUE; else $$ = -1; free($1); } | FQHOST { - if (strcasecmp(user_host, $1) == 0) + if (hostname_matches(user_host, $1) == 0) $$ = TRUE; else $$ = -1; @@ -380,7 +380,7 @@ host : ALL { /* could be an all-caps hostname */ if (aip) $$ = aip->val; - else if (strcasecmp(user_shost, $1) == 0) + else if (hostname_matches(user_shost, $1) == 0) $$ = TRUE; else { if (pedantic) { diff --git a/sudo.tab.c b/sudo.tab.c index e21cb1610..4805d6846 100644 --- a/sudo.tab.c +++ b/sudo.tab.c @@ -1275,7 +1275,7 @@ break; case 31: #line 363 "parse.yacc" { - if (strcasecmp(user_shost, yyvsp[0].string) == 0) + if (hostname_matches(user_shost, yyvsp[0].string) == 0) yyval.BOOLEAN = TRUE; else yyval.BOOLEAN = -1; @@ -1285,7 +1285,7 @@ break; case 32: #line 370 "parse.yacc" { - if (strcasecmp(user_host, yyvsp[0].string) == 0) + if (hostname_matches(user_host, yyvsp[0].string) == 0) yyval.BOOLEAN = TRUE; else yyval.BOOLEAN = -1; @@ -1300,7 +1300,7 @@ case 33: /* could be an all-caps hostname */ if (aip) yyval.BOOLEAN = aip->val; - else if (strcasecmp(user_shost, yyvsp[0].string) == 0) + else if (hostname_matches(user_shost, yyvsp[0].string) == 0) yyval.BOOLEAN = TRUE; else { if (pedantic) { diff --git a/sudoers.cat b/sudoers.cat index 60ac83e7c..a7c035b7e 100644 --- a/sudoers.cat +++ b/sudoers.cat @@ -150,7 +150,11 @@ sudoers(5) FILE FORMATS sudoers(5) ethernet _i_n_t_e_r_f_a_c_e(s) will be used when matching. The netmask may be specified either in dotted quad notation (eg. 255.255.255.0) or CIDR notation (number of bits, eg. - 24). + 24). A hostname may include shell-style wildcards (see + `Wildcards' section below), but unless the hostname + command on your machine returns the fully qualified + hostname, you'll need to use the _f_q_d_n option for wildcards + to be useful. Cmnd_List ::= Cmnd | Cmnd ',' Cmnd_List @@ -164,7 +168,7 @@ sudoers(5) FILE FORMATS sudoers(5) '!'* Cmnd_Alias A Cmnd_List is a list of one or more commandnames, - directories, and other aliases. A commandname is a fully- + directories, and other aliases. A commandname is a fully qualified filename which may include shell-style wildcards (see `Wildcards' section below). A simple filename allows the user to run the command with any arguments he/she @@ -183,13 +187,9 @@ sudoers(5) FILE FORMATS sudoers(5) be escaped with a '\' if they are used in command arguments: ',', ':', '=', '\'. - DDDDeeeeffffaaaauuuullllttttssss - Certain configuration options may be changed from their - default values at runtime via one or more Default_Entry - lines. These may affect all users on any host, all users - on a specific host, or just a specific user. When - multiple entries match, they are applied in order. Where + + @@ -202,6 +202,13 @@ sudoers(5) FILE FORMATS sudoers(5) sudoers(5) FILE FORMATS sudoers(5) + DDDDeeeeffffaaaauuuullllttttssss + + Certain configuration options may be changed from their + default values at runtime via one or more Default_Entry + lines. These may affect all users on any host, all users + on a specific host, or just a specific user. When + multiple entries match, they are applied in order. Where there are conflicting values, the last value on a matching line takes effect. @@ -249,13 +256,6 @@ sudoers(5) FILE FORMATS sudoers(5) if the invoking user exists in the _s_u_d_o_e_r_s file, but is not allowed to run commands on the current host. This flag is off by - default. - - mail_no_perms - If set, mail will be sent to the _m_a_i_l_t_o user - if the invoking user allowed to use ssssuuuuddddoooo but - the command they are trying is not listed in - their _s_u_d_o_e_r_s file entry. This flag is off by @@ -270,6 +270,13 @@ sudoers(5) FILE FORMATS sudoers(5) default. + mail_no_perms + If set, mail will be sent to the _m_a_i_l_t_o user + if the invoking user allowed to use ssssuuuuddddoooo but + the command they are trying is not listed in + their _s_u_d_o_e_r_s file entry. This flag is off by + default. + tty_tickets If set, users must authenticate on a per-tty basis. Normally, ssssuuuuddddoooo uses a directory in the ticket dir with the same name as the user @@ -315,13 +322,6 @@ sudoers(5) FILE FORMATS sudoers(5) set_home If set and ssssuuuuddddoooo is invoked with the -s flag the HOME environment variable will be set to the home directory of the target user (which - is root unless the -u option is used). This - effectively makes the -s flag imply -H. This - flag is off by default. - - path_info Normally, ssssuuuuddddoooo will tell the user when a - command could not be found in their $PATH. - Some sites may wish to disable this as it @@ -334,6 +334,13 @@ sudoers(5) FILE FORMATS sudoers(5) sudoers(5) FILE FORMATS sudoers(5) + is root unless the -u option is used). This + effectively makes the -s flag imply -H. This + flag is off by default. + + path_info Normally, ssssuuuuddddoooo will tell the user when a + command could not be found in their $PATH. + Some sites may wish to disable this as it could be used to gather information on the location of executables that the normal user does not have access to. The disadvantage is @@ -381,13 +388,6 @@ sudoers(5) FILE FORMATS sudoers(5) to get a shell (which would be a root shell and not be logged). - rootpw If set, ssssuuuuddddoooo will prompt for the root password - instead of the password of the invoking user. - - runaspw If set, ssssuuuuddddoooo will prompt for the password of - the user defined by the _r_u_n_a_s___d_e_f_a_u_l_t option - (defaults to root) instead of the password of - the invoking user. @@ -400,6 +400,14 @@ sudoers(5) FILE FORMATS sudoers(5) sudoers(5) FILE FORMATS sudoers(5) + rootpw If set, ssssuuuuddddoooo will prompt for the root password + instead of the password of the invoking user. + + runaspw If set, ssssuuuuddddoooo will prompt for the password of + the user defined by the _r_u_n_a_s___d_e_f_a_u_l_t option + (defaults to root) instead of the password of + the invoking user. + targetpw If set, ssssuuuuddddoooo will prompt for the password of the user specified by the -u flag (defaults to root) instead of the password of the invoking @@ -446,25 +454,25 @@ sudoers(5) FILE FORMATS sudoers(5) passwd_timeout Number of minutes before the ssssuuuuddddoooo password prompt times out. The default is 5, set this - to 0 for no password timeout. - umask Umask to use when running the root command. - Set this to 0777 to not override the user's - umask. The default is 0022. - SSSSttttrrrriiiinnnnggggssss: +22/Mar/2000 1.6.3 7 -22/Mar/2000 1.6.3 7 +sudoers(5) FILE FORMATS sudoers(5) + to 0 for no password timeout. -sudoers(5) FILE FORMATS sudoers(5) + umask Umask to use when running the root command. + Set this to 0777 to not override the user's + umask. The default is 0022. + SSSSttttrrrriiiinnnnggggssss: mailsub Subject of the mail sent to the _m_a_i_l_t_o user. The escape %h will expand to the hostname of @@ -512,14 +520,6 @@ sudoers(5) FILE FORMATS sudoers(5) syslog Syslog facility if syslog is being used for logging (negate to disable syslog logging). - Defaults to "local2". - - mailerpath Path to mail program used to send warning - mail. Defaults to the path to sendmail found - at configure time. - - mailerflags Flags to use when invoking mailer. Defaults to - -t. @@ -532,6 +532,15 @@ sudoers(5) FILE FORMATS sudoers(5) sudoers(5) FILE FORMATS sudoers(5) + Defaults to "local2". + + mailerpath Path to mail program used to send warning + mail. Defaults to the path to sendmail found + at configure time. + + mailerflags Flags to use when invoking mailer. Defaults to + -t. + mailto Address to send warning and erorr mail to. Defaults to "root". @@ -576,16 +585,7 @@ sudoers(5) FILE FORMATS sudoers(5) current host must have the C flag set to avoid entering a password. - any At least one of the user's I entries - for the current host must have the - C flag set to avoid entering a - password. - never The user need never enter a password to use - the B<-l> flag. - - always The user must always enter a password to use - the B<-l> flag. @@ -598,6 +598,17 @@ sudoers(5) FILE FORMATS sudoers(5) sudoers(5) FILE FORMATS sudoers(5) + any At least one of the user's I entries + for the current host must have the + C flag set to avoid entering a + password. + + never The user need never enter a password to use + the B<-l> flag. + + always The user must always enter a password to use + the B<-l> flag. + The default value is `any'. When logging via _s_y_s_l_o_g(3), ssssuuuuddddoooo accepts the following @@ -642,27 +653,26 @@ sudoers(5) FILE FORMATS sudoers(5) The user ddddggggbbbb may run _/_b_i_n_/_l_s, _/_b_i_n_/_k_i_l_l, and _/_u_s_r_/_b_i_n_/_l_p_r_m -- but only as ooooppppeeeerrrraaaattttoooorrrr. Eg. - sudo -u operator /bin/ls. - - It is also possible to override a Runas_Spec later on in - an entry. If we modify the entry like so: - dgb boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm - Then user ddddggggbbbb is now allowed to run _/_b_i_n_/_l_s as ooooppppeeeerrrraaaattttoooorrrr, - but _/_b_i_n_/_k_i_l_l and _/_u_s_r_/_b_i_n_/_l_p_r_m as rrrrooooooootttt. +22/Mar/2000 1.6.3 10 -22/Mar/2000 1.6.3 10 +sudoers(5) FILE FORMATS sudoers(5) + sudo -u operator /bin/ls. + It is also possible to override a Runas_Spec later on in + an entry. If we modify the entry like so: -sudoers(5) FILE FORMATS sudoers(5) + dgb boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm + Then user ddddggggbbbb is now allowed to run _/_b_i_n_/_l_s as ooooppppeeeerrrraaaattttoooorrrr, + but _/_b_i_n_/_k_i_l_l and _/_u_s_r_/_b_i_n_/_l_p_r_m as rrrrooooooootttt. NNNNOOOOPPPPAAAASSSSSSSSWWWWDDDD aaaannnndddd PPPPAAAASSSSSSSSWWWWDDDD @@ -707,16 +717,6 @@ sudoers(5) FILE FORMATS sudoers(5) [...] Matches any character in the specified range. - [!...] Matches any character nnnnooootttt in the specified range. - - \x For any character "x", evaluates to "x". This is - used to escape special characters such as: "*", - "?", "[", and "}". - - Note that a forward slash ('/') will nnnnooootttt be matched by - wildcards used in the pathname. When matching the command - line arguments, however, as slash ddddooooeeeessss get matched by - wildcards. This is to make a path like: @@ -730,6 +730,17 @@ sudoers(5) FILE FORMATS sudoers(5) sudoers(5) FILE FORMATS sudoers(5) + [!...] Matches any character nnnnooootttt in the specified range. + + \x For any character "x", evaluates to "x". This is + used to escape special characters such as: "*", + "?", "[", and "}". + + Note that a forward slash ('/') will nnnnooootttt be matched by + wildcards used in the pathname. When matching the command + line arguments, however, as slash ddddooooeeeessss get matched by + wildcards. This is to make a path like: + /usr/bin/* match /usr/bin/who but not /usr/bin/X11/xterm. @@ -774,17 +785,6 @@ sudoers(5) FILE FORMATS sudoers(5) syntactic characters in a _U_s_e_r _S_p_e_c_i_f_i_c_a_t_i_o_n ('=', ':', '(', ')') is optional. - The following characters must be escaped with a backslash - ('\') when used as part of a word (eg. a username or - hostname): '@', '!', '=', ':', ',', '(', ')', '\'. - -EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS - Below are example _s_u_d_o_e_r_s entries. Admittedly, some of - these are a bit contrived. First, we define our _a_l_i_a_s_e_s: - - - - 22/Mar/2000 1.6.3 12 @@ -796,6 +796,14 @@ EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS sudoers(5) FILE FORMATS sudoers(5) + The following characters must be escaped with a backslash + ('\') when used as part of a word (eg. a username or + hostname): '@', '!', '=', ':', ',', '(', ')', '\'. + +EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS + Below are example _s_u_d_o_e_r_s entries. Admittedly, some of + these are a bit contrived. First, we define our _a_l_i_a_s_e_s: + # User alias specification User_Alias FULLTIMERS = millert, mikef, dowdy User_Alias PARTTIMERS = bostley, jwfox, crawl @@ -843,14 +851,6 @@ sudoers(5) FILE FORMATS sudoers(5) Defaults:millert !authenticate Defaults@SERVERS log_year, logfile=/var/log/sudo.log - The _U_s_e_r _s_p_e_c_i_f_i_c_a_t_i_o_n is the part that actually - determines who may run what. - - root ALL = (ALL) ALL - %wheel ALL = (ALL) ALL - - We let rrrrooooooootttt and any user in group wwwwhhhheeeeeeeellll run any command on - 22/Mar/2000 1.6.3 13 @@ -862,6 +862,13 @@ sudoers(5) FILE FORMATS sudoers(5) sudoers(5) FILE FORMATS sudoers(5) + The _U_s_e_r _s_p_e_c_i_f_i_c_a_t_i_o_n is the part that actually + determines who may run what. + + root ALL = (ALL) ALL + %wheel ALL = (ALL) ALL + + We let rrrrooooooootttt and any user in group wwwwhhhheeeeeeeellll run any command on any host as any user. FULLTIMERS ALL = NOPASSWD: ALL @@ -909,13 +916,6 @@ sudoers(5) FILE FORMATS sudoers(5) assumes _p_a_s_s_w_d(1) does not take multiple usernames on the command line. - bob SPARC = (OP) ALL : SGI = (OP) ALL - - The user bbbboooobbbb may run anything on the _S_P_A_R_C and _S_G_I - machines as any user listed in the _O_P Runas_Alias (rrrrooooooootttt - and ooooppppeeeerrrraaaattttoooorrrr). - - jim +biglab = ALL @@ -928,6 +928,14 @@ sudoers(5) FILE FORMATS sudoers(5) sudoers(5) FILE FORMATS sudoers(5) + bob SPARC = (OP) ALL : SGI = (OP) ALL + + The user bbbboooobbbb may run anything on the _S_P_A_R_C and _S_G_I + machines as any user listed in the _O_P Runas_Alias (rrrrooooooootttt + and ooooppppeeeerrrraaaattttoooorrrr). + + jim +biglab = ALL + The user jjjjiiiimmmm may run any command on machines in the _b_i_g_l_a_b netgroup. SSSSuuuuddddoooo knows that "biglab" is a netgroup due to the '+' prefix. @@ -974,14 +982,6 @@ sudoers(5) FILE FORMATS sudoers(5) On the host www, any user in the _W_E_B_M_A_S_T_E_R_S User_Alias (will, wendy, and wim), may run any command as user www - (which owns the web pages) or simply _s_u(1) to www. - - ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\ - /sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM - - Any user may mount or unmount a CD-ROM on the machines in - the CDROM Host_Alias (orion, perseus, hercules) without - entering a password. This is a bit tedious for users to @@ -994,6 +994,14 @@ sudoers(5) FILE FORMATS sudoers(5) sudoers(5) FILE FORMATS sudoers(5) + (which owns the web pages) or simply _s_u(1) to www. + + ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\ + /sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM + + Any user may mount or unmount a CD-ROM on the machines in + the CDROM Host_Alias (orion, perseus, hercules) without + entering a password. This is a bit tedious for users to type, so it is a prime candiate for encapsulating in a shell script. @@ -1020,9 +1028,9 @@ CCCCAAAAVVVVEEEEAAAATTTTSSSS incorrect _s_u_d_o_e_r_s file. When using netgroups of machines (as opposed to users), if - you store fully-qualified hostnames in the netgroup (as is + you store fully qualified hostnames in the netgroup (as is usually the case), you either need to have the machine's - hostname be fully-qualified as returned by the hostname + hostname be fully qualified as returned by the hostname command or use the _f_q_d_n option in _s_u_d_o_e_r_s. FFFFIIIILLLLEEEESSSS @@ -1043,14 +1051,6 @@ SSSSEEEEEEEE AAAALLLLSSSSOOOO - - - - - - - - 22/Mar/2000 1.6.3 16 diff --git a/sudoers.man.in b/sudoers.man.in index 214c60482..ce7f5d150 100644 --- a/sudoers.man.in +++ b/sudoers.man.in @@ -2,8 +2,8 @@ ''' $RCSfile$$Revision$$Date$ ''' ''' $Log$ -''' Revision 1.3 2000/03/23 03:20:57 millert -''' Document set_logname option and enbolden refs to sudo and visudo. +''' Revision 1.4 2000/03/23 04:09:53 millert +''' Add support for wildcards in the hostname. ''' ''' .de Sh @@ -315,7 +315,11 @@ Again, the value of an item may be negated with the \*(L'!\*(R' operator. If you do not specify a netmask with a network number, the netmask of the host's ethernet \fIinterface\fR\|(s) will be used when matching. The netmask may be specified either in dotted quad notation (eg. -255.255.255.0) or \s-1CIDR\s0 notation (number of bits, eg. 24). +255.255.255.0) or \s-1CIDR\s0 notation (number of bits, eg. 24). A hostname +may include shell-style wildcards (see `Wildcards\*(R' section below), +but unless the \f(CWhostname\fR command on your machine returns the fully +qualified hostname, you'll need to use the \fIfqdn\fR option for wildcards +to be useful. .PP .Vb 2 \& Cmnd_List ::= Cmnd | @@ -332,7 +336,7 @@ The netmask may be specified either in dotted quad notation (eg. \& '!'* Cmnd_Alias .Ve A \f(CWCmnd_List\fR is a list of one or more commandnames, directories, and other -aliases. A commandname is a fully-qualified filename which may include +aliases. A commandname is a fully qualified filename which may include shell-style wildcards (see `Wildcards\*(R' section below). A simple filename allows the user to run the command with any arguments he/she wishes. However, you may also command line arguments (including wildcards). @@ -961,8 +965,8 @@ imperative that \fIsudoers\fR be free of syntax errors since \fBsudo\fR will not run with a syntactically incorrect \fIsudoers\fR file. .PP When using netgroups of machines (as opposed to users), if you -store fully-qualified hostnames in the netgroup (as is usually the -case), you either need to have the machine's hostname be fully-qualified +store fully qualified hostnames in the netgroup (as is usually the +case), you either need to have the machine's hostname be fully qualified as returned by the \f(CWhostname\fR command or use the \fIfqdn\fR option in \fIsudoers\fR. .SH "FILES" diff --git a/sudoers.pod b/sudoers.pod index dba8dd56e..a592f2ad3 100644 --- a/sudoers.pod +++ b/sudoers.pod @@ -162,7 +162,11 @@ Again, the value of an item may be negated with the '!' operator. If you do not specify a netmask with a network number, the netmask of the host's ethernet interface(s) will be used when matching. The netmask may be specified either in dotted quad notation (eg. -255.255.255.0) or CIDR notation (number of bits, eg. 24). +255.255.255.0) or CIDR notation (number of bits, eg. 24). A hostname +may include shell-style wildcards (see `Wildcards' section below), +but unless the C command on your machine returns the fully +qualified hostname, you'll need to use the I option for wildcards +to be useful. Cmnd_List ::= Cmnd | Cmnd ',' Cmnd_List @@ -176,7 +180,7 @@ The netmask may be specified either in dotted quad notation (eg. '!'* Cmnd_Alias A C is a list of one or more commandnames, directories, and other -aliases. A commandname is a fully-qualified filename which may include +aliases. A commandname is a fully qualified filename which may include shell-style wildcards (see `Wildcards' section below). A simple filename allows the user to run the command with any arguments he/she wishes. However, you may also command line arguments (including wildcards). @@ -910,8 +914,8 @@ imperative that I be free of syntax errors since B will not run with a syntactically incorrect I file. When using netgroups of machines (as opposed to users), if you -store fully-qualified hostnames in the netgroup (as is usually the -case), you either need to have the machine's hostname be fully-qualified +store fully qualified hostnames in the netgroup (as is usually the +case), you either need to have the machine's hostname be fully qualified as returned by the C command or use the I option in I. diff --git a/testsudoers.c b/testsudoers.c index 9f7b53374..b517910dd 100644 --- a/testsudoers.c +++ b/testsudoers.c @@ -210,6 +210,18 @@ addr_matches(n) return(FALSE); } +int +hostname_matches(host, pattern) + char *host; + char *pattern; +{ + + if (has_meta(pattern)) + return(fnmatch(pattern, host, FNM_CASEFOLD)); + else + return(strcasecmp(host, pattern)); +} + int usergr_matches(group, user) char *group; diff --git a/visudo.c b/visudo.c index f7cbd984f..b9c53e20a 100644 --- a/visudo.c +++ b/visudo.c @@ -93,6 +93,7 @@ static RETSIGTYPE Exit __P((int)); static void setup_signals __P((void)); int command_matches __P((char *, char *, char *, char *)); int addr_matches __P((char *)); +int hostname_matches __P((char *, char *)); int netgr_matches __P((char *, char *, char *, char *)); int usergr_matches __P((char *, char *)); void init_parser __P((void)); @@ -405,6 +406,13 @@ addr_matches(n) return(TRUE); } +int +hostname_matches(h, p) + char *h, *p; +{ + return(TRUE); +} + int usergr_matches(g, u) char *g, *u; -- 2.40.0