LCOV - code coverage report
Current view: top level - source3/rpc_client - cli_samr.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 76 238 31.9 %
Date: 2024-06-13 04:01:37 Functions: 4 11 36.4 %

          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             :         NTSTATUS status;
      46             :         int rc;
      47             :         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             :         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           2 : 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             :         NTSTATUS status;
     150             :         int rc;
     151             :         struct samr_CryptPassword new_nt_password;
     152             :         struct samr_CryptPassword new_lm_password;
     153             :         struct samr_Password old_nt_hash_enc;
     154             :         struct samr_Password old_lanman_hash_enc;
     155             : 
     156           2 :         uint8_t old_nt_hash[16] = { 0 };
     157             :         uint8_t old_lanman_hash[16];
     158             :         uint8_t new_nt_hash[16];
     159             :         uint8_t new_lanman_hash[16];
     160             :         struct lsa_String server, account;
     161             : 
     162           2 :         DATA_BLOB session_key = data_blob_const(old_nt_hash, 16);
     163             : 
     164           2 :         DEBUG(10,("rpccli_samr_chgpasswd_user2\n"));
     165             : 
     166           2 :         init_lsa_String(&server, srv_name_slash);
     167           2 :         init_lsa_String(&account, username);
     168             : 
     169             :         /* Calculate the MD4 hash (NT compatible) of the password */
     170           2 :         E_md4hash(oldpassword, old_nt_hash);
     171           2 :         E_md4hash(newpassword, new_nt_hash);
     172             : 
     173           2 :         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           2 :                 ZERO_STRUCT(new_lm_password);
     194           2 :                 ZERO_STRUCT(old_lanman_hash_enc);
     195             :         }
     196             : 
     197           2 :         status = init_samr_CryptPassword(newpassword,
     198             :                                          &session_key,
     199             :                                          &new_nt_password);
     200           2 :         if (!NT_STATUS_IS_OK(status)) {
     201           0 :                 return status;
     202             :         }
     203           2 :         rc = E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash);
     204           2 :         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           2 :         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           2 : done:
     221           2 :         ZERO_STRUCT(new_nt_password);
     222           2 :         ZERO_STRUCT(new_lm_password);
     223           2 :         ZERO_STRUCT(old_nt_hash_enc);
     224           2 :         ZERO_STRUCT(old_lanman_hash_enc);
     225           2 :         ZERO_ARRAY(new_nt_hash);
     226           2 :         ZERO_ARRAY(new_lanman_hash);
     227           2 :         ZERO_ARRAY(old_nt_hash);
     228           2 :         ZERO_ARRAY(old_lanman_hash);
     229             : 
     230           2 :         return status;
     231             : }
     232             : 
     233           2 : 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             :         NTSTATUS status;
     240           2 :         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
     241             : 
     242           2 :         status = dcerpc_samr_chgpasswd_user2(cli->binding_handle,
     243             :                                              mem_ctx,
     244           2 :                                              cli->srv_name_slash,
     245             :                                              username,
     246             :                                              newpassword,
     247             :                                              oldpassword,
     248             :                                              &result);
     249           2 :         if (!NT_STATUS_IS_OK(status)) {
     250           0 :                 return status;
     251             :         }
     252             : 
     253           2 :         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             :         NTSTATUS status;
     269             :         struct samr_CryptPassword new_nt_password;
     270             :         struct samr_CryptPassword new_lm_password;
     271             :         struct samr_Password old_nt_hash_enc;
     272             :         struct samr_Password old_lm_hash_enc;
     273             :         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             :         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             :         NTSTATUS status;
     355             :         int rc;
     356             : 
     357             :         struct samr_CryptPassword new_nt_password;
     358             :         struct samr_CryptPassword new_lm_password;
     359             :         struct samr_Password old_nt_hash_enc;
     360             :         struct samr_Password old_lanman_hash_enc;
     361             : 
     362           0 :         uint8_t old_nt_hash[16] = { 0 };
     363             :         uint8_t old_lanman_hash[16];
     364             :         uint8_t new_nt_hash[16];
     365             :         uint8_t new_lanman_hash[16];
     366             : 
     367             :         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             :         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           3 : 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             : #ifdef HAVE_GNUTLS_PBKDF2
     480             :         struct lsa_String server, user_account;
     481           1 :         uint8_t old_nt_key_data[16] = {0};
     482           1 :         gnutls_datum_t old_nt_key = {
     483             :                 .data = old_nt_key_data,
     484             :                 .size = sizeof(old_nt_key),
     485             :         };
     486           1 :         struct samr_EncryptedPasswordAES pwd_buf = {
     487             :                 .cipher_len = 0,
     488             :         };
     489           1 :         DATA_BLOB iv = {
     490             :                 .data = pwd_buf.salt,
     491             :                 .length = sizeof(pwd_buf.salt),
     492             :         };
     493           1 :         gnutls_datum_t iv_datum = {
     494           1 :                 .data = iv.data,
     495           1 :                 .size = iv.length,
     496             :         };
     497           1 :         uint8_t cek_data[16] = {0};
     498           1 :         DATA_BLOB cek = {
     499             :                 .data = cek_data,
     500             :                 .length = sizeof(cek_data),
     501             :         };
     502           1 :         uint64_t pbkdf2_iterations = 0;
     503           1 :         uint8_t pw_data[514] = {0};
     504           1 :         DATA_BLOB plaintext = {
     505             :                 .data = pw_data,
     506             :                 .length = sizeof(pw_data),
     507             :         };
     508           1 :         DATA_BLOB ciphertext = data_blob_null;
     509             :         NTSTATUS status;
     510             :         bool ok;
     511             :         int rc;
     512             : 
     513           1 :         generate_nonce_buffer(iv.data, iv.length);
     514             : 
     515             :         /* Calculate the MD4 hash (NT compatible) of the password */
     516           1 :         E_md4hash(oldpassword, old_nt_key_data);
     517             : 
     518           1 :         init_lsa_String(&server, srv_name_slash);
     519           1 :         init_lsa_String(&user_account, username);
     520             : 
     521           1 :         pbkdf2_iterations = generate_random_u64_range(5000, 1000000);
     522             : 
     523           1 :         rc = gnutls_pbkdf2(GNUTLS_MAC_SHA512,
     524             :                            &old_nt_key,
     525             :                            &iv_datum,
     526             :                            pbkdf2_iterations,
     527           1 :                            cek.data,
     528             :                            cek.length);
     529           1 :         BURN_DATA(old_nt_key_data);
     530           1 :         if (rc < 0) {
     531           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_WRONG_PASSWORD);
     532           0 :                 return status;
     533             :         }
     534             : 
     535           1 :         ok = encode_pwd_buffer514_from_str(pw_data, newpassword, STR_UNICODE);
     536           1 :         if (!ok) {
     537           0 :                 return NT_STATUS_INTERNAL_ERROR;
     538             :         }
     539             : 
     540           1 :         status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_encrypt(
     541             :                 mem_ctx,
     542             :                 &plaintext,
     543             :                 &cek,
     544             :                 &samr_aes256_enc_key_salt,
     545             :                 &samr_aes256_mac_key_salt,
     546             :                 &iv,
     547             :                 &ciphertext,
     548             :                 pwd_buf.auth_data);
     549           1 :         BURN_DATA(pw_data);
     550           1 :         BURN_DATA(cek_data);
     551           1 :         if (!NT_STATUS_IS_OK(status)) {
     552           0 :                 return status;
     553             :         }
     554             : 
     555           1 :         pwd_buf.cipher_len = ciphertext.length;
     556           1 :         pwd_buf.cipher = ciphertext.data;
     557           1 :         pwd_buf.PBKDF2Iterations = pbkdf2_iterations;
     558             : 
     559           1 :         status = dcerpc_samr_ChangePasswordUser4(h,
     560             :                                                  mem_ctx,
     561             :                                                  &server,
     562             :                                                  &user_account,
     563             :                                                  &pwd_buf,
     564             :                                                  presult);
     565           1 :         data_blob_free(&ciphertext);
     566             : 
     567           1 :         return status;
     568             : #else /* HAVE_GNUTLS_PBKDF2 */
     569           2 :         return NT_STATUS_NOT_IMPLEMENTED;
     570             : #endif /* HAVE_GNUTLS_PBKDF2 */
     571             : }
     572             : 
     573             : /* This function returns the bizzare set of (max_entries, max_size) required
     574             :    for the QueryDisplayInfo RPC to actually work against a domain controller
     575             :    with large (10k and higher) numbers of users.  These values were
     576             :    obtained by inspection using ethereal and NT4 running User Manager. */
     577             : 
     578           0 : void dcerpc_get_query_dispinfo_params(int loop_count,
     579             :                                       uint32_t *max_entries,
     580             :                                       uint32_t *max_size)
     581             : {
     582           0 :         switch(loop_count) {
     583           0 :         case 0:
     584           0 :                 *max_entries = 512;
     585           0 :                 *max_size = 16383;
     586           0 :                 break;
     587           0 :         case 1:
     588           0 :                 *max_entries = 1024;
     589           0 :                 *max_size = 32766;
     590           0 :                 break;
     591           0 :         case 2:
     592           0 :                 *max_entries = 2048;
     593           0 :                 *max_size = 65532;
     594           0 :                 break;
     595           0 :         case 3:
     596           0 :                 *max_entries = 4096;
     597           0 :                 *max_size = 131064;
     598           0 :                 break;
     599           0 :         default:              /* loop_count >= 4 */
     600           0 :                 *max_entries = 4096;
     601           0 :                 *max_size = 131071;
     602           0 :                 break;
     603             :         }
     604           0 : }
     605             : 
     606          76 : NTSTATUS dcerpc_try_samr_connects(struct dcerpc_binding_handle *h,
     607             :                                   TALLOC_CTX *mem_ctx,
     608             :                                   const char *srv_name_slash,
     609             :                                   uint32_t access_mask,
     610             :                                   struct policy_handle *connect_pol,
     611             :                                   NTSTATUS *presult)
     612             : {
     613             :         NTSTATUS status;
     614             :         union samr_ConnectInfo info_in, info_out;
     615             :         struct samr_ConnectInfo1 info1;
     616          76 :         uint32_t lvl_out = 0;
     617             : 
     618          76 :         ZERO_STRUCT(info1);
     619             : 
     620          76 :         info1.client_version = SAMR_CONNECT_W2K;
     621          76 :         info_in.info1 = info1;
     622             : 
     623          76 :         status = dcerpc_samr_Connect5(h,
     624             :                                       mem_ctx,
     625             :                                       srv_name_slash,
     626             :                                       access_mask,
     627             :                                       1,
     628             :                                       &info_in,
     629             :                                       &lvl_out,
     630             :                                       &info_out,
     631             :                                       connect_pol,
     632             :                                       presult);
     633          76 :         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(*presult)) {
     634          76 :                 return status;
     635             :         }
     636             : 
     637           0 :         status = dcerpc_samr_Connect4(h,
     638             :                                       mem_ctx,
     639             :                                       srv_name_slash,
     640             :                                       SAMR_CONNECT_W2K,
     641             :                                       access_mask,
     642             :                                       connect_pol,
     643             :                                       presult);
     644           0 :         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(*presult)) {
     645           0 :                 return status;
     646             :         }
     647             : 
     648           0 :         status = dcerpc_samr_Connect2(h,
     649             :                                       mem_ctx,
     650             :                                       srv_name_slash,
     651             :                                       access_mask,
     652             :                                       connect_pol,
     653             :                                       presult);
     654             : 
     655           0 :         return status;
     656             : }
     657             : 
     658             : /* vim: set ts=8 sw=8 noet cindent: */

Generated by: LCOV version 1.13