comparison src/auth/mech-winbind.c @ 6226:315b954801f7 HEAD

waitpid() ntlm_auth workers so they won't be left as zombies.
author Timo Sirainen <tss@iki.fi>
date Tue, 07 Aug 2007 14:45:50 +0300
parents 336ad0e3c78f
children b1cfce4263a2
comparison
equal deleted inserted replaced
6225:336ad0e3c78f 6226:315b954801f7
6 * 6 *
7 * This software is released under the MIT license. 7 * This software is released under the MIT license.
8 */ 8 */
9 9
10 #include "common.h" 10 #include "common.h"
11 #include "lib-signals.h"
11 #include "mech.h" 12 #include "mech.h"
12 #include "str.h" 13 #include "str.h"
13 #include "buffer.h" 14 #include "buffer.h"
14 #include "base64.h" 15 #include "base64.h"
15 #include "istream.h" 16 #include "istream.h"
16 #include "ostream.h" 17 #include "ostream.h"
17 18
18 #include <stdlib.h> 19 #include <stdlib.h>
19 #include <unistd.h> 20 #include <unistd.h>
21 #include <sys/wait.h>
20 22
21 #define DEFAULT_WINBIND_HELPER_PATH "/usr/bin/ntlm_auth" 23 #define DEFAULT_WINBIND_HELPER_PATH "/usr/bin/ntlm_auth"
22 24
23 enum helper_result { 25 enum helper_result {
24 HR_OK = 0, /* OK or continue */ 26 HR_OK = 0, /* OK or continue */
26 HR_RESTART = -2 /* FAIL + try to restart helper */ 28 HR_RESTART = -2 /* FAIL + try to restart helper */
27 }; 29 };
28 30
29 struct winbind_helper { 31 struct winbind_helper {
30 const char *param; 32 const char *param;
33 pid_t pid;
34
31 struct istream *in_pipe; 35 struct istream *in_pipe;
32 struct ostream *out_pipe; 36 struct ostream *out_pipe;
33 }; 37 };
34 38
35 struct winbind_auth_request { 39 struct winbind_auth_request {
38 struct winbind_helper *winbind; 42 struct winbind_helper *winbind;
39 bool continued; 43 bool continued;
40 }; 44 };
41 45
42 static struct winbind_helper winbind_ntlm_context = { 46 static struct winbind_helper winbind_ntlm_context = {
43 "--helper-protocol=squid-2.5-ntlmssp", NULL, NULL 47 "--helper-protocol=squid-2.5-ntlmssp", -1, NULL, NULL
44 }; 48 };
45 static struct winbind_helper winbind_spnego_context = { 49 static struct winbind_helper winbind_spnego_context = {
46 "--helper-protocol=gss-spnego", NULL, NULL 50 "--helper-protocol=gss-spnego", -1, NULL, NULL
47 }; 51 };
52
53 static bool sigchld_handler_set = FALSE;
48 54
49 static void winbind_helper_disconnect(struct winbind_helper *winbind) 55 static void winbind_helper_disconnect(struct winbind_helper *winbind)
50 { 56 {
51 if (winbind->in_pipe != NULL) 57 if (winbind->in_pipe != NULL)
52 i_stream_destroy(&winbind->in_pipe); 58 i_stream_destroy(&winbind->in_pipe);
53 if (winbind->out_pipe != NULL) 59 if (winbind->out_pipe != NULL)
54 o_stream_destroy(&winbind->out_pipe); 60 o_stream_destroy(&winbind->out_pipe);
55 } 61 }
56 62
63 static void winbind_wait_pid(struct winbind_helper *winbind)
64 {
65 int status;
66
67 if (winbind->pid == -1)
68 return;
69
70 /* FIXME: if we ever do some other kind of forking, this needs fixing */
71 if (waitpid(winbind->pid, &status, WNOHANG) == -1) {
72 if (errno != ECHILD && errno != EINTR)
73 i_error("waitpid() failed: %m");
74 return;
75 }
76
77 if (WIFSIGNALED(status)) {
78 i_error("winbind: ntlm_auth died with signal %d",
79 WTERMSIG(status));
80 } else if (WIFEXITED(status)) {
81 i_error("winbind: ntlm_auth exited with exit code %d",
82 WEXITSTATUS(status));
83 } else {
84 /* shouldn't happen */
85 i_error("winbind: ntlm_auth exited with status %d",
86 status);
87 }
88 }
89
90 static void sigchld_handler(int signo __attr_unused__,
91 void *context __attr_unused__)
92 {
93 winbind_wait_pid(&winbind_ntlm_context);
94 winbind_wait_pid(&winbind_spnego_context);
95 }
96
57 static void winbind_helper_connect(struct winbind_helper *winbind) 97 static void winbind_helper_connect(struct winbind_helper *winbind)
58 { 98 {
59 int infd[2], outfd[2]; 99 int infd[2], outfd[2];
60 pid_t pid; 100 pid_t pid;
61 101
62 if (winbind->in_pipe != NULL) 102 if (winbind->in_pipe != NULL || winbind->pid != -1)
63 return; 103 return;
64 104
65 if (pipe(infd) < 0) { 105 if (pipe(infd) < 0) {
66 i_error("pipe() failed: %m"); 106 i_error("pipe() failed: %m");
67 return; 107 return;
107 147
108 winbind->in_pipe = 148 winbind->in_pipe =
109 i_stream_create_fd(infd[0], AUTH_CLIENT_MAX_LINE_LENGTH, TRUE); 149 i_stream_create_fd(infd[0], AUTH_CLIENT_MAX_LINE_LENGTH, TRUE);
110 winbind->out_pipe = 150 winbind->out_pipe =
111 o_stream_create_fd(outfd[1], (size_t)-1, TRUE); 151 o_stream_create_fd(outfd[1], (size_t)-1, TRUE);
152
153 if (!sigchld_handler_set) {
154 sigchld_handler_set = TRUE;
155 lib_signals_set_handler(SIGCHLD, TRUE, sigchld_handler, NULL);
156 }
112 } 157 }
113 158
114 static enum helper_result 159 static enum helper_result
115 do_auth_continue(struct auth_request *auth_request, 160 do_auth_continue(struct auth_request *auth_request,
116 const unsigned char *data, size_t data_size) 161 const unsigned char *data, size_t data_size)