tags 314949 patch upstream thanks On Tue, Jun 21, 2005 at 11:32:31AM +0200, Thomas Hood wrote: > On Sun, Jun 19, 2005 at 05:50:42PM +0200, Thomas Hood wrote: > > I get an error message from sudo even though I have > > > > Defaults !fqdn > > > > in /etc/sudoers. If I change this to > > > > Defaults fqdn > > > > then I get the error message twice. > > I'm not familiar with sudo's code but at the first glance it seems that > all calls to gethostbyname() are protected by the FQDN flag. One > possibility I can think of is that the config file is parsed _after_ the > first hostname check but I do not have enough time to check that.
Well, the config file and the file having hostname-restricted definitions for sudo rights is one and the same file: /etc/sudoers. The current logic is simply to query the FQDN always (./configure-controlled), and only later read /etc/sudoers. Disabling fqdn in that file will prevent any second and further query (it is not remembered whether the FQDN has already been queried at all, either). Right, so this logic needs a serious recosideration. Please find attached a patch which changes the logic as follows: - Querying of the FQDN will happen at most once, by remembering whether set_fqdn() has been succesfully called already - Every time a sudoers line is encountered which involves a hostname (so not 'ALL' or an IP address), the current configuration status is consulted (default is still 'true', but Defaults !fqdn might have disabled it), and a FQDN is performed if it hasn't been done already and the configuration allows it - If the 'fqdn' flag is explicitely set in /etc/sudoers, a FQDN lookup is forced if none has been done yet (this code was already present).[1] As a result, this means that no DNS query is done by default, and no DNS query is done at all as long as you don't have any non-ALL/non-IP 'hosts' statements. Note that my patch also does a FQDN if an alias is used, regardless whether that's needed. [1] For logging, in the logfile it is tried to use the full hostname. This is a trade-off, a lot of error conditions can happen before defaults line are encountered. I don't think logging should be with FQDN, no other deamon/service does that. For people who want FQDN logging, I left the 'force FQDN lookup' upon setting the fqdn option. There is now no way anymore to get FQDN-enhanced logging before the first line of /etc/sudoers is parsed. Note that I didn't update documentation, that still needs to happen, but I've spent enough time right now on this patch to not do it right now, anyone who reads this is invited to give it go, otherwise, I'll do it later. Please don't forget to re-yacc (byacc seems to have been used, not bison). --Jeroen -- Jeroen van Wolffelaar [EMAIL PROTECTED] http://jeroen.A-Eskwadraat.nl
diff -ur sudo-1.6.8p12.old/parse.yacc sudo-1.6.8p12/parse.yacc --- sudo-1.6.8p12.old/parse.yacc 2005-06-19 18:24:32.000000000 +0000 +++ sudo-1.6.8p12/parse.yacc 2006-03-31 20:41:36.000000000 +0000 @@ -396,6 +396,7 @@ free($1); } | NETGROUP { + set_fqdn(); if (netgr_matches($1, user_host, user_shost, NULL)) $$ = TRUE; else @@ -403,6 +404,7 @@ free($1); } | WORD { + set_fqdn(); if (hostname_matches(user_shost, user_host, $1) == 0) $$ = TRUE; else @@ -412,6 +414,7 @@ | ALIAS { aliasinfo *aip = find_alias($1, HOST_ALIAS); + set_fqdn(); /* could be an all-caps hostname */ if (aip) $$ = aip->val; diff -ur sudo-1.6.8p12.old/sudo.c sudo-1.6.8p12/sudo.c --- sudo-1.6.8p12.old/sudo.c 2005-06-19 20:35:46.000000000 +0000 +++ sudo-1.6.8p12/sudo.c 2006-03-31 21:12:45.000000000 +0000 @@ -510,22 +510,18 @@ * "host" is the (possibly fully-qualified) hostname and * "shost" is the unqualified form of the hostname. */ + sudo_user.host_fqdn_queried = FALSE; nohostname = gethostname(thost, sizeof(thost)); if (nohostname) user_host = user_shost = "localhost"; else { user_host = estrdup(thost); - if (def_fqdn) { - /* Defer call to set_fqdn() until log_error() is safe. */ - user_shost = user_host; + if ((p = strchr(user_host, '.'))) { + *p = '\0'; + user_shost = estrdup(user_host); + *p = '.'; } else { - if ((p = strchr(user_host, '.'))) { - *p = '\0'; - user_shost = estrdup(user_host); - *p = '.'; - } else { - user_shost = user_host; - } + user_shost = user_host; } } @@ -566,12 +562,12 @@ /* It is now safe to use log_error() and set_perms() */ - if (def_fqdn) - set_fqdn(); /* may call log_error() */ - if (nohostname) log_error(USE_ERRNO|MSG_ONLY, "can't get hostname"); + /* We don't query FQDN yet, it might get disabled later. Querying is done + * when host matching is executed and def_fqdn still true */ + set_runaspw(*user_runas); /* may call log_error() */ if (*user_runas[0] == '#' && runas_pw->pw_name && runas_pw->pw_name[0]) *user_runas = estrdup(runas_pw->pw_name); @@ -1010,6 +1006,11 @@ struct hostent *hp; char *p; + if (!def_fqdn || sudo_user.host_fqdn_queried) { + /* Only querying just once is good enough */ + return; + } + if (!(hp = gethostbyname(user_host))) { log_error(MSG_ONLY|NO_EXIT, "unable to lookup %s via gethostbyname()", user_host); @@ -1026,6 +1027,7 @@ } else { user_shost = user_host; } + sudo_user.host_fqdn_queried = TRUE; } /* diff -ur sudo-1.6.8p12.old/sudo.h sudo-1.6.8p12/sudo.h --- sudo-1.6.8p12.old/sudo.h 2005-03-23 23:44:46.000000000 +0000 +++ sudo-1.6.8p12/sudo.h 2006-03-31 20:32:21.000000000 +0000 @@ -42,6 +42,7 @@ char cwd[PATH_MAX]; char *host; char *shost; + int host_fqdn_queried; char **runas; char *prompt; char *cmnd; diff -ur sudo-1.6.8p12.old/sudo.tab.c sudo-1.6.8p12/sudo.tab.c