Lines 48-53
Link Here
|
48 |
#define PAM_USE_FPASS_ARG 0x0002 |
48 |
#define PAM_USE_FPASS_ARG 0x0002 |
49 |
#define PAM_TRY_FPASS_ARG 0x0004 |
49 |
#define PAM_TRY_FPASS_ARG 0x0004 |
50 |
|
50 |
|
|
|
51 |
static struct sigaction saved_handler = {.sa_handler = SIG_DFL}; |
52 |
|
51 |
/* ============================ preexec_t ================================== */ |
53 |
/* ============================ preexec_t ================================== */ |
52 |
typedef struct preexec_t { |
54 |
typedef struct preexec_t { |
53 |
const char *user; |
55 |
const char *user; |
Lines 100-105
Link Here
|
100 |
return ctrl; |
102 |
return ctrl; |
101 |
} |
103 |
} |
102 |
|
104 |
|
|
|
105 |
/* spawn_set_sigchld |
106 |
|
107 |
Save the old SIGCHLD handler and then set SIGCHLD to SIG_DFL. This is used |
108 |
against GDM which does not reap childs as we wanted in its SIGCHLD handler, |
109 |
so we install our own handler. Returns the value from sigaction(). |
110 |
*/ |
111 |
static int spawn_set_sigchld(void) { |
112 |
struct sigaction nh; |
113 |
|
114 |
if(saved_handler.sa_handler != SIG_DFL) { |
115 |
return 0; |
116 |
} |
117 |
|
118 |
memset(&nh, 0, sizeof(nh)); |
119 |
nh.sa_handler = SIG_DFL; |
120 |
sigemptyset(&nh.sa_mask); |
121 |
return sigaction(SIGCHLD, &nh, &saved_handler); |
122 |
} |
123 |
|
124 |
|
125 |
/* spawn_restore_sigchld |
126 |
|
127 |
Restore the SIGCHLD handler that was saved during spawn_set_sigchld(). |
128 |
Returns the value from sigaction(). |
129 |
*/ |
130 |
static int spawn_restore_sigchld(void) { |
131 |
int ret; |
132 |
if((ret = sigaction(SIGCHLD, &saved_handler, NULL)) == 0) |
133 |
saved_handler.sa_handler = SIG_DFL; |
134 |
return ret; |
135 |
} |
136 |
|
103 |
/* ============================ read_password () =========================== */ |
137 |
/* ============================ read_password () =========================== */ |
104 |
/* INPUT: pamh; prompt1 |
138 |
/* INPUT: pamh; prompt1 |
105 |
* SIDE AFFECTS: pass points to PAM's (user's) response to prompt |
139 |
* SIDE AFFECTS: pass points to PAM's (user's) response to prompt |
Lines 231-236
Link Here
|
231 |
|
265 |
|
232 |
cmd_line = g_strdup_printf("%s %d", KILL, pid); |
266 |
cmd_line = g_strdup_printf("%s %d", KILL, pid); |
233 |
|
267 |
|
|
|
268 |
if (spawn_set_sigchld()) { |
269 |
return FALSE; |
270 |
} |
271 |
|
234 |
if (!g_shell_parse_argv(cmd_line, NULL, &argv, &err)) { |
272 |
if (!g_shell_parse_argv(cmd_line, NULL, &argv, &err)) { |
235 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: error parsing %s", cmd_line); |
273 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: error parsing %s", cmd_line); |
236 |
goto _return; |
274 |
goto _return; |
Lines 248-253
Link Here
|
248 |
goto _return; |
286 |
goto _return; |
249 |
} |
287 |
} |
250 |
_return: |
288 |
_return: |
|
|
289 |
spawn_restore_sigchld(); |
251 |
return retval; |
290 |
return retval; |
252 |
} |
291 |
} |
253 |
|
292 |
|
Lines 275-280
Link Here
|
275 |
assert(pamh != NULL); |
314 |
assert(pamh != NULL); |
276 |
assert(data != NULL); |
315 |
assert(data != NULL); |
277 |
assert(data->user != NULL); |
316 |
assert(data->user != NULL); |
|
|
317 |
|
318 |
/* Save current SIGCHLD handler and set it to SIG_DFL to avoid GDM to reap our children */ |
319 |
if (spawn_set_sigchld()) { |
320 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: failed to set signal"); |
321 |
return 0; |
322 |
} |
323 |
|
278 |
if (!g_shell_parse_argv(GNOME_KEYRING_DAEMON, NULL, &argv, &err)) { |
324 |
if (!g_shell_parse_argv(GNOME_KEYRING_DAEMON, NULL, &argv, &err)) { |
279 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: error parsing: %s", GNOME_KEYRING_DAEMON); |
325 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: error parsing: %s", GNOME_KEYRING_DAEMON); |
280 |
goto _return; |
326 |
goto _return; |
Lines 285-317
Link Here
|
285 |
g_error_free(err); |
331 |
g_error_free(err); |
286 |
goto _return; |
332 |
goto _return; |
287 |
} |
333 |
} |
288 |
if (WIFEXITED(status) == 0 && standard_out != NULL) { |
334 |
|
289 |
lines = g_strsplit(standard_out, "\n", 3); |
335 |
if (WIFEXITED(status) && standard_out != NULL) { |
290 |
if (lines[0] != NULL && |
336 |
if (WEXITSTATUS(status) == 0) { |
291 |
lines[1] != NULL && |
337 |
lines = g_strsplit(standard_out, "\n", 3); |
292 |
g_str_has_prefix(lines[1], "GNOME_KEYRING_PID=")) { |
338 |
if (lines[0] != NULL && |
293 |
pid_str = lines[1] + strlen("GNOME_KEYRING_PID="); |
339 |
lines[1] != NULL && |
294 |
pid = strtol(pid_str, &end, 10); |
340 |
g_str_has_prefix(lines[1], "GNOME_KEYRING_PID=")) { |
295 |
if (end != pid_str) { |
341 |
pid_str = lines[1] + strlen("GNOME_KEYRING_PID="); |
296 |
fnval = pid; |
342 |
pid = strtol(pid_str, &end, 10); |
297 |
/* set variable for ulock operation */ |
343 |
if (end != pid_str) { |
298 |
data->evar = g_strdup(lines[0]); |
344 |
fnval = pid; |
299 |
/* FIXME: memory leak */ |
345 |
/* set variable for ulock operation */ |
300 |
/* ensure variable will be set in login session */ |
346 |
data->evar = g_strdup(lines[0]); |
301 |
if (pam_putenv (pamh, g_strdup(lines[0])) != PAM_SUCCESS) { |
347 |
/* FIXME: memory leak */ |
302 |
fnval = 0; |
348 |
/* ensure variable will be set in login session */ |
303 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: error setting %s", lines[0]); |
349 |
if (pam_putenv (pamh, g_strdup(lines[0])) != PAM_SUCCESS) { |
304 |
goto _return; |
350 |
fnval = 0; |
|
|
351 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: error setting %s", lines[0]); |
352 |
goto _return; |
353 |
} |
305 |
} |
354 |
} |
306 |
} |
355 |
} |
|
|
356 |
g_strfreev(lines); |
357 |
} else { |
358 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: gnome-keyring-daemon failed to start correctly, exit code: %d", WEXITSTATUS(status)); |
307 |
} |
359 |
} |
308 |
g_strfreev(lines); |
|
|
309 |
} else { |
360 |
} else { |
310 |
/* daemon failed for some reason */ |
361 |
/* daemon failed for some reason */ |
311 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: gnome-keyring-daemon failed to start correctly, exit code: %d", WEXITSTATUS(status)); |
362 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: gnome-keyring-daemon failed to start correctly."); |
312 |
} |
363 |
} |
313 |
g_free(standard_out); |
364 |
g_free(standard_out); |
314 |
_return: |
365 |
_return: |
|
|
366 |
/* Restore old signal handler */ |
367 |
spawn_restore_sigchld(); |
315 |
g_strfreev(argv); |
368 |
g_strfreev(argv); |
316 |
return fnval; |
369 |
return fnval; |
317 |
} |
370 |
} |
Lines 336-341
Link Here
|
336 |
assert(data->user); |
389 |
assert(data->user); |
337 |
assert(authtok); |
390 |
assert(authtok); |
338 |
|
391 |
|
|
|
392 |
/* Save current SIGCHLD handler and set it to SIG_DFL to avoid GDM to reap our children */ |
393 |
if (spawn_set_sigchld()) { |
394 |
pam_syslog(pamh, LOG_ERR, "pam_keyring: failed to set signal"); |
395 |
return PAM_SERVICE_ERR; |
396 |
} |
397 |
|
339 |
if (keyring == NULL) { |
398 |
if (keyring == NULL) { |
340 |
cmd_line = |
399 |
cmd_line = |
341 |
g_strconcat(PAM_KEYRING_TOOL, " -u -s", NULL); |
400 |
g_strconcat(PAM_KEYRING_TOOL, " -u -s", NULL); |
Lines 371-377
Link Here
|
371 |
close(cstderr); |
430 |
close(cstderr); |
372 |
retval = WEXITSTATUS(child_exit) ? PAM_SERVICE_ERR : PAM_SUCCESS; |
431 |
retval = WEXITSTATUS(child_exit) ? PAM_SERVICE_ERR : PAM_SUCCESS; |
373 |
_return: |
432 |
_return: |
374 |
|
433 |
/* Restore old signal handler */ |
|
|
434 |
spawn_restore_sigchld(); |
435 |
|
375 |
g_strfreev(argv); |
436 |
g_strfreev(argv); |
376 |
g_free(cmd_line); |
437 |
g_free(cmd_line); |
377 |
return retval; |
438 |
return retval; |