[BACK]Return to check.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / sudo

Diff for /src/usr.bin/sudo/Attic/check.c between version 1.11 and 1.12

version 1.11, 2003/04/19 21:57:17 version 1.12, 2004/09/28 15:10:50
Line 1 
Line 1 
 /*  /*
  * Copyright (c) 1993-1996,1998-2003 Todd C. Miller <Todd.Miller@courtesan.com>   * Copyright (c) 1993-1996,1998-2004 Todd C. Miller <Todd.Miller@courtesan.com>
  * All rights reserved.  
  *   *
  * Redistribution and use in source and binary forms, with or without   * Permission to use, copy, modify, and distribute this software for any
  * modification, are permitted provided that the following conditions   * purpose with or without fee is hereby granted, provided that the above
  * are met:   * copyright notice and this permission notice appear in all copies.
  *   *
  * 1. Redistributions of source code must retain the above copyright   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  *    notice, this list of conditions and the following disclaimer.   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *   *
  * 2. Redistributions in binary form must reproduce the above copyright  
  *    notice, this list of conditions and the following disclaimer in the  
  *    documentation and/or other materials provided with the distribution.  
  *  
  * 3. The name of the author may not be used to endorse or promote products  
  *    derived from this software without specific prior written permission.  
  *  
  * 4. Products derived from this software may not be called "Sudo" nor  
  *    may "Sudo" appear in their names without specific prior written  
  *    permission from the author.  
  *  
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,  
  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY  
  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL  
  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  
  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
  *  
  * Sponsored in part by the Defense Advanced Research Projects   * Sponsored in part by the Defense Advanced Research Projects
  * Agency (DARPA) and Air Force Research Laboratory, Air Force   * Agency (DARPA) and Air Force Research Laboratory, Air Force
  * Materiel Command, USAF, under agreement number F39502-99-1-0512.   * Materiel Command, USAF, under agreement number F39502-99-1-0512.
Line 41 
Line 23 
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/stat.h>  #include <sys/stat.h>
 #include <sys/file.h>  #ifndef __TANDEM
   # include <sys/file.h>
   #endif
 #include <stdio.h>  #include <stdio.h>
 #ifdef STDC_HEADERS  #ifdef STDC_HEADERS
 # include <stdlib.h>  # include <stdlib.h>
Line 76 
Line 60 
 #include "sudo.h"  #include "sudo.h"
   
 #ifndef lint  #ifndef lint
 static const char rcsid[] = "$Sudo: check.c,v 1.213 2003/04/16 00:42:09 millert Exp $";  static const char rcsid[] = "$Sudo: check.c,v 1.226 2004/09/08 15:48:23 millert Exp $";
 #endif /* lint */  #endif /* lint */
   
 /* Status codes for timestamp_status() */  /* Status codes for timestamp_status() */
Line 89 
Line 73 
 static void  build_timestamp    __P((char **, char **));  static void  build_timestamp    __P((char **, char **));
 static int   timestamp_status   __P((char *, char *, char *, int));  static int   timestamp_status   __P((char *, char *, char *, int));
 static char *expand_prompt      __P((char *, char *, char *));  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 *));  static void  update_timestamp   __P((char *, char *));
   
 /*  /*
  * This function only returns if the user can successfully   * This function only returns if the user can successfully
  * verify who he/she is.   * verify who he/she is.
  */   */
 void  void
 check_user()  check_user(override)
       int override;
 {  {
     char *timestampdir = NULL;      char *timestampdir = NULL;
     char *timestampfile = NULL;      char *timestampfile = NULL;
     char *prompt;      char *prompt;
     int status;      int status;
   
     if (user_uid == 0 || user_is_exempt())      if (user_uid == 0 || user_uid == runas_pw->pw_uid || user_is_exempt())
         return;          return;
   
     build_timestamp(&timestampdir, &timestampfile);      build_timestamp(&timestampdir, &timestampfile);
     status = timestamp_status(timestampdir, timestampfile, user_name, TRUE);      status = timestamp_status(timestampdir, timestampfile, user_name, TRUE);
     if (status != TS_CURRENT) {      if (override || status != TS_CURRENT) {
         if (status == TS_MISSING || status == TS_ERROR)          lecture(status);
             lecture();          /* first time through they get a lecture */  
   
         /* Expand any escapes in the prompt. */          /* Expand any escapes in the prompt. */
         prompt = expand_prompt(user_prompt ? user_prompt : def_str(I_PASSPROMPT),          prompt = expand_prompt(user_prompt ? user_prompt : def_passprompt,
             user_name, user_shost);              user_name, user_shost);
   
         verify_user(auth_pw, prompt);          verify_user(auth_pw, prompt);
Line 131 
Line 115 
  * TODO: allow the user to specify a file name instead.   * TODO: allow the user to specify a file name instead.
  */   */
 static void  static void
 lecture()  lecture(status)
       int status;
 {  {
       FILE *fp;
       char buf[BUFSIZ];
       ssize_t nread;
   
     if (def_flag(I_LECTURE)) {      if (def_lecture == never ||
           (def_lecture == once && status != TS_MISSING && status != TS_ERROR))
           return;
   
       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);
       } else {
         (void) fputs("\n\          (void) fputs("\n\
 We trust you have received the usual lecture from the local System\n\  We trust you have received the usual lecture from the local System\n\
 Administrator. It usually boils down to these two things:\n\  Administrator. It usually boils down to these three things:\n\
 \n\  \n\
         #1) Respect the privacy of others.\n\      #1) Respect the privacy of others.\n\
         #2) Think before you type.\n\n",      #2) Think before you type.\n\
         stderr);      #3) With great power comes great responsibility.\n\n",
       stderr);
     }      }
 }  }
   
Line 153 
Line 149 
     char *timestampdir;      char *timestampdir;
     char *timestampfile;      char *timestampfile;
 {  {
   
     if (timestamp_uid != 0)      if (timestamp_uid != 0)
         set_perms(PERM_TIMESTAMP);          set_perms(PERM_TIMESTAMP);
     if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) {      if (touch(-1, timestampfile ? timestampfile : timestampdir, NULL) == -1) {
         if (timestampfile) {          if (timestampfile) {
             int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600);              int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600);
   
Line 290 
Line 285 
     struct group *grp;      struct group *grp;
     char **gr_mem;      char **gr_mem;
   
     if (!def_str(I_EXEMPT_GROUP))      if (!def_exempt_group)
         return(FALSE);          return(FALSE);
   
     if (!(grp = getgrnam(def_str(I_EXEMPT_GROUP))))      if (!(grp = getgrnam(def_exempt_group)))
         return(FALSE);          return(FALSE);
   
     if (user_gid == grp->gr_gid)      if (user_gid == grp->gr_gid)
Line 318 
Line 313 
     char *dirparent;      char *dirparent;
     int len;      int len;
   
     dirparent = def_str(I_TIMESTAMPDIR);      dirparent = def_timestampdir;
     len = easprintf(timestampdir, "%s/%s", dirparent, user_name);      len = easprintf(timestampdir, "%s/%s", dirparent, user_name);
     if (len >= MAXPATHLEN)      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       * Timestamp file may be a file in the directory or NUL to use
      * the directory as the timestamp.       * the directory as the timestamp.
      */       */
     if (def_flag(I_TTY_TICKETS)) {      if (def_tty_tickets) {
         char *p;          char *p;
   
         if ((p = strrchr(user_tty, '/')))          if ((p = strrchr(user_tty, '/')))
             p++;              p++;
         else          else
             p = user_tty;              p = user_tty;
         if (def_flag(I_TARGETPW))          if (def_targetpw)
             len = easprintf(timestampfile, "%s/%s/%s:%s", dirparent, user_name,              len = easprintf(timestampfile, "%s/%s/%s:%s", dirparent, user_name,
                 p, *user_runas);                  p, *user_runas);
         else          else
             len = easprintf(timestampfile, "%s/%s/%s", dirparent, user_name, p);              len = easprintf(timestampfile, "%s/%s/%s", dirparent, user_name, p);
         if (len >= MAXPATHLEN)          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_flag(I_TARGETPW)) {      } else if (def_targetpw) {
         len = easprintf(timestampfile, "%s/%s/%s", dirparent, user_name,          len = easprintf(timestampfile, "%s/%s/%s", dirparent, user_name,
             *user_runas);              *user_runas);
         if (len >= MAXPATHLEN)          if (len >= PATH_MAX)
             log_error(0, "timestamp path too long: %s", timestampfile);              log_error(0, "timestamp path too long: %s", timestampfile);
     } else      } else
         *timestampfile = NULL;          *timestampfile = NULL;
Line 362 
Line 357 
 {  {
     struct stat sb;      struct stat sb;
     time_t now;      time_t now;
     char *dirparent = def_str(I_TIMESTAMPDIR);      char *dirparent = def_timestampdir;
     int status = TS_ERROR;              /* assume the worst */      int status = TS_ERROR;              /* assume the worst */
   
     if (timestamp_uid != 0)      if (timestamp_uid != 0)
Line 498 
Line 493 
      */       */
     if (status == TS_OLD) {      if (status == TS_OLD) {
         /* Negative timeouts only expire manually (sudo -k). */          /* Negative timeouts only expire manually (sudo -k). */
         if (def_ival(I_TIMESTAMP_TIMEOUT) < 0 && sb.st_mtime != 0)          if (def_timestamp_timeout < 0 && sb.st_mtime != 0)
             status = TS_CURRENT;              status = TS_CURRENT;
         else {          else {
               /* XXX - should use timespec here */
             now = time(NULL);              now = time(NULL);
             if (def_ival(I_TIMESTAMP_TIMEOUT) &&              if (def_timestamp_timeout &&
                 now - sb.st_mtime < 60 * def_ival(I_TIMESTAMP_TIMEOUT)) {                  now - sb.st_mtime < 60 * def_timestamp_timeout) {
                 /*                  /*
                  * Check for bogus time on the stampfile.  The clock may                   * Check for bogus time on the stampfile.  The clock may
                  * have been set back or someone could be trying to spoof us.                   * have been set back or someone could be trying to spoof us.
                  */                   */
                 if (sb.st_mtime > now + 60 * def_ival(I_TIMESTAMP_TIMEOUT) * 2) {                  if (sb.st_mtime > now + 60 * def_timestamp_timeout * 2) {
                     log_error(NO_EXIT,                      log_error(NO_EXIT,
                         "timestamp too far in the future: %20.20s",                          "timestamp too far in the future: %20.20s",
                         4 + ctime(&sb.st_mtime));                          4 + ctime(&sb.st_mtime));
Line 535 
Line 531 
 remove_timestamp(remove)  remove_timestamp(remove)
     int remove;      int remove;
 {  {
     char *timestampdir;      struct timespec ts;
     char *timestampfile;      char *timestampdir, *timestampfile, *path;
     char *ts;  
     int status;      int status;
   
     build_timestamp(&timestampdir, &timestampfile);      build_timestamp(&timestampdir, &timestampfile);
     status = timestamp_status(timestampdir, timestampfile, user_name, FALSE);      status = timestamp_status(timestampdir, timestampfile, user_name, FALSE);
     if (status == TS_OLD || status == TS_CURRENT) {      if (status == TS_OLD || status == TS_CURRENT) {
         ts = timestampfile ? timestampfile : timestampdir;          path = timestampfile ? timestampfile : timestampdir;
         if (remove) {          if (remove) {
             if (timestampfile)              if (timestampfile)
                 status = unlink(timestampfile);                  status = unlink(timestampfile);
Line 551 
Line 546 
                 status = rmdir(timestampdir);                  status = rmdir(timestampdir);
             if (status == -1 && errno != ENOENT) {              if (status == -1 && errno != ENOENT) {
                 log_error(NO_EXIT, "can't remove %s (%s), will reset to Epoch",                  log_error(NO_EXIT, "can't remove %s (%s), will reset to Epoch",
                     ts, strerror(errno));                      path, strerror(errno));
                 remove = FALSE;                  remove = FALSE;
             }              }
           } else {
               timespecclear(&ts);
               if (touch(-1, path, &ts) == -1)
                   err(1, "can't reset %s to Epoch", path);
         }          }
         if (!remove && touch(ts, 0) == -1)  
             err(1, "can't reset %s to Epoch", ts);  
     }      }
   
     free(timestampdir);      free(timestampdir);

Legend:
Removed from v.1.11  
changed lines
  Added in v.1.12