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