You are not logged in.
Despite having configured /etc/pam.d/login according to the Gnome Keyring: Automatic Unlocking / PAM directions, after logging in to the console, the "login" keyring is not unlocked, nor is gnome-keyring-daemon started:
/etc/pam.d/login:
#%PAM-1.0
auth required pam_securetty.so
auth requisite pam_nologin.so
auth include system-local-login
auth optional pam_gnome_keyring.so
account include system-local-login
session include system-local-login
session optional pam_gnome_keyring.so auto_start
/var/log/auth.log: nothing about gnome-keyring-daemon
Everything else (/etc/pam/system-*) uses the default values, so there are no sufficient pam control keywords that could halt execution of the pam stack
Most obviously, the "login" keyring password matches my actual login password.
The keyring directory seems OK and I can manually unlock the "login" keyring later:
$ ls -h .gnome2/keyrings/
default default.keyring default.keyring.temp-50754670 login.keyring user.keystore
GNOME_KEYRING_CONTROL environment variable is unset during boot (egrep -R GNOME_KEYRING_CONTROL /etc/rc* /etc/profile.d/) which would halt pam_gnome_keyring.so.
I can't really think of anything else to check. On the other hand, if pam_gnome_keyring.so were broken the "login" keyring would not be unlocked from GDM - works for everyone using GDM, right (use seahorse to check)?
Last edited by orbisvicis (2012-07-10 18:12:50)
Offline
When passing a bogus argument to pam_gnome_keyring, an error is logged to "/var/log/auth.log"
auth required pam_gnome_keyring.so try_first_pass auto_start
Jul 10 08:32:48 localhost login: gkr-pam: invalid option: try_first_pass
This means that control has been succesfully passed to the pam_gnome_keyring.so module in the pam stack. Similary, since login was successful:
Jul 10 08:33:04 localhost login: LOGIN ON tty1 BY orbisvicis
and I changed the control value from "optional" to "required", pam_gnome_keyring.so was successful. This means either no password was obtained by the module, or that it is not operating correctly, as per GnomeKeyring/Pam/Manual.
Further investigation into /etc/pam.d/passwd which contains
password optional pam_gnome_keyring.so
password required pam_unix.so sha512 shadow nullok
If "gnome-keyring-daemon" is running, using "passwd" to change my password also changes the "login" keyring password. Ironically, if authentication via "pam_unix.so" does not succeed, "pam_gnome_keyring.so" will nonetheless change the "login" keyring password, leaving it unsynchronized with the system password. Most likely the "use_authtok" argument to "pam_gnome.keyring.so prevents this behavior.
Jul 10 08:16:07 localhost passwd[5147]: gkr-pam: changed password for login keyring
However when "gnome-keyring-daemon" is not running, "pam_gnome_keyring.so" is unable change the "login" keyring password
Jul 10 08:38:48 localhost passwd[3035]: Couldn't access gnome keyring socket: /home/orbisvicis/.cache/keyring-uLeAQI/control: No such file or directory
Jul 10 08:38:48 localhost passwd[2900]: gkr-pam: couldn't change password for the login keyring.
Both messages suggest that the "pam_gnome_keyring.so" manages to retrieve the password, but is unable to spawn the "gnome-keyring-daemon". Once again, more testing.
Each new login session, "pam_gnome_keyring.so" (gkr-pam) exports two unique environment variables.
GNOME_KEYRING_CONTROL
GNOME_KEYRING
Since the "pam_gnome_keyring.so" module was unable to spawn the "gnome-keyring-daemon --daemonize --login" instance, the "gnome-keyring-daemon --start" instance started from xinitrc/start to fully initialize "gnome-keyring-daemon" is unable to connect to the socket specified by GNOME_KEYRING_CONTROL. The additional errors (last three lines) can be ignored, "gnome-keyring-daemon" is attempting to export the variables to the gnome session manager over dbus, which is not available.
Jul 10 14:13:24 localhost gnome-keyring-daemon[12728]: couldn't access conrol socket: /home/orbisvicis/.cache/keyring-uLeAQI/control: No such file or directory
Jul 10 14:13:24 localhost gnome-keyring-daemon[12729]: couldn't set environment variable in session: The name org.gnome.SessionManager was not provided by any .service files
Jul 10 14:13:24 localhost gnome-keyring-daemon[12729]: couldn't set environment variable in session: The name org.gnome.SessionManager was not provided by any .service files
Jul 10 14:13:24 localhost gnome-keyring-daemon[12729]: couldn't set environment variable in session: The name org.gnome.SessionManager was not provided by any .service files
What's weird is that when "pam_gnome_keyring.so" obtains incorrect credentials (when I type an incorrect password to login/console) and gkr-pam explicitly logs an error, "gnome-keyring-daemon --daemonize --login" is nonetheless executed. Of course the spawned daemon is useless and dies after a default 60 seconds (I think).
This is exactly what happens:
"pam_unix.so" fails
"pam_gnome_keyring.so" of type "session" displays a second login prompt, which it should not do
since it is only a session module, the new login prompt does not work
"gnome-keyring-daemon" is then spawned
the next login prompt is from "pam_unix.so", and can be used
of course, upon logging in the "gnome-keyring-daemon" process is now useless and dies shortly thereafter
Jul 10 13:22:44 localhost login: pam_unix(login:auth): authentication failure; logname=LOGIN uid=0 euid=0 tty=tty2 ruser= rhost= user=orbisvicis
Jul 10 13:22:46 localhost login: FAILED LOGIN 1 FROM tty2 FOR orbisvicis, Authentication failure
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: Gck: gck_module_new: assertion `funcs != NULL' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: module_instances: assertion `module' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: egg_error_message: assertion `error' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: couldn't find secret store module: (unknown)
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: lookup_login_keyring: assertion `GCK_IS_SESSION (session)' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: create_credential: assertion `GCK_IS_SESSION (session)' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: egg_error_message: assertion `error' failed
Jul 10 13:22:48 localhost gnome-keyring-daemon[10871]: couldn't create login credential: (unknown)
Jul 10 13:22:48 localhost login: gkr-pam: the password for the login keyring was invalid.
Jul 10 13:22:51 localhost login: FAILED LOGIN SESSION FROM tty2 FOR orbisvicis, Error in service module
Offline
I think there is enough information to warrant a bug report.
edit::FS#30631
Last edited by orbisvicis (2012-07-11 05:53:55)
Offline
Is
$ gnome-keyring-daemon --daemonize --login
supposed to fork, or is bash supposed to wait indefinitely.
Edit:
This is the appropriate behavior, "gnome-keyring-daemon --login" will block reading a password - verified by "ltrace" and booting a liveCD.
Last edited by orbisvicis (2012-07-13 18:58:28)
Offline
Simulating pam_gnome_keyring.so forking outside of the X11/DBus session to launch "gnome-keyring-daemon":
eval $(gnome-keyring-daemon --login --daemonize <<<"ThePassword")
gnome-keyring-daemon --start
Result: no errors, and the "login" keyring created if necessary.
Then, patched "gkr-pam-module.c" to print for every function:
syslog (GKR_LOG_INFO, "gkr-pam: inside NAME_OF_FUNCTION");
and "gkd-main.c" to notify upon startup:
g_message("STARTING GNOME KEYRING DAEMON");
Result:
Jul 13 04:22:56 localhost login: gkr-pam: inside pam_sm_authenticate
Jul 13 04:22:56 localhost login: gkr-pam: inside parse_args
Jul 13 04:22:56 localhost login: gkr-pam: inside get_any_env
Jul 13 04:22:56 localhost login: gkr-pam: inside pam_sm_setcred
Jul 13 04:22:56 localhost login: pam_unix(login:session): session opened for user orbisvicis by LOGIN(uid=0)
Jul 13 04:22:57 localhost login: gkr-pam: inside pam_sm_open_session
Jul 13 04:22:57 localhost login: gkr-pam: inside parse_args
Jul 13 04:22:57 localhost login: gkr-pam: inside start_daemon_if_necessary
Jul 13 04:22:57 localhost login: gkr-pam: inside get_any_env
Jul 13 04:22:57 localhost login: gkr-pam: inside start_daemon
Jul 13 04:22:57 localhost login: gkr-pam: inside setup_child
Jul 13 04:22:57 localhost login: gkr-pam: inside setup_pam_env
Jul 13 04:22:57 localhost login: gnome-keyring-daemon[1790]: STARTING GNOME KEYRING DAEMON
Jul 13 04:22:59 localhost login: gkr-pam: inside setup_environment
Jul 13 04:22:59 localhost login: gkr-pam: inside setup_environment
Jul 13 04:22:59 localhost login: gkr-pam: inside get_any_env
Jul 13 04:22:59 localhost login: gkr-pam: inside pam_sm_setcred
Jul 13 04:22:59 localhost login: LOGIN ON tty1 BY orbisvicis
Notice how "gnome-keyring-daemon --daemonize --login" expects to output two lines - the environment variables GNOME_KEYRING_CONTROL and GNOME_KEYRING_PID - and "setup_environment" has been called twice.
gnome-keyring-daemon dies before strace can be attached.
$ while true; do gkd_pid="$(pgrep -f gnome-keyring-daemon)"; if ((${gkd_pid:-1}>0)); then echo -e "${gkd_pid}\n"; sudo strace -p"$gkd_pid"; break; fi; done
1696
attach: ptrace(PTRACE_ATTACH, ...): No such process
edit: thought this might be faster, guess not:
while true; do if gkd_pid="$(pgrep -f gnome-keyring-daemon)"; then printf "%s\n----------\n" "${gkd_pid}"; sudo strace -p"$gkd_pid"; break; fi; done
Init: disabled TTY2 for respawning too fast, heh.
Last edited by orbisvicis (2012-07-14 16:25:26)
Offline
Attempt running "gnome-keyring-daemon" in an empty environment without DBus, X11, or any environment variables:
sudo init 1
su orbisvicis
id -u #euid->1000
id -ru # ruid->1000
while IFS=: read -r var; do var="${var%%=*}"; if [[ "$var" != "PATH" ]]; then unset "${var%%=*}"; fi; done<<<"$(env)"
gnome-keyring-daemon --daemonize --login
Result: works fine. The PAM environment spawning "gnome-keyring-daemon" should not be an issue.
Offline
The shutdown sequence:
Jul 14 11:56:13 localhost login: pam_unix(login:session): session closed for user orbisvicis
Jul 14 11:56:13 localhost login: gkr-pam: inside pam_sm_close_session
Jul 14 11:56:13 localhost login: gkr-pam: inside stop_daemon
specifically the function "stop_daemon", shows no errors, so I must assume "gkr-pam-pid" was never stored. why?
-----
"When the PAM session is closed, if the PAM module started gnome-keyring-daemon it is killed." -- from GnomeKeyring/Pam
After a succesful login, "/sbin/agetty -8 -s 38400 tty2 linux" is replaced by "login -- orbisvicis" which runs for the duration of the session, until logout when auth.log reports "login:session: session closed" and "login" is once again replaced by "agetty".
If this is not the correct behavior, possibly "pam_gnome_keyring.so" is accidentally triggering the shutdown of "gnome-keyring-daemon". Any input?
Offline
Patched for more information:
--- daemon/gkd-main.c.bak 2012-07-14 11:36:22.977678410 -0400
+++ daemon/gkd-main.c 2012-07-14 11:37:02.909728023 -0400
@@ -388,16 +388,29 @@
signal_thread (gpointer user_data)
{
GMainLoop *loop = user_data;
- int sig, err;
+ int err;
+ siginfo_t siginfo;
+ int fd;
+ char filename[24];
+ char arg_list[1024];
+ size_t length;
for (;;) {
- err = sigwait (&signal_set, &sig);
- if (err != EINTR && err != 0) {
- g_warning ("couldn't wait for signals: %s", g_strerror (err));
+ err = sigwaitinfo (&signal_set, &siginfo);
+ if (err < 0 && errno!=EINTR){
+ g_warning ("couldn't wait for signals: %i:%s", err, g_strerror (errno));
return NULL;
}
+ g_message("GNOME KEYRING DAEMON: Got signal '%d' from process '%d' of user '%d'\n",
+ siginfo.si_signo, siginfo.si_pid, siginfo.si_uid);
+ snprintf(filename,sizeof(filename),"/proc/%d/cmdline",siginfo.si_pid);
+ fd = open(filename, O_RDONLY);
+ length = read(fd,arg_list,sizeof(arg_list));
+ close(fd);
+ g_message("GNOME KEYRING DAEMON: SENDING PID INFO: %.*s",length,arg_list);
- switch (sig) {
+
+ switch (siginfo.si_signo) {
case SIGUSR1:
#ifdef WITH_DEBUG
dump_diagnostics ();
@@ -413,7 +426,7 @@
g_main_loop_quit (loop);
return NULL;
default:
- g_warning ("received unexpected signal when waiting for signals: %d", sig);
+ g_warning ("received unexpected signal when waiting for signals: %d", siginfo.si_signo);
break;
}
}
Resulting login/logout sequence shows in /var/log/auth.log as:
Jul 14 11:56:12 localhost login: gkr-pam: inside pam_sm_authenticate
Jul 14 11:56:12 localhost login: gkr-pam: inside parse_args
Jul 14 11:56:12 localhost login: gkr-pam: inside get_any_env
Jul 14 11:56:12 localhost login: gkr-pam: inside pam_sm_setcred
Jul 14 11:56:12 localhost login: pam_unix(login:session): session opened for user orbisvicis by LOGIN(uid=0)
Jul 14 11:56:12 localhost login: gkr-pam: inside pam_sm_open_session
Jul 14 11:56:12 localhost login: gkr-pam: inside parse_args
Jul 14 11:56:12 localhost login: gkr-pam: inside start_daemon_if_necessary
Jul 14 11:56:12 localhost login: gkr-pam: inside get_any_env
Jul 14 11:56:12 localhost login: gkr-pam: inside start_daemon
Jul 14 11:56:12 localhost login: gkr-pam: inside setup_child
Jul 14 11:56:12 localhost login: gkr-pam: inside setup_pam_env
Jul 14 11:56:12 localhost gnome-keyring-daemon[5903]: STARTING GNOME KEYRING DAEMON
Jul 14 11:56:12 localhost gnome-keyring-daemon[5903]: GNOME KEYRING DAEMON, JUST ADDED TIMEOUT CALLBACK
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: STARTING GNOME KEYRING DAEMON MAINLOOP
Jul 14 11:56:12 localhost login: gkr-pam: inside setup_environment
Jul 14 11:56:12 localhost login: gkr-pam: inside setup_environment
Jul 14 11:56:12 localhost login: gkr-pam: inside get_any_env
Jul 14 11:56:12 localhost login: gkr-pam: inside pam_sm_setcred
Jul 14 11:56:12 localhost login: LOGIN ON tty2 BY orbisvicis
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: GNOME KEYRING DAEMON: Got signal '1' from process '28840' of user '0'
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: GNOME KEYRING DAEMON: SENDING PID INFO: login -- orbisvicis
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: GNOME KEYRING DAEMON, SIGNAL THREAD CAUGHT SIGTERM
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: LEAVING GNOME KEYRING DAEMON MAINLOOP
Jul 14 11:56:12 localhost gnome-keyring-daemon[5905]: EXITING GNOME KEYRING DAEMON
Jul 14 11:56:13 localhost login: gkr-pam: inside pam_sm_setcred
Jul 14 11:56:13 localhost login: pam_unix(login:session): session closed for user orbisvicis
Jul 14 11:56:13 localhost login: gkr-pam: inside pam_sm_close_session
Jul 14 11:56:13 localhost login: gkr-pam: inside stop_daemon
I can guarantee that neither the functions
stop_daemon ::gkr-pam-module.c
gkd_main_quit ::gkd-main.c
have been called since they've been patched to log function entry via syslog and would be present above. Furthermore, from grepping the source, these are the only functions in the entire package which shut down the gnome-keyring daemon.
From the log above, it is clear that the "/bin/login" process is terminating "gnome-keyring-daemon". However, this is a bit vague, because I believe "/bin/login" hosts "pam_gnome_keyring.so" as well as the entire pam stack. So it is possible any other pam module is responsible.
It is also possible for the child fork to die after the parent exits - How to make child process die after parent exits - but I didn't see anything like that in the "gnome-keyring-daemon" package.
So unfortunately, this fiasco is still a mystery...
Last edited by orbisvicis (2012-07-14 16:55:46)
Offline
Its actually a SIGHUP, not a SIGTERM, that shuts down gnome-keyring-daemon. However, according to strace the only process to receive SIGHUP is "/bin/login" (execve), once from the kernel, once from itself, and it shouldn't be propagated. There are no sigqueue/kill/system calls sending SIGHUP. There is, however, a sigtimedwait() from a gnome-keyring-daemon fork()/clone() which waits upon a signal set including SIGHUP, though I can't figure out where this system call comes from.
strace -f -e trace=process,signal -ff -o gkd -p"${AGETTY_TTY2_PID}"
Offline
More precisely:
gkd.8358:rt_sigaction(SIGHUP, {SIG_IGN, [HUP], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
gkd.8358:--- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
gkd.8358:rt_sigaction(SIGHUP, {SIG_DFL, [HUP], SA_RESTART}, {SIG_IGN, [HUP], SA_RESTART}, 8) = 0
gkd.8358:rt_sigaction(SIGHUP, {SIG_IGN, [], 0}, {SIG_DFL, [HUP], SA_RESTART}, 8) = 0
gkd.8358:--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=8358, si_uid=0} ---
gkd.8358:rt_sigaction(SIGHUP, {0x804c2d0, [], 0}, NULL, 8) = 0
gkd.9205:rt_sigtimedwait([HUP USR1 PIPE TERM], {si_signo=SIGHUP, si_code=SI_USER, si_pid=8358, si_uid=0}, NULL, 8) = 1
gkd.9206:rt_sigaction(SIGHUP, {SIG_DFL, [HUP], SA_RESTART}, NULL, 8) = 0
gkd.9206:rt_sigaction(SIGHUP, {0x8094c80, [HUP INT ILL TRAP ABRT BUS FPE USR1 SEGV USR2 PIPE ALRM TERM XCPU XFSZ VTALRM SYS], 0}, {SIG_DFL, [], 0}, 8) = 0
gkd.9208:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9210:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9211:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9214:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9216:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9218:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
gkd.9220:rt_sigaction(SIGHUP, {SIG_DFL, [], 0}, NULL, 8) = 0
8358 -> agetty -> execve("/bin/login",...) -(which loads)-> pam_gnome_keyring.so -> rest of PAM stack
9202 -> (from pam_gnome_keyring.so) fork() -> execve("/usr/bin/gnome-keyring-daemon",[...,"--daemonize", "--login"],...)
9203 -> (from "/usr/bin/gnome-keyring-daemon --daemonize --login") fork()
9204 -> (from "/usr/bin/gnome-keyring-daemon" -> fork()
9205 -> (from "/usr/bin/gnome-keyring-daemon" -> rt_sigtimedwait([...],{si_signo=SIGHUP,...},...) -> exit
9206 -> execve("/bin/bash",...)
9208 -> execve("/usr/bin/tty"...)
...
bash profile / .xinitrc initialization
Edit::because it's easier to understand this way
8358: pam_gnome_keyring.so (loaded from /bin/login) which waitpid() on the initial fork()
9202: pam_gnome_keyring.so initial fork() which executes/becomes "gnome-keyring-daemon --daemonize --login" and waitpid() on the intermediate process
9203: gnome-keyring-daemon intermediate fork() which also write() the environment variables to the TTY, then fork() and exit() without waiting
9204: gnome-keyring-daemon final fork(), daemon which executes gdk::main() and starts the GMainLoop
9205: the parallel signal-thread which is responsible for handling signals, (all the other threads ignore the signals)
since "--daemonize" forks twice to ensure that it is reparented onto init, and to guarantee that it is not a session leader, ie unable to obtain a controlling TTY.
Last edited by orbisvicis (2012-07-15 00:41:18)
Offline
I can't figure out how the signal thread of gnome-keyring-daemon receives SIGHUP. Excerpt from strace:
set_robust_list(0xb7053bb0, 12) = 0
rt_sigtimedwait([HUP USR1 PIPE TERM], {si_signo=SIGHUP, si_code=SI_USER, si_pid=9236, si_uid=0}, NULL, 8) = 1
--- SIGCONT {si_signo=SIGCONT, si_code=SI_USER, si_pid=9236, si_uid=0} ---
mmap2(NULL, 2097152, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0xb6653000
SIGHUP seems to magically appear as the argument to rt_sigtimedwait(), and isn't even logged by strace, unlike the subsequent SIGCONT.
Furthermore, "/bin/login" appears to ignore all SIGHUP signals that it receives:
from strace:
rt_sigaction(SIGHUP, {SIG_IGN, [HUP], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
vhangup() = 0
--- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} ---
--- SIGCONT {si_signo=SIGCONT, si_code=SI_KERNEL} ---
rt_sigaction(SIGHUP, {SIG_DFL, [HUP], SA_RESTART}, {SIG_IGN, [HUP], SA_RESTART}, 8) = 0
corresponding login.c:
signal(SIGHUP, SIG_IGN); /* so vhangup() wont kill us */
vhangup();
signal(SIGHUP, SIG_DFL);
from strace:
rt_sigaction(SIGHUP, {SIG_IGN, [], 0}, {SIG_DFL, [HUP], SA_RESTART}, 8) = 0
ioctl(0, TIOCNOTTY) = 0
--- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=9236, si_uid=0} ---
--- SIGCONT {si_signo=SIGCONT, si_code=SI_USER, si_pid=9236, si_uid=0} ---
rt_sigaction(SIGHUP, {0x804c2d0, [], 0}, NULL, 8) = 0
corresponding login.c:
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGHUP, &sa, &oldsa_hup); /* ignore when TIOCNOTTY */
/*
* detach the controlling tty
* -- we needn't the tty in parent who waits for child only.
* The child calls setsid() that detach from the tty as well.
*/
ioctl(0, TIOCNOTTY, NULL);
/*
* We have care about SIGTERM, because leave PAM session without
* pam_close_session() is pretty bad thing.
*/
sa.sa_handler = sig_handler;
sigaction(SIGHUP, &sa, NULL);
sigaction(SIGTERM, &sa, &oldsa_term);
static void sig_handler(int signal)
{
if (child_pid)
kill(-child_pid, signal);
else
got_sig = 1;
if (signal == SIGTERM)
kill(-child_pid, SIGHUP); /* because the shell often ignores SIGTERM */
}
It also seems that sig_handler() is never called, so "/bin/login" in this particular codepath does not send any signals to its children.
------------
Several month ago, "gnome-keyring-daemon" integrated into "/bin/login" via pam_gnome_keyring.so without difficulty. If indeed a change in the behavior of "/bin/login" is responsible for the current failure of "gnome-keyring-daemon", I can't find any recent commits in the util-linux git repository that could be the culprit. These are the files I've checked:
$ find . \( -iname 'login*.c' -o -iname 'login*.h' \)
./login.c
./logindefs.c
./logindefs.h
Last edited by orbisvicis (2012-07-15 01:07:46)
Offline
Two possible theories about the SIGHUP signal:
Intermediate fork, by writing to the TTY, re-acquires the controlling terminal. When this fork exits(), it causes a SIGHUP.
When the first fork dies the gnome-keyring-daemon process group becomes orphaned, causing a SIGHUP/SIGCONT combination.
I really have no clue.
Offline
Couldn't reproduce either ideas:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stropts.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
static void child(int* fd){
fprintf(stdout,"child pid: %i\n",getpid());
fprintf(stdout,"child ppid: %i\n",getppid());
fprintf(stdout,"child pgid: %i\n",getpgid(0));
fprintf(stdout,"child sid: %i\n",getsid(0));
if( dup2(fd[0],0)<0 )
exit(-1);
for (int i=2; i < 64; ++i)
close(i);
close( fd[0] );
close( fd[1] );
fd[0] = -1;
fd[1] = -1;
char* const args[] = { strdup("/usr/bin/gnome-keyring-daemon"),strdup("--daemonize"),strdup("--login"), NULL};
execv (args[0], args);
for(int i=0; !args[i]; i++)
free(args[i]);
exit(-1);
}
static void parent(int* fd,pid_t pid){
char passwd[] = "ThePassword\n";
close( fd[0] );
fd[0] = -1;
if( write(fd[1],passwd,sizeof(passwd)) < 0 )
exit(-1);
close( fd[1] );
fd[1] = -1;
if( waitpid(pid,NULL,0)<0 )
exit(-1);
}
int main(){
if ((fork()) != 0)
exit(0);
setsid();
if ((fork()) != 0)
exit(0);
vhangup();
ioctl(0, TIOCNOTTY, NULL);
fprintf(stdout,"\n");
fprintf(stdout,"parent pid: %i\n",getpid());
fprintf(stdout,"parent ppid: %i\n",getppid());
fprintf(stdout,"parent pgid: %i\n",getpgid(0));
fprintf(stdout,"parent sid: %i\n",getsid(0));
int fd[2] = {-1,-1};
pid_t pid;
if( pipe(fd)<0 )
exit(-1);
switch( pid = fork() ){
case -1:
exit(-1);
break;
case 0:
child(fd);
break;
default:
parent(fd,pid);
break;
};
}
// vim:set ts=2 sw=2 et:
Edit::Clarification:
pam_sm_close_session() is called when login/pam_unix closses the login session, which occurs naturally from running logout/exit in the bash login shell... which is long after gnome-keyring-daemon receives the SIGHUP.
The SIGHUP occurs after log_syslog() in login.c (from util-linux) - after a login is committed. I assume the SIGHUP occurs before /bin/login/ executes/becomes /bin/bash - stemming from the assumption that execvp/kernel would update the information in /proc/pid/cmdline (according to /proc/pid/cmdline, "login" is responsible for the SIGHUP).
Last edited by orbisvicis (2012-07-16 15:43:41)
Offline
For the record, the patch that fixes the problem:
--- daemon/gkd-main.c.bak 2012-07-17 13:49:35.951945395 -0400
+++ daemon/gkd-main.c 2012-07-17 13:49:38.235208426 -0400
@@ -677,6 +677,12 @@
if (run_daemonized) {
+ /* Become session leader of a new session, process group leader of a new
+ * process group, and detach from the controlling TTY, so that SIGHUP is
+ * not sent to this process when the previous session leader dies
+ */
+ setsid();
+
/* Double fork if need to daemonize properly */
pid = fork ();
I'm still not sure which session leader died, or how ptrace was unable to trace the signal, but it works.
Offline
I had the same problem and wanted to thank you for your intensive investigation regarding this issue. It is very much appreciated .
Offline
I'm having the same issue with a fresh install of Arch with Gnome 3 as my DE. I prefer to start Gnome with startx.
I have the same login and passwd files in my /etc/pam.d directory as the OP.
Adding the pam_gnome_keyring.so lines to the login file seemed to be sufficient to unlock the keyring upon login in the past.
Is anybody else experiencing this? Surely, we can't be the only ones.
The OP's awesome work seems to be a workaround to the problem.
I do not want to edit any sources.
Offline
I'm also affected by this. I'll see if I can patch the sources when I have the time to see if it also fixes it for me.
EDIT: Tried the patch, it works.
Last edited by dkasak (2012-10-16 18:35:21)
Offline
^Is this still the current working solution?
How does one go about applying the patch? (sorry for the newb question)
Last edited by snoxu (2013-05-16 21:20:32)
Offline
How does one go about applying the patch? (sorry for the newb question)
Offline