LCOV - code coverage report
Current view: top level - source3/auth - auth_generic.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 171 304 56.2 %
Date: 2024-04-21 15:09:00 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/Netbios implementation.
       3             :    Version 3.0
       4             :    handle GENSEC authentication, server side
       5             : 
       6             :    Copyright (C) Andrew Tridgell      2001
       7             :    Copyright (C) Andrew Bartlett 2001-2003,2011
       8             :    Copyright (C) Simo Sorce 2010.
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "includes.h"
      25             : #include <tevent.h>
      26             : #include "../lib/util/tevent_ntstatus.h"
      27             : #include "auth.h"
      28             : #include "../lib/tsocket/tsocket.h"
      29             : #include "auth/gensec/gensec.h"
      30             : #include "lib/param/param.h"
      31             : #ifdef HAVE_KRB5
      32             : #include "librpc/gen_ndr/ndr_krb5pac.h"
      33             : #include "auth/kerberos/pac_utils.h"
      34             : #include "nsswitch/libwbclient/wbclient.h"
      35             : #endif
      36             : #include "librpc/crypto/gse.h"
      37             : #include "auth/credentials/credentials.h"
      38             : #include "lib/param/loadparm.h"
      39             : #include "librpc/gen_ndr/dcerpc.h"
      40             : #include "source3/lib/substitute.h"
      41             : 
      42         864 : static NTSTATUS generate_pac_session_info(
      43             :         TALLOC_CTX *mem_ctx,
      44             :         const char *princ_name,
      45             :         const char *rhost,
      46             :         DATA_BLOB *pac_blob,
      47             :         struct auth_session_info **psession_info)
      48             : {
      49           0 :         NTSTATUS status;
      50         864 :         struct wbcAuthUserParams params = {0};
      51         864 :         struct wbcAuthUserInfo *info = NULL;
      52         864 :         struct wbcAuthErrorInfo *err = NULL;
      53         864 :         struct auth_serversupplied_info *server_info = NULL;
      54         864 :         char *original_user_name = NULL;
      55         864 :         char *p = NULL;
      56           0 :         wbcErr wbc_err;
      57             : 
      58             :         /*
      59             :          * Let winbind decode the PAC.
      60             :          * This will also store the user
      61             :          * data in the netsamlogon cache.
      62             :          *
      63             :          * This used to be a cache prime
      64             :          * optimization, but now we delegate
      65             :          * all logic to winbindd, as we require
      66             :          * winbindd as domain member anyway.
      67             :          */
      68         864 :         params.level = WBC_AUTH_USER_LEVEL_PAC;
      69         864 :         params.password.pac.data = pac_blob->data;
      70         864 :         params.password.pac.length = pac_blob->length;
      71             : 
      72             :         /* we are contacting the privileged pipe */
      73         864 :         become_root();
      74         864 :         wbc_err = wbcAuthenticateUserEx(&params, &info, &err);
      75         864 :         unbecome_root();
      76             : 
      77             :         /*
      78             :          * As this is merely a cache prime
      79             :          * WBC_ERR_WINBIND_NOT_AVAILABLE
      80             :          * is not a fatal error, treat it
      81             :          * as success.
      82             :          */
      83             : 
      84         864 :         switch (wbc_err) {
      85         862 :         case WBC_ERR_SUCCESS:
      86         862 :                 break;
      87           0 :         case WBC_ERR_WINBIND_NOT_AVAILABLE:
      88           0 :                 status = NT_STATUS_NO_LOGON_SERVERS;
      89           0 :                 DBG_ERR("winbindd not running - "
      90             :                         "but required as domain member: %s\n",
      91             :                         nt_errstr(status));
      92           2 :                 return status;
      93           2 :         case WBC_ERR_AUTH_ERROR:
      94           2 :                 wbcFreeMemory(err);
      95           2 :                 return NT_STATUS(err->nt_status);
      96           0 :         case WBC_ERR_NO_MEMORY:
      97           0 :                 return NT_STATUS_NO_MEMORY;
      98           0 :         default:
      99           0 :                 return NT_STATUS_LOGON_FAILURE;
     100             :         }
     101             : 
     102         862 :         status = make_server_info_wbcAuthUserInfo(mem_ctx,
     103         862 :                                                   info->account_name,
     104         862 :                                                   info->domain_name,
     105             :                                                   info,
     106             :                                                   &server_info);
     107         862 :         wbcFreeMemory(info);
     108         862 :         if (!NT_STATUS_IS_OK(status)) {
     109           4 :                 DEBUG(10, ("make_server_info_wbcAuthUserInfo failed: %s\n",
     110             :                            nt_errstr(status)));
     111           4 :                 return status;
     112             :         }
     113             : 
     114             :         /* We skip doing this step if the caller asked us not to */
     115         858 :         if (!(server_info->guest)) {
     116         858 :                 const char *unix_username = server_info->unix_name;
     117             : 
     118             :                 /* We might not be root if we are an RPC call */
     119         858 :                 become_root();
     120         858 :                 status = smb_pam_accountcheck(unix_username, rhost);
     121         858 :                 unbecome_root();
     122             : 
     123         858 :                 if (!NT_STATUS_IS_OK(status)) {
     124           0 :                         DEBUG(3, ("check_ntlm_password:  PAM Account for user [%s] "
     125             :                                           "FAILED with error %s\n",
     126             :                                           unix_username, nt_errstr(status)));
     127           0 :                         return status;
     128             :                 }
     129             : 
     130         858 :                 DEBUG(5, ("check_ntlm_password:  PAM Account for user [%s] "
     131             :                           "succeeded\n", unix_username));
     132             :         }
     133             : 
     134         858 :         DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name));
     135             : 
     136         858 :         p = strchr_m(princ_name, '@');
     137         858 :         if (!p) {
     138           0 :                 DEBUG(3, ("[%s] Doesn't look like a valid principal\n",
     139             :                                   princ_name));
     140           0 :                 return NT_STATUS_LOGON_FAILURE;
     141             :         }
     142             : 
     143         858 :         original_user_name = talloc_strndup(mem_ctx,
     144             :                                             princ_name,
     145         858 :                                             p - princ_name);
     146         858 :         if (original_user_name == NULL) {
     147           0 :                 return NT_STATUS_NO_MEMORY;
     148             :         }
     149             : 
     150         858 :         status = create_local_token(
     151             :                 mem_ctx, server_info, NULL, original_user_name, psession_info);
     152         858 :         if (!NT_STATUS_IS_OK(status)) {
     153           0 :                 DEBUG(10, ("create_local_token failed: %s\n",
     154             :                                    nt_errstr(status)));
     155           0 :                 return status;
     156             :         }
     157             : 
     158         858 :         return NT_STATUS_OK;
     159             : }
     160             : 
     161           0 : static NTSTATUS generate_krb5_session_info(
     162             :         TALLOC_CTX *mem_ctx,
     163             :         const char *princ_name,
     164             :         const char *rhost,
     165             :         DATA_BLOB *pac_blob,
     166             :         struct auth_session_info **psession_info)
     167             : {
     168           0 :         bool is_mapped = false;
     169           0 :         bool is_guest = false;
     170           0 :         char *ntuser = NULL;
     171           0 :         char *ntdomain = NULL;
     172           0 :         char *username = NULL;
     173           0 :         struct passwd *pw = NULL;
     174           0 :         NTSTATUS status;
     175             : 
     176           0 :         if (pac_blob != NULL) {
     177           0 :                 struct PAC_LOGON_NAME *logon_name = NULL;
     178           0 :                 struct PAC_LOGON_INFO *logon_info = NULL;
     179           0 :                 struct PAC_DATA *pac_data = NULL;
     180           0 :                 enum ndr_err_code ndr_err;
     181           0 :                 size_t i;
     182             : 
     183           0 :                 pac_data = talloc_zero(mem_ctx, struct PAC_DATA);
     184           0 :                 if (pac_data == NULL) {
     185           0 :                         return NT_STATUS_NO_MEMORY;
     186             :                 }
     187             : 
     188           0 :                 ndr_err = ndr_pull_struct_blob(pac_blob,
     189             :                                                pac_data,
     190             :                                                pac_data,
     191             :                                                (ndr_pull_flags_fn_t)
     192             :                                                        ndr_pull_PAC_DATA);
     193           0 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     194           0 :                         status = ndr_map_error2ntstatus(ndr_err);
     195           0 :                         DBG_ERR("Can't parse the PAC: %s\n", nt_errstr(status));
     196           0 :                         return status;
     197             :                 }
     198             : 
     199           0 :                 if (pac_data->num_buffers < 4) {
     200           0 :                         DBG_ERR("We expect at least 4 PAC buffers.\n");
     201           0 :                         return NT_STATUS_INVALID_PARAMETER;
     202             :                 }
     203             : 
     204           0 :                 for (i = 0; i < pac_data->num_buffers; i++) {
     205           0 :                         struct PAC_BUFFER *data_buf = &pac_data->buffers[i];
     206             : 
     207           0 :                         switch (data_buf->type) {
     208           0 :                         case PAC_TYPE_LOGON_NAME:
     209           0 :                                 logon_name = &data_buf->info->logon_name;
     210           0 :                                 break;
     211           0 :                         case PAC_TYPE_LOGON_INFO:
     212           0 :                                 if (!data_buf->info) {
     213           0 :                                         break;
     214             :                                 }
     215           0 :                                 logon_info = data_buf->info->logon_info.info;
     216           0 :                                 break;
     217           0 :                         default:
     218           0 :                                 break;
     219             :                         }
     220             :                 }
     221             : 
     222           0 :                 if (logon_name == NULL) {
     223           0 :                         TALLOC_FREE(pac_data);
     224           0 :                         DBG_ERR("PAC without logon_name\n");
     225           0 :                         return NT_STATUS_INVALID_PARAMETER;
     226             :                 }
     227             : 
     228           0 :                 if (logon_info != NULL) {
     229             :                         /*
     230             :                         * In standalone mode we don't expect a MS-PAC!
     231             :                         * we only support MIT realms
     232             :                         */
     233           0 :                         TALLOC_FREE(pac_data);
     234           0 :                         status = NT_STATUS_BAD_TOKEN_TYPE;
     235           0 :                         DBG_WARNING("Unexpected PAC for [%s] in standalone mode - %s\n",
     236             :                                 princ_name, nt_errstr(status));
     237           0 :                         return status;
     238             :                 }
     239             : 
     240           0 :                 TALLOC_FREE(pac_data);
     241             :         }
     242             : 
     243           0 :         status = get_user_from_kerberos_info(mem_ctx,
     244             :                                              rhost,
     245             :                                              princ_name,
     246             :                                              &is_mapped,
     247             :                                              &is_guest,
     248             :                                              &ntuser,
     249             :                                              &ntdomain,
     250             :                                              &username,
     251             :                                              &pw);
     252           0 :         if (!NT_STATUS_IS_OK(status)) {
     253           0 :                 DBG_NOTICE("Failed to map kerberos principal to system user "
     254             :                           "(%s)\n", nt_errstr(status));
     255           0 :                 return NT_STATUS_ACCESS_DENIED;
     256             :         }
     257             : 
     258           0 :         status = make_session_info_krb5(mem_ctx,
     259             :                                         ntuser,
     260             :                                         ntdomain,
     261             :                                         username,
     262             :                                         pw,
     263             :                                         is_guest,
     264             :                                         is_mapped,
     265             :                                         psession_info);
     266           0 :         if (!NT_STATUS_IS_OK(status)) {
     267           0 :                 DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n",
     268             :                           nt_errstr(status)));
     269           0 :                 status = nt_status_squash(status);
     270           0 :                 return status;
     271             :         }
     272             : 
     273           0 :         return NT_STATUS_OK;
     274             : }
     275             : 
     276         864 : static NTSTATUS auth3_generate_session_info_pac(
     277             :         struct auth4_context *auth_ctx,
     278             :         TALLOC_CTX *mem_ctx,
     279             :         struct smb_krb5_context *smb_krb5_context,
     280             :         DATA_BLOB *pac_blob,
     281             :         const char *princ_name,
     282             :         const struct tsocket_address *remote_address,
     283             :         uint32_t session_info_flags,
     284             :         struct auth_session_info **psession_info)
     285             : {
     286         864 :         enum server_role server_role = lp_server_role();
     287         864 :         struct auth_session_info *session_info = NULL;
     288           0 :         const char *rhost;
     289           0 :         NTSTATUS status;
     290         864 :         TALLOC_CTX *tmp_ctx = NULL;
     291             : 
     292         864 :         tmp_ctx = talloc_new(mem_ctx);
     293         864 :         if (tmp_ctx == NULL) {
     294           0 :                 return NT_STATUS_NO_MEMORY;
     295             :         }
     296             : 
     297         864 :         if (tsocket_address_is_inet(remote_address, "ip")) {
     298         864 :                 rhost = tsocket_address_inet_addr_string(remote_address,
     299             :                                                          tmp_ctx);
     300         864 :                 if (rhost == NULL) {
     301           0 :                         status = NT_STATUS_NO_MEMORY;
     302           0 :                         goto done;
     303             :                 }
     304             :         } else {
     305           0 :                 rhost = "127.0.0.1";
     306             :         }
     307             : 
     308         864 :         switch (server_role) {
     309         864 :         case ROLE_DOMAIN_MEMBER:
     310             :         case ROLE_DOMAIN_BDC:
     311             :         case ROLE_DOMAIN_PDC:
     312             :         case ROLE_ACTIVE_DIRECTORY_DC:
     313             :         case ROLE_IPA_DC:
     314             :                 /* This requires a complete MS-PAC including logon_info */
     315         864 :                 status = generate_pac_session_info(
     316             :                         tmp_ctx, princ_name, rhost, pac_blob, &session_info);
     317         864 :                 break;
     318           0 :         case ROLE_STANDALONE:
     319             :                 /* This requires no PAC or a minimal PAC */
     320           0 :                 status = generate_krb5_session_info(
     321             :                         tmp_ctx, princ_name, rhost, pac_blob, &session_info);
     322           0 :                 break;
     323           0 :         default:
     324           0 :                 status = NT_STATUS_INVALID_PARAMETER;
     325           0 :                 goto done;
     326             :         }
     327             : 
     328         864 :         if (!NT_STATUS_IS_OK(status)) {
     329           6 :                 goto done;
     330             :         }
     331             : 
     332             :         /* setup the string used by %U */
     333         858 :         set_current_user_info(session_info->unix_info->sanitized_username,
     334         858 :                               session_info->unix_info->unix_name,
     335         858 :                               session_info->info->domain_name);
     336             : 
     337             :         /* reload services so that the new %U is taken into account */
     338         858 :         lp_load_with_shares(get_dyn_CONFIGFILE());
     339             : 
     340         858 :         DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n",
     341             :                   session_info->info->account_name,
     342             :                   session_info->info->domain_name,
     343             :                   rhost));
     344             : 
     345         858 :         *psession_info = talloc_move(mem_ctx, &session_info);
     346             : 
     347         858 :         status = NT_STATUS_OK;
     348         864 : done:
     349         864 :         TALLOC_FREE(tmp_ctx);
     350         864 :         return status;
     351             : }
     352             : 
     353       77045 : static struct auth4_context *make_auth4_context_s3(TALLOC_CTX *mem_ctx, struct auth_context *auth_context)
     354             : {
     355       77045 :         struct auth4_context *auth4_context = talloc_zero(mem_ctx, struct auth4_context);
     356       77045 :         if (auth4_context == NULL) {
     357           0 :                 DEBUG(10, ("failed to allocate auth4_context failed\n"));
     358           0 :                 return NULL;
     359             :         }
     360       77045 :         auth4_context->generate_session_info_pac = auth3_generate_session_info_pac;
     361       77045 :         auth4_context->generate_session_info = auth3_generate_session_info;
     362       77045 :         auth4_context->get_ntlm_challenge = auth3_get_challenge;
     363       77045 :         auth4_context->set_ntlm_challenge = auth3_set_challenge;
     364       77045 :         auth4_context->check_ntlm_password_send = auth3_check_password_send;
     365       77045 :         auth4_context->check_ntlm_password_recv = auth3_check_password_recv;
     366       77045 :         auth4_context->private_data = talloc_steal(auth4_context, auth_context);
     367       77045 :         return auth4_context;
     368             : }
     369             : 
     370       34130 : NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_context_out)
     371             : {
     372           0 :         struct auth_context *auth_context;
     373           0 :         NTSTATUS nt_status;
     374             : 
     375       34130 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     376       34130 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     377             : 
     378       34130 :         nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
     379       34130 :         if (!NT_STATUS_IS_OK(nt_status)) {
     380           0 :                 TALLOC_FREE(tmp_ctx);
     381           0 :                 return nt_status;
     382             :         }
     383             : 
     384       34130 :         if (auth_context->make_auth4_context) {
     385       15460 :                 nt_status = auth_context->make_auth4_context(auth_context, mem_ctx, auth4_context_out);
     386       15460 :                 TALLOC_FREE(tmp_ctx);
     387       15460 :                 return nt_status;
     388             : 
     389             :         } else {
     390       18670 :                 struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
     391       18670 :                 if (auth4_context == NULL) {
     392           0 :                         TALLOC_FREE(tmp_ctx);
     393           0 :                         return NT_STATUS_NO_MEMORY;
     394             :                 }
     395       18670 :                 *auth4_context_out = talloc_steal(mem_ctx, auth4_context);
     396       18670 :                 TALLOC_FREE(tmp_ctx);
     397       18670 :                 return NT_STATUS_OK;
     398             :         }
     399             : }
     400             : 
     401       82941 : NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
     402             :                               const struct tsocket_address *remote_address,
     403             :                               const struct tsocket_address *local_address,
     404             :                               const char *service_description,
     405             :                               struct gensec_security **gensec_security_out)
     406             : {
     407        2087 :         struct gensec_security *gensec_security;
     408       82941 :         struct auth_context *auth_context = NULL;
     409        2087 :         NTSTATUS nt_status;
     410             : 
     411       82941 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     412       82941 :         NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     413             : 
     414       82941 :         nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
     415       82941 :         if (!NT_STATUS_IS_OK(nt_status)) {
     416           0 :                 goto done;
     417             :         }
     418             : 
     419       82941 :         if (auth_context->prepare_gensec) {
     420       24566 :                 nt_status = auth_context->prepare_gensec(auth_context, tmp_ctx,
     421             :                                                          &gensec_security);
     422       24566 :                 if (!NT_STATUS_IS_OK(nt_status)) {
     423           0 :                         goto done;
     424             :                 }
     425             :         } else {
     426       58375 :                 const struct gensec_security_ops **backends = NULL;
     427           0 :                 struct gensec_settings *gensec_settings;
     428           0 :                 struct loadparm_context *lp_ctx;
     429       58375 :                 size_t idx = 0;
     430           0 :                 struct cli_credentials *server_credentials;
     431           0 :                 const char *dns_name;
     432           0 :                 const char *dns_domain;
     433           0 :                 bool ok;
     434       58375 :                 struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
     435       58375 :                 if (auth4_context == NULL) {
     436           0 :                         goto nomem;
     437             :                 }
     438             : 
     439       58375 :                 lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_helpers());
     440       58375 :                 if (lp_ctx == NULL) {
     441           0 :                         DEBUG(10, ("loadparm_init_s3 failed\n"));
     442           0 :                         nt_status = NT_STATUS_INVALID_SERVER_STATE;
     443           0 :                         goto done;
     444             :                 }
     445             : 
     446       58375 :                 gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx);
     447       58375 :                 if (lp_ctx == NULL) {
     448           0 :                         DEBUG(10, ("lpcfg_gensec_settings failed\n"));
     449           0 :                         goto nomem;
     450             :                 }
     451             : 
     452             :                 /*
     453             :                  * This should be a 'netbios domain -> DNS domain'
     454             :                  * mapping, and can currently validly return NULL on
     455             :                  * poorly configured systems.
     456             :                  *
     457             :                  * This is used for the NTLMSSP server
     458             :                  *
     459             :                  */
     460       58375 :                 dns_name = get_mydnsfullname();
     461       58375 :                 if (dns_name == NULL) {
     462           0 :                         dns_name = "";
     463             :                 }
     464             : 
     465       58375 :                 dns_domain = get_mydnsdomname(tmp_ctx);
     466       58375 :                 if (dns_domain == NULL) {
     467           0 :                         dns_domain = "";
     468             :                 }
     469             : 
     470       58375 :                 gensec_settings->server_dns_name = strlower_talloc(gensec_settings, dns_name);
     471       58375 :                 if (gensec_settings->server_dns_name == NULL) {
     472           0 :                         goto nomem;
     473             :                 }
     474             : 
     475       58375 :                 gensec_settings->server_dns_domain = strlower_talloc(gensec_settings, dns_domain);
     476       58375 :                 if (gensec_settings->server_dns_domain == NULL) {
     477           0 :                         goto nomem;
     478             :                 }
     479             : 
     480       58375 :                 backends = talloc_zero_array(gensec_settings,
     481             :                                              const struct gensec_security_ops *, 6);
     482       58375 :                 if (backends == NULL) {
     483           0 :                         goto nomem;
     484             :                 }
     485       58375 :                 gensec_settings->backends = backends;
     486             : 
     487       58375 :                 gensec_init();
     488             : 
     489             :                 /* These need to be in priority order, krb5 before NTLMSSP */
     490             : #if defined(HAVE_KRB5)
     491       58375 :                 backends[idx++] = &gensec_gse_krb5_security_ops;
     492             : #endif
     493             : 
     494       58375 :                 backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);
     495             : 
     496       58375 :                 backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO);
     497             : 
     498       58375 :                 backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL);
     499             : 
     500       58375 :                 backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM);
     501             : 
     502             :                 /*
     503             :                  * This is anonymous for now, because we just use it
     504             :                  * to set the kerberos state at the moment
     505             :                  */
     506       58375 :                 server_credentials = cli_credentials_init_anon(tmp_ctx);
     507       58375 :                 if (!server_credentials) {
     508           0 :                         DEBUG(0, ("auth_generic_prepare: Failed to init server credentials\n"));
     509           0 :                         goto nomem;
     510             :                 }
     511             : 
     512       58375 :                 ok = cli_credentials_set_conf(server_credentials, lp_ctx);
     513       58375 :                 if (!ok) {
     514           0 :                         DBG_ERR("Failed to set server credentials defaults "
     515             :                                 "from smb.conf.\n");
     516           0 :                         goto nomem;
     517             :                 }
     518             : 
     519       58375 :                 if (lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
     520        4411 :                         cli_credentials_set_kerberos_state(server_credentials,
     521             :                                                            CRED_USE_KERBEROS_DESIRED,
     522             :                                                            CRED_SPECIFIED);
     523             :                 } else {
     524       53964 :                         cli_credentials_set_kerberos_state(server_credentials,
     525             :                                                            CRED_USE_KERBEROS_DISABLED,
     526             :                                                            CRED_SPECIFIED);
     527             :                 }
     528             : 
     529       58375 :                 nt_status = gensec_server_start(tmp_ctx, gensec_settings,
     530             :                                                 auth4_context, &gensec_security);
     531             : 
     532       58375 :                 if (!NT_STATUS_IS_OK(nt_status)) {
     533           0 :                         goto done;
     534             :                 }
     535             : 
     536       58375 :                 nt_status = gensec_set_credentials(
     537             :                         gensec_security, server_credentials);
     538       58375 :                 if (!NT_STATUS_IS_OK(nt_status)) {
     539           0 :                         goto done;
     540             :                 }
     541             :         }
     542             : 
     543       82941 :         nt_status = gensec_set_remote_address(gensec_security,
     544             :                                               remote_address);
     545       82941 :         if (!NT_STATUS_IS_OK(nt_status)) {
     546           0 :                 goto done;
     547             :         }
     548             : 
     549       82941 :         nt_status = gensec_set_local_address(gensec_security,
     550             :                                              local_address);
     551       82941 :         if (!NT_STATUS_IS_OK(nt_status)) {
     552           0 :                 goto done;
     553             :         }
     554             : 
     555       82941 :         nt_status = gensec_set_target_service_description(gensec_security,
     556             :                                                           service_description);
     557       82941 :         if (!NT_STATUS_IS_OK(nt_status)) {
     558           0 :                 goto done;
     559             :         }
     560             : 
     561       82941 :         *gensec_security_out = talloc_move(mem_ctx, &gensec_security);
     562       82941 :         nt_status = NT_STATUS_OK;
     563       82941 :         goto done;
     564           0 : nomem:
     565           0 :         nt_status = NT_STATUS_NO_MEMORY;
     566       82941 : done:
     567       82941 :         TALLOC_FREE(tmp_ctx);
     568       82941 :         return nt_status;
     569             : }
     570             : 
     571             : /*
     572             :  * Check a username and password, and return the final session_info.
     573             :  * We also log the authorization of the session here, just as
     574             :  * gensec_session_info() does.
     575             :  */
     576          98 : NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
     577             :                                           TALLOC_CTX *mem_ctx,
     578             :                                           struct auth_usersupplied_info *user_info,
     579             :                                           struct auth_session_info **session_info)
     580             : {
     581           0 :         NTSTATUS nt_status;
     582           0 :         void *server_info;
     583          98 :         uint8_t authoritative = 1;
     584          98 :         struct tevent_context *ev = NULL;
     585          98 :         struct tevent_req *subreq = NULL;
     586           0 :         bool ok;
     587             : 
     588          98 :         ev = samba_tevent_context_init(talloc_tos());
     589          98 :         if (ev == NULL) {
     590           0 :                 return NT_STATUS_NO_MEMORY;
     591             :         }
     592             : 
     593          98 :         subreq = auth_context->check_ntlm_password_send(ev, ev,
     594             :                                                         auth_context,
     595             :                                                         user_info);
     596          98 :         if (subreq == NULL) {
     597           0 :                 TALLOC_FREE(ev);
     598           0 :                 return NT_STATUS_NO_MEMORY;
     599             :         }
     600          98 :         ok = tevent_req_poll_ntstatus(subreq, ev, &nt_status);
     601          98 :         if (!ok) {
     602           0 :                 TALLOC_FREE(ev);
     603           0 :                 return nt_status;
     604             :         }
     605          98 :         nt_status = auth_context->check_ntlm_password_recv(subreq,
     606             :                                                            talloc_tos(),
     607             :                                                            &authoritative,
     608             :                                                            &server_info,
     609             :                                                            NULL, NULL);
     610          98 :         TALLOC_FREE(ev);
     611          98 :         if (!NT_STATUS_IS_OK(nt_status)) {
     612           2 :                 return nt_status;
     613             :         }
     614             : 
     615          96 :         nt_status = auth_context->generate_session_info(auth_context,
     616             :                                                         mem_ctx,
     617             :                                                         server_info,
     618             :                                                         user_info->client.account_name,
     619             :                                                         AUTH_SESSION_INFO_UNIX_TOKEN |
     620             :                                                         AUTH_SESSION_INFO_DEFAULT_GROUPS |
     621             :                                                         AUTH_SESSION_INFO_NTLM,
     622             :                                                         session_info);
     623          96 :         TALLOC_FREE(server_info);
     624             : 
     625          96 :         if (!NT_STATUS_IS_OK(nt_status)) {
     626           0 :                 return nt_status;
     627             :         }
     628             : 
     629             :         /*
     630             :          * This is rather redundant (the authentication has just been
     631             :          * logged, with much the same details), but because we want to
     632             :          * log all authorizations consistently (be they NLTM, NTLMSSP
     633             :          * or krb5) we log this info again as an authorization.
     634             :          */
     635          96 :         log_successful_authz_event(auth_context->msg_ctx,
     636             :                                    auth_context->lp_ctx,
     637             :                                    user_info->remote_host,
     638             :                                    user_info->local_host,
     639             :                                    user_info->service_description,
     640             :                                    user_info->auth_description,
     641             :                                    AUTHZ_TRANSPORT_PROTECTION_SMB,
     642             :                                    *session_info,
     643             :                                    NULL /* client_audit_info */,
     644             :                                    NULL /* server_audit_info */);
     645             : 
     646          96 :         return nt_status;
     647             : }

Generated by: LCOV version 1.14