LCOV - code coverage report
Current view: top level - source3/rpc_client - cli_samr.c (source / functions) Hit Total Coverage
Test: coverage report for master 70ed9daf Lines: 43 277 15.5 %
Date: 2024-01-11 09:59:51 Functions: 2 11 18.2 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    RPC pipe client
       4             :    Copyright (C) Tim Potter                        2000-2001,
       5             :    Copyright (C) Andrew Tridgell              1992-1997,2000,
       6             :    Copyright (C) Rafal Szczesniak                       2002.
       7             :    Copyright (C) Jeremy Allison                         2005.
       8             :    Copyright (C) Guenther Deschner                      2008.
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include "rpc_client/rpc_client.h"
      26             : #include "../libcli/auth/libcli_auth.h"
      27             : #include "../librpc/gen_ndr/ndr_samr_c.h"
      28             : #include "rpc_client/cli_samr.h"
      29             : #include "rpc_client/init_lsa.h"
      30             : #include "rpc_client/init_samr.h"
      31             : #include "librpc/rpc/dcerpc_samr.h"
      32             : #include "lib/crypto/gnutls_helpers.h"
      33             : #include <gnutls/gnutls.h>
      34             : #include <gnutls/crypto.h>
      35             : 
      36             : /* User change password */
      37             : 
      38           0 : NTSTATUS dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle *h,
      39             :                                     TALLOC_CTX *mem_ctx,
      40             :                                     struct policy_handle *user_handle,
      41             :                                     const char *newpassword,
      42             :                                     const char *oldpassword,
      43             :                                     NTSTATUS *presult)
      44             : {
      45           0 :         NTSTATUS status;
      46           0 :         int rc;
      47           0 :         struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6;
      48             : 
      49           0 :         uint8_t old_nt_hash[16] = {0};
      50           0 :         uint8_t old_lm_hash[16] = {0};
      51           0 :         uint8_t new_nt_hash[16] = {0};
      52           0 :         uint8_t new_lm_hash[16] = {0};
      53             : 
      54           0 :         DEBUG(10,("rpccli_samr_chgpasswd_user\n"));
      55             : 
      56           0 :         E_md4hash(oldpassword, old_nt_hash);
      57           0 :         E_md4hash(newpassword, new_nt_hash);
      58             : 
      59           0 :         E_deshash(oldpassword, old_lm_hash);
      60           0 :         E_deshash(newpassword, new_lm_hash);
      61             : 
      62           0 :         rc = E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash);
      63           0 :         if (rc != 0) {
      64           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
      65           0 :                 goto done;
      66             :         }
      67           0 :         rc = E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash);
      68           0 :         if (rc != 0) {
      69           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
      70           0 :                 goto done;
      71             :         }
      72           0 :         rc = E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash);
      73           0 :         if (rc != 0) {
      74           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
      75           0 :                 goto done;
      76             :         }
      77           0 :         rc = E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash);
      78           0 :         if (rc != 0) {
      79           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
      80           0 :                 goto done;
      81             :         }
      82           0 :         rc = E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash);
      83           0 :         if (rc != 0) {
      84           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
      85           0 :                 goto done;
      86             :         }
      87           0 :         rc = E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash);
      88           0 :         if (rc != 0) {
      89           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
      90           0 :                 goto done;
      91             :         }
      92             : 
      93           0 :         status = dcerpc_samr_ChangePasswordUser(h,
      94             :                                                 mem_ctx,
      95             :                                                 user_handle,
      96             :                                                 true,
      97             :                                                 &hash1,
      98             :                                                 &hash2,
      99             :                                                 true,
     100             :                                                 &hash3,
     101             :                                                 &hash4,
     102             :                                                 true,
     103             :                                                 &hash5,
     104             :                                                 true,
     105             :                                                 &hash6,
     106             :                                                 presult);
     107             : 
     108           0 : done:
     109           0 :         ZERO_ARRAY(old_nt_hash);
     110           0 :         ZERO_ARRAY(old_lm_hash);
     111           0 :         ZERO_ARRAY(new_nt_hash);
     112           0 :         ZERO_ARRAY(new_lm_hash);
     113             : 
     114           0 :         return status;
     115             : }
     116             : 
     117           0 : NTSTATUS rpccli_samr_chgpasswd_user(struct rpc_pipe_client *cli,
     118             :                                     TALLOC_CTX *mem_ctx,
     119             :                                     struct policy_handle *user_handle,
     120             :                                     const char *newpassword,
     121             :                                     const char *oldpassword)
     122             : {
     123           0 :         NTSTATUS status;
     124           0 :         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     125             : 
     126           0 :         status = dcerpc_samr_chgpasswd_user(cli->binding_handle,
     127             :                                             mem_ctx,
     128             :                                             user_handle,
     129             :                                             newpassword,
     130             :                                             oldpassword,
     131             :                                             &result);
     132           0 :         if (!NT_STATUS_IS_OK(status)) {
     133           0 :                 return status;
     134             :         }
     135             : 
     136           0 :         return result;
     137             : }
     138             : 
     139             : /* User change password */
     140             : 
     141           0 : NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h,
     142             :                                      TALLOC_CTX *mem_ctx,
     143             :                                      const char *srv_name_slash,
     144             :                                      const char *username,
     145             :                                      const char *newpassword,
     146             :                                      const char *oldpassword,
     147             :                                      NTSTATUS *presult)
     148             : {
     149           0 :         NTSTATUS status;
     150           0 :         int rc;
     151           0 :         struct samr_CryptPassword new_nt_password;
     152           0 :         struct samr_CryptPassword new_lm_password;
     153           0 :         struct samr_Password old_nt_hash_enc;
     154           0 :         struct samr_Password old_lanman_hash_enc;
     155             : 
     156           0 :         uint8_t old_nt_hash[16] = { 0 };
     157           0 :         uint8_t old_lanman_hash[16];
     158           0 :         uint8_t new_nt_hash[16];
     159           0 :         uint8_t new_lanman_hash[16];
     160           0 :         struct lsa_String server, account;
     161             : 
     162           0 :         DATA_BLOB session_key = data_blob_const(old_nt_hash, 16);
     163             : 
     164           0 :         DEBUG(10,("rpccli_samr_chgpasswd_user2\n"));
     165             : 
     166           0 :         init_lsa_String(&server, srv_name_slash);
     167           0 :         init_lsa_String(&account, username);
     168             : 
     169             :         /* Calculate the MD4 hash (NT compatible) of the password */
     170           0 :         E_md4hash(oldpassword, old_nt_hash);
     171           0 :         E_md4hash(newpassword, new_nt_hash);
     172             : 
     173           0 :         if (lp_client_lanman_auth() &&
     174           0 :             E_deshash(newpassword, new_lanman_hash) &&
     175           0 :             E_deshash(oldpassword, old_lanman_hash)) {
     176             :                 /* E_deshash returns false for 'long' passwords (> 14
     177             :                    DOS chars).  This allows us to match Win2k, which
     178             :                    does not store a LM hash for these passwords (which
     179             :                    would reduce the effective password length to 14) */
     180           0 :                 status = init_samr_CryptPassword(newpassword,
     181             :                                                  &session_key,
     182             :                                                  &new_lm_password);
     183           0 :                 if (!NT_STATUS_IS_OK(status)) {
     184           0 :                         return status;
     185             :                 }
     186             : 
     187           0 :                 rc = E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
     188           0 :                 if (rc != 0) {
     189           0 :                         status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
     190           0 :                         goto done;
     191             :                 }
     192             :         } else {
     193           0 :                 ZERO_STRUCT(new_lm_password);
     194           0 :                 ZERO_STRUCT(old_lanman_hash_enc);
     195             :         }
     196             : 
     197           0 :         status = init_samr_CryptPassword(newpassword,
     198             :                                          &session_key,
     199             :                                          &new_nt_password);
     200           0 :         if (!NT_STATUS_IS_OK(status)) {
     201           0 :                 return status;
     202             :         }
     203           0 :         rc = E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
     204           0 :         if (rc != 0) {
     205           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
     206           0 :                 goto done;
     207             :         }
     208             : 
     209           0 :         status = dcerpc_samr_ChangePasswordUser2(h,
     210             :                                                  mem_ctx,
     211             :                                                  &server,
     212             :                                                  &account,
     213             :                                                  &new_nt_password,
     214             :                                                  &old_nt_hash_enc,
     215             :                                                  true,
     216             :                                                  &new_lm_password,
     217             :                                                  &old_lanman_hash_enc,
     218             :                                                  presult);
     219             : 
     220           0 : done:
     221           0 :         ZERO_STRUCT(new_nt_password);
     222           0 :         ZERO_STRUCT(new_lm_password);
     223           0 :         ZERO_STRUCT(old_nt_hash_enc);
     224           0 :         ZERO_STRUCT(old_lanman_hash_enc);
     225           0 :         ZERO_ARRAY(new_nt_hash);
     226           0 :         ZERO_ARRAY(new_lanman_hash);
     227           0 :         ZERO_ARRAY(old_nt_hash);
     228           0 :         ZERO_ARRAY(old_lanman_hash);
     229             : 
     230           0 :         return status;
     231             : }
     232             : 
     233           0 : NTSTATUS rpccli_samr_chgpasswd_user2(struct rpc_pipe_client *cli,
     234             :                                      TALLOC_CTX *mem_ctx,
     235             :                                      const char *username,
     236             :                                      const char *newpassword,
     237             :                                      const char *oldpassword)
     238             : {
     239           0 :         NTSTATUS status;
     240           0 :         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     241             : 
     242           0 :         status = dcerpc_samr_chgpasswd_user2(cli->binding_handle,
     243             :                                              mem_ctx,
     244           0 :                                              cli->srv_name_slash,
     245             :                                              username,
     246             :                                              newpassword,
     247             :                                              oldpassword,
     248             :                                              &result);
     249           0 :         if (!NT_STATUS_IS_OK(status)) {
     250           0 :                 return status;
     251             :         }
     252             : 
     253           0 :         return result;
     254             : }
     255             : 
     256             : /* User change password given blobs */
     257             : 
     258           0 : NTSTATUS dcerpc_samr_chng_pswd_auth_crap(struct dcerpc_binding_handle *h,
     259             :                                          TALLOC_CTX *mem_ctx,
     260             :                                          const char *srv_name_slash,
     261             :                                          const char *username,
     262             :                                          DATA_BLOB new_nt_password_blob,
     263             :                                          DATA_BLOB old_nt_hash_enc_blob,
     264             :                                          DATA_BLOB new_lm_password_blob,
     265             :                                          DATA_BLOB old_lm_hash_enc_blob,
     266             :                                          NTSTATUS *presult)
     267             : {
     268           0 :         NTSTATUS status;
     269           0 :         struct samr_CryptPassword new_nt_password;
     270           0 :         struct samr_CryptPassword new_lm_password;
     271           0 :         struct samr_Password old_nt_hash_enc;
     272           0 :         struct samr_Password old_lm_hash_enc;
     273           0 :         struct lsa_String server, account;
     274             : 
     275           0 :         DEBUG(10,("rpccli_samr_chng_pswd_auth_crap\n"));
     276             : 
     277           0 :         ZERO_STRUCT(new_nt_password);
     278           0 :         ZERO_STRUCT(new_lm_password);
     279           0 :         ZERO_STRUCT(old_nt_hash_enc);
     280           0 :         ZERO_STRUCT(old_lm_hash_enc);
     281             : 
     282           0 :         init_lsa_String(&server, srv_name_slash);
     283           0 :         init_lsa_String(&account, username);
     284             : 
     285           0 :         if (new_nt_password_blob.data && new_nt_password_blob.length >= 516) {
     286           0 :                 memcpy(&new_nt_password.data, new_nt_password_blob.data, 516);
     287             :         }
     288             : 
     289           0 :         if (new_lm_password_blob.data && new_lm_password_blob.length >= 516) {
     290           0 :                 memcpy(&new_lm_password.data, new_lm_password_blob.data, 516);
     291             :         }
     292             : 
     293           0 :         if (old_nt_hash_enc_blob.data && old_nt_hash_enc_blob.length >= 16) {
     294           0 :                 memcpy(&old_nt_hash_enc.hash, old_nt_hash_enc_blob.data, 16);
     295             :         }
     296             : 
     297           0 :         if (old_lm_hash_enc_blob.data && old_lm_hash_enc_blob.length >= 16) {
     298           0 :                 memcpy(&old_lm_hash_enc.hash, old_lm_hash_enc_blob.data, 16);
     299             :         }
     300             : 
     301           0 :         status = dcerpc_samr_ChangePasswordUser2(h,
     302             :                                                  mem_ctx,
     303             :                                                  &server,
     304             :                                                  &account,
     305             :                                                  &new_nt_password,
     306             :                                                  &old_nt_hash_enc,
     307             :                                                  true,
     308             :                                                  &new_lm_password,
     309             :                                                  &old_lm_hash_enc,
     310             :                                                  presult);
     311             : 
     312           0 :         return status;
     313             : }
     314             : 
     315           0 : NTSTATUS rpccli_samr_chng_pswd_auth_crap(struct rpc_pipe_client *cli,
     316             :                                          TALLOC_CTX *mem_ctx,
     317             :                                          const char *username,
     318             :                                          DATA_BLOB new_nt_password_blob,
     319             :                                          DATA_BLOB old_nt_hash_enc_blob,
     320             :                                          DATA_BLOB new_lm_password_blob,
     321             :                                          DATA_BLOB old_lm_hash_enc_blob)
     322             : {
     323           0 :         NTSTATUS status;
     324           0 :         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     325             : 
     326           0 :         status = dcerpc_samr_chng_pswd_auth_crap(cli->binding_handle,
     327             :                                                  mem_ctx,
     328           0 :                                                  cli->srv_name_slash,
     329             :                                                  username,
     330             :                                                  new_nt_password_blob,
     331             :                                                  old_nt_hash_enc_blob,
     332             :                                                  new_lm_password_blob,
     333             :                                                  old_lm_hash_enc_blob,
     334             :                                                  &result);
     335           0 :         if (!NT_STATUS_IS_OK(status)) {
     336           0 :                 return status;
     337             :         }
     338             : 
     339           0 :         return result;
     340             : }
     341             : 
     342             : /* change password 3 */
     343             : 
     344           0 : NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h,
     345             :                                      TALLOC_CTX *mem_ctx,
     346             :                                      const char *srv_name_slash,
     347             :                                      const char *username,
     348             :                                      const char *newpassword,
     349             :                                      const char *oldpassword,
     350             :                                      struct samr_DomInfo1 **dominfo1,
     351             :                                      struct userPwdChangeFailureInformation **reject,
     352             :                                      NTSTATUS *presult)
     353             : {
     354           0 :         NTSTATUS status;
     355           0 :         int rc;
     356             : 
     357           0 :         struct samr_CryptPassword new_nt_password;
     358           0 :         struct samr_CryptPassword new_lm_password;
     359           0 :         struct samr_Password old_nt_hash_enc;
     360           0 :         struct samr_Password old_lanman_hash_enc;
     361             : 
     362           0 :         uint8_t old_nt_hash[16] = { 0 };
     363           0 :         uint8_t old_lanman_hash[16];
     364           0 :         uint8_t new_nt_hash[16];
     365           0 :         uint8_t new_lanman_hash[16];
     366             : 
     367           0 :         struct lsa_String server, account;
     368             : 
     369           0 :         DATA_BLOB session_key = data_blob_const(old_nt_hash, 16);
     370             : 
     371           0 :         DEBUG(10,("rpccli_samr_chgpasswd_user3\n"));
     372             : 
     373           0 :         init_lsa_String(&server, srv_name_slash);
     374           0 :         init_lsa_String(&account, username);
     375             : 
     376             :         /* Calculate the MD4 hash (NT compatible) of the password */
     377           0 :         E_md4hash(oldpassword, old_nt_hash);
     378           0 :         E_md4hash(newpassword, new_nt_hash);
     379             : 
     380           0 :         if (lp_client_lanman_auth() &&
     381           0 :             E_deshash(newpassword, new_lanman_hash) &&
     382           0 :             E_deshash(oldpassword, old_lanman_hash)) {
     383             :                 /* E_deshash returns false for 'long' passwords (> 14
     384             :                    DOS chars).  This allows us to match Win2k, which
     385             :                    does not store a LM hash for these passwords (which
     386             :                    would reduce the effective password length to 14) */
     387           0 :                 status = init_samr_CryptPassword(newpassword,
     388             :                                                  &session_key,
     389             :                                                  &new_lm_password);
     390           0 :                 if (!NT_STATUS_IS_OK(status)) {
     391           0 :                         return status;
     392             :                 }
     393             : 
     394           0 :                 rc = E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash);
     395           0 :                 if (rc != 0) {
     396           0 :                         status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
     397           0 :                         goto done;
     398             :                 }
     399             :         } else {
     400           0 :                 ZERO_STRUCT(new_lm_password);
     401           0 :                 ZERO_STRUCT(old_lanman_hash_enc);
     402             :         }
     403             : 
     404           0 :         status = init_samr_CryptPassword(newpassword,
     405             :                                          &session_key,
     406             :                                          &new_nt_password);
     407           0 :         if (!NT_STATUS_IS_OK(status)) {
     408           0 :                 return status;
     409             :         }
     410             : 
     411           0 :         rc = E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
     412           0 :         if (rc != 0) {
     413           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
     414           0 :                 goto done;
     415             :         }
     416             : 
     417           0 :         status = dcerpc_samr_ChangePasswordUser3(h,
     418             :                                                  mem_ctx,
     419             :                                                  &server,
     420             :                                                  &account,
     421             :                                                  &new_nt_password,
     422             :                                                  &old_nt_hash_enc,
     423             :                                                  true,
     424             :                                                  &new_lm_password,
     425             :                                                  &old_lanman_hash_enc,
     426             :                                                  NULL,
     427             :                                                  dominfo1,
     428             :                                                  reject,
     429             :                                                  presult);
     430             : 
     431           0 : done:
     432           0 :         ZERO_STRUCT(new_nt_password);
     433           0 :         ZERO_STRUCT(new_lm_password);
     434           0 :         ZERO_STRUCT(old_nt_hash_enc);
     435           0 :         ZERO_STRUCT(old_lanman_hash_enc);
     436           0 :         ZERO_ARRAY(new_nt_hash);
     437           0 :         ZERO_ARRAY(new_lanman_hash);
     438           0 :         ZERO_ARRAY(old_nt_hash);
     439           0 :         ZERO_ARRAY(old_lanman_hash);
     440             : 
     441           0 :         return status;
     442             : }
     443             : 
     444           0 : NTSTATUS rpccli_samr_chgpasswd_user3(struct rpc_pipe_client *cli,
     445             :                                      TALLOC_CTX *mem_ctx,
     446             :                                      const char *username,
     447             :                                      const char *newpassword,
     448             :                                      const char *oldpassword,
     449             :                                      struct samr_DomInfo1 **dominfo1,
     450             :                                      struct userPwdChangeFailureInformation **reject)
     451             : {
     452           0 :         NTSTATUS status;
     453           0 :         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     454             : 
     455           0 :         status = dcerpc_samr_chgpasswd_user3(cli->binding_handle,
     456             :                                              mem_ctx,
     457           0 :                                              cli->srv_name_slash,
     458             :                                              username,
     459             :                                              newpassword,
     460             :                                              oldpassword,
     461             :                                              dominfo1,
     462             :                                              reject,
     463             :                                              &result);
     464           0 :         if (!NT_STATUS_IS_OK(status)) {
     465           0 :                 return status;
     466             :         }
     467             : 
     468           0 :         return result;
     469             : }
     470             : 
     471           6 : NTSTATUS dcerpc_samr_chgpasswd_user4(struct dcerpc_binding_handle *h,
     472             :                                      TALLOC_CTX *mem_ctx,
     473             :                                      const char *srv_name_slash,
     474             :                                      const char *username,
     475             :                                      const char *oldpassword,
     476             :                                      const char *newpassword,
     477             :                                      NTSTATUS *presult)
     478             : {
     479           0 :         struct lsa_String server, user_account;
     480           6 :         uint8_t old_nt_key_data[16] = {0};
     481           6 :         gnutls_datum_t old_nt_key = {
     482             :                 .data = old_nt_key_data,
     483             :                 .size = sizeof(old_nt_key),
     484             :         };
     485           6 :         struct samr_EncryptedPasswordAES pwd_buf = {
     486             :                 .cipher_len = 0,
     487             :         };
     488           6 :         DATA_BLOB iv = {
     489             :                 .data = pwd_buf.salt,
     490             :                 .length = sizeof(pwd_buf.salt),
     491             :         };
     492           6 :         gnutls_datum_t iv_datum = {
     493           6 :                 .data = iv.data,
     494           6 :                 .size = iv.length,
     495             :         };
     496           6 :         uint8_t cek_data[16] = {0};
     497           6 :         DATA_BLOB cek = {
     498             :                 .data = cek_data,
     499             :                 .length = sizeof(cek_data),
     500             :         };
     501           6 :         uint64_t pbkdf2_iterations = 0;
     502           6 :         uint8_t pw_data[514] = {0};
     503           6 :         DATA_BLOB plaintext = {
     504             :                 .data = pw_data,
     505             :                 .length = sizeof(pw_data),
     506             :         };
     507           6 :         DATA_BLOB ciphertext = data_blob_null;
     508           0 :         NTSTATUS status;
     509           0 :         bool ok;
     510           0 :         int rc;
     511             : 
     512           6 :         generate_nonce_buffer(iv.data, iv.length);
     513             : 
     514             :         /* Calculate the MD4 hash (NT compatible) of the password */
     515           6 :         E_md4hash(oldpassword, old_nt_key_data);
     516             : 
     517           6 :         init_lsa_String(&server, srv_name_slash);
     518           6 :         init_lsa_String(&user_account, username);
     519             : 
     520           6 :         pbkdf2_iterations = generate_random_u64_range(5000, 1000000);
     521             : 
     522           6 :         rc = gnutls_pbkdf2(GNUTLS_MAC_SHA512,
     523             :                            &old_nt_key,
     524             :                            &iv_datum,
     525             :                            pbkdf2_iterations,
     526           6 :                            cek.data,
     527             :                            cek.length);
     528           6 :         BURN_DATA(old_nt_key_data);
     529           6 :         if (rc < 0) {
     530           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_WRONG_PASSWORD);
     531           0 :                 return status;
     532             :         }
     533             : 
     534           6 :         ok = encode_pwd_buffer514_from_str(pw_data, newpassword, STR_UNICODE);
     535           6 :         if (!ok) {
     536           0 :                 return NT_STATUS_INTERNAL_ERROR;
     537             :         }
     538             : 
     539           6 :         status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt(
     540             :                 mem_ctx,
     541             :                 &plaintext,
     542             :                 &cek,
     543             :                 &samr_aes256_enc_key_salt,
     544             :                 &samr_aes256_mac_key_salt,
     545             :                 &iv,
     546             :                 &ciphertext,
     547             :                 pwd_buf.auth_data);
     548           6 :         BURN_DATA(pw_data);
     549           6 :         BURN_DATA(cek_data);
     550           6 :         if (!NT_STATUS_IS_OK(status)) {
     551           0 :                 return status;
     552             :         }
     553             : 
     554           6 :         pwd_buf.cipher_len = ciphertext.length;
     555           6 :         pwd_buf.cipher = ciphertext.data;
     556           6 :         pwd_buf.PBKDF2Iterations = pbkdf2_iterations;
     557             : 
     558           6 :         status = dcerpc_samr_ChangePasswordUser4(h,
     559             :                                                  mem_ctx,
     560             :                                                  &server,
     561             :                                                  &user_account,
     562             :                                                  &pwd_buf,
     563             :                                                  presult);
     564           6 :         data_blob_free(&ciphertext);
     565             : 
     566           6 :         return status;
     567             : }
     568             : 
     569             : /* This function returns the bizarre set of (max_entries, max_size) required
     570             :    for the QueryDisplayInfo RPC to actually work against a domain controller
     571             :    with large (10k and higher) numbers of users.  These values were
     572             :    obtained by inspection using ethereal and NT4 running User Manager. */
     573             : 
     574           0 : void dcerpc_get_query_dispinfo_params(int loop_count,
     575             :                                       uint32_t *max_entries,
     576             :                                       uint32_t *max_size)
     577             : {
     578           0 :         switch(loop_count) {
     579           0 :         case 0:
     580           0 :                 *max_entries = 512;
     581           0 :                 *max_size = 16383;
     582           0 :                 break;
     583           0 :         case 1:
     584           0 :                 *max_entries = 1024;
     585           0 :                 *max_size = 32766;
     586           0 :                 break;
     587           0 :         case 2:
     588           0 :                 *max_entries = 2048;
     589           0 :                 *max_size = 65532;
     590           0 :                 break;
     591           0 :         case 3:
     592           0 :                 *max_entries = 4096;
     593           0 :                 *max_size = 131064;
     594           0 :                 break;
     595           0 :         default:              /* loop_count >= 4 */
     596           0 :                 *max_entries = 4096;
     597           0 :                 *max_size = 131071;
     598           0 :                 break;
     599             :         }
     600           0 : }
     601             : 
     602          82 : NTSTATUS dcerpc_try_samr_connects(struct dcerpc_binding_handle *h,
     603             :                                   TALLOC_CTX *mem_ctx,
     604             :                                   const char *srv_name_slash,
     605             :                                   uint32_t access_mask,
     606             :                                   struct policy_handle *connect_pol,
     607             :                                   NTSTATUS *presult)
     608             : {
     609           0 :         NTSTATUS status;
     610           0 :         union samr_ConnectInfo info_in, info_out;
     611           0 :         struct samr_ConnectInfo1 info1;
     612          82 :         uint32_t lvl_out = 0;
     613             : 
     614          82 :         ZERO_STRUCT(info1);
     615             : 
     616          82 :         info1.client_version = SAMR_CONNECT_W2K;
     617          82 :         info_in.info1 = info1;
     618             : 
     619          82 :         status = dcerpc_samr_Connect5(h,
     620             :                                       mem_ctx,
     621             :                                       srv_name_slash,
     622             :                                       access_mask,
     623             :                                       1,
     624             :                                       &info_in,
     625             :                                       &lvl_out,
     626             :                                       &info_out,
     627             :                                       connect_pol,
     628             :                                       presult);
     629          82 :         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(*presult)) {
     630          82 :                 return status;
     631             :         }
     632             : 
     633           0 :         status = dcerpc_samr_Connect4(h,
     634             :                                       mem_ctx,
     635             :                                       srv_name_slash,
     636             :                                       SAMR_CONNECT_W2K,
     637             :                                       access_mask,
     638             :                                       connect_pol,
     639             :                                       presult);
     640           0 :         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(*presult)) {
     641           0 :                 return status;
     642             :         }
     643             : 
     644           0 :         status = dcerpc_samr_Connect2(h,
     645             :                                       mem_ctx,
     646             :                                       srv_name_slash,
     647             :                                       access_mask,
     648             :                                       connect_pol,
     649             :                                       presult);
     650             : 
     651           0 :         return status;
     652             : }
     653             : 
     654             : /* vim: set ts=8 sw=8 noet cindent: */

Generated by: LCOV version 1.14