summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/rpc_samr.h8
-rw-r--r--source3/libsmb/smbencrypt.c19
-rw-r--r--source3/rpc_parse/parse_samr.c38
-rw-r--r--source3/rpc_server/srv_samr_nt.c50
4 files changed, 101 insertions, 14 deletions
diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h
index e53bc1ede8..e0b179224d 100644
--- a/source3/include/rpc_samr.h
+++ b/source3/include/rpc_samr.h
@@ -277,6 +277,13 @@ typedef struct sam_user_info_25
UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel no */
} SAM_USER_INFO_25;
+/* SAM_USER_INFO_26 */
+typedef struct sam_user_info_26
+{
+ uint8 pass[532];
+ uint8 pw_len;
+} SAM_USER_INFO_26;
+
/* SAM_USER_INFO_21 */
typedef struct sam_user_info_21
@@ -1272,6 +1279,7 @@ typedef struct sam_userinfo_ctr_info
SAM_USER_INFO_23 *id23;
SAM_USER_INFO_24 *id24;
SAM_USER_INFO_25 *id25;
+ SAM_USER_INFO_26 *id26;
void* id; /* to make typecasting easy */
} info;
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index 99f99f23f8..5bdd0acd3e 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -531,6 +531,25 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd,
}
/***********************************************************
+ Decode an arc4 encrypted password change buffer.
+************************************************************/
+
+void encode_or_decode_arc4_passwd_buffer(char pw_buf[532], const DATA_BLOB *psession_key)
+{
+ struct MD5Context tctx;
+ unsigned char key_out[16];
+
+ /* Confounder is last 16 bytes. */
+
+ MD5Init(&tctx);
+ MD5Update(&tctx, &pw_buf[516], 16);
+ MD5Update(&tctx, psession_key->data, psession_key->length);
+ MD5Final(key_out, &tctx);
+ /* arc4 with key_out. */
+ SamOEMhash(pw_buf, key_out, 516);
+}
+
+/***********************************************************
Encrypt/Decrypt used for LSA secrets and trusted domain
passwords.
************************************************************/
diff --git a/source3/rpc_parse/parse_samr.c b/source3/rpc_parse/parse_samr.c
index d13d3c9d4a..a0108d9eb7 100644
--- a/source3/rpc_parse/parse_samr.c
+++ b/source3/rpc_parse/parse_samr.c
@@ -5404,13 +5404,41 @@ static BOOL sam_io_user_info24(const char *desc, SAM_USER_INFO_24 * usr,
if (MARSHALLING(ps) && (usr->pw_len != 0)) {
if (!prs_uint16("pw_len", ps, depth, &usr->pw_len))
return False;
+ } else if (UNMARSHALLING(ps)) {
+ if (!prs_uint16("pw_len", ps, depth, &usr->pw_len))
+ return False;
}
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+static BOOL sam_io_user_info26(const char *desc, SAM_USER_INFO_26 * usr,
+ prs_struct *ps, int depth)
+{
+ if (usr == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "sam_io_user_info26");
+ depth++;
+
if(!prs_align(ps))
return False;
+ if(!prs_uint8s(False, "password", ps, depth, usr->pass,
+ sizeof(usr->pass)))
+ return False;
+
+ if (!prs_uint8("pw_len", ps, depth, &usr->pw_len))
+ return False;
+
return True;
}
+
/*************************************************************************
init_sam_user_info23
@@ -6475,6 +6503,16 @@ static BOOL samr_io_userinfo_ctr(const char *desc, SAM_USERINFO_CTR **ppctr,
}
ret = sam_io_user_info25("", ctr->info.id25, ps, depth);
break;
+ case 26:
+ if (UNMARSHALLING(ps))
+ ctr->info.id26 = PRS_ALLOC_MEM(ps,SAM_USER_INFO_26,1);
+
+ if (ctr->info.id26 == NULL) {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ ret = sam_io_user_info26("", ctr->info.id26, ps, depth);
+ break;
default:
DEBUG(2, ("samr_io_userinfo_ctr: unknown switch level 0x%x\n", ctr->switch_value));
ret = False;
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index 81344cdc1e..52f922b924 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -3316,27 +3316,27 @@ NTSTATUS _samr_set_userinfo(pipes_struct *p, SAMR_Q_SET_USERINFO *q_u, SAMR_R_SE
break;
case 25:
-#if 0
- /*
- * Currently we don't really know how to unmarshall
- * the level 25 struct, and the password encryption
- * is different. This is a placeholder for when we
- * do understand it. In the meantime just return INVALID
- * info level and W2K SP2 drops down to level 23... JRA.
- */
-
if (!p->session_key.length) {
r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
}
- SamOEMhashBlob(ctr->info.id25->pass, 532, &p->session_key);
+ encode_or_decode_arc4_passwd_buffer(ctr->info.id25->pass, &p->session_key);
dump_data(100, (char *)ctr->info.id25->pass, 532);
- if (!set_user_info_pw(ctr->info.id25->pass, &sid))
+ if (!set_user_info_pw(ctr->info.id25->pass, pwd))
r_u->status = NT_STATUS_ACCESS_DENIED;
break;
-#endif
- r_u->status = NT_STATUS_INVALID_INFO_CLASS;
+
+ case 26:
+ if (!p->session_key.length) {
+ r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
+ }
+ encode_or_decode_arc4_passwd_buffer(ctr->info.id26->pass, &p->session_key);
+
+ dump_data(100, (char *)ctr->info.id26->pass, 516);
+
+ if (!set_user_info_pw(ctr->info.id26->pass, pwd))
+ r_u->status = NT_STATUS_ACCESS_DENIED;
break;
case 23:
@@ -3432,7 +3432,7 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
has_enough_rights = nt_token_check_domain_rid( p->pipe_user.nt_user_token, DOMAIN_GROUP_RID_ADMINS );
}
- DEBUG(5, ("_samr_set_userinfo: %s does%s possess sufficient rights\n",
+ DEBUG(5, ("_samr_set_userinfo2: %s does%s possess sufficient rights\n",
p->pipe_user_name, has_enough_rights ? "" : " not"));
/* ================ BEGIN SeMachineAccountPrivilege BLOCK ================ */
@@ -3464,6 +3464,28 @@ NTSTATUS _samr_set_userinfo2(pipes_struct *p, SAMR_Q_SET_USERINFO2 *q_u, SAMR_R_
if (!set_user_info_21(ctr->info.id21, pwd))
return NT_STATUS_ACCESS_DENIED;
break;
+ case 23:
+ if (!p->session_key.length) {
+ r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
+ }
+ SamOEMhashBlob(ctr->info.id23->pass, 516, &p->session_key);
+
+ dump_data(100, (char *)ctr->info.id23->pass, 516);
+
+ if (!set_user_info_23(ctr->info.id23, pwd))
+ r_u->status = NT_STATUS_ACCESS_DENIED;
+ break;
+ case 26:
+ if (!p->session_key.length) {
+ r_u->status = NT_STATUS_NO_USER_SESSION_KEY;
+ }
+ encode_or_decode_arc4_passwd_buffer(ctr->info.id26->pass, &p->session_key);
+
+ dump_data(100, (char *)ctr->info.id26->pass, 516);
+
+ if (!set_user_info_pw(ctr->info.id26->pass, pwd))
+ r_u->status = NT_STATUS_ACCESS_DENIED;
+ break;
default:
r_u->status = NT_STATUS_INVALID_INFO_CLASS;
}