From ed360fe5e51caafb769fedca73a811abb5246bf2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 20 Mar 2007 12:44:40 +0000 Subject: r21887: Fix annoying bug where in a pam_close_session (or a pam_setcred with the PAM_DELETE_CREDS flag set) any user could delete krb5 credential caches. Make sure that only root can do this. Jerry, Jeremy, please check. Guenther (This used to be commit 947a59a849e9132631ec56b7ade09137e508d5d6) --- source3/nsswitch/winbindd_pam.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'source3') diff --git a/source3/nsswitch/winbindd_pam.c b/source3/nsswitch/winbindd_pam.c index 6fdead5982..6ee548292c 100644 --- a/source3/nsswitch/winbindd_pam.c +++ b/source3/nsswitch/winbindd_pam.c @@ -2092,7 +2092,9 @@ void winbindd_pam_logoff(struct winbindd_cli_state *state) { struct winbindd_domain *domain; fstring name_domain, user; - + uid_t caller_uid = (uid_t)-1; + uid_t request_uid = state->request.data.logoff.uid; + DEBUG(3, ("[%5lu]: pam logoff %s\n", (unsigned long)state->pid, state->request.data.logoff.user)); @@ -2103,6 +2105,10 @@ void winbindd_pam_logoff(struct winbindd_cli_state *state) state->request.data.logoff.krb5ccname [sizeof(state->request.data.logoff.krb5ccname)-1]='\0'; + if (request_uid == (gid_t)-1) { + goto failed; + } + if (!canonicalize_username(state->request.data.logoff.user, name_domain, user)) { goto failed; } @@ -2111,6 +2117,28 @@ void winbindd_pam_logoff(struct winbindd_cli_state *state) goto failed; } + if ((sys_getpeereid(state->sock, &caller_uid)) != 0) { + DEBUG(1,("winbindd_pam_logoff: failed to check peerid: %s\n", + strerror(errno))); + goto failed; + } + + switch (caller_uid) { + case -1: + goto failed; + case 0: + /* root must be able to logoff any user - gd */ + state->request.data.logoff.uid = request_uid; + break; + default: + if (caller_uid != request_uid) { + DEBUG(1,("winbindd_pam_logoff: caller requested invalid uid\n")); + goto failed; + } + state->request.data.logoff.uid = caller_uid; + break; + } + sendto_domain(state, domain); return; -- cgit