Author: gd
Date: 2007-03-20 12:44:40 +0000 (Tue, 20 Mar 2007)
New Revision: 21887

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=21887

Log:
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


Modified:
   branches/SAMBA_3_0/source/nsswitch/winbindd_pam.c
   branches/SAMBA_3_0_25/source/nsswitch/winbindd_pam.c


Changeset:
Modified: branches/SAMBA_3_0/source/nsswitch/winbindd_pam.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbindd_pam.c   2007-03-20 08:17:50 UTC 
(rev 21886)
+++ branches/SAMBA_3_0/source/nsswitch/winbindd_pam.c   2007-03-20 12:44:40 UTC 
(rev 21887)
@@ -2092,7 +2092,9 @@
 {
        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 @@
        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 @@
                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;
 

Modified: branches/SAMBA_3_0_25/source/nsswitch/winbindd_pam.c
===================================================================
--- branches/SAMBA_3_0_25/source/nsswitch/winbindd_pam.c        2007-03-20 
08:17:50 UTC (rev 21886)
+++ branches/SAMBA_3_0_25/source/nsswitch/winbindd_pam.c        2007-03-20 
12:44:40 UTC (rev 21887)
@@ -2092,7 +2092,9 @@
 {
        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 @@
        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 @@
                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;
 

Reply via email to