s3: lib: Signal handling - ensure smbrun and change password code save and restore...
authorJeremy Allison <jra@samba.org>
Tue, 23 Sep 2014 21:51:18 +0000 (14:51 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 30 Sep 2014 18:40:16 +0000 (20:40 +0200)
Bug #10831 - SIGCLD Signal handler not correctly reinstalled on old library code use - smbrun etc.

https://bugzilla.samba.org/show_bug.cgi?id=10831

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Martin Schwenke <martin@meltin.net>
source3/lib/smbrun.c
source3/rpc_server/samr/srv_samr_chgpasswd.c

index 15a0c886e4779a81432f5edc0dfa1b79d22762f0..55f7a871d3ac267eaeabe05a460cf35fbfdc6790 100644 (file)
@@ -73,6 +73,7 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize)
        pid_t pid;
        uid_t uid = current_user.ut.uid;
        gid_t gid = current_user.ut.gid;
+       void (*saved_handler)(int);
 
        /*
         * Lose any elevated privileges.
@@ -94,11 +95,11 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize)
         * SIGCLD signals as it also eats the exit status code. JRA.
         */
 
-       CatchChildLeaveStatus();
+       saved_handler = CatchChildLeaveStatus();
                                        
        if ((pid=fork()) < 0) {
                DEBUG(0,("smbrun: fork failed with error %s\n", strerror(errno) ));
-               CatchChild(); 
+               (void)CatchSignal(SIGCLD, saved_handler);
                if (outfd) {
                        close(*outfd);
                        *outfd = -1;
@@ -123,7 +124,7 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize)
                        break;
                }
 
-               CatchChild(); 
+               (void)CatchSignal(SIGCLD, saved_handler);
 
                if (wpid != pid) {
                        DEBUG(2,("waitpid(%d) : %s\n",(int)pid,strerror(errno)));
@@ -148,7 +149,7 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize)
                return status;
        }
        
-       CatchChild(); 
+       (void)CatchChild();
        
        /* we are in the child. we exec /bin/sh to do the work for us. we
           don't directly exec the command we want because it may be a
@@ -237,6 +238,7 @@ int smbrunsecret(const char *cmd, const char *secret)
        uid_t uid = current_user.ut.uid;
        gid_t gid = current_user.ut.gid;
        int ifd[2];
+       void (*saved_handler)(int);
        
        /*
         * Lose any elevated privileges.
@@ -257,11 +259,11 @@ int smbrunsecret(const char *cmd, const char *secret)
         * SIGCLD signals as it also eats the exit status code. JRA.
         */
 
-       CatchChildLeaveStatus();
+       saved_handler = CatchChildLeaveStatus();
                                        
        if ((pid=fork()) < 0) {
                DEBUG(0, ("smbrunsecret: fork failed with error %s\n", strerror(errno)));
-               CatchChild(); 
+               (void)CatchSignal(SIGCLD, saved_handler);
                return errno;
        }
 
@@ -293,7 +295,7 @@ int smbrunsecret(const char *cmd, const char *secret)
                        break;
                }
 
-               CatchChild(); 
+               (void)CatchSignal(SIGCLD, saved_handler);
 
                if (wpid != pid) {
                        DEBUG(2, ("waitpid(%d) : %s\n", (int)pid, strerror(errno)));
@@ -309,7 +311,7 @@ int smbrunsecret(const char *cmd, const char *secret)
                return status;
        }
        
-       CatchChild(); 
+       (void)CatchChild();
        
        /* we are in the child. we exec /bin/sh to do the work for us. we
           don't directly exec the command we want because it may be a
index 1c9c33a09cf4d856bea1447d02c50833dfdc2f0b..684ccee0fb92e2db2842eec0fdcae5ea1e4d9b0f 100644 (file)
@@ -391,6 +391,7 @@ static bool chat_with_program(char *passwordprogram, const struct passwd *pass,
        pid_t pid, wpid;
        int wstat;
        bool chstat = False;
+       void (*saved_handler)(int);
 
        if (pass == NULL) {
                DEBUG(0, ("chat_with_program: user doesn't exist in the UNIX password database.\n"));
@@ -408,13 +409,13 @@ static bool chat_with_program(char *passwordprogram, const struct passwd *pass,
         * SIGCLD signals as it also eats the exit status code. JRA.
         */
 
-       CatchChildLeaveStatus();
+       saved_handler = CatchChildLeaveStatus();
 
        if ((pid = fork()) < 0) {
                DEBUG(3, ("chat_with_program: Cannot fork() child for password change: %s\n", pass->pw_name));
                SAFE_FREE(slavedev);
                close(master);
-               CatchChild();
+               (void)CatchSignal(SIGCLD, saved_handler);
                return (False);
        }
 
@@ -439,14 +440,14 @@ static bool chat_with_program(char *passwordprogram, const struct passwd *pass,
                if (wpid < 0) {
                        DEBUG(3, ("chat_with_program: The process is no longer waiting!\n\n"));
                        close(master);
-                       CatchChild();
+                       (void)CatchSignal(SIGCLD, saved_handler);
                        return (False);
                }
 
                /*
                 * Go back to ignoring children.
                 */
-               CatchChild();
+               (void)CatchSignal(SIGCLD, saved_handler);
 
                close(master);