/* Validate an incoming authenticator against the credentials for the remote machine. The credentials are (re)read and from the schannel database, and written back after the caclulations are performed. The creds_out parameter (if not NULL) returns the credentials, if the caller needs some of that information. */ NTSTATUS schannel_creds_server_step_check_ldb(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const char *computer_name, bool schannel_required_for_call, bool schannel_in_use, struct netr_Authenticator *received_authenticator, struct netr_Authenticator *return_authenticator, struct netlogon_creds_CredentialState **creds_out) { struct netlogon_creds_CredentialState *creds; NTSTATUS nt_status; int ret; ret = ldb_transaction_start(ldb); if (ret != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } /* Because this is a shared structure (even across * disconnects) we must update the database every time we * update the structure */ nt_status = schannel_fetch_session_key_ldb(ldb, ldb, computer_name, &creds); /* If we are flaged that schannel is required for a call, and * it is not in use, then make this an error */ /* It would be good to make this mandetory once schannel is * negoiated, bu this is not what windows does */ if (schannel_required_for_call && !schannel_in_use) { DEBUG(0,("schannel_creds_server_step_check: client %s not using schannel for netlogon, despite negotiating it\n", creds->computer_name )); ldb_transaction_cancel(ldb); return NT_STATUS_ACCESS_DENIED; } if (NT_STATUS_IS_OK(nt_status)) { nt_status = netlogon_creds_server_step_check(creds, received_authenticator, return_authenticator); } if (NT_STATUS_IS_OK(nt_status)) { nt_status = schannel_store_session_key_ldb(ldb, mem_ctx, creds); } if (NT_STATUS_IS_OK(nt_status)) { ldb_transaction_commit(ldb); if (creds_out) { *creds_out = creds; talloc_steal(mem_ctx, creds); } } else { ldb_transaction_cancel(ldb); } return nt_status; }
NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, const char *computer_name, const char *domain, struct creds_CredentialState **creds) { NTSTATUS nt_status; struct ldb_context *ldb; ldb = schannel_db_connect(mem_ctx); if (!ldb) { return NT_STATUS_ACCESS_DENIED; } nt_status = schannel_fetch_session_key_ldb(mem_ctx, ldb, computer_name, domain, creds); talloc_free(ldb); return nt_status; }