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

Diff for /src/usr.bin/passwd/pwd_check.c between version 1.10 and 1.11

version 1.10, 2005/03/04 15:36:03 version 1.11, 2005/05/01 00:05:10
Line 44 
Line 44 
 #include <grp.h>  #include <grp.h>
 #include <paths.h>  #include <paths.h>
 #include <login_cap.h>  #include <login_cap.h>
   #include <signal.h>
   
 struct pattern {  struct pattern {
         char *match;          char *match;
Line 85 
Line 86 
         regex_t rgx;          regex_t rgx;
         int i, res, min_len;          int i, res, min_len;
         char *checker;          char *checker;
           char *argp[] = { "sh", "-c", NULL, NULL};
         int pipefds[2];          int pipefds[2];
         pid_t child;          pid_t child;
           uid_t uid;
           gid_t gid;
   
         min_len = (int)login_getcapnum(lc, "minpasswordlen", 6, 6);          min_len = (int)login_getcapnum(lc, "minpasswordlen", 6, 6);
         if (min_len > 0 && strlen(password) < min_len) {          if (min_len > 0 && strlen(password) < min_len) {
Line 94 
Line 98 
                 return (0);                  return (0);
         }          }
   
         for (i = 0; i < sizeof(patterns) / sizeof(struct pattern); i++) {          /* External password check program */
                 if (regcomp(&rgx, patterns[i].match, patterns[i].flags) != 0)  
                         continue;  
                 res = regexec(&rgx, password, 0, NULL, 0);  
                 regfree(&rgx);  
                 if (!res) {  
                         printf("%s\nUnusual capitalization, control characters or digits are suggested.\n", patterns[i].response);  
                         return (0);  
                 }  
         }  
   
         /* If no external checker is specified, just accept the password */  
         checker = login_getcapstr(lc, "passwordcheck", NULL, NULL);          checker = login_getcapstr(lc, "passwordcheck", NULL, NULL);
         if (checker == NULL)  
                 return (1);  
   
         /* Okay, now pass control to an external program */          /* Pipes are only used for external checker */
         if (pipe(pipefds) == -1) {          if (checker != NULL && pipe(pipefds) == -1) {
                 warn("pipe");                  warn("pipe");
                 goto out;                  goto out;
         }          }
   
         child = fork();          /* Check password in low-privileged child */
         if (child == 0) {          switch (child = fork()) {
                 char *argp[] = { "sh", "-c", NULL, NULL};          case -1:
                   warn("fork");
                   goto out;
           case 0:
                   (void)signal(SIGINT, SIG_DFL);
                   (void)signal(SIGQUIT, SIG_DFL);
                   uid = getuid();
                   gid = getgid();
                   if (setresgid(gid, gid, gid) == -1) {
                           warn("setresgid");
                           exit(1);
                   }
                   if (setgroups(1, &gid) == -1) {
                           warn("setgroups");
                           exit(1);
                   }
                   if (setresuid(uid, uid, uid) == -1) {
                           warn("setresuid");
                           exit(1);
                   }
   
                 /* Drop privileges */                  for (i = 0; i < sizeof(patterns) / sizeof(*patterns); i++) {
                 seteuid(getuid());                          if (regcomp(&rgx, patterns[i].match,
                 setuid(getuid());                              patterns[i].flags) != 0)
                                   continue;
                           res = regexec(&rgx, password, 0, NULL, 0);
                           regfree(&rgx);
                           if (res == 0) {
                                   printf("%s\n", patterns[i].response);
                                   exit(1);
                           }
                   }
   
                 if (dup2(pipefds[0], STDIN_FILENO) == -1)                  /* If no external checker in use, accept the password */
                         exit(1);                  if (checker == NULL)
                           exit(0);
   
                   /* Otherwise, pass control to checker program */
                   argp[2] = checker;
                   if (dup2(pipefds[0], STDIN_FILENO) == -1) {
                           warn("dup2");
                           exit(1);
                   }
                 close(pipefds[0]);                  close(pipefds[0]);
                 close(pipefds[1]);                  close(pipefds[1]);
   
                 argp[2] = checker;                  if (execv(_PATH_BSHELL, argp) == -1) {
                 if (execv(_PATH_BSHELL, argp) == -1)                          warn("exec");
                         exit(1);                          exit(1);
                 /* NOT REACHED */                  }
         } else if (child == -1) {                  /* NOTREACHED */
                 warn("fork");          default:
                 goto out;                  break; /* parent continues below */
         }          }
         close(pipefds[0]);  
   
         /* Send the password to STDIN of child */          if (checker != NULL) {
         write(pipefds[1], password, strlen(password) + 1);                  /* Send the password to STDIN of child */
         close(pipefds[1]);                  close(pipefds[0]);
                   write(pipefds[1], password, strlen(password) + 1);
                   close(pipefds[1]);
           }
   
         /* get the return value from the child */          /* get the return value from the child */
         wait(&child);          wait(&child);
         if (WIFEXITED(child) && WEXITSTATUS(child) == 0) {          if (WIFEXITED(child) && WEXITSTATUS(child) == 0) {
                 free(checker);                  if (checker != NULL)
                           free(checker);
                 return (1);                  return (1);
         }          }
   
  out:   out:
         free(checker);          if (checker != NULL)
                   free(checker);
         printf("Please use a different password. Unusual capitalization,\n");          printf("Please use a different password. Unusual capitalization,\n");
         printf("control characters, or digits are suggested.\n");          printf("control characters, or digits are suggested.\n");
   
         return (0);          return (0);
 }  }
   

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