Author: vlendec Date: 2005-09-01 07:59:41 +0000 (Thu, 01 Sep 2005) New Revision: 9882
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=9882 Log: Merge head up to r9881 Modified: branches/tmp/vl-cluster/source/include/ntlmssp.h branches/tmp/vl-cluster/source/libsmb/cliconnect.c branches/tmp/vl-cluster/source/libsmb/ntlmssp.c branches/tmp/vl-cluster/source/rpc_server/srv_reg_nt.c branches/tmp/vl-cluster/source/tdb/tdb.c branches/tmp/vl-cluster/source/utils/ntlm_auth.c Changeset: Modified: branches/tmp/vl-cluster/source/include/ntlmssp.h =================================================================== --- branches/tmp/vl-cluster/source/include/ntlmssp.h 2005-09-01 07:44:59 UTC (rev 9881) +++ branches/tmp/vl-cluster/source/include/ntlmssp.h 2005-09-01 07:59:41 UTC (rev 9882) @@ -34,7 +34,8 @@ NTLMSSP_NEGOTIATE = 1, NTLMSSP_CHALLENGE = 2, NTLMSSP_AUTH = 3, - NTLMSSP_UNKNOWN = 4 + NTLMSSP_UNKNOWN = 4, + NTLMSSP_DONE = 5 /* samba final state */ }; /* NTLMSSP negotiation flags */ Modified: branches/tmp/vl-cluster/source/libsmb/cliconnect.c =================================================================== --- branches/tmp/vl-cluster/source/libsmb/cliconnect.c 2005-09-01 07:44:59 UTC (rev 9881) +++ branches/tmp/vl-cluster/source/libsmb/cliconnect.c 2005-09-01 07:59:41 UTC (rev 9882) @@ -600,7 +600,7 @@ nt_status = ntlmssp_update(ntlmssp_state, blob_in, &blob_out); data_blob_free(&blob_in); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) { if (turn == 1) { /* and wrap it in a SPNEGO wrapper */ msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); Modified: branches/tmp/vl-cluster/source/libsmb/ntlmssp.c =================================================================== --- branches/tmp/vl-cluster/source/libsmb/ntlmssp.c 2005-09-01 07:44:59 UTC (rev 9881) +++ branches/tmp/vl-cluster/source/libsmb/ntlmssp.c 2005-09-01 07:59:41 UTC (rev 9882) @@ -218,6 +218,12 @@ uint32 ntlmssp_command; int i; + if (ntlmssp_state->expected_state == NTLMSSP_DONE) { + /* Called update after negotiations finished. */ + DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n")); + return NT_STATUS_INVALID_PARAMETER; + } + *out = data_blob(NULL, 0); if (!in.length && ntlmssp_state->stored_response.length) { @@ -534,7 +540,7 @@ DATA_BLOB lm_session_key = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); uint32 ntlmssp_command, auth_flags; - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_OK; /* used by NTLM2 */ BOOL doing_ntlm2 = False; @@ -784,8 +790,8 @@ data_blob_free(&encrypted_session_key); - /* allow arbitarily many authentications */ - ntlmssp_state->expected_state = NTLMSSP_AUTH; + /* Only one authentication allowed per server state. */ + ntlmssp_state->expected_state = NTLMSSP_DONE; return nt_status; } @@ -897,7 +903,7 @@ DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB encrypted_session_key = data_blob(NULL, 0); - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_OK; if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", @@ -1098,14 +1104,13 @@ ntlmssp_state->lm_resp = lm_response; ntlmssp_state->nt_resp = nt_response; - ntlmssp_state->expected_state = NTLMSSP_UNKNOWN; + ntlmssp_state->expected_state = NTLMSSP_DONE; if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); - return nt_status; } - return NT_STATUS_MORE_PROCESSING_REQUIRED; + return nt_status; } NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) Modified: branches/tmp/vl-cluster/source/rpc_server/srv_reg_nt.c =================================================================== --- branches/tmp/vl-cluster/source/rpc_server/srv_reg_nt.c 2005-09-01 07:44:59 UTC (rev 9881) +++ branches/tmp/vl-cluster/source/rpc_server/srv_reg_nt.c 2005-09-01 07:59:41 UTC (rev 9882) @@ -133,21 +133,24 @@ parent ? parent->name : "NULL", subkeyname)); /* strip any trailing '\'s */ + pstrcpy( subkeyname2, subkeyname ); subkey_len = strlen ( subkeyname2 ); + if ( subkey_len && subkeyname2[subkey_len-1] == '\\' ) subkeyname2[subkey_len-1] = '\0'; - if ((regkey=SMB_MALLOC_P(REGISTRY_KEY)) == NULL) + if ( !(regkey=SMB_MALLOC_P(REGISTRY_KEY)) ) return WERR_NOMEM; ZERO_STRUCTP( regkey ); /* Tag this as a Performance Counter Key */ - if(0==StrnCaseCmp(subkeyname, KEY_HKPD, strlen(KEY_HKPD))) - regkey->type = REG_KEY_HKPD; + + if( StrnCaseCmp(subkeyname, KEY_HKPD, strlen(KEY_HKPD)) == 0 ) + regkey->type = REG_KEY_HKPD; else - regkey->type = REG_KEY_GENERIC; + regkey->type = REG_KEY_GENERIC; /* * very crazy, but regedit.exe on Win2k will attempt to call Modified: branches/tmp/vl-cluster/source/tdb/tdb.c =================================================================== --- branches/tmp/vl-cluster/source/tdb/tdb.c 2005-09-01 07:44:59 UTC (rev 9881) +++ branches/tmp/vl-cluster/source/tdb/tdb.c 2005-09-01 07:59:41 UTC (rev 9882) @@ -1248,6 +1248,54 @@ /* Lock each chain from the start one. */ for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { + + /* this is an optimisation for the common case where + the hash chain is empty, which is particularly + common for the use of tdb with ldb, where large + hashes are used. In that case we spend most of our + time in tdb_brlock(), locking empty hash chains. + + To avoid this, we do an unlocked pre-check to see + if the hash chain is empty before starting to look + inside it. If it is empty then we can avoid that + hash chain. If it isn't empty then we can't believe + the value we get back, as we read it without a + lock, so instead we get the lock and re-fetch the + value below. + + Notice that not doing this optimisation on the + first hash chain is critical. We must guarantee + that we have done at least one fcntl lock at the + start of a search to guarantee that memory is + coherent on SMP systems. If records are added by + others during the search then thats OK, and we + could possibly miss those with this trick, but we + could miss them anyway without this trick, so the + semantics don't change. + + With a non-indexed ldb search this trick gains us a + factor of around 80 in speed on a linux 2.6.x + system (testing using ldbtest). + */ + if (!tlock->off && tlock->hash != 0) { + u32 off; + if (tdb->map_ptr) { + for (;tlock->hash < tdb->header.hash_size;tlock->hash++) { + if (0 != *(u32 *)(TDB_HASH_TOP(tlock->hash) + (unsigned char *)tdb->map_ptr)) { + break; + } + } + if (tlock->hash == tdb->header.hash_size) { + continue; + } + } else { + if (ofs_read(tdb, TDB_HASH_TOP(tlock->hash), &off) == 0 && + off == 0) { + continue; + } + } + } + if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1) return -1; Modified: branches/tmp/vl-cluster/source/utils/ntlm_auth.c =================================================================== --- branches/tmp/vl-cluster/source/utils/ntlm_auth.c 2005-09-01 07:44:59 UTC (rev 9881) +++ branches/tmp/vl-cluster/source/utils/ntlm_auth.c 2005-09-01 07:59:41 UTC (rev 9882) @@ -693,7 +693,8 @@ data_blob_free(&reply); DEBUG(10, ("NTLMSSP challenge\n")); } else if (NT_STATUS_IS_OK(nt_status)) { - x_fprintf(x_stdout, "AF\n"); + char *reply_base64 = base64_encode_data_blob(reply); + x_fprintf(x_stdout, "AF %s\n", reply_base64); DEBUG(10, ("NTLMSSP OK!\n")); if (ntlmssp_state) ntlmssp_end(&ntlmssp_state); @@ -1059,8 +1060,9 @@ status = ntlmssp_update(client_ntlmssp_state, null_blob, &spnego.negTokenInit.mechToken); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED, got: %s\n", + if ( !(NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || + NT_STATUS_IS_OK(status)) ) { + DEBUG(1, ("Expected OK or MORE_PROCESSING_REQUIRED, got: %s\n", nt_errstr(status))); ntlmssp_end(&client_ntlmssp_state); return False;
