LCOV - code coverage report
Current view: top level - source4/libnet - libnet_passwd.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 233 483 48.2 %
Date: 2021-09-23 10:06:22 Functions: 11 15 73.3 %

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

Generated by: LCOV version 1.13