X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=check.c;h=4889ac7af96acbdcfb49f6d15f147540561b4d1b;hb=6850c41061e133f6ab21bc84330f62d6058fd27c;hp=c1fa93187d2796c2e35e9e506053bbb9d9b72664;hpb=c2b0b328d4a66431e671fb26b47997033feb5e29;p=debian%2Fsudo diff --git a/check.c b/check.c index c1fa931..4889ac7 100644 --- a/check.c +++ b/check.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1993-1996,1998-2004 Todd C. Miller + * Copyright (c) 1993-1996,1998-2005 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,7 +18,7 @@ * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ -#include "config.h" +#include #include #include @@ -56,11 +56,14 @@ #include #include #include +#ifndef HAVE_TIMESPEC +# include +#endif #include "sudo.h" #ifndef lint -static const char rcsid[] = "$Sudo: check.c,v 1.226 2004/09/08 15:48:23 millert Exp $"; +__unused static const char rcsid[] = "$Sudo: check.c,v 1.223.2.10 2008/01/05 23:59:42 millert Exp $"; #endif /* lint */ /* Status codes for timestamp_status() */ @@ -70,6 +73,10 @@ static const char rcsid[] = "$Sudo: check.c,v 1.226 2004/09/08 15:48:23 millert #define TS_NOFILE 3 #define TS_ERROR 4 +/* Flags for timestamp_status() */ +#define TS_MAKE_DIRS 1 +#define TS_REMOVE 2 + static void build_timestamp __P((char **, char **)); static int timestamp_status __P((char *, char *, char *, int)); static char *expand_prompt __P((char *, char *, char *)); @@ -81,8 +88,8 @@ static void update_timestamp __P((char *, char *)); * verify who he/she is. */ void -check_user(override) - int override; +check_user(validated) + int validated; { char *timestampdir = NULL; char *timestampfile = NULL; @@ -93,8 +100,9 @@ check_user(override) return; build_timestamp(×tampdir, ×tampfile); - status = timestamp_status(timestampdir, timestampfile, user_name, TRUE); - if (override || status != TS_CURRENT) { + status = timestamp_status(timestampdir, timestampfile, user_name, + TS_MAKE_DIRS); + if (status != TS_CURRENT || ISSET(validated, FLAG_CHECK_USER)) { lecture(status); /* Expand any escapes in the prompt. */ @@ -103,11 +111,11 @@ check_user(override) verify_user(auth_pw, prompt); } - if (status != TS_ERROR) + /* Only update timestamp if user was validated. */ + if (status != TS_ERROR && ISSET(validated, VALIDATE_OK)) update_timestamp(timestampdir, timestampfile); - free(timestampdir); - if (timestampfile) - free(timestampfile); + efree(timestampdir); + efree(timestampfile); } /* @@ -129,6 +137,7 @@ lecture(status) if (def_lecture_file && (fp = fopen(def_lecture_file, "r")) != NULL) { while ((nread = fread(buf, sizeof(char), sizeof(buf), fp)) != 0) fwrite(buf, nread, 1, stderr); + fclose(fp); } else { (void) fputs("\n\ We trust you have received the usual lecture from the local System\n\ @@ -197,6 +206,16 @@ expand_prompt(old_prompt, user, host) len += strlen(user_host) - 2; subst = 1; break; + case 'p': + p++; + if (def_rootpw) + len += 2; + else if (def_targetpw || def_runaspw) + len += strlen(*user_runas) - 2; + else + len += strlen(user_name) - 2; + subst = 1; + break; case 'u': p++; len += strlen(user_name) - 2; @@ -238,6 +257,18 @@ expand_prompt(old_prompt, user, host) goto oflow; np += n; continue; + case 'p': + p++; + if (def_rootpw) + n = strlcpy(np, "root", np - endp); + else if (def_targetpw || def_runaspw) + n = strlcpy(np, *user_runas, np - endp); + else + n = strlcpy(np, user_name, np - endp); + if (n >= np - endp) + goto oflow; + np += n; + continue; case 'u': p++; n = strlcpy(np, user_name, np - endp); @@ -316,7 +347,7 @@ build_timestamp(timestampdir, timestampfile) dirparent = def_timestampdir; len = easprintf(timestampdir, "%s/%s", dirparent, user_name); if (len >= PATH_MAX) - log_error(0, "timestamp path too long: %s", timestampdir); + log_error(0, "timestamp path too long: %s", *timestampdir); /* * Timestamp file may be a file in the directory or NUL to use @@ -335,12 +366,12 @@ build_timestamp(timestampdir, timestampfile) else len = easprintf(timestampfile, "%s/%s/%s", dirparent, user_name, p); if (len >= PATH_MAX) - log_error(0, "timestamp path too long: %s", timestampfile); + log_error(0, "timestamp path too long: %s", *timestampfile); } else if (def_targetpw) { len = easprintf(timestampfile, "%s/%s/%s", dirparent, user_name, *user_runas); if (len >= PATH_MAX) - log_error(0, "timestamp path too long: %s", timestampfile); + log_error(0, "timestamp path too long: %s", *timestampfile); } else *timestampfile = NULL; } @@ -349,11 +380,11 @@ build_timestamp(timestampdir, timestampfile) * Check the timestamp file and directory and return their status. */ static int -timestamp_status(timestampdir, timestampfile, user, make_dirs) +timestamp_status(timestampdir, timestampfile, user, flags) char *timestampdir; char *timestampfile; char *user; - int make_dirs; + int flags; { struct stat sb; time_t now; @@ -373,7 +404,7 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs) if (lstat(dirparent, &sb) == 0) { if (!S_ISDIR(sb.st_mode)) log_error(NO_EXIT, "%s exists but is not a directory (0%o)", - dirparent, sb.st_mode); + dirparent, (unsigned int) sb.st_mode); else if (sb.st_uid != timestamp_uid) log_error(NO_EXIT, "%s owned by uid %lu, should be uid %lu", dirparent, (unsigned long) sb.st_uid, @@ -381,7 +412,7 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs) else if ((sb.st_mode & 0000022)) log_error(NO_EXIT, "%s writable by non-owner (0%o), should be mode 0700", - dirparent, sb.st_mode); + dirparent, (unsigned int) sb.st_mode); else { if ((sb.st_mode & 0000777) != 0700) (void) chmod(dirparent, 0700); @@ -391,7 +422,7 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs) log_error(NO_EXIT|USE_ERRNO, "can't stat %s", dirparent); } else { /* No dirparent, try to make one. */ - if (make_dirs) { + if (ISSET(flags, TS_MAKE_DIRS)) { if (mkdir(dirparent, S_IRWXU)) log_error(NO_EXIT|USE_ERRNO, "can't mkdir %s", dirparent); @@ -420,7 +451,7 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs) status = TS_MISSING; } else log_error(NO_EXIT, "%s exists but is not a directory (0%o)", - timestampdir, sb.st_mode); + timestampdir, (unsigned int) sb.st_mode); } else if (sb.st_uid != timestamp_uid) log_error(NO_EXIT, "%s owned by uid %lu, should be uid %lu", timestampdir, (unsigned long) sb.st_uid, @@ -428,7 +459,7 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs) else if ((sb.st_mode & 0000022)) log_error(NO_EXIT, "%s writable by non-owner (0%o), should be mode 0700", - timestampdir, sb.st_mode); + timestampdir, (unsigned int) sb.st_mode); else { if ((sb.st_mode & 0000777) != 0700) (void) chmod(timestampdir, 0700); @@ -441,9 +472,9 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs) /* * If there is no user ticket dir, AND we are in tty ticket mode, - * AND the make_dirs flag is set, create the user ticket dir. + * AND the TS_MAKE_DIRS flag is set, create the user ticket dir. */ - if (status == TS_MISSING && timestampfile && make_dirs) { + if (status == TS_MISSING && timestampfile && ISSET(flags, TS_MAKE_DIRS)) { if (mkdir(timestampdir, S_IRWXU) == -1) { status = TS_ERROR; log_error(NO_EXIT|USE_ERRNO, "can't mkdir %s", timestampdir); @@ -460,19 +491,19 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs) if (!S_ISREG(sb.st_mode)) { status = TS_ERROR; log_error(NO_EXIT, "%s exists but is not a regular file (0%o)", - timestampfile, sb.st_mode); + timestampfile, (unsigned int) sb.st_mode); } else { /* If bad uid or file mode, complain and kill the bogus file. */ if (sb.st_uid != timestamp_uid) { log_error(NO_EXIT, - "%s owned by uid %ud, should be uid %lu", + "%s owned by uid %lu, should be uid %lu", timestampfile, (unsigned long) sb.st_uid, (unsigned long) timestamp_uid); (void) unlink(timestampfile); } else if ((sb.st_mode & 0000022)) { log_error(NO_EXIT, "%s writable by non-owner (0%o), should be mode 0600", - timestampfile, sb.st_mode); + timestampfile, (unsigned int) sb.st_mode); (void) unlink(timestampfile); } else { /* If not mode 0600, fix it. */ @@ -489,9 +520,9 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs) } /* - * If the file/dir exists, check its mtime. + * If the file/dir exists and we are not removing it, check its mtime. */ - if (status == TS_OLD) { + if (status == TS_OLD && !ISSET(flags, TS_REMOVE)) { /* Negative timeouts only expire manually (sudo -k). */ if (def_timestamp_timeout < 0 && sb.st_mtime != 0) status = TS_CURRENT; @@ -536,7 +567,8 @@ remove_timestamp(remove) int status; build_timestamp(×tampdir, ×tampfile); - status = timestamp_status(timestampdir, timestampfile, user_name, FALSE); + status = timestamp_status(timestampdir, timestampfile, user_name, + TS_REMOVE); if (status == TS_OLD || status == TS_CURRENT) { path = timestampfile ? timestampfile : timestampdir; if (remove) { @@ -556,7 +588,6 @@ remove_timestamp(remove) } } - free(timestampdir); - if (timestampfile) - free(timestampfile); + efree(timestampdir); + efree(timestampfile); }