summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2009-08-27 23:30:14 +0200
committerGünther Deschner <gd@samba.org>2009-09-02 10:47:35 +0200
commit71e9dfc0cd7d054dd52508faa4c07db9205b541a (patch)
tree05945383ffb735be6e20b315295763c3f7242320
parentbde679e6f84b16d63a8007fe48789ee7951b9f34 (diff)
downloadsamba-71e9dfc0cd7d054dd52508faa4c07db9205b541a.tar.gz
samba-71e9dfc0cd7d054dd52508faa4c07db9205b541a.tar.bz2
samba-71e9dfc0cd7d054dd52508faa4c07db9205b541a.zip
s3-netlogon: rework _netr_ServerPasswordSet.
Guenther
-rw-r--r--source3/rpc_server/srv_netlog_nt.c185
1 files changed, 123 insertions, 62 deletions
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index 3daf45bbdd..ce0a3fa255 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -655,48 +655,23 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
}
/*************************************************************************
- _netr_ServerPasswordSet
*************************************************************************/
-NTSTATUS _netr_ServerPasswordSet(pipes_struct *p,
- struct netr_ServerPasswordSet *r)
+static NTSTATUS netr_find_machine_account(TALLOC_CTX *mem_ctx,
+ const char *account_name,
+ struct samu **sampassp)
{
- NTSTATUS status = NT_STATUS_OK;
- struct samu *sampass=NULL;
- bool ret = False;
- int i;
- uint32 acct_ctrl;
- const uchar *old_pw;
- struct netlogon_creds_CredentialState *creds;
-
- DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
-
- become_root();
- status = netr_creds_server_step_check(p, p->mem_ctx,
- r->in.computer_name,
- r->in.credential,
- r->out.return_authenticator,
- &creds);
- unbecome_root();
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth "
- "request from client %s machine account %s\n",
- r->in.computer_name, creds->computer_name));
- TALLOC_FREE(creds);
- return status;
- }
+ struct samu *sampass;
+ bool ret = false;
+ uint32_t acct_ctrl;
- DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
- r->in.computer_name, creds->computer_name));
-
- sampass = samu_new( NULL );
+ sampass = samu_new(mem_ctx);
if (!sampass) {
return NT_STATUS_NO_MEMORY;
}
become_root();
- ret = pdb_getsampwnam(sampass, creds->account_name);
+ ret = pdb_getsampwnam(sampass, account_name);
unbecome_root();
if (!ret) {
@@ -709,56 +684,142 @@ NTSTATUS _netr_ServerPasswordSet(pipes_struct *p,
acct_ctrl = pdb_get_acct_ctrl(sampass);
if (!(acct_ctrl & ACB_WSTRUST ||
- acct_ctrl & ACB_SVRTRUST ||
- acct_ctrl & ACB_DOMTRUST)) {
+ acct_ctrl & ACB_SVRTRUST ||
+ acct_ctrl & ACB_DOMTRUST)) {
TALLOC_FREE(sampass);
return NT_STATUS_NO_SUCH_USER;
}
- if (pdb_get_acct_ctrl(sampass) & ACB_DISABLED) {
+ if (acct_ctrl & ACB_DISABLED) {
TALLOC_FREE(sampass);
return NT_STATUS_ACCOUNT_DISABLED;
}
- /* Woah - what does this to to the credential chain ? JRA */
- netlogon_creds_des_decrypt(creds, r->in.new_password);
+ *sampassp = sampass;
- DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
- for(i = 0; i < sizeof(r->in.new_password->hash); i++)
- DEBUG(100,("%02X ", r->in.new_password->hash[i]));
- DEBUG(100,("\n"));
+ return NT_STATUS_OK;
+}
- old_pw = pdb_get_nt_passwd(sampass);
+/*************************************************************************
+ *************************************************************************/
- if (old_pw && memcmp(r->in.new_password->hash, old_pw, 16) == 0) {
- /* Avoid backend modificiations and other fun if the
- client changed the password to the *same thing* */
+static NTSTATUS netr_set_machine_account_password(TALLOC_CTX *mem_ctx,
+ struct samu *sampass,
+ DATA_BLOB *plaintext_blob,
+ struct samr_Password *nt_hash,
+ struct samr_Password *lm_hash)
+{
+ NTSTATUS status;
+ const uchar *old_pw;
+ const char *plaintext = NULL;
+ size_t plaintext_len;
+ struct samr_Password nt_hash_local;
- ret = True;
- } else {
+ if (!sampass) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
- /* LM password should be NULL for machines */
- if (!pdb_set_lanman_passwd(sampass, NULL, PDB_CHANGED)) {
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_MEMORY;
+ if (plaintext_blob) {
+ if (!convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX,
+ plaintext_blob->data, plaintext_blob->length,
+ &plaintext, &plaintext_len, false))
+ {
+ plaintext = NULL;
+ mdfour(nt_hash_local.hash, plaintext_blob->data, plaintext_blob->length);
+ nt_hash = &nt_hash_local;
}
+ }
- if (!pdb_set_nt_passwd(sampass, r->in.new_password->hash, PDB_CHANGED)) {
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_MEMORY;
+ if (plaintext) {
+ if (!pdb_set_plaintext_passwd(sampass, plaintext)) {
+ return NT_STATUS_ACCESS_DENIED;
}
- if (!pdb_set_pass_last_set_time(sampass, time(NULL), PDB_CHANGED)) {
- TALLOC_FREE(sampass);
- /* Not quite sure what this one qualifies as, but this will do */
- return NT_STATUS_UNSUCCESSFUL;
+ goto done;
+ }
+
+ if (nt_hash) {
+ old_pw = pdb_get_nt_passwd(sampass);
+
+ if (old_pw && memcmp(nt_hash->hash, old_pw, 16) == 0) {
+ /* Avoid backend modificiations and other fun if the
+ client changed the password to the *same thing* */
+ } else {
+ /* LM password should be NULL for machines */
+ if (!pdb_set_lanman_passwd(sampass, NULL, PDB_CHANGED)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (!pdb_set_nt_passwd(sampass, nt_hash->hash, PDB_CHANGED)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!pdb_set_pass_last_set_time(sampass, time(NULL), PDB_CHANGED)) {
+ /* Not quite sure what this one qualifies as, but this will do */
+ return NT_STATUS_UNSUCCESSFUL;
+ }
}
+ }
+
+ done:
+ become_root();
+ status = pdb_update_sam_account(sampass);
+ unbecome_root();
+
+ return status;
+}
- become_root();
- status = pdb_update_sam_account(sampass);
- unbecome_root();
+/*************************************************************************
+ _netr_ServerPasswordSet
+ *************************************************************************/
+
+NTSTATUS _netr_ServerPasswordSet(pipes_struct *p,
+ struct netr_ServerPasswordSet *r)
+{
+ NTSTATUS status = NT_STATUS_OK;
+ struct samu *sampass=NULL;
+ int i;
+ struct netlogon_creds_CredentialState *creds;
+
+ DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
+
+ become_root();
+ status = netr_creds_server_step_check(p, p->mem_ctx,
+ r->in.computer_name,
+ r->in.credential,
+ r->out.return_authenticator,
+ &creds);
+ unbecome_root();
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth "
+ "request from client %s machine account %s\n",
+ r->in.computer_name, creds->computer_name));
+ TALLOC_FREE(creds);
+ return status;
+ }
+
+ DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
+ r->in.computer_name, creds->computer_name));
+
+ netlogon_creds_des_decrypt(creds, r->in.new_password);
+
+ DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
+ for(i = 0; i < sizeof(r->in.new_password->hash); i++)
+ DEBUG(100,("%02X ", r->in.new_password->hash[i]));
+ DEBUG(100,("\n"));
+
+ status = netr_find_machine_account(p->mem_ctx,
+ creds->account_name,
+ &sampass);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
+ status = netr_set_machine_account_password(sampass,
+ sampass,
+ NULL,
+ r->in.new_password,
+ NULL);
TALLOC_FREE(sampass);
return status;
}