r9112: Fix #2953 - credentials chain on DC gets out of sync with client when
authorJim McDonough <jmcd@samba.org>
Fri, 5 Aug 2005 12:33:00 +0000 (12:33 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:00:26 +0000 (11:00 -0500)
NT_STATUS_NO_USER returned.  We were moving to the next step in the
chain when the client wasn't.  Only update when the user logs on.
(This used to be commit b01a3a4111f544eef5bd678237d07a82d1ce9c22)

source3/libsmb/credentials.c
source3/rpc_server/srv_netlog_nt.c

index 0d521bae8ac42c7421f6db043bee74a48c0e3217..322b25ee43fa930254554d5fea628f74f36391b5 100644 (file)
@@ -208,8 +208,36 @@ BOOL deal_with_creds(uchar sess_key[8],
        
        DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data)));
 
-       /* store new seed in client credentials */
-       SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
+       /* Bug #2953 - don't store new seed in client credentials 
+          here, because we need to make sure we're moving forward first
+        */
 
        return True;
 }
+
+/*
+  stores new seed in client credentials
+  jmcd - Bug #2953 - moved this functionality out of deal_with_creds, because we're
+  not supposed to move to the next step in the chain if a nonexistent user tries to logon
+*/
+void reseed_client_creds(DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_clnt_cred)
+{
+       UTIME new_clnt_time;
+       uint32 new_cred;
+
+       /* increment client time by one second */
+       new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1;
+
+       /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
+       new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
+       new_cred += new_clnt_time.time;
+
+       DEBUG(5,("reseed_client_creds: new_cred[0]=%x\n", new_cred));
+       DEBUG(5,("reseed_client_creds: new_clnt_time=%x\n", 
+                new_clnt_time.time));
+       DEBUG(5,("reseed_client_creds: clnt_cred=%s\n", 
+                credstr(sto_clnt_cred->challenge.data)));
+
+       /* store new seed in client credentials */
+       SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
+}      
index 7880a724b5c70d225bcd9579b813d709c8419021..0af8b14fe216f1d90581e5172e37eaf98336856d 100644 (file)
@@ -449,6 +449,7 @@ NTSTATUS _net_srv_pwset(pipes_struct *p, NET_Q_SRV_PWSET *q_u, NET_R_SRV_PWSET *
        if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->clnt_id.cred, &srv_cred)))
                return NT_STATUS_INVALID_HANDLE;
 
+       reseed_client_creds(&p->dc.clnt_cred, &q_u->clnt_id.cred);
        memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
 
        DEBUG(5,("_net_srv_pwset: %d\n", __LINE__));
@@ -545,6 +546,8 @@ NTSTATUS _net_sam_logoff(pipes_struct *p, NET_Q_SAM_LOGOFF *q_u, NET_R_SAM_LOGOF
                                                     &q_u->sam_id.client.cred, &srv_cred)))
                return NT_STATUS_INVALID_HANDLE;
 
+       /* what happens if we get a logoff for an unknown user? */
+       reseed_client_creds(&p->dc.clnt_cred, &q_u->sam_id.client.cred);
        memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
 
        /* XXXX maybe we want to say 'no', reject the client's credentials */
@@ -603,11 +606,6 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
        if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred)))
                return NT_STATUS_INVALID_HANDLE;
 
-       memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
-    
-       r_u->buffer_creds = 1; /* yes, we have valid server credentials */
-       memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds));
-
        /* find the username */
     
        switch (q_u->sam_id.logon_level) {
@@ -719,6 +717,15 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
                return status;
        }
 
+       /* moved from right after deal_with_creds above, since we weren't
+          supposed to update unless logon was successful */
+
+       reseed_client_creds(&p->dc.clnt_cred, &q_u->sam_id.client.cred);
+       memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
+    
+       r_u->buffer_creds = 1; /* yes, we have valid server credentials */
+       memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds));
+
        if (server_info->guest) {
                /* We don't like guest domain logons... */
                DEBUG(5,("_net_sam_logon: Attempted domain logon as GUEST denied.\n"));