summaryrefslogtreecommitdiff
path: root/source4/libnet/libnet_passwd.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2004-08-24 16:28:08 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:58:18 -0500
commit13c899de96a751bf38aef6818aaca72a9fd5ccee (patch)
tree057f460ac700c5ae7e822d3972dee66df0ad1f54 /source4/libnet/libnet_passwd.c
parent36e52d5d9ab0f4ec972f3c8efae82db7ffe4dd1e (diff)
downloadsamba-13c899de96a751bf38aef6818aaca72a9fd5ccee.tar.gz
samba-13c899de96a751bf38aef6818aaca72a9fd5ccee.tar.bz2
samba-13c899de96a751bf38aef6818aaca72a9fd5ccee.zip
r2021: add password change fallback to SetUserInfo level 25,24,23
metze (This used to be commit d31405ff2f379e9627cc9ee3acaf61e2ccc0f6e4)
Diffstat (limited to 'source4/libnet/libnet_passwd.c')
-rw-r--r--source4/libnet/libnet_passwd.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c
index 98005b9f41..acb226e299 100644
--- a/source4/libnet/libnet_passwd.c
+++ b/source4/libnet/libnet_passwd.c
@@ -281,6 +281,9 @@ NTSTATUS libnet_ChangePassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
* 5. do a samr_LookupNames to get the users rid
* 6. do a samr_OpenUser to get a user handle
* 7. try samr_SetUserInfo level 26 to set the password
+ * 8. try samr_SetUserInfo level 25 to set the password
+ * 8. try samr_SetUserInfo level 24 to set the password
+ *10. try samr_SetUserInfo level 23 to set the password
*/
static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
{
@@ -447,6 +450,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
}
/* prepare samr_SetUserInfo level 26 */
+ ZERO_STRUCT(u_info);
encode_pw_buffer(u_info.info26.password.data, r->samr.in.newpassword, STR_UNICODE);
u_info.info26.pw_len = strlen(r->samr.in.newpassword);
@@ -489,7 +493,133 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
goto UserInfo25;
}
+ goto disconnect;
+
UserInfo25:
+ /* prepare samr_SetUserInfo level 25 */
+ ZERO_STRUCT(u_info);
+ u_info.info25.info.fields_present = SAMR_FIELD_PASSWORD;
+ encode_pw_buffer(u_info.info25.password.data, r->samr.in.newpassword, STR_UNICODE);
+
+ status = dcerpc_fetch_session_key(c.pdc.out.dcerpc_pipe, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ r->samr.out.error_string = talloc_asprintf(mem_ctx,
+ "dcerpc_fetch_session_key failed: %s\n",
+ nt_errstr(status));
+ goto disconnect;
+ }
+
+ generate_random_buffer((uint8_t *)confounder, 16);
+
+ MD5Init(&md5);
+ MD5Update(&md5, confounder, 16);
+ MD5Update(&md5, session_key.data, session_key.length);
+ MD5Final(confounded_session_key.data, &md5);
+
+ arcfour_crypt_blob(u_info.info25.password.data, 516, &confounded_session_key);
+ memcpy(&u_info.info25.password.data[516], confounder, 16);
+
+ sui.in.handle = &u_handle;
+ sui.in.info = &u_info;
+ sui.in.level = 25;
+
+ /* 8. try samr_SetUserInfo level 25 to set the password */
+ status = dcerpc_samr_SetUserInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &sui);
+ if (!NT_STATUS_IS_OK(status)) {
+ r->samr.out.error_string = talloc_asprintf(mem_ctx,
+ "SetUserInfo level 25 for [%s] failed: %s\n",
+ r->samr.in.account_name, nt_errstr(status));
+ goto UserInfo24;
+ }
+
+ /* check result of samr_SetUserInfo level 25 */
+ if (!NT_STATUS_IS_OK(sui.out.result)) {
+ r->samr.out.error_string = talloc_asprintf(mem_ctx,
+ "SetUserInfo level 25 for [%s] failed: %s\n",
+ r->samr.in.account_name, nt_errstr(sui.out.result));
+ goto UserInfo24;
+ }
+
+ goto disconnect;
+
+UserInfo24:
+ /* prepare samr_SetUserInfo level 24 */
+ ZERO_STRUCT(u_info);
+ encode_pw_buffer(u_info.info24.password.data, r->samr.in.newpassword, STR_UNICODE);
+ /* w2k3 ignores this length */
+ u_info.info24.pw_len = str_charnum(r->samr.in.newpassword)*2;
+
+ status = dcerpc_fetch_session_key(c.pdc.out.dcerpc_pipe, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ r->samr.out.error_string = talloc_asprintf(mem_ctx,
+ "dcerpc_fetch_session_key failed: %s\n",
+ nt_errstr(status));
+ goto disconnect;
+ }
+
+ arcfour_crypt_blob(u_info.info24.password.data, 516, &session_key);
+
+ sui.in.handle = &u_handle;
+ sui.in.info = &u_info;
+ sui.in.level = 24;
+
+ /* 9. try samr_SetUserInfo level 24 to set the password */
+ status = dcerpc_samr_SetUserInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &sui);
+ if (!NT_STATUS_IS_OK(status)) {
+ r->samr.out.error_string = talloc_asprintf(mem_ctx,
+ "SetUserInfo level 24 for [%s] failed: %s\n",
+ r->samr.in.account_name, nt_errstr(status));
+ goto UserInfo23;
+ }
+
+ /* check result of samr_SetUserInfo level 24 */
+ if (!NT_STATUS_IS_OK(sui.out.result)) {
+ r->samr.out.error_string = talloc_asprintf(mem_ctx,
+ "SetUserInfo level 24 for [%s] failed: %s\n",
+ r->samr.in.account_name, nt_errstr(sui.out.result));
+ goto UserInfo23;
+ }
+
+ goto disconnect;
+
+UserInfo23:
+ /* prepare samr_SetUserInfo level 23 */
+ ZERO_STRUCT(u_info);
+ u_info.info23.info.fields_present = SAMR_FIELD_PASSWORD;
+ encode_pw_buffer(u_info.info23.password.data, r->samr.in.newpassword, STR_UNICODE);
+
+ status = dcerpc_fetch_session_key(c.pdc.out.dcerpc_pipe, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ r->samr.out.error_string = talloc_asprintf(mem_ctx,
+ "dcerpc_fetch_session_key failed: %s\n",
+ nt_errstr(status));
+ goto disconnect;
+ }
+
+ arcfour_crypt_blob(u_info.info23.password.data, 516, &session_key);
+
+ sui.in.handle = &u_handle;
+ sui.in.info = &u_info;
+ sui.in.level = 23;
+
+ /* 10. try samr_SetUserInfo level 23 to set the password */
+ status = dcerpc_samr_SetUserInfo(c.pdc.out.dcerpc_pipe, mem_ctx, &sui);
+ if (!NT_STATUS_IS_OK(status)) {
+ r->samr.out.error_string = talloc_asprintf(mem_ctx,
+ "SetUserInfo level 23 for [%s] failed: %s\n",
+ r->samr.in.account_name, nt_errstr(status));
+ goto disconnect;
+ }
+
+ /* check result of samr_SetUserInfo level 23 */
+ if (!NT_STATUS_IS_OK(sui.out.result)) {
+ r->samr.out.error_string = talloc_asprintf(mem_ctx,
+ "SetUserInfo level 23 for [%s] failed: %s\n",
+ r->samr.in.account_name, nt_errstr(sui.out.result));
+ goto disconnect;
+ }
+
+ goto disconnect;
disconnect:
/* close connection */