2 Unix SMB/CIFS implementation.
4 Copyright (C) Stefan Metzmacher 2004
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * 1. connect to the SAMR pipe of *our* PDC
23 * 2. try samr_ChangePassword3
25 static NTSTATUS libnet_ChangePassword_rpc(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct net_ChangePassword *r)
28 struct dcerpc_pipe *p = NULL;
29 struct samr_ChangePasswordUser3 pw3;
30 struct samr_Name server, account;
31 struct samr_CryptPassword nt_pass, lm_pass;
32 struct samr_Password nt_verifier, lm_verifier;
33 uint8_t old_nt_hash[16], new_nt_hash[16];
34 uint8_t old_lm_hash[16], new_lm_hash[16];
36 /* connect to the SAMR pipe of the */
37 status = libnet_rpc_connect_pdc(ctx, mem_ctx,
38 r->rpc.in.domain_name,
43 if (!NT_STATUS_IS_OK(status)) {
44 r->rpc.out.error_string = talloc_asprintf(mem_ctx,
45 "Connection to SAMR pipe of PDC of domain '%s' failed\n",
46 r->rpc.in.domain_name);
50 server.name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
51 init_samr_Name(&account, r->rpc.in.account_name);
53 E_md4hash(r->rpc.in.oldpassword, old_nt_hash);
54 E_md4hash(r->rpc.in.newpassword, new_nt_hash);
56 E_deshash(r->rpc.in.oldpassword, old_lm_hash);
57 E_deshash(r->rpc.in.newpassword, new_lm_hash);
59 encode_pw_buffer(lm_pass.data, r->rpc.in.newpassword, STR_UNICODE);
60 arcfour_crypt(lm_pass.data, old_nt_hash, 516);
61 E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
63 encode_pw_buffer(nt_pass.data, r->rpc.in.newpassword, STR_UNICODE);
64 arcfour_crypt(nt_pass.data, old_nt_hash, 516);
65 E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
67 pw3.in.server = &server;
68 pw3.in.account = &account;
69 pw3.in.nt_password = &nt_pass;
70 pw3.in.nt_verifier = &nt_verifier;
72 pw3.in.lm_password = &lm_pass;
73 pw3.in.lm_verifier = &lm_verifier;
74 pw3.in.password3 = NULL;
76 status = dcerpc_samr_ChangePassword3(p, mem_ctx, &pw3);
77 if (!NT_STATUS_IS_OK(status)) {
78 r->rpc.out.error_string = talloc_asprintf(mem_ctx,
79 "ChangePassword3 failed: %s\n",nt_errstr(status);
83 if (!NT_STATUS_IS_OK(r->rpc.out.result)) {
84 r->rpc.out.error_string = talloc_asprintf(mem_ctx,
85 "ChangePassword3 for '%s\\%s' failed: %s\n",
86 r->rpc.in.domain_name, r->rpc.in.account_name,
88 /* TODO: give the reason of the reject */
98 static NTSTATUS libnet_ChangePassword_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct net_ChangePassword *r)
100 return NT_STATUS_NOT_IMPLEMTED;
103 NTSTATUS libnet_ChangePassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct net_ChangePassword *r)
105 switch (r->generic.level) {
106 case LIBNET_CHANGE_PASSWORD_GENERIC:
107 return libnet_ChangePassword_generic(ctx, mem_ctx, r);
108 case LIBNET_CHANGE_PASSWORD_RPC:
109 return libnet_ChangePassword_rpc(ctx, mem_ctx, r);
110 case LIBNET_CHANGE_PASSWORD_ADS:
111 return NT_STATUS_NOT_IMPLEMTED;
112 case LIBNET_CHANGE_PASSWORD_RAP:
113 return NT_STATUS_NOT_IMPLEMTED;
116 return NT_STATUS_INVALID_LEVEL;