LCOV - code coverage report
Current view: top level - auth/gensec - gensec_util.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 84 101 83.2 %
Date: 2024-04-21 15:09:00 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Generic Authentication Interface
       5             : 
       6             :    Copyright (C) Andrew Tridgell 2003
       7             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2006
       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 "auth/gensec/gensec.h"
      25             : #include "auth/gensec/gensec_internal.h"
      26             : #include "auth/common_auth.h"
      27             : #include "../lib/util/asn1.h"
      28             : #include "param/param.h"
      29             : #include "libds/common/roles.h"
      30             : 
      31             : #undef DBGC_CLASS
      32             : #define DBGC_CLASS DBGC_AUTH
      33             : 
      34       33476 : NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
      35             :                                           struct gensec_security *gensec_security,
      36             :                                           struct smb_krb5_context *smb_krb5_context,
      37             :                                           DATA_BLOB *pac_blob,
      38             :                                           const char *principal_string,
      39             :                                           const struct tsocket_address *remote_address,
      40             :                                           struct auth_session_info **session_info)
      41             : {
      42       33476 :         uint32_t session_info_flags = 0;
      43       33476 :         struct auth4_context *auth_context = NULL;
      44         881 :         NTSTATUS status;
      45             : 
      46       33476 :         if (gensec_security->want_features & GENSEC_FEATURE_UNIX_TOKEN) {
      47        8175 :                 session_info_flags |= AUTH_SESSION_INFO_UNIX_TOKEN;
      48             :         }
      49             : 
      50       33476 :         session_info_flags |= AUTH_SESSION_INFO_DEFAULT_GROUPS;
      51             : 
      52       33476 :         if (!pac_blob) {
      53          13 :                 enum server_role server_role =
      54          13 :                         lpcfg_server_role(gensec_security->settings->lp_ctx);
      55             : 
      56             :                 /*
      57             :                  * For any domain setup (DC or member) we require having
      58             :                  * a PAC, as the service ticket comes from an AD DC,
      59             :                  * which will always provide a PAC, unless
      60             :                  * UF_NO_AUTH_DATA_REQUIRED is configured for our
      61             :                  * account, but that's just an invalid configuration,
      62             :                  * the admin configured for us!
      63             :                  *
      64             :                  * As a legacy case, we still allow kerberos tickets from an MIT
      65             :                  * realm, but only in standalone mode. In that mode we'll only
      66             :                  * ever accept a kerberos authentication with a keytab file
      67             :                  * being explicitly configured via the 'keytab method' option.
      68             :                  */
      69          13 :                 if (server_role != ROLE_STANDALONE) {
      70          13 :                         DBG_WARNING("Unable to find PAC in ticket from %s, "
      71             :                                     "failing to allow access\n",
      72             :                                     principal_string);
      73          13 :                         return NT_STATUS_NO_IMPERSONATION_TOKEN;
      74             :                 }
      75           0 :                 DBG_NOTICE("Unable to find PAC for %s, resorting to local "
      76             :                            "user lookup\n", principal_string);
      77             :         }
      78             : 
      79       33463 :         auth_context = gensec_security->auth_context;
      80             : 
      81       33463 :         if ((auth_context == NULL) ||
      82       33463 :             (auth_context->generate_session_info_pac == NULL)) {
      83           0 :                 DBG_ERR("Cannot generate a session_info without "
      84             :                         "the auth_context\n");
      85           0 :                 return NT_STATUS_INTERNAL_ERROR;
      86             :         }
      87             : 
      88       33463 :         status = auth_context->generate_session_info_pac(
      89             :                 auth_context,
      90             :                 mem_ctx,
      91             :                 smb_krb5_context,
      92             :                 pac_blob,
      93             :                 principal_string,
      94             :                 remote_address,
      95             :                 session_info_flags,
      96             :                 session_info);
      97       33463 :         return status;
      98             : }
      99             : 
     100             : /*
     101             :   magic check a GSS-API wrapper packet for an Kerberos OID
     102             : */
     103          83 : static bool gensec_gssapi_check_oid(const DATA_BLOB *blob, const char *oid)
     104             : {
     105          83 :         bool ret = false;
     106          83 :         struct asn1_data *data = asn1_init(NULL, ASN1_MAX_TREE_DEPTH);
     107             : 
     108          83 :         if (!data) return false;
     109             : 
     110          83 :         if (!asn1_load(data, *blob)) goto err;
     111          83 :         if (!asn1_start_tag(data, ASN1_APPLICATION(0))) goto err;
     112          45 :         if (!asn1_check_OID(data, oid)) goto err;
     113             : 
     114          45 :         ret = !asn1_has_error(data);
     115             : 
     116          83 :   err:
     117             : 
     118          83 :         asn1_free(data);
     119          83 :         return ret;
     120             : }
     121             : 
     122             : /**
     123             :  * Check if the packet is one for the KRB5 mechanism
     124             :  *
     125             :  * NOTE: This is a helper that can be employed by multiple mechanisms, do
     126             :  * not make assumptions about the private_data
     127             :  *
     128             :  * @param gensec_security GENSEC state, unused
     129             :  * @param in The request, as a DATA_BLOB
     130             :  * @return Error, INVALID_PARAMETER if it's not a packet for us
     131             :  *                or NT_STATUS_OK if the packet is ok.
     132             :  */
     133             : 
     134          83 : NTSTATUS gensec_magic_check_krb5_oid(struct gensec_security *unused,
     135             :                                         const DATA_BLOB *blob)
     136             : {
     137          83 :         if (gensec_gssapi_check_oid(blob, GENSEC_OID_KERBEROS5)) {
     138          45 :                 return NT_STATUS_OK;
     139             :         } else {
     140          38 :                 return NT_STATUS_INVALID_PARAMETER;
     141             :         }
     142             : }
     143             : 
     144       50918 : void gensec_child_want_feature(struct gensec_security *gensec_security,
     145             :                                uint32_t feature)
     146             : {
     147       50918 :         struct gensec_security *child_security = gensec_security->child_security;
     148             : 
     149       50918 :         gensec_security->want_features |= feature;
     150       50918 :         if (child_security == NULL) {
     151       44479 :                 return;
     152             :         }
     153        5554 :         gensec_want_feature(child_security, feature);
     154             : }
     155             : 
     156     2669294 : bool gensec_child_have_feature(struct gensec_security *gensec_security,
     157             :                                uint32_t feature)
     158             : {
     159     2669294 :         struct gensec_security *child_security = gensec_security->child_security;
     160             : 
     161     2669294 :         if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
     162             :                 /*
     163             :                  * All mechs with sub (child) mechs need to provide DCERPC
     164             :                  * header signing! This is required because the negotiation
     165             :                  * of header signing is done before the authentication
     166             :                  * is completed.
     167             :                  */
     168       17167 :                 return true;
     169             :         }
     170             : 
     171     2651833 :         if (child_security == NULL) {
     172           0 :                 return false;
     173             :         }
     174             : 
     175     2651833 :         return gensec_have_feature(child_security, feature);
     176             : }
     177             : 
     178      299426 : NTSTATUS gensec_child_unseal_packet(struct gensec_security *gensec_security,
     179             :                                     uint8_t *data, size_t length,
     180             :                                     const uint8_t *whole_pdu, size_t pdu_length,
     181             :                                     const DATA_BLOB *sig)
     182             : {
     183      299426 :         if (gensec_security->child_security == NULL) {
     184           0 :                 return NT_STATUS_INVALID_PARAMETER;
     185             :         }
     186             : 
     187      299426 :         return gensec_unseal_packet(gensec_security->child_security,
     188             :                                     data, length,
     189             :                                     whole_pdu, pdu_length,
     190             :                                     sig);
     191             : }
     192             : 
     193       58690 : NTSTATUS gensec_child_check_packet(struct gensec_security *gensec_security,
     194             :                                    const uint8_t *data, size_t length,
     195             :                                    const uint8_t *whole_pdu, size_t pdu_length,
     196             :                                    const DATA_BLOB *sig)
     197             : {
     198       58690 :         if (gensec_security->child_security == NULL) {
     199           0 :                 return NT_STATUS_INVALID_PARAMETER;
     200             :         }
     201             : 
     202       58690 :         return gensec_check_packet(gensec_security->child_security,
     203             :                                    data, length,
     204             :                                    whole_pdu, pdu_length,
     205             :                                    sig);
     206             : }
     207             : 
     208      299467 : NTSTATUS gensec_child_seal_packet(struct gensec_security *gensec_security,
     209             :                                   TALLOC_CTX *mem_ctx,
     210             :                                   uint8_t *data, size_t length,
     211             :                                   const uint8_t *whole_pdu, size_t pdu_length,
     212             :                                   DATA_BLOB *sig)
     213             : {
     214      299467 :         if (gensec_security->child_security == NULL) {
     215           0 :                 return NT_STATUS_INVALID_PARAMETER;
     216             :         }
     217             : 
     218      299467 :         return gensec_seal_packet(gensec_security->child_security,
     219             :                                   mem_ctx,
     220             :                                   data, length,
     221             :                                   whole_pdu, pdu_length,
     222             :                                   sig);
     223             : }
     224             : 
     225       58759 : NTSTATUS gensec_child_sign_packet(struct gensec_security *gensec_security,
     226             :                                   TALLOC_CTX *mem_ctx,
     227             :                                   const uint8_t *data, size_t length,
     228             :                                   const uint8_t *whole_pdu, size_t pdu_length,
     229             :                                   DATA_BLOB *sig)
     230             : {
     231       58759 :         if (gensec_security->child_security == NULL) {
     232           0 :                 return NT_STATUS_INVALID_PARAMETER;
     233             :         }
     234             : 
     235       58759 :         return gensec_sign_packet(gensec_security->child_security,
     236             :                                   mem_ctx,
     237             :                                   data, length,
     238             :                                   whole_pdu, pdu_length,
     239             :                                   sig);
     240             : }
     241             : 
     242     1474865 : NTSTATUS gensec_child_wrap(struct gensec_security *gensec_security,
     243             :                            TALLOC_CTX *mem_ctx,
     244             :                            const DATA_BLOB *in,
     245             :                            DATA_BLOB *out)
     246             : {
     247     1474865 :         if (gensec_security->child_security == NULL) {
     248           0 :                 return NT_STATUS_INVALID_PARAMETER;
     249             :         }
     250             : 
     251     1474865 :         return gensec_wrap(gensec_security->child_security,
     252             :                            mem_ctx, in, out);
     253             : }
     254             : 
     255     1474578 : NTSTATUS gensec_child_unwrap(struct gensec_security *gensec_security,
     256             :                              TALLOC_CTX *mem_ctx,
     257             :                              const DATA_BLOB *in,
     258             :                              DATA_BLOB *out)
     259             : {
     260     1474578 :         if (gensec_security->child_security == NULL) {
     261           0 :                 return NT_STATUS_INVALID_PARAMETER;
     262             :         }
     263             : 
     264     1474578 :         return gensec_unwrap(gensec_security->child_security,
     265             :                              mem_ctx, in, out);
     266             : }
     267             : 
     268      107520 : size_t gensec_child_sig_size(struct gensec_security *gensec_security,
     269             :                              size_t data_size)
     270             : {
     271      107520 :         if (gensec_security->child_security == NULL) {
     272           0 :                 return 0;
     273             :         }
     274             : 
     275      107520 :         return gensec_sig_size(gensec_security->child_security, data_size);
     276             : }
     277             : 
     278       51904 : size_t gensec_child_max_input_size(struct gensec_security *gensec_security)
     279             : {
     280       51904 :         if (gensec_security->child_security == NULL) {
     281           0 :                 return 0;
     282             :         }
     283             : 
     284       51904 :         return gensec_max_input_size(gensec_security->child_security);
     285             : }
     286             : 
     287       51904 : size_t gensec_child_max_wrapped_size(struct gensec_security *gensec_security)
     288             : {
     289       51904 :         if (gensec_security->child_security == NULL) {
     290           0 :                 return 0;
     291             :         }
     292             : 
     293       51904 :         return gensec_max_wrapped_size(gensec_security->child_security);
     294             : }
     295             : 
     296       38348 : NTSTATUS gensec_child_session_key(struct gensec_security *gensec_security,
     297             :                                   TALLOC_CTX *mem_ctx,
     298             :                                   DATA_BLOB *session_key)
     299             : {
     300       38348 :         if (gensec_security->child_security == NULL) {
     301           0 :                 return NT_STATUS_INVALID_PARAMETER;
     302             :         }
     303             : 
     304       38348 :         return gensec_session_key(gensec_security->child_security,
     305             :                                   mem_ctx,
     306             :                                   session_key);
     307             : }
     308             : 
     309       64707 : NTSTATUS gensec_child_session_info(struct gensec_security *gensec_security,
     310             :                                    TALLOC_CTX *mem_ctx,
     311             :                                    struct auth_session_info **session_info)
     312             : {
     313       64707 :         if (gensec_security->child_security == NULL) {
     314           0 :                 return NT_STATUS_INVALID_PARAMETER;
     315             :         }
     316             : 
     317       64707 :         return gensec_session_info(gensec_security->child_security,
     318             :                                    mem_ctx,
     319             :                                    session_info);
     320             : }
     321             : 
     322       49998 : NTTIME gensec_child_expire_time(struct gensec_security *gensec_security)
     323             : {
     324       49998 :         if (gensec_security->child_security == NULL) {
     325           0 :                 return GENSEC_EXPIRE_TIME_INFINITY;
     326             :         }
     327             : 
     328       49998 :         return gensec_expire_time(gensec_security->child_security);
     329             : }
     330             : 
     331       64633 : const char *gensec_child_final_auth_type(struct gensec_security *gensec_security)
     332             : {
     333       64633 :         if (gensec_security->child_security == NULL) {
     334           0 :                 return "NONE";
     335             :         }
     336             : 
     337       64633 :         return gensec_final_auth_type(gensec_security->child_security);
     338             : }

Generated by: LCOV version 1.14