libnet_passwd.c
来自「samba最新软件」· C语言 代码 · 共 704 行 · 第 1/2 页
C
704 行
return NT_STATUS_INVALID_PARAMETER_MIX; } /* prepare samr_SetUserInfo2 level 25 */ ZERO_STRUCT(u_info); u_info.info25.info = *r->samr_handle.in.info21; u_info.info25.info.fields_present |= SAMR_FIELD_PASSWORD; encode_pw_buffer(u_info.info25.password.data, r->samr_handle.in.newpassword, STR_UNICODE); status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, "dcerpc_fetch_session_key failed: %s", nt_errstr(status)); return status; } 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.user_handle = r->samr_handle.in.user_handle; sui.in.info = &u_info; sui.in.level = 25; /* 8. try samr_SetUserInfo2 level 25 to set the password */ status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, "SetUserInfo2 level 25 for [%s] failed: %s", r->samr_handle.in.account_name, nt_errstr(status)); } return status;}static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){ NTSTATUS status; struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; DATA_BLOB session_key; if (r->samr_handle.in.info21) { return NT_STATUS_INVALID_PARAMETER_MIX; } /* prepare samr_SetUserInfo2 level 24 */ ZERO_STRUCT(u_info); encode_pw_buffer(u_info.info24.password.data, r->samr_handle.in.newpassword, STR_UNICODE); /* w2k3 ignores this length */ u_info.info24.pw_len = strlen_m(r->samr_handle.in.newpassword)*2; status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, "dcerpc_fetch_session_key failed: %s", nt_errstr(status)); return status; } arcfour_crypt_blob(u_info.info24.password.data, 516, &session_key); sui.in.user_handle = r->samr_handle.in.user_handle; sui.in.info = &u_info; sui.in.level = 24; /* 9. try samr_SetUserInfo2 level 24 to set the password */ status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, "SetUserInfo2 level 24 for [%s] failed: %s", r->samr_handle.in.account_name, nt_errstr(status)); } return status;}static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){ NTSTATUS status; struct samr_SetUserInfo2 sui; union samr_UserInfo u_info; DATA_BLOB session_key; if (!r->samr_handle.in.info21) { return NT_STATUS_INVALID_PARAMETER_MIX; } /* prepare samr_SetUserInfo2 level 23 */ ZERO_STRUCT(u_info); u_info.info23.info = *r->samr_handle.in.info21; u_info.info23.info.fields_present |= SAMR_FIELD_PASSWORD; encode_pw_buffer(u_info.info23.password.data, r->samr_handle.in.newpassword, STR_UNICODE); status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, "dcerpc_fetch_session_key failed: %s", nt_errstr(status)); return status; } arcfour_crypt_blob(u_info.info23.password.data, 516, &session_key); sui.in.user_handle = r->samr_handle.in.user_handle; sui.in.info = &u_info; sui.in.level = 23; /* 10. try samr_SetUserInfo2 level 23 to set the password */ status = dcerpc_samr_SetUserInfo2(r->samr_handle.in.dcerpc_pipe, mem_ctx, &sui); if (!NT_STATUS_IS_OK(status)) { r->samr_handle.out.error_string = talloc_asprintf(mem_ctx, "SetUserInfo2 level 23 for [%s] failed: %s", r->samr_handle.in.account_name, nt_errstr(status)); } return status;}/* * 1. try samr_SetUserInfo2 level 26 to set the password * 2. try samr_SetUserInfo2 level 25 to set the password * 3. try samr_SetUserInfo2 level 24 to set the password * 4. try samr_SetUserInfo2 level 23 to set the password*/static NTSTATUS libnet_SetPassword_samr_handle(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){ NTSTATUS status; enum libnet_SetPassword_level levels[] = { LIBNET_SET_PASSWORD_SAMR_HANDLE_26, LIBNET_SET_PASSWORD_SAMR_HANDLE_25, LIBNET_SET_PASSWORD_SAMR_HANDLE_24, LIBNET_SET_PASSWORD_SAMR_HANDLE_23, }; int i; for (i=0; i < ARRAY_SIZE(levels); i++) { r->generic.level = levels[i]; status = libnet_SetPassword(ctx, mem_ctx, r); if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS) || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER_MIX) || NT_STATUS_EQUAL(status, NT_STATUS_NET_WRITE_FAULT)) { /* Try another password set mechanism */ continue; } break; } return status;}/* * set a password with DCERPC/SAMR calls * 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) * is it correct to contact the the pdc of the domain of the user who's password should be set? * 2. do a samr_Connect to get a policy handle * 3. do a samr_LookupDomain to get the domain sid * 4. do a samr_OpenDomain to get a domain handle * 5. do a samr_LookupNames to get the users rid * 6. do a samr_OpenUser to get a user handle * 7 call libnet_SetPassword_samr_handle to set the password */static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){ NTSTATUS status; struct libnet_RpcConnect c; struct samr_Connect sc; struct policy_handle p_handle; struct samr_LookupDomain ld; struct lsa_String d_name; struct samr_OpenDomain od; struct policy_handle d_handle; struct samr_LookupNames ln; struct samr_OpenUser ou; struct policy_handle u_handle; union libnet_SetPassword r2; /* prepare connect to the SAMR pipe of users domain PDC */ c.level = LIBNET_RPC_CONNECT_PDC; c.in.name = r->samr.in.domain_name; c.in.dcerpc_iface = &ndr_table_samr; /* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */ status = libnet_RpcConnect(ctx, mem_ctx, &c); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "Connection to SAMR pipe of PDC of domain '%s' failed: %s", r->samr.in.domain_name, nt_errstr(status)); return status; } /* prepare samr_Connect */ ZERO_STRUCT(p_handle); sc.in.system_name = NULL; sc.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; sc.out.connect_handle = &p_handle; /* 2. do a samr_Connect to get a policy handle */ status = dcerpc_samr_Connect(c.out.dcerpc_pipe, mem_ctx, &sc); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_Connect failed: %s", nt_errstr(status)); goto disconnect; } /* prepare samr_LookupDomain */ d_name.string = r->samr.in.domain_name; ld.in.connect_handle = &p_handle; ld.in.domain_name = &d_name; /* 3. do a samr_LookupDomain to get the domain sid */ status = dcerpc_samr_LookupDomain(c.out.dcerpc_pipe, mem_ctx, &ld); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_LookupDomain for [%s] failed: %s", r->samr.in.domain_name, nt_errstr(status)); goto disconnect; } /* prepare samr_OpenDomain */ ZERO_STRUCT(d_handle); od.in.connect_handle = &p_handle; od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; od.in.sid = ld.out.sid; od.out.domain_handle = &d_handle; /* 4. do a samr_OpenDomain to get a domain handle */ status = dcerpc_samr_OpenDomain(c.out.dcerpc_pipe, mem_ctx, &od); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_OpenDomain for [%s] failed: %s", r->samr.in.domain_name, nt_errstr(status)); goto disconnect; } /* prepare samr_LookupNames */ ln.in.domain_handle = &d_handle; ln.in.num_names = 1; ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1); if (!ln.in.names) { r->samr.out.error_string = "Out of Memory"; return NT_STATUS_NO_MEMORY; } ln.in.names[0].string = r->samr.in.account_name; /* 5. do a samr_LookupNames to get the users rid */ status = dcerpc_samr_LookupNames(c.out.dcerpc_pipe, mem_ctx, &ln); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_LookupNames for [%s] failed: %s", r->samr.in.account_name, nt_errstr(status)); goto disconnect; } /* check if we got one RID for the user */ if (ln.out.rids.count != 1) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_LookupNames for [%s] returns %d RIDs", r->samr.in.account_name, ln.out.rids.count); status = NT_STATUS_INVALID_PARAMETER; goto disconnect; } /* prepare samr_OpenUser */ ZERO_STRUCT(u_handle); ou.in.domain_handle = &d_handle; ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; ou.in.rid = ln.out.rids.ids[0]; ou.out.user_handle = &u_handle; /* 6. do a samr_OpenUser to get a user handle */ status = dcerpc_samr_OpenUser(c.out.dcerpc_pipe, mem_ctx, &ou); if (!NT_STATUS_IS_OK(status)) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_OpenUser for [%s] failed: %s", r->samr.in.account_name, nt_errstr(status)); goto disconnect; } r2.samr_handle.level = LIBNET_SET_PASSWORD_SAMR_HANDLE; r2.samr_handle.in.account_name = r->samr.in.account_name; r2.samr_handle.in.newpassword = r->samr.in.newpassword; r2.samr_handle.in.user_handle = &u_handle; r2.samr_handle.in.dcerpc_pipe = c.out.dcerpc_pipe; r2.samr_handle.in.info21 = NULL; status = libnet_SetPassword(ctx, mem_ctx, &r2); r->generic.out.error_string = r2.samr_handle.out.error_string;disconnect: /* close connection */ talloc_free(c.out.dcerpc_pipe); return status;}static NTSTATUS libnet_SetPassword_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){ NTSTATUS status; union libnet_SetPassword r2; r2.samr.level = LIBNET_SET_PASSWORD_SAMR; r2.samr.in.account_name = r->generic.in.account_name; r2.samr.in.domain_name = r->generic.in.domain_name; r2.samr.in.newpassword = r->generic.in.newpassword; r->generic.out.error_string = "Unknown Error"; status = libnet_SetPassword(ctx, mem_ctx, &r2); r->generic.out.error_string = r2.samr.out.error_string; return status;}NTSTATUS libnet_SetPassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r){ switch (r->generic.level) { case LIBNET_SET_PASSWORD_GENERIC: return libnet_SetPassword_generic(ctx, mem_ctx, r); case LIBNET_SET_PASSWORD_SAMR: return libnet_SetPassword_samr(ctx, mem_ctx, r); case LIBNET_SET_PASSWORD_SAMR_HANDLE: return libnet_SetPassword_samr_handle(ctx, mem_ctx, r); case LIBNET_SET_PASSWORD_SAMR_HANDLE_26: return libnet_SetPassword_samr_handle_26(ctx, mem_ctx, r); case LIBNET_SET_PASSWORD_SAMR_HANDLE_25: return libnet_SetPassword_samr_handle_25(ctx, mem_ctx, r); case LIBNET_SET_PASSWORD_SAMR_HANDLE_24: return libnet_SetPassword_samr_handle_24(ctx, mem_ctx, r); case LIBNET_SET_PASSWORD_SAMR_HANDLE_23: return libnet_SetPassword_samr_handle_23(ctx, mem_ctx, r); case LIBNET_SET_PASSWORD_KRB5: return NT_STATUS_NOT_IMPLEMENTED; case LIBNET_SET_PASSWORD_LDAP: return NT_STATUS_NOT_IMPLEMENTED; case LIBNET_SET_PASSWORD_RAP: return NT_STATUS_NOT_IMPLEMENTED; } return NT_STATUS_INVALID_LEVEL;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?