LCOV - code coverage report
Current view: top level - source3/rpc_client - cli_netlogon.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 170 350 48.6 %
Date: 2021-09-23 10:06:22 Functions: 7 9 77.8 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    NT Domain Authentication SMB / MSRPC client
       4             :    Copyright (C) Andrew Tridgell 1992-2000
       5             :    Copyright (C) Jeremy Allison                    1998.
       6             :    Largely re-written by Jeremy Allison (C)        2005.
       7             :    Copyright (C) Guenther Deschner                 2008.
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "system/filesys.h"
      25             : #include "libsmb/libsmb.h"
      26             : #include "rpc_client/rpc_client.h"
      27             : #include "rpc_client/cli_pipe.h"
      28             : #include "../libcli/auth/libcli_auth.h"
      29             : #include "../libcli/auth/netlogon_creds_cli.h"
      30             : #include "../librpc/gen_ndr/ndr_netlogon_c.h"
      31             : #include "../librpc/gen_ndr/schannel.h"
      32             : #include "rpc_client/cli_netlogon.h"
      33             : #include "rpc_client/util_netlogon.h"
      34             : #include "../libcli/security/security.h"
      35             : #include "lib/param/param.h"
      36             : #include "libcli/smb/smbXcli_base.h"
      37             : #include "dbwrap/dbwrap.h"
      38             : #include "dbwrap/dbwrap_open.h"
      39             : #include "util_tdb.h"
      40             : #include "lib/crypto/gnutls_helpers.h"
      41             : 
      42             : 
      43         193 : NTSTATUS rpccli_pre_open_netlogon_creds(void)
      44             : {
      45             :         static bool already_open = false;
      46             :         TALLOC_CTX *frame;
      47             :         struct loadparm_context *lp_ctx;
      48             :         char *fname;
      49             :         struct db_context *global_db;
      50             :         NTSTATUS status;
      51             : 
      52         193 :         if (already_open) {
      53          11 :                 return NT_STATUS_OK;
      54             :         }
      55             : 
      56         182 :         frame = talloc_stackframe();
      57             : 
      58         182 :         lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
      59         182 :         if (lp_ctx == NULL) {
      60           0 :                 TALLOC_FREE(frame);
      61           0 :                 return NT_STATUS_NO_MEMORY;
      62             :         }
      63             : 
      64         182 :         fname = lpcfg_private_db_path(frame, lp_ctx, "netlogon_creds_cli");
      65         182 :         if (fname == NULL) {
      66           0 :                 TALLOC_FREE(frame);
      67           0 :                 return NT_STATUS_NO_MEMORY;
      68             :         }
      69             : 
      70         182 :         global_db = db_open(frame, fname,
      71             :                             0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH,
      72             :                             O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_2,
      73             :                             DBWRAP_FLAG_OPTIMIZE_READONLY_ACCESS);
      74         182 :         if (global_db == NULL) {
      75           0 :                 TALLOC_FREE(frame);
      76           0 :                 return NT_STATUS_NO_MEMORY;
      77             :         }
      78             : 
      79         182 :         status = netlogon_creds_cli_set_global_db(&global_db);
      80         182 :         TALLOC_FREE(frame);
      81         182 :         if (!NT_STATUS_IS_OK(status)) {
      82           0 :                 return status;
      83             :         }
      84             : 
      85         182 :         already_open = true;
      86         182 :         return NT_STATUS_OK;
      87             : }
      88             : 
      89         120 : static NTSTATUS rpccli_create_netlogon_creds(
      90             :         const char *server_computer,
      91             :         const char *server_netbios_domain,
      92             :         const char *server_dns_domain,
      93             :         const char *client_account,
      94             :         enum netr_SchannelType sec_chan_type,
      95             :         struct messaging_context *msg_ctx,
      96             :         TALLOC_CTX *mem_ctx,
      97             :         struct netlogon_creds_cli_context **netlogon_creds)
      98             : {
      99         120 :         TALLOC_CTX *frame = talloc_stackframe();
     100             :         struct loadparm_context *lp_ctx;
     101             :         NTSTATUS status;
     102             : 
     103         120 :         status = rpccli_pre_open_netlogon_creds();
     104         120 :         if (!NT_STATUS_IS_OK(status)) {
     105           0 :                 TALLOC_FREE(frame);
     106           0 :                 return status;
     107             :         }
     108             : 
     109         120 :         lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
     110         120 :         if (lp_ctx == NULL) {
     111           0 :                 TALLOC_FREE(frame);
     112           0 :                 return NT_STATUS_NO_MEMORY;
     113             :         }
     114         120 :         status = netlogon_creds_cli_context_global(lp_ctx,
     115             :                                                    msg_ctx,
     116             :                                                    client_account,
     117             :                                                    sec_chan_type,
     118             :                                                    server_computer,
     119             :                                                    server_netbios_domain,
     120             :                                                    server_dns_domain,
     121             :                                                    mem_ctx, netlogon_creds);
     122         120 :         TALLOC_FREE(frame);
     123         120 :         if (!NT_STATUS_IS_OK(status)) {
     124           0 :                 return status;
     125             :         }
     126             : 
     127         120 :         return NT_STATUS_OK;
     128             : }
     129             : 
     130         120 : NTSTATUS rpccli_create_netlogon_creds_ctx(
     131             :         struct cli_credentials *creds,
     132             :         const char *server_computer,
     133             :         struct messaging_context *msg_ctx,
     134             :         TALLOC_CTX *mem_ctx,
     135             :         struct netlogon_creds_cli_context **creds_ctx)
     136             : {
     137             :         enum netr_SchannelType sec_chan_type;
     138             :         const char *server_netbios_domain;
     139             :         const char *server_dns_domain;
     140             :         const char *client_account;
     141             : 
     142         120 :         sec_chan_type = cli_credentials_get_secure_channel_type(creds);
     143         120 :         client_account = cli_credentials_get_username(creds);
     144         120 :         server_netbios_domain = cli_credentials_get_domain(creds);
     145         120 :         server_dns_domain = cli_credentials_get_realm(creds);
     146             : 
     147         120 :         return rpccli_create_netlogon_creds(server_computer,
     148             :                                             server_netbios_domain,
     149             :                                             server_dns_domain,
     150             :                                             client_account,
     151             :                                             sec_chan_type,
     152             :                                             msg_ctx, mem_ctx,
     153             :                                             creds_ctx);
     154             : }
     155             : 
     156         118 : NTSTATUS rpccli_setup_netlogon_creds_locked(
     157             :         struct cli_state *cli,
     158             :         enum dcerpc_transport_t transport,
     159             :         struct netlogon_creds_cli_context *creds_ctx,
     160             :         bool force_reauth,
     161             :         struct cli_credentials *cli_creds,
     162             :         uint32_t *negotiate_flags)
     163             : {
     164         118 :         TALLOC_CTX *frame = talloc_stackframe();
     165         118 :         struct rpc_pipe_client *netlogon_pipe = NULL;
     166         118 :         struct netlogon_creds_CredentialState *creds = NULL;
     167         118 :         uint8_t num_nt_hashes = 0;
     168         118 :         const struct samr_Password *nt_hashes[2] = { NULL, NULL };
     169         118 :         uint8_t idx_nt_hashes = 0;
     170             :         NTSTATUS status;
     171             : 
     172         118 :         status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
     173         118 :         if (NT_STATUS_IS_OK(status)) {
     174          41 :                 const char *action = "using";
     175             : 
     176          41 :                 if (force_reauth) {
     177          12 :                         action = "overwrite";
     178             :                 }
     179             : 
     180          41 :                 DEBUG(5,("%s: %s cached netlogon_creds cli[%s/%s] to %s\n",
     181             :                          __FUNCTION__, action,
     182             :                          creds->account_name, creds->computer_name,
     183             :                          smbXcli_conn_remote_name(cli->conn)));
     184          41 :                 if (!force_reauth) {
     185          29 :                         goto done;
     186             :                 }
     187          12 :                 TALLOC_FREE(creds);
     188             :         }
     189             : 
     190          89 :         nt_hashes[0] = cli_credentials_get_nt_hash(cli_creds, talloc_tos());
     191          89 :         if (nt_hashes[0] == NULL) {
     192           0 :                 TALLOC_FREE(frame);
     193           0 :                 return NT_STATUS_NO_MEMORY;
     194             :         }
     195          89 :         num_nt_hashes = 1;
     196             : 
     197          89 :         nt_hashes[1] = cli_credentials_get_old_nt_hash(cli_creds,
     198             :                                                        talloc_tos());
     199          89 :         if (nt_hashes[1] != NULL) {
     200           0 :                 num_nt_hashes = 2;
     201             :         }
     202             : 
     203          89 :         status = cli_rpc_pipe_open_noauth_transport(cli,
     204             :                                                     transport,
     205             :                                                     &ndr_table_netlogon,
     206             :                                                     &netlogon_pipe);
     207          89 :         if (!NT_STATUS_IS_OK(status)) {
     208           0 :                 DEBUG(5,("%s: failed to open noauth netlogon connection to %s - %s\n",
     209             :                          __FUNCTION__,
     210             :                          smbXcli_conn_remote_name(cli->conn),
     211             :                          nt_errstr(status)));
     212           0 :                 TALLOC_FREE(frame);
     213           0 :                 return status;
     214             :         }
     215          89 :         talloc_steal(frame, netlogon_pipe);
     216             : 
     217         158 :         status = netlogon_creds_cli_auth(creds_ctx,
     218          89 :                                          netlogon_pipe->binding_handle,
     219             :                                          num_nt_hashes,
     220             :                                          nt_hashes,
     221             :                                          &idx_nt_hashes);
     222          89 :         if (!NT_STATUS_IS_OK(status)) {
     223           7 :                 TALLOC_FREE(frame);
     224           7 :                 return status;
     225             :         }
     226             : 
     227          82 :         status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
     228          82 :         if (!NT_STATUS_IS_OK(status)) {
     229           0 :                 TALLOC_FREE(frame);
     230           0 :                 return NT_STATUS_INTERNAL_ERROR;
     231             :         }
     232             : 
     233          82 :         DEBUG(5,("%s: using new netlogon_creds cli[%s/%s] to %s\n",
     234             :                  __FUNCTION__,
     235             :                  creds->account_name, creds->computer_name,
     236             :                  smbXcli_conn_remote_name(cli->conn)));
     237             : 
     238         111 : done:
     239         111 :         if (negotiate_flags != NULL) {
     240           0 :                 *negotiate_flags = creds->negotiate_flags;
     241             :         }
     242             : 
     243         111 :         TALLOC_FREE(frame);
     244         111 :         return NT_STATUS_OK;
     245             : }
     246             : 
     247         118 : NTSTATUS rpccli_setup_netlogon_creds(
     248             :         struct cli_state *cli,
     249             :         enum dcerpc_transport_t transport,
     250             :         struct netlogon_creds_cli_context *creds_ctx,
     251             :         bool force_reauth,
     252             :         struct cli_credentials *cli_creds)
     253             : {
     254         118 :         TALLOC_CTX *frame = talloc_stackframe();
     255             :         struct netlogon_creds_cli_lck *lck;
     256             :         NTSTATUS status;
     257             : 
     258         118 :         status = netlogon_creds_cli_lck(
     259             :                 creds_ctx, NETLOGON_CREDS_CLI_LCK_EXCLUSIVE,
     260             :                 frame, &lck);
     261         118 :         if (!NT_STATUS_IS_OK(status)) {
     262           0 :                 DBG_WARNING("netlogon_creds_cli_lck failed: %s\n",
     263             :                             nt_errstr(status));
     264           0 :                 TALLOC_FREE(frame);
     265           0 :                 return status;
     266             :         }
     267             : 
     268         118 :         status = rpccli_setup_netlogon_creds_locked(
     269             :                 cli, transport, creds_ctx, force_reauth, cli_creds, NULL);
     270             : 
     271         118 :         TALLOC_FREE(frame);
     272             : 
     273         118 :         return status;
     274             : }
     275             : 
     276           2 : NTSTATUS rpccli_connect_netlogon(
     277             :         struct cli_state *cli,
     278             :         enum dcerpc_transport_t transport,
     279             :         struct netlogon_creds_cli_context *creds_ctx,
     280             :         bool force_reauth,
     281             :         struct cli_credentials *trust_creds,
     282             :         struct rpc_pipe_client **_rpccli)
     283             : {
     284           2 :         TALLOC_CTX *frame = talloc_stackframe();
     285           2 :         struct netlogon_creds_CredentialState *creds = NULL;
     286             :         enum netlogon_creds_cli_lck_type lck_type;
     287             :         enum netr_SchannelType sec_chan_type;
     288           2 :         struct netlogon_creds_cli_lck *lck = NULL;
     289             :         uint32_t negotiate_flags;
     290           2 :         uint8_t found_session_key[16] = {0};
     291           2 :         bool found_existing_creds = false;
     292             :         bool do_serverauth;
     293             :         struct rpc_pipe_client *rpccli;
     294             :         NTSTATUS status;
     295           2 :         bool retry = false;
     296             : 
     297           2 :         sec_chan_type = cli_credentials_get_secure_channel_type(trust_creds);
     298           2 :         if (sec_chan_type == SEC_CHAN_NULL) {
     299           0 :                 DBG_ERR("secure_channel_type gave SEC_CHAN_NULL\n");
     300           0 :                 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     301           0 :                 goto fail;
     302             :         }
     303             : 
     304           2 : again:
     305             : 
     306             :         /*
     307             :          * See whether we can use existing netlogon_creds or
     308             :          * whether we have to serverauthenticate.
     309             :          */
     310           2 :         status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
     311             : 
     312           2 :         if (NT_STATUS_IS_OK(status)) {
     313           2 :                 int cmp = memcmp(found_session_key,
     314           2 :                                  creds->session_key,
     315             :                                  sizeof(found_session_key));
     316           2 :                 found_existing_creds = (cmp != 0);
     317             : 
     318           2 :                 memcpy(found_session_key,
     319           2 :                        creds->session_key,
     320             :                        sizeof(found_session_key));
     321             : 
     322           2 :                 TALLOC_FREE(creds);
     323             :         }
     324             : 
     325           3 :         lck_type = (force_reauth || !found_existing_creds) ?
     326           3 :                 NETLOGON_CREDS_CLI_LCK_EXCLUSIVE :
     327             :                 NETLOGON_CREDS_CLI_LCK_SHARED;
     328             : 
     329           2 :         status = netlogon_creds_cli_lck(creds_ctx, lck_type, frame, &lck);
     330           2 :         if (!NT_STATUS_IS_OK(status)) {
     331           0 :                 DBG_DEBUG("netlogon_creds_cli_lck failed: %s\n",
     332             :                           nt_errstr(status));
     333           0 :                 goto fail;
     334             :         }
     335             : 
     336           2 :         if (!found_existing_creds) {
     337             :                 /*
     338             :                  * Try to find creds under the lock again. Someone
     339             :                  * else might have done it for us.
     340             :                  */
     341           0 :                 status = netlogon_creds_cli_get(creds_ctx, frame, &creds);
     342             : 
     343           0 :                 if (NT_STATUS_IS_OK(status)) {
     344           0 :                         int cmp = memcmp(found_session_key,
     345           0 :                                          creds->session_key,
     346             :                                          sizeof(found_session_key));
     347           0 :                         found_existing_creds = (cmp != 0);
     348             : 
     349           0 :                         memcpy(found_session_key, creds->session_key,
     350             :                                sizeof(found_session_key));
     351             : 
     352           0 :                         TALLOC_FREE(creds);
     353             :                 }
     354             :         }
     355             : 
     356           2 :         do_serverauth = force_reauth || !found_existing_creds;
     357             : 
     358           2 :         if (!do_serverauth) {
     359             :                 /*
     360             :                  * Do the quick schannel bind without a reauth
     361             :                  */
     362           2 :                 status = cli_rpc_pipe_open_bind_schannel(
     363             :                         cli, &ndr_table_netlogon, transport, creds_ctx,
     364             :                         &rpccli);
     365           2 :                 if (!retry && NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
     366           0 :                         DBG_DEBUG("Retrying with serverauthenticate\n");
     367           0 :                         TALLOC_FREE(lck);
     368           0 :                         retry = true;
     369           0 :                         goto again;
     370             :                 }
     371           2 :                 if (!NT_STATUS_IS_OK(status)) {
     372           0 :                         DBG_DEBUG("cli_rpc_pipe_open_bind_schannel "
     373             :                                   "failed: %s\n", nt_errstr(status));
     374           0 :                         goto fail;
     375             :                 }
     376           2 :                 goto done;
     377             :         }
     378             : 
     379           0 :         if (cli_credentials_is_anonymous(trust_creds)) {
     380           0 :                 DBG_WARNING("get_trust_credential for %s only gave anonymous,"
     381             :                             "unable to negotiate NETLOGON credentials\n",
     382             :                             netlogon_creds_cli_debug_string(
     383             :                                     creds_ctx, frame));
     384           0 :                 status = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     385           0 :                 goto fail;
     386             :         }
     387             : 
     388           0 :         status = rpccli_setup_netlogon_creds_locked(
     389             :                 cli, transport, creds_ctx, true, trust_creds,
     390             :                 &negotiate_flags);
     391           0 :         if (!NT_STATUS_IS_OK(status)) {
     392           0 :                 DBG_DEBUG("rpccli_setup_netlogon_creds failed for %s, "
     393             :                           "unable to setup NETLOGON credentials: %s\n",
     394             :                           netlogon_creds_cli_debug_string(
     395             :                                   creds_ctx, frame),
     396             :                           nt_errstr(status));
     397           0 :                 goto fail;
     398             :         }
     399             : 
     400           0 :         if (!(negotiate_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
     401           0 :                 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
     402           0 :                         status = NT_STATUS_DOWNGRADE_DETECTED;
     403           0 :                         DBG_WARNING("Unwilling to make connection to %s"
     404             :                                     "without connection level security, "
     405             :                                     "must set 'winbind sealed pipes = false'"
     406             :                                     " and 'require strong key = false' "
     407             :                                     "to proceed: %s\n",
     408             :                                     netlogon_creds_cli_debug_string(
     409             :                                             creds_ctx, frame),
     410             :                                     nt_errstr(status));
     411           0 :                         goto fail;
     412             :                 }
     413             : 
     414           0 :                 status = cli_rpc_pipe_open_noauth_transport(
     415             :                         cli, transport, &ndr_table_netlogon, &rpccli);
     416           0 :                 if (!NT_STATUS_IS_OK(status)) {
     417           0 :                         DBG_DEBUG("cli_rpc_pipe_open_noauth_transport "
     418             :                                   "failed: %s\n", nt_errstr(status));
     419           0 :                         goto fail;
     420             :                 }
     421           0 :                 goto done;
     422             :         }
     423             : 
     424           0 :         status = cli_rpc_pipe_open_bind_schannel(
     425             :                 cli, &ndr_table_netlogon, transport, creds_ctx, &rpccli);
     426           0 :         if (!NT_STATUS_IS_OK(status)) {
     427           0 :                 DBG_DEBUG("cli_rpc_pipe_open_bind_schannel "
     428             :                           "failed: %s\n", nt_errstr(status));
     429           0 :                 goto fail;
     430             :         }
     431             : 
     432           0 :         status = netlogon_creds_cli_check(creds_ctx, rpccli->binding_handle,
     433             :                                           NULL);
     434           0 :         if (!NT_STATUS_IS_OK(status)) {
     435           0 :                 DBG_WARNING("netlogon_creds_cli_check failed: %s\n",
     436             :                             nt_errstr(status));
     437           0 :                 goto fail;
     438             :         }
     439             : 
     440           0 : done:
     441           2 :         *_rpccli = rpccli;
     442           2 :         status = NT_STATUS_OK;
     443           2 : fail:
     444           2 :         ZERO_STRUCT(found_session_key);
     445           2 :         TALLOC_FREE(lck);
     446           2 :         TALLOC_FREE(frame);
     447           2 :         return status;
     448             : }
     449             : 
     450             : /* Logon domain user */
     451             : 
     452          42 : NTSTATUS rpccli_netlogon_password_logon(
     453             :         struct netlogon_creds_cli_context *creds_ctx,
     454             :         struct dcerpc_binding_handle *binding_handle,
     455             :         TALLOC_CTX *mem_ctx,
     456             :         uint32_t logon_parameters,
     457             :         const char *domain,
     458             :         const char *username,
     459             :         const char *password,
     460             :         const char *workstation,
     461             :         const uint64_t logon_id,
     462             :         enum netr_LogonInfoClass logon_type,
     463             :         uint8_t *authoritative,
     464             :         uint32_t *flags,
     465             :         uint16_t *_validation_level,
     466             :         union netr_Validation **_validation)
     467             : {
     468          42 :         TALLOC_CTX *frame = talloc_stackframe();
     469             :         NTSTATUS status;
     470             :         union netr_LogonLevel *logon;
     471          42 :         uint16_t validation_level = 0;
     472          42 :         union netr_Validation *validation = NULL;
     473          42 :         char *workstation_slash = NULL;
     474             : 
     475             :         unsigned char local_nt_response[24];
     476             :         unsigned char local_lm_response[24];
     477          42 :         struct samr_Password lmpassword = {.hash = {0}};
     478          42 :         struct samr_Password ntpassword = {.hash = {0}};
     479          42 :         struct netr_ChallengeResponse lm = {0};
     480          42 :         struct netr_ChallengeResponse nt = {0};
     481             : 
     482          42 :         logon = talloc_zero(frame, union netr_LogonLevel);
     483          42 :         if (logon == NULL) {
     484           0 :                 TALLOC_FREE(frame);
     485           0 :                 return NT_STATUS_NO_MEMORY;
     486             :         }
     487             : 
     488          42 :         if (workstation == NULL) {
     489          20 :                 workstation = lp_netbios_name();
     490             :         }
     491             : 
     492          42 :         workstation_slash = talloc_asprintf(frame, "\\\\%s", workstation);
     493          42 :         if (workstation_slash == NULL) {
     494           0 :                 TALLOC_FREE(frame);
     495           0 :                 return NT_STATUS_NO_MEMORY;
     496             :         }
     497             : 
     498             :         /* Initialise input parameters */
     499             : 
     500          42 :         switch (logon_type) {
     501           6 :         case NetlogonInteractiveInformation:
     502             :         case NetlogonInteractiveTransitiveInformation: {
     503             : 
     504             :                 struct netr_PasswordInfo *password_info;
     505             : 
     506             : 
     507           6 :                 password_info = talloc_zero(frame, struct netr_PasswordInfo);
     508           6 :                 if (password_info == NULL) {
     509           0 :                         TALLOC_FREE(frame);
     510           0 :                         return NT_STATUS_NO_MEMORY;
     511             :                 }
     512             : 
     513           6 :                 nt_lm_owf_gen(password, ntpassword.hash, lmpassword.hash);
     514             : 
     515           6 :                 password_info->identity_info.domain_name.string              = domain;
     516           6 :                 password_info->identity_info.parameter_control               = logon_parameters;
     517           6 :                 password_info->identity_info.logon_id                        = logon_id;
     518           6 :                 password_info->identity_info.account_name.string     = username;
     519           6 :                 password_info->identity_info.workstation.string              = workstation_slash;
     520             : 
     521           6 :                 password_info->lmpassword = lmpassword;
     522           6 :                 password_info->ntpassword = ntpassword;
     523             : 
     524           6 :                 logon->password = password_info;
     525             : 
     526           6 :                 break;
     527             :         }
     528          36 :         case NetlogonNetworkInformation:
     529             :         case NetlogonNetworkTransitiveInformation: {
     530             :                 struct netr_NetworkInfo *network_info;
     531             :                 uint8_t chal[8];
     532             :                 int rc;
     533             : 
     534          36 :                 ZERO_STRUCT(lm);
     535          36 :                 ZERO_STRUCT(nt);
     536             : 
     537          36 :                 network_info = talloc_zero(frame, struct netr_NetworkInfo);
     538          36 :                 if (network_info == NULL) {
     539           0 :                         TALLOC_FREE(frame);
     540           0 :                         return NT_STATUS_NO_MEMORY;
     541             :                 }
     542             : 
     543          36 :                 generate_random_buffer(chal, 8);
     544             : 
     545          36 :                 SMBencrypt(password, chal, local_lm_response);
     546          36 :                 rc = SMBNTencrypt(password, chal, local_nt_response);
     547          36 :                 if (rc != 0) {
     548           0 :                         TALLOC_FREE(frame);
     549           0 :                         return gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
     550             :                 }
     551             : 
     552          36 :                 lm.length = 24;
     553          36 :                 lm.data = local_lm_response;
     554             : 
     555          36 :                 nt.length = 24;
     556          36 :                 nt.data = local_nt_response;
     557             : 
     558          36 :                 network_info->identity_info.domain_name.string               = domain;
     559          36 :                 network_info->identity_info.parameter_control                = logon_parameters;
     560          36 :                 network_info->identity_info.logon_id                 = logon_id;
     561          36 :                 network_info->identity_info.account_name.string              = username;
     562          36 :                 network_info->identity_info.workstation.string               = workstation_slash;
     563             : 
     564          36 :                 memcpy(network_info->challenge, chal, 8);
     565          36 :                 network_info->nt = nt;
     566          36 :                 network_info->lm = lm;
     567             : 
     568          36 :                 logon->network = network_info;
     569             : 
     570          36 :                 break;
     571             :         }
     572           0 :         default:
     573           0 :                 DEBUG(0, ("switch value %d not supported\n",
     574             :                         logon_type));
     575           0 :                 TALLOC_FREE(frame);
     576           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
     577             :         }
     578             : 
     579          42 :         status = netlogon_creds_cli_LogonSamLogon(creds_ctx,
     580             :                                                   binding_handle,
     581             :                                                   logon_type,
     582             :                                                   logon,
     583             :                                                   mem_ctx,
     584             :                                                   &validation_level,
     585             :                                                   &validation,
     586             :                                                   authoritative,
     587             :                                                   flags);
     588          42 :         if (!NT_STATUS_IS_OK(status)) {
     589          12 :                 TALLOC_FREE(frame);
     590          12 :                 return status;
     591             :         }
     592             : 
     593          30 :         TALLOC_FREE(frame);
     594          30 :         *_validation_level = validation_level;
     595          30 :         *_validation = validation;
     596             : 
     597          30 :         return NT_STATUS_OK;
     598             : }
     599             : 
     600             : /**
     601             :  * Logon domain user with an 'network' SAM logon
     602             :  *
     603             :  * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller.
     604             :  **/
     605             : 
     606             : 
     607           0 : NTSTATUS rpccli_netlogon_network_logon(
     608             :         struct netlogon_creds_cli_context *creds_ctx,
     609             :         struct dcerpc_binding_handle *binding_handle,
     610             :         TALLOC_CTX *mem_ctx,
     611             :         uint32_t logon_parameters,
     612             :         const char *username,
     613             :         const char *domain,
     614             :         const char *workstation,
     615             :         const uint64_t logon_id,
     616             :         const uint8_t chal[8],
     617             :         DATA_BLOB lm_response,
     618             :         DATA_BLOB nt_response,
     619             :         enum netr_LogonInfoClass logon_type,
     620             :         uint8_t *authoritative,
     621             :         uint32_t *flags,
     622             :         uint16_t *_validation_level,
     623             :         union netr_Validation **_validation)
     624             : {
     625             :         NTSTATUS status;
     626             :         const char *workstation_name_slash;
     627           0 :         union netr_LogonLevel *logon = NULL;
     628             :         struct netr_NetworkInfo *network_info;
     629           0 :         uint16_t validation_level = 0;
     630           0 :         union netr_Validation *validation = NULL;
     631             :         struct netr_ChallengeResponse lm;
     632             :         struct netr_ChallengeResponse nt;
     633             : 
     634           0 :         *_validation = NULL;
     635             : 
     636           0 :         ZERO_STRUCT(lm);
     637           0 :         ZERO_STRUCT(nt);
     638             : 
     639           0 :         switch (logon_type) {
     640           0 :         case NetlogonNetworkInformation:
     641             :         case NetlogonNetworkTransitiveInformation:
     642           0 :                 break;
     643           0 :         default:
     644           0 :                 DEBUG(0, ("switch value %d not supported\n",
     645             :                         logon_type));
     646           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
     647             :         }
     648             : 
     649           0 :         logon = talloc_zero(mem_ctx, union netr_LogonLevel);
     650           0 :         if (!logon) {
     651           0 :                 return NT_STATUS_NO_MEMORY;
     652             :         }
     653             : 
     654           0 :         network_info = talloc_zero(mem_ctx, struct netr_NetworkInfo);
     655           0 :         if (!network_info) {
     656           0 :                 return NT_STATUS_NO_MEMORY;
     657             :         }
     658             : 
     659           0 :         if (workstation[0] != '\\' && workstation[1] != '\\') {
     660           0 :                 workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation);
     661             :         } else {
     662           0 :                 workstation_name_slash = workstation;
     663             :         }
     664             : 
     665           0 :         if (!workstation_name_slash) {
     666           0 :                 DEBUG(0, ("talloc_asprintf failed!\n"));
     667           0 :                 return NT_STATUS_NO_MEMORY;
     668             :         }
     669             : 
     670             :         /* Initialise input parameters */
     671             : 
     672           0 :         lm.data = lm_response.data;
     673           0 :         lm.length = lm_response.length;
     674           0 :         nt.data = nt_response.data;
     675           0 :         nt.length = nt_response.length;
     676             : 
     677           0 :         network_info->identity_info.domain_name.string               = domain;
     678           0 :         network_info->identity_info.parameter_control                = logon_parameters;
     679           0 :         network_info->identity_info.logon_id                 = logon_id;
     680           0 :         network_info->identity_info.account_name.string              = username;
     681           0 :         network_info->identity_info.workstation.string               = workstation_name_slash;
     682             : 
     683           0 :         memcpy(network_info->challenge, chal, 8);
     684           0 :         network_info->nt = nt;
     685           0 :         network_info->lm = lm;
     686             : 
     687           0 :         logon->network = network_info;
     688             : 
     689             :         /* Marshall data and send request */
     690             : 
     691           0 :         status = netlogon_creds_cli_LogonSamLogon(creds_ctx,
     692             :                                                   binding_handle,
     693             :                                                   logon_type,
     694             :                                                   logon,
     695             :                                                   mem_ctx,
     696             :                                                   &validation_level,
     697             :                                                   &validation,
     698             :                                                   authoritative,
     699             :                                                   flags);
     700           0 :         if (!NT_STATUS_IS_OK(status)) {
     701           0 :                 return status;
     702             :         }
     703             : 
     704           0 :         *_validation_level = validation_level;
     705           0 :         *_validation = validation;
     706             : 
     707           0 :         return NT_STATUS_OK;
     708             : }
     709             : 
     710           0 : NTSTATUS rpccli_netlogon_interactive_logon(
     711             :         struct netlogon_creds_cli_context *creds_ctx,
     712             :         struct dcerpc_binding_handle *binding_handle,
     713             :         TALLOC_CTX *mem_ctx,
     714             :         uint32_t logon_parameters,
     715             :         const char *username,
     716             :         const char *domain,
     717             :         const char *workstation,
     718             :         const uint64_t logon_id,
     719             :         DATA_BLOB lm_hash,
     720             :         DATA_BLOB nt_hash,
     721             :         enum netr_LogonInfoClass logon_type,
     722             :         uint8_t *authoritative,
     723             :         uint32_t *flags,
     724             :         uint16_t *_validation_level,
     725             :         union netr_Validation **_validation)
     726             : {
     727           0 :         TALLOC_CTX *frame = talloc_stackframe();
     728             :         NTSTATUS status;
     729             :         const char *workstation_name_slash;
     730           0 :         union netr_LogonLevel *logon = NULL;
     731           0 :         struct netr_PasswordInfo *password_info = NULL;
     732           0 :         uint16_t validation_level = 0;
     733           0 :         union netr_Validation *validation = NULL;
     734             :         struct netr_ChallengeResponse lm;
     735             :         struct netr_ChallengeResponse nt;
     736             : 
     737           0 :         *_validation = NULL;
     738             : 
     739           0 :         ZERO_STRUCT(lm);
     740           0 :         ZERO_STRUCT(nt);
     741             : 
     742           0 :         switch (logon_type) {
     743           0 :         case NetlogonInteractiveInformation:
     744             :         case NetlogonInteractiveTransitiveInformation:
     745           0 :                 break;
     746           0 :         default:
     747           0 :                 DEBUG(0, ("switch value %d not supported\n",
     748             :                         logon_type));
     749           0 :                 TALLOC_FREE(frame);
     750           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
     751             :         }
     752             : 
     753           0 :         logon = talloc_zero(mem_ctx, union netr_LogonLevel);
     754           0 :         if (logon == NULL) {
     755           0 :                 TALLOC_FREE(frame);
     756           0 :                 return NT_STATUS_NO_MEMORY;
     757             :         }
     758             : 
     759           0 :         password_info = talloc_zero(logon, struct netr_PasswordInfo);
     760           0 :         if (password_info == NULL) {
     761           0 :                 TALLOC_FREE(frame);
     762           0 :                 return NT_STATUS_NO_MEMORY;
     763             :         }
     764             : 
     765           0 :         if (workstation[0] != '\\' && workstation[1] != '\\') {
     766           0 :                 workstation_name_slash = talloc_asprintf(frame, "\\\\%s", workstation);
     767             :         } else {
     768           0 :                 workstation_name_slash = workstation;
     769             :         }
     770             : 
     771           0 :         if (workstation_name_slash == NULL) {
     772           0 :                 TALLOC_FREE(frame);
     773           0 :                 return NT_STATUS_NO_MEMORY;
     774             :         }
     775             : 
     776             :         /* Initialise input parameters */
     777             : 
     778           0 :         password_info->identity_info.domain_name.string              = domain;
     779           0 :         password_info->identity_info.parameter_control               = logon_parameters;
     780           0 :         password_info->identity_info.logon_id                        = logon_id;
     781           0 :         password_info->identity_info.account_name.string     = username;
     782           0 :         password_info->identity_info.workstation.string              = workstation_name_slash;
     783             : 
     784           0 :         if (nt_hash.length != sizeof(password_info->ntpassword.hash)) {
     785           0 :                 TALLOC_FREE(frame);
     786           0 :                 return NT_STATUS_INVALID_PARAMETER;
     787             :         }
     788           0 :         memcpy(password_info->ntpassword.hash, nt_hash.data, nt_hash.length);
     789           0 :         if (lm_hash.length != 0) {
     790           0 :                 if (lm_hash.length != sizeof(password_info->lmpassword.hash)) {
     791           0 :                         TALLOC_FREE(frame);
     792           0 :                         return NT_STATUS_INVALID_PARAMETER;
     793             :                 }
     794           0 :                 memcpy(password_info->lmpassword.hash, lm_hash.data, lm_hash.length);
     795             :         }
     796             : 
     797           0 :         logon->password = password_info;
     798             : 
     799             :         /* Marshall data and send request */
     800             : 
     801           0 :         status = netlogon_creds_cli_LogonSamLogon(creds_ctx,
     802             :                                                   binding_handle,
     803             :                                                   logon_type,
     804             :                                                   logon,
     805             :                                                   mem_ctx,
     806             :                                                   &validation_level,
     807             :                                                   &validation,
     808             :                                                   authoritative,
     809             :                                                   flags);
     810           0 :         if (!NT_STATUS_IS_OK(status)) {
     811           0 :                 TALLOC_FREE(frame);
     812           0 :                 return status;
     813             :         }
     814             : 
     815           0 :         *_validation_level = validation_level;
     816           0 :         *_validation = validation;
     817             : 
     818           0 :         TALLOC_FREE(frame);
     819           0 :         return NT_STATUS_OK;
     820             : }

Generated by: LCOV version 1.13