[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha8-1341-g9bf74d0
Günther Deschner
gd at samba.org
Wed Sep 2 02:48:15 MDT 2009
The branch, master has been updated
via 9bf74d0ed9c7496bb133e5108ba297abb1b00747 (commit)
via 2b8afd2257d8c9886f785929ca8dfcd04eb45755 (commit)
via 71e9dfc0cd7d054dd52508faa4c07db9205b541a (commit)
from bde679e6f84b16d63a8007fe48789ee7951b9f34 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 9bf74d0ed9c7496bb133e5108ba297abb1b00747
Author: Günther Deschner <gd at samba.org>
Date: Fri Aug 28 16:04:08 2009 +0200
s4-smbtorture: test netr_ServerSetPassword2 against Samba3.
Guenther
commit 2b8afd2257d8c9886f785929ca8dfcd04eb45755
Author: Günther Deschner <gd at samba.org>
Date: Thu Aug 27 23:30:50 2009 +0200
s3-netlogon: implement _netr_ServerPasswordSet2.
Guenther
commit 71e9dfc0cd7d054dd52508faa4c07db9205b541a
Author: Günther Deschner <gd at samba.org>
Date: Thu Aug 27 23:30:14 2009 +0200
s3-netlogon: rework _netr_ServerPasswordSet.
Guenther
-----------------------------------------------------------------------
Summary of changes:
source3/rpc_server/srv_netlog_nt.c | 241 ++++++++++++++++++++++++++----------
source4/torture/rpc/netlogon.c | 1 +
2 files changed, 174 insertions(+), 68 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c
index 3daf45b..0b476e1 100644
--- a/source3/rpc_server/srv_netlog_nt.c
+++ b/source3/rpc_server/srv_netlog_nt.c
@@ -491,7 +491,8 @@ NTSTATUS _netr_ServerAuthenticate3(pipes_struct *p,
NETLOGON_NEG_FULL_SYNC_REPL |
NETLOGON_NEG_MULTIPLE_SIDS |
NETLOGON_NEG_REDO |
- NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL;
+ NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
+ NETLOGON_NEG_PASSWORD_SET2;
/* Ensure we support strong (128-bit) keys. */
if (in_neg_flags & NETLOGON_NEG_STRONG_KEYS) {
@@ -655,6 +656,120 @@ static NTSTATUS netr_creds_server_step_check(pipes_struct *p,
}
/*************************************************************************
+ *************************************************************************/
+
+static NTSTATUS netr_find_machine_account(TALLOC_CTX *mem_ctx,
+ const char *account_name,
+ struct samu **sampassp)
+{
+ struct samu *sampass;
+ bool ret = false;
+ uint32_t acct_ctrl;
+
+ sampass = samu_new(mem_ctx);
+ if (!sampass) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ become_root();
+ ret = pdb_getsampwnam(sampass, account_name);
+ unbecome_root();
+
+ if (!ret) {
+ TALLOC_FREE(sampass);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* Ensure the account exists and is a machine account. */
+
+ acct_ctrl = pdb_get_acct_ctrl(sampass);
+
+ if (!(acct_ctrl & ACB_WSTRUST ||
+ acct_ctrl & ACB_SVRTRUST ||
+ acct_ctrl & ACB_DOMTRUST)) {
+ TALLOC_FREE(sampass);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ if (acct_ctrl & ACB_DISABLED) {
+ TALLOC_FREE(sampass);
+ return NT_STATUS_ACCOUNT_DISABLED;
+ }
+
+ *sampassp = sampass;
+
+ return NT_STATUS_OK;
+}
+
+/*************************************************************************
+ *************************************************************************/
+
+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;
+
+ if (!sampass) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ 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 (plaintext) {
+ if (!pdb_set_plaintext_passwd(sampass, plaintext)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ 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;
+}
+
+/*************************************************************************
_netr_ServerPasswordSet
*************************************************************************/
@@ -663,10 +778,7 @@ NTSTATUS _netr_ServerPasswordSet(pipes_struct *p,
{
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__));
@@ -690,37 +802,6 @@ NTSTATUS _netr_ServerPasswordSet(pipes_struct *p,
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 );
- if (!sampass) {
- return NT_STATUS_NO_MEMORY;
- }
-
- become_root();
- ret = pdb_getsampwnam(sampass, creds->account_name);
- unbecome_root();
-
- if (!ret) {
- TALLOC_FREE(sampass);
- return NT_STATUS_ACCESS_DENIED;
- }
-
- /* Ensure the account exists and is a machine account. */
-
- acct_ctrl = pdb_get_acct_ctrl(sampass);
-
- if (!(acct_ctrl & ACB_WSTRUST ||
- 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) {
- 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);
DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
@@ -728,37 +809,71 @@ NTSTATUS _netr_ServerPasswordSet(pipes_struct *p,
DEBUG(100,("%02X ", r->in.new_password->hash[i]));
DEBUG(100,("\n"));
- old_pw = pdb_get_nt_passwd(sampass);
+ status = netr_find_machine_account(p->mem_ctx,
+ creds->account_name,
+ &sampass);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- 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* */
+ status = netr_set_machine_account_password(sampass,
+ sampass,
+ NULL,
+ r->in.new_password,
+ NULL);
+ TALLOC_FREE(sampass);
+ return status;
+}
- ret = True;
- } else {
+/****************************************************************
+ _netr_ServerPasswordSet2
+****************************************************************/
- /* LM password should be NULL for machines */
- if (!pdb_set_lanman_passwd(sampass, NULL, PDB_CHANGED)) {
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_MEMORY;
- }
+NTSTATUS _netr_ServerPasswordSet2(pipes_struct *p,
+ struct netr_ServerPasswordSet2 *r)
+{
+ NTSTATUS status;
+ struct netlogon_creds_CredentialState *creds;
+ struct samu *sampass;
+ DATA_BLOB plaintext;
+ struct samr_CryptPassword password_buf;
- if (!pdb_set_nt_passwd(sampass, r->in.new_password->hash, PDB_CHANGED)) {
- TALLOC_FREE(sampass);
- return NT_STATUS_NO_MEMORY;
- }
+ 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 (!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;
- }
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(2,("_netr_ServerPasswordSet2: 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;
+ }
+
+ memcpy(password_buf.data, r->in.new_password->data, 512);
+ SIVAL(password_buf.data, 512, r->in.new_password->length);
+ netlogon_creds_arcfour_crypt(creds, password_buf.data, 516);
- become_root();
- status = pdb_update_sam_account(sampass);
- unbecome_root();
+ if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, &plaintext)) {
+ return NT_STATUS_WRONG_PASSWORD;
}
+ 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,
+ &plaintext,
+ NULL,
+ NULL);
TALLOC_FREE(sampass);
return status;
}
@@ -1309,16 +1424,6 @@ NTSTATUS _netr_LogonGetDomainInfo(pipes_struct *p,
/****************************************************************
****************************************************************/
-NTSTATUS _netr_ServerPasswordSet2(pipes_struct *p,
- struct netr_ServerPasswordSet2 *r)
-{
- p->rng_fault_state = true;
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-/****************************************************************
-****************************************************************/
-
WERROR _netr_ServerPasswordGet(pipes_struct *p,
struct netr_ServerPasswordGet *r)
{
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index 9a73cfe..40561dc 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -2749,6 +2749,7 @@ struct torture_suite *torture_rpc_netlogon_s3(TALLOC_CTX *mem_ctx)
torture_rpc_tcase_add_test_creds(tcase, "SamLogon", test_SamLogon);
torture_rpc_tcase_add_test_creds(tcase, "SetPassword", test_SetPassword);
torture_rpc_tcase_add_test_creds(tcase, "SetPassword_with_flags", test_SetPassword_with_flags);
+ torture_rpc_tcase_add_test_creds(tcase, "SetPassword2", test_SetPassword2);
torture_rpc_tcase_add_test(tcase, "LogonControl", test_LogonControl);
torture_rpc_tcase_add_test(tcase, "LogonControl2", test_LogonControl2);
torture_rpc_tcase_add_test(tcase, "LogonControl2Ex", test_LogonControl2Ex);
--
Samba Shared Repository
More information about the samba-cvs
mailing list