summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2014-09-23 14:51:18 -0700
committerJeremy Allison <jra@samba.org>2014-09-30 20:40:16 +0200
commit93e81d423d790ce7ccfe0bd13286dbf49a637db2 (patch)
treefcf2a7f25ba54d893bf4ba7c0f49944888618ee1
parentfc8e1056fee9779a8bc40e7398b49bfbaa94ccd7 (diff)
downloadsamba-93e81d423d790ce7ccfe0bd13286dbf49a637db2.tar.gz
s3: lib: Signal handling - ensure smbrun and change password code save and restore existing SIGCHLD handlers.
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>
-rw-r--r--source3/lib/smbrun.c18
-rw-r--r--source3/rpc_server/samr/srv_samr_chgpasswd.c9
2 files changed, 15 insertions, 12 deletions
diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c
index 15a0c886e47..55f7a871d3a 100644
--- a/source3/lib/smbrun.c
+++ b/source3/lib/smbrun.c
@@ -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
diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c
index 1c9c33a09cf..684ccee0fb9 100644
--- a/source3/rpc_server/samr/srv_samr_chgpasswd.c
+++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c
@@ -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);