LCOV - code coverage report
Current view: top level - source3/rpc_client - cli_netlogon.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 141 404 34.9 %
Date: 2024-02-28 12:06:22 Functions: 6 9 66.7 %

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

Generated by: LCOV version 1.14