diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/auth/gensec/schannel.c | 4 | ||||
-rw-r--r-- | source4/auth/gensec/schannel_sign.c | 8 | ||||
-rw-r--r-- | source4/auth/gensec/schannel_state.c | 127 | ||||
-rw-r--r-- | source4/rpc_server/netlogon/dcerpc_netlogon.c | 221 | ||||
-rw-r--r-- | source4/torture/rpc/schannel.c | 11 |
5 files changed, 235 insertions, 136 deletions
diff --git a/source4/auth/gensec/schannel.c b/source4/auth/gensec/schannel.c index dd0bc1eddd..10c8f9853a 100644 --- a/source4/auth/gensec/schannel.c +++ b/source4/auth/gensec/schannel.c @@ -149,7 +149,7 @@ NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, struct creds_CredentialState **creds) { - struct schannel_state *state = gensec_security->private_data; + struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state); *creds = talloc_reference(mem_ctx, state->creds); if (!*creds) { @@ -167,7 +167,7 @@ NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security, static NTSTATUS schannel_session_info(struct gensec_security *gensec_security, struct auth_session_info **_session_info) { - struct schannel_state *state = gensec_security->private_data; + struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state); return auth_anonymous_session_info(state, _session_info); } diff --git a/source4/auth/gensec/schannel_sign.c b/source4/auth/gensec/schannel_sign.c index f143ccd4c7..b4549ddefd 100644 --- a/source4/auth/gensec/schannel_sign.c +++ b/source4/auth/gensec/schannel_sign.c @@ -105,7 +105,7 @@ NTSTATUS schannel_unseal_packet(struct gensec_security *gensec_security, const uint8_t *whole_pdu, size_t pdu_length, const DATA_BLOB *sig) { - struct schannel_state *state = gensec_security->private_data; + struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state); uint8_t digest_final[16]; uint8_t confounder[8]; @@ -156,7 +156,7 @@ NTSTATUS schannel_check_packet(struct gensec_security *gensec_security, const uint8_t *whole_pdu, size_t pdu_length, const DATA_BLOB *sig) { - struct schannel_state *state = gensec_security->private_data; + struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state); uint8_t digest_final[16]; uint8_t seq_num[8]; @@ -204,7 +204,7 @@ NTSTATUS schannel_seal_packet(struct gensec_security *gensec_security, const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { - struct schannel_state *state = gensec_security->private_data; + struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state); uint8_t digest_final[16]; uint8_t confounder[8]; @@ -252,7 +252,7 @@ NTSTATUS schannel_sign_packet(struct gensec_security *gensec_security, const uint8_t *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { - struct schannel_state *state = gensec_security->private_data; + struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state); uint8_t digest_final[16]; uint8_t seq_num[8]; diff --git a/source4/auth/gensec/schannel_state.c b/source4/auth/gensec/schannel_state.c index 7ef64ca00b..a73e450ec8 100644 --- a/source4/auth/gensec/schannel_state.c +++ b/source4/auth/gensec/schannel_state.c @@ -29,7 +29,7 @@ /* connect to the schannel ldb */ -static struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx) +struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx) { char *path; struct ldb_context *ldb; @@ -64,44 +64,35 @@ static struct ldb_context *schannel_db_connect(TALLOC_CTX *mem_ctx) remember an established session key for a netr server authentication use a simple ldb structure */ -NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, - struct creds_CredentialState *creds) +NTSTATUS schannel_store_session_key_ldb(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + struct creds_CredentialState *creds) { - struct ldb_context *ldb; struct ldb_message *msg; - struct ldb_val val, seed; + struct ldb_val val, seed, client_state, server_state; char *f; char *sct; int ret; - ldb = schannel_db_connect(mem_ctx); - if (ldb == NULL) { - return NT_STATUS_NO_MEMORY; - } - f = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->negotiate_flags); if (f == NULL) { - talloc_free(ldb); return NT_STATUS_NO_MEMORY; } sct = talloc_asprintf(mem_ctx, "%u", (unsigned int)creds->secure_channel_type); if (sct == NULL) { - talloc_free(ldb); return NT_STATUS_NO_MEMORY; } msg = ldb_msg_new(ldb); if (msg == NULL) { - talloc_free(ldb); return NT_STATUS_NO_MEMORY; } msg->dn = ldb_dn_build_child(msg, "computerName", creds->computer_name, NULL); if (msg->dn == NULL) { - talloc_free(ldb); return NT_STATUS_NO_MEMORY; } @@ -111,9 +102,16 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, seed.data = creds->seed.data; seed.length = sizeof(creds->seed.data); + client_state.data = creds->client.data; + client_state.length = sizeof(creds->client.data); + server_state.data = creds->server.data; + server_state.length = sizeof(creds->server.data); + ldb_msg_add_string(msg, "objectClass", "schannelState"); ldb_msg_add_value(msg, "sessionKey", &val); ldb_msg_add_value(msg, "seed", &seed); + ldb_msg_add_value(msg, "clientState", &client_state); + ldb_msg_add_value(msg, "serverState", &server_state); ldb_msg_add_string(msg, "negotiateFlags", f); ldb_msg_add_string(msg, "secureChannelType", sct); ldb_msg_add_string(msg, "accountName", creds->account_name); @@ -121,49 +119,65 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, ldb_msg_add_string(msg, "flatname", creds->domain); samdb_msg_add_dom_sid(ldb, mem_ctx, msg, "objectSid", creds->sid); - ret = ldb_transaction_start(ldb); + ldb_delete(ldb, msg->dn); + + ret = ldb_add(ldb, msg); + if (ret != 0) { - DEBUG(0,("Unable to start transaction to add %s to session key db - %s\n", + DEBUG(0,("Unable to add %s to session key db - %s\n", ldb_dn_linearize(msg, msg->dn), ldb_errstring(ldb))); - talloc_free(ldb); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - ldb_delete(ldb, msg->dn); + return NT_STATUS_OK; +} - ret = ldb_add(ldb, msg); +NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx, + struct creds_CredentialState *creds) +{ + struct ldb_context *ldb; + NTSTATUS nt_status; + int ret; + + ldb = schannel_db_connect(mem_ctx); + if (!ldb) { + return NT_STATUS_ACCESS_DENIED; + } + ret = ldb_transaction_start(ldb); if (ret != 0) { - DEBUG(0,("Unable to add %s to session key db - %s\n", - ldb_dn_linearize(msg, msg->dn), ldb_errstring(ldb))); talloc_free(ldb); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - ret = ldb_transaction_commit(ldb); + nt_status = schannel_store_session_key_ldb(mem_ctx, ldb, creds); + + if (NT_STATUS_IS_OK(nt_status)) { + ret = ldb_transaction_commit(ldb); + } else { + ret = ldb_transaction_cancel(ldb); + } if (ret != 0) { - DEBUG(0,("Unable to commit adding %s to session key db - %s\n", - ldb_dn_linearize(msg, msg->dn), ldb_errstring(ldb))); + DEBUG(0,("Unable to commit adding credentials for %s to schannel key db - %s\n", + creds->computer_name, ldb_errstring(ldb))); talloc_free(ldb); return NT_STATUS_INTERNAL_DB_CORRUPTION; } talloc_free(ldb); - - return NT_STATUS_OK; + return nt_status; } - /* read back a credentials back for a computer */ -NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, - const char *computer_name, - const char *domain, - struct creds_CredentialState **creds) +NTSTATUS schannel_fetch_session_key_ldb(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + const char *computer_name, + const char *domain, + struct creds_CredentialState **creds) { - struct ldb_context *ldb; struct ldb_result *res; int ret; const struct ldb_val *val; @@ -174,27 +188,21 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - ldb = schannel_db_connect(mem_ctx); - if (ldb == NULL) { - return NT_STATUS_NO_MEMORY; - } - - expr = talloc_asprintf(mem_ctx, "(&(computerName=%s)(flatname=%s))", computer_name, domain); + expr = talloc_asprintf(mem_ctx, "(&(computerName=%s)(flatname=%s))", + computer_name, domain); if (expr == NULL) { - talloc_free(ldb); return NT_STATUS_NO_MEMORY; } ret = ldb_search(ldb, NULL, LDB_SCOPE_SUBTREE, expr, NULL, &res); if (ret != LDB_SUCCESS || res->count != 1) { - talloc_free(ldb); + DEBUG(3,("schannel: Failed to find a record for client: %s\n", computer_name)); return NT_STATUS_INVALID_HANDLE; } val = ldb_msg_find_ldb_val(res->msgs[0], "sessionKey"); if (val == NULL || val->length != 16) { DEBUG(1,("schannel: record in schannel DB must contain a sessionKey of length 16, when searching for client: %s\n", computer_name)); - talloc_free(ldb); return NT_STATUS_INTERNAL_ERROR; } @@ -203,12 +211,25 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, val = ldb_msg_find_ldb_val(res->msgs[0], "seed"); if (val == NULL || val->length != 8) { DEBUG(1,("schannel: record in schannel DB must contain a vaid seed of length 8, when searching for client: %s\n", computer_name)); - talloc_free(ldb); return NT_STATUS_INTERNAL_ERROR; } memcpy((*creds)->seed.data, val->data, 8); + val = ldb_msg_find_ldb_val(res->msgs[0], "clientState"); + if (val == NULL || val->length != 8) { + DEBUG(1,("schannel: record in schannel DB must contain a vaid clientState of length 8, when searching for client: %s\n", computer_name)); + return NT_STATUS_INTERNAL_ERROR; + } + memcpy((*creds)->client.data, val->data, 8); + + val = ldb_msg_find_ldb_val(res->msgs[0], "serverState"); + if (val == NULL || val->length != 8) { + DEBUG(1,("schannel: record in schannel DB must contain a vaid serverState of length 8, when searching for client: %s\n", computer_name)); + return NT_STATUS_INTERNAL_ERROR; + } + memcpy((*creds)->server.data, val->data, 8); + (*creds)->negotiate_flags = ldb_msg_find_int(res->msgs[0], "negotiateFlags", 0); (*creds)->secure_channel_type = ldb_msg_find_int(res->msgs[0], "secureChannelType", 0); @@ -221,7 +242,25 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx, (*creds)->sid = samdb_result_dom_sid(*creds, res->msgs[0], "objectSid"); - talloc_free(ldb); - return NT_STATUS_OK; } + +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; +} diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index f3ef74641d..03d325020f 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -128,6 +128,7 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL struct netr_ServerAuthenticate3 *r) { struct server_pipe_state *pipe_state = dce_call->context->private; + struct creds_CredentialState *creds; void *sam_ctx; struct samr_Password *mach_pwd; uint16_t acct_flags; @@ -203,37 +204,39 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL return NT_STATUS_ACCESS_DENIED; } - if (pipe_state->creds) { - talloc_free(pipe_state->creds); - } - pipe_state->creds = talloc(pipe_state, struct creds_CredentialState); - if (!pipe_state->creds) { + creds = talloc(mem_ctx, struct creds_CredentialState); + if (!creds) { return NT_STATUS_NO_MEMORY; } - creds_server_init(pipe_state->creds, &pipe_state->client_challenge, + creds_server_init(creds, &pipe_state->client_challenge, &pipe_state->server_challenge, mach_pwd, r->out.credentials, *r->in.negotiate_flags); - if (!creds_server_check(pipe_state->creds, r->in.credentials)) { - talloc_free(pipe_state->creds); - pipe_state->creds = NULL; + if (!creds_server_check(creds, r->in.credentials)) { + talloc_free(creds); return NT_STATUS_ACCESS_DENIED; } - pipe_state->creds->account_name = talloc_steal(pipe_state->creds, r->in.account_name); + creds->account_name = talloc_steal(creds, r->in.account_name); - pipe_state->creds->computer_name = talloc_steal(pipe_state->creds, r->in.computer_name); + creds->computer_name = talloc_steal(creds, r->in.computer_name); + creds->domain = talloc_strdup(creds, lp_workgroup()); - pipe_state->creds->secure_channel_type = r->in.secure_channel_type; + creds->secure_channel_type = r->in.secure_channel_type; - pipe_state->creds->sid = samdb_result_dom_sid(pipe_state->creds, msgs[0], "objectSid"); + creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid"); - pipe_state->creds->domain = talloc_strdup(pipe_state->creds, lp_workgroup()); /* remember this session key state */ - nt_status = schannel_store_session_key(mem_ctx, pipe_state->creds); + nt_status = schannel_store_session_key(mem_ctx, creds); + + if (pipe_state->creds) { + talloc_free(pipe_state->creds); + } + talloc_steal(pipe_state, creds); + pipe_state->creds = creds; return nt_status; } @@ -285,29 +288,76 @@ static NTSTATUS netr_ServerAuthenticate2(struct dcesrv_call_state *dce_call, TAL static NTSTATUS netr_creds_server_step_check(struct server_pipe_state *pipe_state, + TALLOC_CTX *mem_ctx, struct netr_Authenticator *received_authenticator, - struct netr_Authenticator *return_authenticator) + struct netr_Authenticator *return_authenticator, + struct creds_CredentialState **creds_out) { + struct creds_CredentialState *creds; + NTSTATUS nt_status; + struct ldb_context *ldb; + int ret; + if (!pipe_state) { DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); return NT_STATUS_ACCESS_DENIED; } - return creds_server_step_check(pipe_state->creds, - received_authenticator, - return_authenticator); + ldb = schannel_db_connect(mem_ctx); + if (!ldb) { + return NT_STATUS_ACCESS_DENIED; + } + + ret = ldb_transaction_start(ldb); + if (ret != 0) { + talloc_free(ldb); + 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, pipe_state->creds->computer_name, + pipe_state->creds->domain, &creds); + if (NT_STATUS_IS_OK(nt_status)) { + nt_status = creds_server_step_check(creds, + received_authenticator, + return_authenticator); + } + if (NT_STATUS_IS_OK(nt_status)) { + nt_status = schannel_store_session_key_ldb(ldb, ldb, 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); + } + talloc_free(ldb); + return nt_status; } +/* + Change the machine account password for the currently connected + client. Supplies only the NT#. +*/ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct netr_ServerPasswordSet *r) { struct server_pipe_state *pipe_state = dce_call->context->private; - + struct creds_CredentialState *creds; struct ldb_context *sam_ctx; NTSTATUS nt_status; - nt_status = netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator); + nt_status = netr_creds_server_step_check(pipe_state, mem_ctx, + &r->in.credential, &r->out.return_authenticator, + &creds); NT_STATUS_NOT_OK_RETURN(nt_status); sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx)); @@ -315,11 +365,11 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO return NT_STATUS_INVALID_SYSTEM_SERVICE; } - creds_des_decrypt(pipe_state->creds, &r->in.new_password); + creds_des_decrypt(creds, &r->in.new_password); /* Using the sid for the account as the key, set the password */ nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, - pipe_state->creds->sid, + creds->sid, NULL, /* Don't have plaintext */ NULL, &r->in.new_password, False, /* This is not considered a password change */ @@ -328,6 +378,55 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO return nt_status; } +/* + Change the machine account password for the currently connected + client. Supplies new plaintext. +*/ +static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, + struct netr_ServerPasswordSet2 *r) +{ + struct server_pipe_state *pipe_state = dce_call->context->private; + struct creds_CredentialState *creds; + struct ldb_context *sam_ctx; + NTSTATUS nt_status; + char new_pass[512]; + uint32_t new_pass_len; + BOOL ret; + + struct samr_CryptPassword password_buf; + + nt_status = netr_creds_server_step_check(pipe_state, mem_ctx, + &r->in.credential, &r->out.return_authenticator, + &creds); + NT_STATUS_NOT_OK_RETURN(nt_status); + + sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx)); + if (sam_ctx == NULL) { + return NT_STATUS_INVALID_SYSTEM_SERVICE; + } + + memcpy(password_buf.data, r->in.new_password.data, 512); + SIVAL(password_buf.data,512,r->in.new_password.length); + creds_arcfour_crypt(creds, password_buf.data, 516); + + ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass), + &new_pass_len, STR_UNICODE); + if (!ret) { + DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n")); + return NT_STATUS_ACCESS_DENIED; + } + + /* Using the sid for the account as the key, set the password */ + nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, + creds->sid, + new_pass, /* we have plaintext */ + NULL, NULL, + False, /* This is not considered a password change */ + False, /* don't restrict this password change (match w2k3) */ + NULL, NULL); + return nt_status; +} + /* netr_LogonUasLogon @@ -358,7 +457,7 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_ struct netr_LogonSamLogonEx *r) { struct server_pipe_state *pipe_state = dce_call->context->private; - + struct creds_CredentialState *creds = pipe_state->creds; struct auth_context *auth_context; struct auth_usersupplied_info *user_info; struct auth_serversupplied_info *server_info; @@ -383,15 +482,15 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_ case 3: case 5: if (pipe_state->creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { - creds_arcfour_crypt(pipe_state->creds, + creds_arcfour_crypt(creds, r->in.logon.password->lmpassword.hash, sizeof(r->in.logon.password->lmpassword.hash)); - creds_arcfour_crypt(pipe_state->creds, + creds_arcfour_crypt(creds, r->in.logon.password->ntpassword.hash, sizeof(r->in.logon.password->ntpassword.hash)); } else { - creds_des_decrypt(pipe_state->creds, &r->in.logon.password->lmpassword); - creds_des_decrypt(pipe_state->creds, &r->in.logon.password->ntpassword); + creds_des_decrypt(creds, &r->in.logon.password->lmpassword); + creds_des_decrypt(creds, &r->in.logon.password->ntpassword); } /* TODO: we need to deny anonymous access here */ @@ -459,8 +558,8 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_ sizeof(sam->key.key)) != 0) { /* This key is sent unencrypted without the ARCFOUR flag set */ - if (pipe_state->creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { - creds_arcfour_crypt(pipe_state->creds, + if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + creds_arcfour_crypt(creds, sam->key.key, sizeof(sam->key.key)); } @@ -471,12 +570,12 @@ static NTSTATUS netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_ if ((r->in.validation_level != 6) && memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) { - if (pipe_state->creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { - creds_arcfour_crypt(pipe_state->creds, + if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + creds_arcfour_crypt(creds, sam->LMSessKey.key, sizeof(sam->LMSessKey.key)); } else { - creds_des_encrypt_LMKey(pipe_state->creds, + creds_des_encrypt_LMKey(creds, &sam->LMSessKey); } } @@ -535,7 +634,9 @@ static NTSTATUS netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, return_authenticator = talloc(mem_ctx, struct netr_Authenticator); NT_STATUS_HAVE_NO_MEMORY(return_authenticator); - nt_status = netr_creds_server_step_check(pipe_state, r->in.credential, return_authenticator); + nt_status = netr_creds_server_step_check(pipe_state, mem_ctx, + r->in.credential, return_authenticator, + NULL); NT_STATUS_NOT_OK_RETURN(nt_status); ZERO_STRUCT(r2); @@ -844,8 +945,10 @@ static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALL const char *local_domain; - status = netr_creds_server_step_check(pipe_state, - r->in.credential, r->out.return_authenticator); + status = netr_creds_server_step_check(pipe_state, mem_ctx, + r->in.credential, + r->out.return_authenticator, + NULL); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -918,52 +1021,6 @@ static NTSTATUS netr_LogonGetDomainInfo(struct dcesrv_call_state *dce_call, TALL } -/* - netr_ServerPasswordSet2 -*/ -static NTSTATUS netr_ServerPasswordSet2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct netr_ServerPasswordSet2 *r) -{ - struct server_pipe_state *pipe_state = dce_call->context->private; - - struct ldb_context *sam_ctx; - NTSTATUS nt_status; - char new_pass[512]; - uint32_t new_pass_len; - BOOL ret; - - struct samr_CryptPassword password_buf; - - nt_status = netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator); - NT_STATUS_NOT_OK_RETURN(nt_status); - - sam_ctx = samdb_connect(mem_ctx, system_session(mem_ctx)); - if (sam_ctx == NULL) { - return NT_STATUS_INVALID_SYSTEM_SERVICE; - } - - memcpy(password_buf.data, r->in.new_password.data, 512); - SIVAL(password_buf.data,512,r->in.new_password.length); - creds_arcfour_crypt(pipe_state->creds, password_buf.data, 516); - - ret = decode_pw_buffer(password_buf.data, new_pass, sizeof(new_pass), - &new_pass_len, STR_UNICODE); - if (!ret) { - DEBUG(3,("netr_ServerPasswordSet2: failed to decode password buffer\n")); - return NT_STATUS_ACCESS_DENIED; - } - - /* Using the sid for the account as the key, set the password */ - nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, - pipe_state->creds->sid, - new_pass, /* we have plaintext */ - NULL, NULL, - False, /* This is not considered a password change */ - False, /* don't restrict this password change (match w2k3) */ - NULL, NULL); - return nt_status; -} - /* netr_NETRSERVERPASSWORDGET diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index 8e2aa41281..9084fb7ac3 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -393,15 +393,18 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx, goto failed; } - /* We can only do the 'ex' ops, because the original SamLogon - * call does shared credentials stuff Samba4 doesn't pass - * yet */ - + /* Try the schannel-only SamLogonEx operation */ if (!test_netlogon_ex_ops(p_netlogon2, test_ctx, credentials, creds)) { printf("Failed to process schannel secured NETLOGON EX ops\n"); ret = False; } + /* And the more traditional style */ + if (!test_netlogon_ops(p_netlogon2, test_ctx, credentials, creds)) { + printf("Failed to process schannel secured NETLOGON EX ops\n"); + ret = False; + } + torture_leave_domain(join_ctx); talloc_free(test_ctx); return ret; |