Author: jmcd Date: 2005-08-05 12:33:03 +0000 (Fri, 05 Aug 2005) New Revision: 9113
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=9113 Log: Fix #2953 - credentials chain on DC gets out of sync with client when 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. Modified: trunk/source/libsmb/credentials.c trunk/source/rpc_server/srv_netlog_nt.c Changeset: Modified: trunk/source/libsmb/credentials.c =================================================================== --- trunk/source/libsmb/credentials.c 2005-08-05 12:33:00 UTC (rev 9112) +++ trunk/source/libsmb/credentials.c 2005-08-05 12:33:03 UTC (rev 9113) @@ -208,8 +208,36 @@ 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); +} Modified: trunk/source/rpc_server/srv_netlog_nt.c =================================================================== --- trunk/source/rpc_server/srv_netlog_nt.c 2005-08-05 12:33:00 UTC (rev 9112) +++ trunk/source/rpc_server/srv_netlog_nt.c 2005-08-05 12:33:03 UTC (rev 9113) @@ -449,6 +449,7 @@ 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 @@ &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 @@ 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 @@ 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"));