]> granicus.if.org Git - linux-pam/blobdiff - modules/pam_unix/pam_unix_passwd.c
Relevant BUGIDs:
[linux-pam] / modules / pam_unix / pam_unix_passwd.c
index d221220f222358885e6f4e84e44b373a1b2df00a..9386d87f1797029cf47d962bd8a642ff3ec5a888 100644 (file)
@@ -139,7 +139,7 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const
     const char *fromwhat, const char *towhat, int remember)
 {
     int retval, child, fds[2];
-    void (*sighandler)(int) = NULL;
+    struct sigaction newsa, oldsa;
 
     D(("called."));
     /* create a pipe for the password */
@@ -157,13 +157,15 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const
         * The "noreap" module argument is provided so that the admin can
         * override this behavior.
         */
-       sighandler = signal(SIGCHLD, SIG_DFL);
+        memset(&newsa, '\0', sizeof(newsa));
+        newsa.sa_handler = SIG_DFL;
+        sigaction(SIGCHLD, &newsa, &oldsa);
     }
 
     /* fork */
     child = fork();
     if (child == 0) {
-        size_t i=0;
+        int i=0;
         struct rlimit rlim;
        static char *envp[] = { NULL };
        char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
@@ -171,14 +173,14 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const
 
        /* XXX - should really tidy up PAM here too */
 
-       close(0); close(1);
        /* reopen stdin as pipe */
-       close(fds[1]);
        dup2(fds[0], STDIN_FILENO);
 
        if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
-         for (i=2; i < rlim.rlim_max; i++) {
-           if ((unsigned int)fds[0] != i)
+         if (rlim.rlim_max >= MAX_FD_NO)
+           rlim.rlim_max = MAX_FD_NO;
+         for (i=0; i < (int)rlim.rlim_max; i++) {
+           if (i != STDIN_FILENO)
                   close(i);
          }
        }
@@ -236,8 +238,8 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const
        retval = PAM_AUTH_ERR;
     }
 
-    if (sighandler != SIG_ERR) {
-        (void) signal(SIGCHLD, sighandler);   /* restore old signal handler */
+    if (off(UNIX_NOREAP, ctrl)) {
+        sigaction(SIGCHLD, &oldsa, NULL);   /* restore old signal handler */
     }
 
     return retval;
@@ -378,7 +380,7 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho,
                          return _unix_run_update_binary(pamh, ctrl, forwho, fromwhat, towhat, remember);
 #endif
                /* first, save old password */
-               if (save_old_password(forwho, fromwhat, remember)) {
+               if (save_old_password(pamh, forwho, fromwhat, remember)) {
                        retval = PAM_AUTHTOK_ERR;
                        goto done;
                }
@@ -699,6 +701,10 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                                pass_new = NULL;
                        }
                        retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new);
+                       
+                       if (retval != PAM_SUCCESS && off(UNIX_NOT_SET_PASS, ctrl)) {
+                               pam_set_item(pamh, PAM_AUTHTOK, NULL);
+                       }
                }
 
                if (retval != PAM_SUCCESS) {
@@ -745,7 +751,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                 * First we encrypt the new password.
                 */
 
-               tpass = create_password_hash(pass_new, ctrl, rounds);
+               tpass = create_password_hash(pamh, pass_new, ctrl, rounds);
                if (tpass == NULL) {
                        pam_syslog(pamh, LOG_CRIT,
                                "out of memory for password");