Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : Copyright (C) Stefan Metzmacher 2004
5 : Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "includes.h"
22 : #include "libnet/libnet.h"
23 : #include "libcli/auth/libcli_auth.h"
24 : #include "librpc/gen_ndr/ndr_samr_c.h"
25 : #include "source4/librpc/rpc/dcerpc.h"
26 : #include "auth/credentials/credentials.h"
27 : #include "libcli/smb/smb_constants.h"
28 : #include "librpc/rpc/dcerpc_samr.h"
29 : #include "source3/rpc_client/init_samr.h"
30 : #include "lib/param/loadparm.h"
31 : #include "lib/param/param.h"
32 :
33 : #include "lib/crypto/gnutls_helpers.h"
34 : #include <gnutls/gnutls.h>
35 : #include <gnutls/crypto.h>
36 :
37 54 : static NTSTATUS libnet_ChangePassword_samr_aes(TALLOC_CTX *mem_ctx,
38 : struct dcerpc_binding_handle *h,
39 : struct lsa_String *server,
40 : struct lsa_String *account,
41 : const char *old_password,
42 : const char *new_password,
43 : const char **error_string)
44 : {
45 42 : struct samr_ChangePasswordUser4 r;
46 54 : uint8_t old_nt_key_data[16] = {0};
47 54 : gnutls_datum_t old_nt_key = {
48 : .data = old_nt_key_data,
49 : .size = sizeof(old_nt_key_data),
50 : };
51 54 : uint8_t cek_data[16] = {0};
52 54 : DATA_BLOB cek = {
53 : .data = cek_data,
54 : .length = sizeof(cek_data),
55 : };
56 54 : struct samr_EncryptedPasswordAES pwd_buf = {
57 : .cipher_len = 0
58 : };
59 54 : DATA_BLOB salt = {
60 : .data = pwd_buf.salt,
61 : .length = sizeof(pwd_buf.salt),
62 : };
63 54 : gnutls_datum_t salt_datum = {
64 : .data = pwd_buf.salt,
65 : .size = sizeof(pwd_buf.salt),
66 : };
67 54 : uint64_t pbkdf2_iterations = generate_random_u64_range(5000, 1000000);
68 42 : NTSTATUS status;
69 42 : int rc;
70 :
71 54 : E_md4hash(old_password, old_nt_key_data);
72 :
73 54 : generate_nonce_buffer(salt.data, salt.length);
74 :
75 108 : rc = gnutls_pbkdf2(GNUTLS_MAC_SHA512,
76 : &old_nt_key,
77 : &salt_datum,
78 : pbkdf2_iterations,
79 54 : cek.data,
80 : cek.length);
81 54 : BURN_DATA(old_nt_key_data);
82 54 : if (rc < 0) {
83 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
84 0 : if (!NT_STATUS_IS_OK(status)) {
85 0 : goto done;
86 : }
87 : }
88 :
89 54 : status = init_samr_CryptPasswordAES(mem_ctx,
90 : new_password,
91 : &salt,
92 : &cek,
93 : &pwd_buf);
94 54 : data_blob_clear(&cek);
95 54 : if (!NT_STATUS_IS_OK(status)) {
96 0 : goto done;
97 : }
98 :
99 54 : pwd_buf.PBKDF2Iterations = pbkdf2_iterations;
100 :
101 54 : r.in.server = server;
102 54 : r.in.account = account;
103 54 : r.in.password = &pwd_buf;
104 :
105 54 : status = dcerpc_samr_ChangePasswordUser4_r(h, mem_ctx, &r);
106 54 : if (!NT_STATUS_IS_OK(status)) {
107 0 : goto done;
108 : }
109 54 : if (!NT_STATUS_IS_OK(r.out.result)) {
110 24 : status = r.out.result;
111 24 : *error_string = talloc_asprintf(mem_ctx,
112 : "samr_ChangePasswordUser4 for "
113 : "'%s\\%s' failed: %s",
114 : server->string,
115 : account->string,
116 : nt_errstr(status));
117 24 : goto done;
118 : }
119 :
120 30 : done:
121 54 : BURN_DATA(pwd_buf);
122 :
123 54 : return status;
124 : }
125 :
126 0 : static NTSTATUS libnet_ChangePassword_samr_rc4(TALLOC_CTX *mem_ctx,
127 : struct dcerpc_binding_handle *h,
128 : struct lsa_String *server,
129 : struct lsa_String *account,
130 : const char *old_password,
131 : const char *new_password,
132 : const char **error_string)
133 : {
134 0 : struct samr_OemChangePasswordUser2 oe2;
135 0 : struct samr_ChangePasswordUser2 pw2;
136 0 : struct samr_ChangePasswordUser3 pw3;
137 0 : struct samr_CryptPassword nt_pass, lm_pass;
138 0 : uint8_t old_nt_hash[16], new_nt_hash[16];
139 0 : uint8_t old_lm_hash[16], new_lm_hash[16];
140 0 : struct samr_Password nt_verifier, lm_verifier;
141 0 : struct lsa_AsciiString a_server, a_account;
142 0 : gnutls_cipher_hd_t cipher_hnd = NULL;
143 0 : gnutls_datum_t nt_session_key = {
144 : .data = old_nt_hash,
145 : .size = sizeof(old_nt_hash),
146 : };
147 0 : gnutls_datum_t lm_session_key = {
148 : .data = old_lm_hash,
149 : .size = sizeof(old_lm_hash),
150 : };
151 0 : struct samr_DomInfo1 *dominfo = NULL;
152 0 : struct userPwdChangeFailureInformation *reject = NULL;
153 0 : NTSTATUS status;
154 0 : int rc;
155 :
156 0 : E_md4hash(old_password, old_nt_hash);
157 0 : E_md4hash(new_password, new_nt_hash);
158 :
159 0 : E_deshash(old_password, old_lm_hash);
160 0 : E_deshash(new_password, new_lm_hash);
161 :
162 : /* prepare samr_ChangePasswordUser3 */
163 0 : encode_pw_buffer(lm_pass.data, new_password, STR_UNICODE);
164 :
165 0 : rc = gnutls_cipher_init(&cipher_hnd,
166 : GNUTLS_CIPHER_ARCFOUR_128,
167 : &nt_session_key,
168 : NULL);
169 0 : if (rc < 0) {
170 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
171 0 : goto done;
172 : }
173 :
174 0 : rc = gnutls_cipher_encrypt(cipher_hnd,
175 : lm_pass.data,
176 : 516);
177 0 : gnutls_cipher_deinit(cipher_hnd);
178 0 : if (rc < 0) {
179 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
180 0 : goto done;
181 : }
182 :
183 0 : rc = E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
184 0 : if (rc != 0) {
185 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
186 0 : goto done;
187 : }
188 :
189 0 : encode_pw_buffer(nt_pass.data, new_password, STR_UNICODE);
190 :
191 0 : rc = gnutls_cipher_init(&cipher_hnd,
192 : GNUTLS_CIPHER_ARCFOUR_128,
193 : &nt_session_key,
194 : NULL);
195 0 : if (rc < 0) {
196 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
197 0 : goto done;
198 : }
199 :
200 0 : rc = gnutls_cipher_encrypt(cipher_hnd,
201 : nt_pass.data,
202 : 516);
203 0 : gnutls_cipher_deinit(cipher_hnd);
204 0 : if (rc < 0) {
205 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
206 0 : goto done;
207 : }
208 :
209 0 : rc = E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
210 0 : if (rc != 0) {
211 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
212 0 : goto done;
213 : }
214 :
215 0 : pw3.in.server = server;
216 0 : pw3.in.account = account;
217 0 : pw3.in.nt_password = &nt_pass;
218 0 : pw3.in.nt_verifier = &nt_verifier;
219 0 : pw3.in.lm_change = 1;
220 0 : pw3.in.lm_password = &lm_pass;
221 0 : pw3.in.lm_verifier = &lm_verifier;
222 0 : pw3.in.password3 = NULL;
223 0 : pw3.out.dominfo = &dominfo;
224 0 : pw3.out.reject = &reject;
225 :
226 : /* 2. try samr_ChangePasswordUser3 */
227 0 : status = dcerpc_samr_ChangePasswordUser3_r(h, mem_ctx, &pw3);
228 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
229 0 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(pw3.out.result)) {
230 0 : status = pw3.out.result;
231 : }
232 0 : if (!NT_STATUS_IS_OK(status)) {
233 0 : *error_string = talloc_asprintf(
234 : mem_ctx,
235 : "samr_ChangePasswordUser3 failed: %s",
236 : nt_errstr(status));
237 0 : *error_string =
238 0 : talloc_asprintf(mem_ctx,
239 : "samr_ChangePasswordUser3 for "
240 : "'%s\\%s' failed: %s",
241 : server->string,
242 : account->string,
243 : nt_errstr(status));
244 : }
245 0 : goto done;
246 : }
247 :
248 : /* prepare samr_ChangePasswordUser2 */
249 0 : encode_pw_buffer(lm_pass.data, new_password, STR_ASCII | STR_TERMINATE);
250 :
251 0 : rc = gnutls_cipher_init(&cipher_hnd,
252 : GNUTLS_CIPHER_ARCFOUR_128,
253 : &lm_session_key,
254 : NULL);
255 0 : if (rc < 0) {
256 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
257 0 : goto done;
258 : }
259 :
260 0 : rc = gnutls_cipher_encrypt(cipher_hnd,
261 : lm_pass.data,
262 : 516);
263 0 : gnutls_cipher_deinit(cipher_hnd);
264 0 : if (rc < 0) {
265 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
266 0 : goto done;
267 : }
268 :
269 0 : rc = E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
270 0 : if (rc != 0) {
271 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
272 0 : goto done;
273 : }
274 :
275 0 : encode_pw_buffer(nt_pass.data, new_password, STR_UNICODE);
276 :
277 0 : rc = gnutls_cipher_init(&cipher_hnd,
278 : GNUTLS_CIPHER_ARCFOUR_128,
279 : &nt_session_key,
280 : NULL);
281 0 : if (rc < 0) {
282 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
283 0 : goto done;
284 : }
285 0 : rc = gnutls_cipher_encrypt(cipher_hnd,
286 : nt_pass.data,
287 : 516);
288 0 : gnutls_cipher_deinit(cipher_hnd);
289 0 : if (rc < 0) {
290 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
291 0 : goto done;
292 : }
293 :
294 0 : rc = E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash);
295 0 : if (rc != 0) {
296 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
297 0 : goto done;
298 : }
299 :
300 0 : pw2.in.server = server;
301 0 : pw2.in.account = account;
302 0 : pw2.in.nt_password = &nt_pass;
303 0 : pw2.in.nt_verifier = &nt_verifier;
304 0 : pw2.in.lm_change = 1;
305 0 : pw2.in.lm_password = &lm_pass;
306 0 : pw2.in.lm_verifier = &lm_verifier;
307 :
308 : /* 3. try samr_ChangePasswordUser2 */
309 0 : status = dcerpc_samr_ChangePasswordUser2_r(h, mem_ctx, &pw2);
310 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
311 0 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(pw2.out.result)) {
312 0 : status = pw2.out.result;
313 : }
314 0 : if (!NT_STATUS_IS_OK(status)) {
315 0 : *error_string =
316 0 : talloc_asprintf(mem_ctx,
317 : "samr_ChangePasswordUser2 for "
318 : "'%s\\%s' failed: %s",
319 : server->string,
320 : account->string,
321 : nt_errstr(status));
322 : }
323 0 : goto done;
324 : }
325 :
326 :
327 : /* prepare samr_OemChangePasswordUser2 */
328 0 : a_server.string = server->string;
329 0 : a_account.string = account->string;
330 :
331 0 : encode_pw_buffer(lm_pass.data, new_password, STR_ASCII);
332 :
333 0 : rc = gnutls_cipher_init(&cipher_hnd,
334 : GNUTLS_CIPHER_ARCFOUR_128,
335 : &lm_session_key,
336 : NULL);
337 0 : if (rc < 0) {
338 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
339 0 : goto done;
340 : }
341 :
342 0 : rc = gnutls_cipher_encrypt(cipher_hnd,
343 : lm_pass.data,
344 : 516);
345 0 : gnutls_cipher_deinit(cipher_hnd);
346 0 : if (rc < 0) {
347 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
348 0 : goto done;
349 : }
350 :
351 0 : rc = E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash);
352 0 : if (rc != 0) {
353 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
354 0 : goto done;
355 : }
356 :
357 0 : oe2.in.server = &a_server;
358 0 : oe2.in.account = &a_account;
359 0 : oe2.in.password = &lm_pass;
360 0 : oe2.in.hash = &lm_verifier;
361 :
362 : /* 4. try samr_OemChangePasswordUser2 */
363 0 : status = dcerpc_samr_OemChangePasswordUser2_r(h, mem_ctx, &oe2);
364 0 : if (!NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
365 0 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(oe2.out.result)) {
366 0 : status = oe2.out.result;
367 : }
368 0 : if (!NT_STATUS_IS_OK(oe2.out.result)) {
369 0 : *error_string =
370 0 : talloc_asprintf(mem_ctx,
371 : "samr_OemChangePasswordUser2 "
372 : "for '%s\\%s' failed: %s",
373 : server->string,
374 : account->string,
375 : nt_errstr(status));
376 : }
377 0 : goto done;
378 : }
379 :
380 0 : status = NT_STATUS_OK;
381 0 : done:
382 0 : return status;
383 : }
384 :
385 : /*
386 : * do a password change using DCERPC/SAMR calls
387 : * 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation)
388 : * 2. try samr_ChangePasswordUser3
389 : * 3. try samr_ChangePasswordUser2
390 : * 4. try samr_OemChangePasswordUser2
391 : */
392 54 : static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_ChangePassword *r)
393 : {
394 42 : NTSTATUS status;
395 42 : struct libnet_RpcConnect c;
396 42 : struct lsa_String server, account;
397 :
398 54 : ZERO_STRUCT(c);
399 :
400 : /* prepare connect to the SAMR pipe of the users domain PDC */
401 54 : c.level = LIBNET_RPC_CONNECT_PDC;
402 54 : c.in.name = r->samr.in.domain_name;
403 54 : c.in.dcerpc_iface = &ndr_table_samr;
404 54 : c.in.dcerpc_flags = DCERPC_ANON_FALLBACK;
405 :
406 : /* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */
407 54 : status = libnet_RpcConnect(ctx, mem_ctx, &c);
408 54 : if (!NT_STATUS_IS_OK(status)) {
409 0 : r->samr.out.error_string = talloc_asprintf(mem_ctx,
410 : "Connection to SAMR pipe of PDC of domain '%s' failed: %s",
411 : r->samr.in.domain_name, nt_errstr(status));
412 12 : return status;
413 : }
414 :
415 : /* prepare password change for account */
416 54 : server.string = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(c.out.dcerpc_pipe));
417 54 : account.string = r->samr.in.account_name;
418 :
419 96 : status = libnet_ChangePassword_samr_aes(
420 : mem_ctx,
421 54 : c.out.dcerpc_pipe->binding_handle,
422 : &server,
423 : &account,
424 : r->samr.in.oldpassword,
425 : r->samr.in.newpassword,
426 : &(r->samr.out.error_string));
427 54 : if (NT_STATUS_IS_OK(status)) {
428 30 : goto disconnect;
429 24 : } else if (NT_STATUS_EQUAL(status,
430 24 : NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE) ||
431 24 : NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED) ||
432 3 : NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
433 : /*
434 : * Don't fallback to RC4 based SAMR if weak crypto is not
435 : * allowed.
436 : */
437 0 : if (lpcfg_weak_crypto(ctx->lp_ctx) ==
438 : SAMBA_WEAK_CRYPTO_DISALLOWED) {
439 3 : goto disconnect;
440 : }
441 : } else {
442 : /* libnet_ChangePassword_samr_aes is implemented and failed */
443 24 : goto disconnect;
444 : }
445 :
446 0 : status = libnet_ChangePassword_samr_rc4(
447 : mem_ctx,
448 0 : c.out.dcerpc_pipe->binding_handle,
449 : &server,
450 : &account,
451 : r->samr.in.oldpassword,
452 : r->samr.in.newpassword,
453 : &(r->samr.out.error_string));
454 0 : if (!NT_STATUS_IS_OK(status)) {
455 0 : goto disconnect;
456 : }
457 :
458 0 : disconnect:
459 : /* close connection */
460 54 : talloc_unlink(ctx, c.out.dcerpc_pipe);
461 :
462 54 : return status;
463 : }
464 :
465 54 : static NTSTATUS libnet_ChangePassword_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_ChangePassword *r)
466 : {
467 42 : NTSTATUS status;
468 42 : union libnet_ChangePassword r2;
469 :
470 54 : r2.samr.level = LIBNET_CHANGE_PASSWORD_SAMR;
471 54 : r2.samr.in.account_name = r->generic.in.account_name;
472 54 : r2.samr.in.domain_name = r->generic.in.domain_name;
473 54 : r2.samr.in.oldpassword = r->generic.in.oldpassword;
474 54 : r2.samr.in.newpassword = r->generic.in.newpassword;
475 :
476 54 : status = libnet_ChangePassword(ctx, mem_ctx, &r2);
477 :
478 54 : r->generic.out.error_string = r2.samr.out.error_string;
479 :
480 54 : return status;
481 : }
482 :
483 108 : NTSTATUS libnet_ChangePassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_ChangePassword *r)
484 : {
485 108 : switch (r->generic.level) {
486 54 : case LIBNET_CHANGE_PASSWORD_GENERIC:
487 78 : return libnet_ChangePassword_generic(ctx, mem_ctx, r);
488 54 : case LIBNET_CHANGE_PASSWORD_SAMR:
489 54 : return libnet_ChangePassword_samr(ctx, mem_ctx, r);
490 0 : case LIBNET_CHANGE_PASSWORD_KRB5:
491 0 : return NT_STATUS_NOT_IMPLEMENTED;
492 0 : case LIBNET_CHANGE_PASSWORD_LDAP:
493 0 : return NT_STATUS_NOT_IMPLEMENTED;
494 0 : case LIBNET_CHANGE_PASSWORD_RAP:
495 0 : return NT_STATUS_NOT_IMPLEMENTED;
496 : }
497 :
498 0 : return NT_STATUS_INVALID_LEVEL;
499 : }
500 :
501 562 : static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
502 : {
503 458 : NTSTATUS status;
504 458 : struct samr_SetUserInfo2 sui;
505 458 : union samr_UserInfo u_info;
506 458 : DATA_BLOB session_key;
507 :
508 562 : if (r->samr_handle.in.info21) {
509 557 : return NT_STATUS_INVALID_PARAMETER_MIX;
510 : }
511 :
512 : /* prepare samr_SetUserInfo2 level 26 */
513 5 : ZERO_STRUCT(u_info);
514 5 : u_info.info26.password_expired = 0;
515 :
516 5 : status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
517 5 : if (!NT_STATUS_IS_OK(status)) {
518 0 : r->samr_handle.out.error_string = talloc_asprintf(mem_ctx,
519 : "dcerpc_fetch_session_key failed: %s",
520 : nt_errstr(status));
521 0 : return status;
522 : }
523 :
524 5 : status = encode_rc4_passwd_buffer(r->samr_handle.in.newpassword,
525 : &session_key,
526 : &u_info.info26.password);
527 5 : if (!NT_STATUS_IS_OK(status)) {
528 0 : r->samr_handle.out.error_string =
529 0 : talloc_asprintf(mem_ctx,
530 : "encode_rc4_passwd_buffer failed: %s",
531 : nt_errstr(status));
532 0 : return status;
533 : }
534 :
535 5 : sui.in.user_handle = r->samr_handle.in.user_handle;
536 5 : sui.in.info = &u_info;
537 5 : sui.in.level = 26;
538 :
539 : /* 7. try samr_SetUserInfo2 level 26 to set the password */
540 5 : status = dcerpc_samr_SetUserInfo2_r(r->samr_handle.in.dcerpc_pipe->binding_handle, mem_ctx, &sui);
541 : /* check result of samr_SetUserInfo2 level 26 */
542 5 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sui.out.result)) {
543 1 : status = sui.out.result;
544 : }
545 5 : if (!NT_STATUS_IS_OK(status)) {
546 1 : r->samr_handle.out.error_string
547 1 : = talloc_asprintf(mem_ctx,
548 : "SetUserInfo2 level 26 for [%s] failed: %s",
549 : r->samr_handle.in.account_name, nt_errstr(status));
550 : }
551 :
552 5 : return status;
553 : }
554 :
555 557 : static NTSTATUS libnet_SetPassword_samr_handle_25(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
556 : {
557 453 : NTSTATUS status;
558 453 : struct samr_SetUserInfo2 sui;
559 453 : union samr_UserInfo u_info;
560 453 : DATA_BLOB session_key;
561 :
562 557 : if (!r->samr_handle.in.info21) {
563 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
564 : }
565 :
566 : /* prepare samr_SetUserInfo2 level 25 */
567 557 : ZERO_STRUCT(u_info);
568 557 : u_info.info25.info = *r->samr_handle.in.info21;
569 557 : u_info.info25.info.fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
570 :
571 557 : status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
572 557 : if (!NT_STATUS_IS_OK(status)) {
573 0 : r->samr_handle.out.error_string = talloc_asprintf(mem_ctx,
574 : "dcerpc_fetch_session_key failed: %s",
575 : nt_errstr(status));
576 0 : return status;
577 : }
578 :
579 557 : status = encode_rc4_passwd_buffer(r->samr_handle.in.newpassword,
580 : &session_key,
581 : &u_info.info25.password);
582 557 : if (!NT_STATUS_IS_OK(status)) {
583 0 : r->samr_handle.out.error_string =
584 0 : talloc_asprintf(mem_ctx,
585 : "encode_rc4_passwd_buffer failed: %s",
586 : nt_errstr(status));
587 0 : return status;
588 : }
589 :
590 :
591 557 : sui.in.user_handle = r->samr_handle.in.user_handle;
592 557 : sui.in.info = &u_info;
593 557 : sui.in.level = 25;
594 :
595 : /* 8. try samr_SetUserInfo2 level 25 to set the password */
596 557 : status = dcerpc_samr_SetUserInfo2_r(r->samr_handle.in.dcerpc_pipe->binding_handle, mem_ctx, &sui);
597 557 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sui.out.result)) {
598 0 : status = sui.out.result;
599 : }
600 557 : if (!NT_STATUS_IS_OK(status)) {
601 0 : r->samr_handle.out.error_string
602 0 : = talloc_asprintf(mem_ctx,
603 : "SetUserInfo2 level 25 for [%s] failed: %s",
604 : r->samr_handle.in.account_name, nt_errstr(status));
605 : }
606 :
607 557 : return status;
608 : }
609 :
610 0 : static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
611 : {
612 0 : NTSTATUS status;
613 0 : struct samr_SetUserInfo2 sui;
614 0 : union samr_UserInfo u_info;
615 0 : DATA_BLOB session_key;
616 0 : gnutls_cipher_hd_t cipher_hnd = NULL;
617 0 : gnutls_datum_t enc_session_key;
618 0 : int rc;
619 :
620 0 : if (r->samr_handle.in.info21) {
621 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
622 : }
623 :
624 : /* prepare samr_SetUserInfo2 level 24 */
625 0 : ZERO_STRUCT(u_info);
626 0 : encode_pw_buffer(u_info.info24.password.data, r->samr_handle.in.newpassword, STR_UNICODE);
627 0 : u_info.info24.password_expired = 0;
628 :
629 0 : status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
630 0 : if (!NT_STATUS_IS_OK(status)) {
631 0 : r->samr_handle.out.error_string = talloc_asprintf(mem_ctx,
632 : "dcerpc_fetch_session_key failed: %s",
633 : nt_errstr(status));
634 0 : return status;
635 : }
636 :
637 0 : enc_session_key = (gnutls_datum_t) {
638 0 : .data = session_key.data,
639 0 : .size = session_key.length,
640 : };
641 :
642 0 : rc = gnutls_cipher_init(&cipher_hnd,
643 : GNUTLS_CIPHER_ARCFOUR_128,
644 : &enc_session_key,
645 : NULL);
646 0 : if (rc < 0) {
647 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
648 0 : goto out;
649 : }
650 :
651 0 : rc = gnutls_cipher_encrypt(cipher_hnd,
652 : u_info.info24.password.data,
653 : 516);
654 0 : gnutls_cipher_deinit(cipher_hnd);
655 0 : if (rc < 0) {
656 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
657 0 : goto out;
658 : }
659 :
660 0 : sui.in.user_handle = r->samr_handle.in.user_handle;
661 0 : sui.in.info = &u_info;
662 0 : sui.in.level = 24;
663 :
664 : /* 9. try samr_SetUserInfo2 level 24 to set the password */
665 0 : status = dcerpc_samr_SetUserInfo2_r(r->samr_handle.in.dcerpc_pipe->binding_handle, mem_ctx, &sui);
666 0 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sui.out.result)) {
667 0 : status = sui.out.result;
668 : }
669 0 : if (!NT_STATUS_IS_OK(status)) {
670 0 : r->samr_handle.out.error_string
671 0 : = talloc_asprintf(mem_ctx,
672 : "SetUserInfo2 level 24 for [%s] failed: %s",
673 : r->samr_handle.in.account_name, nt_errstr(status));
674 : }
675 :
676 0 : out:
677 0 : data_blob_clear(&session_key);
678 0 : return status;
679 : }
680 :
681 0 : static NTSTATUS libnet_SetPassword_samr_handle_23(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
682 : {
683 0 : NTSTATUS status;
684 0 : struct samr_SetUserInfo2 sui;
685 0 : union samr_UserInfo u_info;
686 0 : DATA_BLOB session_key;
687 0 : gnutls_cipher_hd_t cipher_hnd = NULL;
688 0 : gnutls_datum_t _session_key;
689 0 : int rc;
690 :
691 0 : if (!r->samr_handle.in.info21) {
692 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
693 : }
694 :
695 : /* prepare samr_SetUserInfo2 level 23 */
696 0 : ZERO_STRUCT(u_info);
697 0 : u_info.info23.info = *r->samr_handle.in.info21;
698 0 : u_info.info23.info.fields_present |= SAMR_FIELD_NT_PASSWORD_PRESENT;
699 0 : encode_pw_buffer(u_info.info23.password.data, r->samr_handle.in.newpassword, STR_UNICODE);
700 :
701 0 : status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
702 0 : if (!NT_STATUS_IS_OK(status)) {
703 0 : r->samr_handle.out.error_string
704 0 : = talloc_asprintf(mem_ctx,
705 : "dcerpc_fetch_session_key failed: %s",
706 : nt_errstr(status));
707 0 : return status;
708 : }
709 :
710 0 : _session_key = (gnutls_datum_t) {
711 0 : .data = session_key.data,
712 0 : .size = session_key.length,
713 : };
714 :
715 0 : rc = gnutls_cipher_init(&cipher_hnd,
716 : GNUTLS_CIPHER_ARCFOUR_128,
717 : &_session_key,
718 : NULL);
719 0 : if (rc < 0) {
720 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
721 0 : goto out;
722 : }
723 :
724 0 : rc = gnutls_cipher_encrypt(cipher_hnd,
725 : u_info.info23.password.data,
726 : 516);
727 0 : data_blob_clear_free(&session_key);
728 0 : gnutls_cipher_deinit(cipher_hnd);
729 0 : if (rc < 0) {
730 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
731 0 : goto out;
732 : }
733 :
734 0 : sui.in.user_handle = r->samr_handle.in.user_handle;
735 0 : sui.in.info = &u_info;
736 0 : sui.in.level = 23;
737 :
738 : /* 10. try samr_SetUserInfo2 level 23 to set the password */
739 0 : status = dcerpc_samr_SetUserInfo2_r(r->samr_handle.in.dcerpc_pipe->binding_handle, mem_ctx, &sui);
740 0 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sui.out.result)) {
741 0 : status = sui.out.result;
742 : }
743 0 : if (!NT_STATUS_IS_OK(status)) {
744 0 : r->samr_handle.out.error_string
745 0 : = talloc_asprintf(mem_ctx,
746 : "SetUserInfo2 level 23 for [%s] failed: %s",
747 : r->samr_handle.in.account_name, nt_errstr(status));
748 : }
749 :
750 0 : out:
751 0 : return status;
752 : }
753 :
754 114 : static NTSTATUS libnet_SetPassword_samr_handle_18(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
755 : {
756 76 : NTSTATUS status;
757 76 : struct samr_SetUserInfo2 sui;
758 76 : union samr_UserInfo u_info;
759 76 : struct samr_Password ntpwd;
760 76 : DATA_BLOB ntpwd_in;
761 76 : DATA_BLOB ntpwd_out;
762 76 : DATA_BLOB session_key;
763 76 : int rc;
764 :
765 114 : if (r->samr_handle.in.info21) {
766 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
767 : }
768 :
769 : /* prepare samr_SetUserInfo2 level 18 (nt_hash) */
770 114 : ZERO_STRUCT(u_info);
771 114 : E_md4hash(r->samr_handle.in.newpassword, ntpwd.hash);
772 114 : ntpwd_in = data_blob_const(ntpwd.hash, sizeof(ntpwd.hash));
773 114 : ntpwd_out = data_blob_const(u_info.info18.nt_pwd.hash,
774 : sizeof(u_info.info18.nt_pwd.hash));
775 114 : u_info.info18.nt_pwd_active = 1;
776 114 : u_info.info18.password_expired = 0;
777 :
778 114 : status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
779 114 : if (!NT_STATUS_IS_OK(status)) {
780 0 : r->samr_handle.out.error_string = talloc_asprintf(mem_ctx,
781 : "dcerpc_fetch_session_key failed: %s",
782 : nt_errstr(status));
783 0 : return status;
784 : }
785 :
786 114 : rc = sess_crypt_blob(&ntpwd_out, &ntpwd_in,
787 : &session_key, SAMBA_GNUTLS_ENCRYPT);
788 114 : if (rc < 0) {
789 0 : status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
790 0 : goto out;
791 : }
792 :
793 114 : sui.in.user_handle = r->samr_handle.in.user_handle;
794 114 : sui.in.info = &u_info;
795 114 : sui.in.level = 18;
796 :
797 : /* 9. try samr_SetUserInfo2 level 18 to set the password */
798 114 : status = dcerpc_samr_SetUserInfo2_r(r->samr_handle.in.dcerpc_pipe->binding_handle, mem_ctx, &sui);
799 114 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sui.out.result)) {
800 0 : status = sui.out.result;
801 : }
802 114 : if (!NT_STATUS_IS_OK(status)) {
803 0 : r->samr_handle.out.error_string
804 0 : = talloc_asprintf(mem_ctx,
805 : "SetUserInfo2 level 18 for [%s] failed: %s",
806 : r->samr_handle.in.account_name, nt_errstr(status));
807 : }
808 :
809 114 : out:
810 114 : data_blob_clear(&session_key);
811 114 : return status;
812 : }
813 :
814 : /*
815 : * 1. try samr_SetUserInfo2 level 26 to set the password
816 : * 2. try samr_SetUserInfo2 level 25 to set the password
817 : * 3. try samr_SetUserInfo2 level 24 to set the password
818 : * 4. try samr_SetUserInfo2 level 23 to set the password
819 : */
820 676 : static NTSTATUS libnet_SetPassword_samr_handle(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
821 : {
822 :
823 534 : NTSTATUS status;
824 676 : enum libnet_SetPassword_level levels[] = {
825 : LIBNET_SET_PASSWORD_SAMR_HANDLE_26,
826 : LIBNET_SET_PASSWORD_SAMR_HANDLE_25,
827 : LIBNET_SET_PASSWORD_SAMR_HANDLE_24,
828 : LIBNET_SET_PASSWORD_SAMR_HANDLE_23,
829 : };
830 534 : unsigned int i;
831 :
832 676 : if (r->samr_handle.samr_level != 0) {
833 114 : r->generic.level = r->samr_handle.samr_level;
834 218 : return libnet_SetPassword(ctx, mem_ctx, r);
835 : }
836 :
837 1119 : for (i=0; i < ARRAY_SIZE(levels); i++) {
838 1119 : r->generic.level = levels[i];
839 1119 : status = libnet_SetPassword(ctx, mem_ctx, r);
840 1119 : if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)
841 1119 : || NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER_MIX)
842 562 : || NT_STATUS_EQUAL(status, NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE)) {
843 : /* Try another password set mechanism */
844 557 : continue;
845 : }
846 104 : break;
847 : }
848 :
849 562 : return status;
850 : }
851 : /*
852 : * set a password with DCERPC/SAMR calls
853 : * 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation)
854 : * is it correct to contact the the pdc of the domain of the user who's password should be set?
855 : * 2. do a samr_Connect to get a policy handle
856 : * 3. do a samr_LookupDomain to get the domain sid
857 : * 4. do a samr_OpenDomain to get a domain handle
858 : * 5. do a samr_LookupNames to get the users rid
859 : * 6. do a samr_OpenUser to get a user handle
860 : * 7 call libnet_SetPassword_samr_handle to set the password
861 : */
862 119 : static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
863 : {
864 81 : NTSTATUS status;
865 81 : struct libnet_RpcConnect c;
866 81 : struct samr_Connect sc;
867 81 : struct policy_handle p_handle;
868 81 : struct samr_LookupDomain ld;
869 119 : struct dom_sid2 *sid = NULL;
870 81 : struct lsa_String d_name;
871 81 : struct samr_OpenDomain od;
872 81 : struct policy_handle d_handle;
873 81 : struct samr_LookupNames ln;
874 81 : struct samr_Ids rids, types;
875 81 : struct samr_OpenUser ou;
876 81 : struct policy_handle u_handle;
877 81 : union libnet_SetPassword r2;
878 :
879 119 : ZERO_STRUCT(c);
880 : /* prepare connect to the SAMR pipe of users domain PDC */
881 119 : c.level = LIBNET_RPC_CONNECT_PDC;
882 119 : c.in.name = r->samr.in.domain_name;
883 119 : c.in.dcerpc_iface = &ndr_table_samr;
884 :
885 : /* 1. connect to the SAMR pipe of users domain PDC (maybe a standalone server or workstation) */
886 119 : status = libnet_RpcConnect(ctx, mem_ctx, &c);
887 119 : if (!NT_STATUS_IS_OK(status)) {
888 0 : r->samr.out.error_string = talloc_asprintf(mem_ctx,
889 : "Connection to SAMR pipe of PDC of domain '%s' failed: %s",
890 : r->samr.in.domain_name, nt_errstr(status));
891 38 : return status;
892 : }
893 :
894 : /* prepare samr_Connect */
895 119 : ZERO_STRUCT(p_handle);
896 119 : sc.in.system_name = NULL;
897 119 : sc.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
898 119 : sc.out.connect_handle = &p_handle;
899 :
900 : /* 2. do a samr_Connect to get a policy handle */
901 119 : status = dcerpc_samr_Connect_r(c.out.dcerpc_pipe->binding_handle, mem_ctx, &sc);
902 119 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(sc.out.result)) {
903 0 : status = sc.out.result;
904 : }
905 119 : if (!NT_STATUS_IS_OK(status)) {
906 0 : r->samr.out.error_string = talloc_asprintf(mem_ctx,
907 : "samr_Connect failed: %s",
908 : nt_errstr(status));
909 0 : goto disconnect;
910 : }
911 :
912 : /* prepare samr_LookupDomain */
913 119 : d_name.string = r->samr.in.domain_name;
914 119 : ld.in.connect_handle = &p_handle;
915 119 : ld.in.domain_name = &d_name;
916 119 : ld.out.sid = &sid;
917 :
918 : /* 3. do a samr_LookupDomain to get the domain sid */
919 119 : status = dcerpc_samr_LookupDomain_r(c.out.dcerpc_pipe->binding_handle, mem_ctx, &ld);
920 119 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(ld.out.result)) {
921 0 : status = ld.out.result;
922 : }
923 119 : if (!NT_STATUS_IS_OK(status)) {
924 0 : r->samr.out.error_string = talloc_asprintf(mem_ctx,
925 : "samr_LookupDomain for [%s] failed: %s",
926 : r->samr.in.domain_name, nt_errstr(status));
927 0 : goto disconnect;
928 : }
929 :
930 : /* prepare samr_OpenDomain */
931 119 : ZERO_STRUCT(d_handle);
932 119 : od.in.connect_handle = &p_handle;
933 119 : od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
934 119 : od.in.sid = *ld.out.sid;
935 119 : od.out.domain_handle = &d_handle;
936 :
937 : /* 4. do a samr_OpenDomain to get a domain handle */
938 119 : status = dcerpc_samr_OpenDomain_r(c.out.dcerpc_pipe->binding_handle, mem_ctx, &od);
939 119 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(od.out.result)) {
940 0 : status = od.out.result;
941 : }
942 119 : if (!NT_STATUS_IS_OK(status)) {
943 0 : r->samr.out.error_string = talloc_asprintf(mem_ctx,
944 : "samr_OpenDomain for [%s] failed: %s",
945 : r->samr.in.domain_name, nt_errstr(status));
946 0 : goto disconnect;
947 : }
948 :
949 : /* prepare samr_LookupNames */
950 119 : ln.in.domain_handle = &d_handle;
951 119 : ln.in.num_names = 1;
952 119 : ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
953 119 : ln.out.rids = &rids;
954 119 : ln.out.types = &types;
955 119 : if (!ln.in.names) {
956 0 : r->samr.out.error_string = "Out of Memory";
957 0 : return NT_STATUS_NO_MEMORY;
958 : }
959 119 : ln.in.names[0].string = r->samr.in.account_name;
960 :
961 : /* 5. do a samr_LookupNames to get the users rid */
962 119 : status = dcerpc_samr_LookupNames_r(c.out.dcerpc_pipe->binding_handle, mem_ctx, &ln);
963 119 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(ln.out.result)) {
964 0 : status = ln.out.result;
965 : }
966 119 : if (!NT_STATUS_IS_OK(status)) {
967 0 : r->samr.out.error_string = talloc_asprintf(mem_ctx,
968 : "samr_LookupNames for [%s] failed: %s",
969 : r->samr.in.account_name, nt_errstr(status));
970 0 : goto disconnect;
971 : }
972 :
973 : /* check if we got one RID for the user */
974 119 : if (ln.out.rids->count != 1) {
975 0 : r->samr.out.error_string = talloc_asprintf(mem_ctx,
976 : "samr_LookupNames for [%s] returns %d RIDs",
977 0 : r->samr.in.account_name, ln.out.rids->count);
978 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
979 0 : goto disconnect;
980 : }
981 :
982 119 : if (ln.out.types->count != 1) {
983 0 : r->samr.out.error_string = talloc_asprintf(mem_ctx,
984 : "samr_LookupNames for [%s] returns %d RID TYPEs",
985 0 : r->samr.in.account_name, ln.out.types->count);
986 0 : status = NT_STATUS_INVALID_NETWORK_RESPONSE;
987 0 : goto disconnect;
988 : }
989 :
990 : /* prepare samr_OpenUser */
991 119 : ZERO_STRUCT(u_handle);
992 119 : ou.in.domain_handle = &d_handle;
993 119 : ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
994 119 : ou.in.rid = ln.out.rids->ids[0];
995 119 : ou.out.user_handle = &u_handle;
996 :
997 : /* 6. do a samr_OpenUser to get a user handle */
998 119 : status = dcerpc_samr_OpenUser_r(c.out.dcerpc_pipe->binding_handle, mem_ctx, &ou);
999 119 : if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(ou.out.result)) {
1000 0 : status = ou.out.result;
1001 : }
1002 119 : if (!NT_STATUS_IS_OK(status)) {
1003 0 : r->samr.out.error_string = talloc_asprintf(mem_ctx,
1004 : "samr_OpenUser for [%s] failed: %s",
1005 : r->samr.in.account_name, nt_errstr(status));
1006 0 : goto disconnect;
1007 : }
1008 :
1009 119 : ZERO_STRUCT(r2);
1010 119 : r2.samr_handle.level = LIBNET_SET_PASSWORD_SAMR_HANDLE;
1011 119 : r2.samr_handle.samr_level = r->samr.samr_level;
1012 119 : r2.samr_handle.in.account_name = r->samr.in.account_name;
1013 119 : r2.samr_handle.in.newpassword = r->samr.in.newpassword;
1014 119 : r2.samr_handle.in.user_handle = &u_handle;
1015 119 : r2.samr_handle.in.dcerpc_pipe = c.out.dcerpc_pipe;
1016 119 : r2.samr_handle.in.info21 = NULL;
1017 :
1018 119 : status = libnet_SetPassword(ctx, mem_ctx, &r2);
1019 :
1020 119 : r->generic.out.error_string = r2.samr_handle.out.error_string;
1021 :
1022 119 : disconnect:
1023 : /* close connection */
1024 119 : talloc_unlink(ctx, c.out.dcerpc_pipe);
1025 :
1026 119 : return status;
1027 : }
1028 :
1029 119 : static NTSTATUS libnet_SetPassword_generic(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
1030 : {
1031 81 : NTSTATUS status;
1032 81 : union libnet_SetPassword r2;
1033 :
1034 119 : ZERO_STRUCT(r2);
1035 119 : r2.samr.level = LIBNET_SET_PASSWORD_SAMR;
1036 119 : r2.samr.samr_level = r->generic.samr_level;
1037 119 : r2.samr.in.account_name = r->generic.in.account_name;
1038 119 : r2.samr.in.domain_name = r->generic.in.domain_name;
1039 119 : r2.samr.in.newpassword = r->generic.in.newpassword;
1040 :
1041 119 : r->generic.out.error_string = "Unknown Error";
1042 119 : status = libnet_SetPassword(ctx, mem_ctx, &r2);
1043 :
1044 119 : r->generic.out.error_string = r2.samr.out.error_string;
1045 :
1046 119 : return status;
1047 : }
1048 :
1049 2147 : NTSTATUS libnet_SetPassword(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, union libnet_SetPassword *r)
1050 : {
1051 1683 : enum smb_encryption_setting encryption_state =
1052 2147 : cli_credentials_get_smb_encryption(ctx->cred);
1053 2147 : NTSTATUS status = NT_STATUS_INVALID_LEVEL;
1054 :
1055 2147 : switch (r->generic.level) {
1056 119 : case LIBNET_SET_PASSWORD_GENERIC:
1057 119 : status = libnet_SetPassword_generic(ctx, mem_ctx, r);
1058 545 : break;
1059 119 : case LIBNET_SET_PASSWORD_SAMR:
1060 119 : status = libnet_SetPassword_samr(ctx, mem_ctx, r);
1061 119 : break;
1062 676 : case LIBNET_SET_PASSWORD_SAMR_HANDLE:
1063 676 : status = libnet_SetPassword_samr_handle(ctx, mem_ctx, r);
1064 676 : break;
1065 562 : case LIBNET_SET_PASSWORD_SAMR_HANDLE_26:
1066 562 : if (encryption_state == SMB_ENCRYPTION_REQUIRED) {
1067 0 : GNUTLS_FIPS140_SET_LAX_MODE();
1068 : }
1069 562 : status = libnet_SetPassword_samr_handle_26(ctx, mem_ctx, r);
1070 562 : break;
1071 557 : case LIBNET_SET_PASSWORD_SAMR_HANDLE_25:
1072 557 : if (encryption_state == SMB_ENCRYPTION_REQUIRED) {
1073 0 : GNUTLS_FIPS140_SET_LAX_MODE();
1074 : }
1075 557 : status = libnet_SetPassword_samr_handle_25(ctx, mem_ctx, r);
1076 557 : break;
1077 0 : case LIBNET_SET_PASSWORD_SAMR_HANDLE_24:
1078 0 : if (encryption_state == SMB_ENCRYPTION_REQUIRED) {
1079 0 : GNUTLS_FIPS140_SET_LAX_MODE();
1080 : }
1081 0 : status = libnet_SetPassword_samr_handle_24(ctx, mem_ctx, r);
1082 0 : break;
1083 0 : case LIBNET_SET_PASSWORD_SAMR_HANDLE_23:
1084 0 : if (encryption_state == SMB_ENCRYPTION_REQUIRED) {
1085 0 : GNUTLS_FIPS140_SET_LAX_MODE();
1086 : }
1087 0 : status = libnet_SetPassword_samr_handle_23(ctx, mem_ctx, r);
1088 0 : break;
1089 114 : case LIBNET_SET_PASSWORD_SAMR_HANDLE_18:
1090 114 : if (encryption_state == SMB_ENCRYPTION_REQUIRED) {
1091 0 : GNUTLS_FIPS140_SET_LAX_MODE();
1092 : }
1093 114 : status = libnet_SetPassword_samr_handle_18(ctx, mem_ctx, r);
1094 114 : break;
1095 0 : case LIBNET_SET_PASSWORD_KRB5:
1096 0 : status = NT_STATUS_NOT_IMPLEMENTED;
1097 0 : break;
1098 0 : case LIBNET_SET_PASSWORD_LDAP:
1099 0 : status = NT_STATUS_NOT_IMPLEMENTED;
1100 0 : break;
1101 0 : case LIBNET_SET_PASSWORD_RAP:
1102 0 : status = NT_STATUS_NOT_IMPLEMENTED;
1103 0 : break;
1104 : }
1105 :
1106 2147 : GNUTLS_FIPS140_SET_STRICT_MODE();
1107 2147 : return status;
1108 : }
|