summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbindd_pam.c
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2007-03-20 12:44:40 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:18:44 -0500
commited360fe5e51caafb769fedca73a811abb5246bf2 (patch)
tree109ee14df23280384722c02b6480cf233258d0d2 /source3/nsswitch/winbindd_pam.c
parent679a313517cc94e13d1be6eb6e8cc42128c8412c (diff)
downloadsamba-ed360fe5e51caafb769fedca73a811abb5246bf2.tar.gz
samba-ed360fe5e51caafb769fedca73a811abb5246bf2.tar.bz2
samba-ed360fe5e51caafb769fedca73a811abb5246bf2.zip
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)
Diffstat (limited to 'source3/nsswitch/winbindd_pam.c')
-rw-r--r--source3/nsswitch/winbindd_pam.c30
1 files changed, 29 insertions, 1 deletions
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;