Mercurial > dovecot > original-hg > dovecot-1.2
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) |