LCOV - code coverage report
Current view: top level - source4/kdc/mit-kdb - kdb_samba_policies.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 229 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 8 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Samba KDB plugin for MIT Kerberos
       5             : 
       6             :    Copyright (c) 2010      Simo Sorce <idra@samba.org>.
       7             :    Copyright (c) 2014-2021 Andreas Schneider <asn@samba.org>
       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 "lib/replace/replace.h"
      24             : #include "lib/replace/system/kerberos.h"
      25             : #include "lib/util/data_blob.h"
      26             : #include "lib/util/debug.h"
      27             : #include "lib/util/fault.h"
      28             : #include "lib/util/memory.h"
      29             : 
      30             : #include <profile.h>
      31             : #include <kdb.h>
      32             : 
      33             : #include "kdc/mit_samba.h"
      34             : #include "kdb_samba.h"
      35             : 
      36             : #undef DBGC_CLASS
      37             : #define DBGC_CLASS DBGC_KERBEROS
      38             : 
      39             : /* FIXME: This is a krb5 function which is exported, but in no header */
      40             : extern krb5_error_code decode_krb5_padata_sequence(const krb5_data *output,
      41             :                                                    krb5_pa_data ***rep);
      42             : 
      43           0 : static krb5_error_code ks_get_netbios_name(krb5_address **addrs, char **name)
      44             : {
      45           0 :         char *nb_name = NULL;
      46             :         int len, i;
      47             : 
      48           0 :         for (i = 0; addrs[i]; i++) {
      49           0 :                 if (addrs[i]->addrtype != ADDRTYPE_NETBIOS) {
      50           0 :                         continue;
      51             :                 }
      52           0 :                 len = MIN(addrs[i]->length, 15);
      53           0 :                 nb_name = strndup((const char *)addrs[i]->contents, len);
      54           0 :                 if (!nb_name) {
      55           0 :                         return ENOMEM;
      56             :                 }
      57           0 :                 break;
      58             :         }
      59             : 
      60           0 :         if (nb_name) {
      61             :                 /* Strip space padding */
      62           0 :                 i = strlen(nb_name) - 1;
      63           0 :                 for (i = strlen(nb_name) - 1;
      64           0 :                      i > 0 && nb_name[i] == ' ';
      65           0 :                      i--) {
      66           0 :                         nb_name[i] = '\0';
      67             :                 }
      68             :         }
      69             : 
      70           0 :         *name = nb_name;
      71             : 
      72           0 :         return 0;
      73             : }
      74             : 
      75           0 : krb5_error_code kdb_samba_db_check_policy_as(krb5_context context,
      76             :                                              krb5_kdc_req *kdcreq,
      77             :                                              krb5_db_entry *client,
      78             :                                              krb5_db_entry *server,
      79             :                                              krb5_timestamp kdc_time,
      80             :                                              const char **status,
      81             :                                              krb5_pa_data ***e_data_out)
      82             : {
      83             :         struct mit_samba_context *mit_ctx;
      84             :         krb5_error_code code;
      85           0 :         char *client_name = NULL;
      86           0 :         char *server_name = NULL;
      87           0 :         char *netbios_name = NULL;
      88           0 :         char *realm = NULL;
      89           0 :         bool password_change = false;
      90             :         krb5_const_principal client_princ;
      91           0 :         DATA_BLOB int_data = { NULL, 0 };
      92             :         krb5_data d;
      93             :         krb5_pa_data **e_data;
      94             : 
      95           0 :         mit_ctx = ks_get_context(context);
      96           0 :         if (mit_ctx == NULL) {
      97           0 :                 return KRB5_KDB_DBNOTINITED;
      98             :         }
      99             : 
     100             :         /* Prefer canonicalised name from client entry */
     101           0 :         client_princ = client ? client->princ : kdcreq->client;
     102             : 
     103           0 :         if (client_princ == NULL || ks_is_kadmin(context, client_princ)) {
     104           0 :                 return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
     105             :         }
     106             : 
     107           0 :         if (krb5_princ_size(context, kdcreq->server) == 2 &&
     108           0 :             ks_is_kadmin_changepw(context, kdcreq->server)) {
     109           0 :                 code = krb5_get_default_realm(context, &realm);
     110           0 :                 if (code) {
     111           0 :                         goto done;
     112             :                 }
     113             : 
     114           0 :                 if (ks_data_eq_string(kdcreq->server->realm, realm)) {
     115           0 :                         password_change = true;
     116             :                 }
     117             :         }
     118             : 
     119           0 :         code = krb5_unparse_name(context, kdcreq->server, &server_name);
     120           0 :         if (code) {
     121           0 :                 goto done;
     122             :         }
     123             : 
     124           0 :         code = krb5_unparse_name(context, client_princ, &client_name);
     125           0 :         if (code) {
     126           0 :                 goto done;
     127             :         }
     128             : 
     129           0 :         if (kdcreq->addresses) {
     130           0 :                 code = ks_get_netbios_name(kdcreq->addresses, &netbios_name);
     131           0 :                 if (code) {
     132           0 :                         goto done;
     133             :                 }
     134             :         }
     135             : 
     136           0 :         code = mit_samba_check_client_access(mit_ctx,
     137             :                                              client,
     138             :                                              client_name,
     139             :                                              server,
     140             :                                              server_name,
     141             :                                              netbios_name,
     142             :                                              password_change,
     143             :                                              &int_data);
     144             : 
     145           0 :         if (int_data.length && int_data.data) {
     146             : 
     147             :                 /* make sure the mapped return code is returned - gd */
     148             :                 int code_tmp;
     149             : 
     150           0 :                 d = ks_make_data(int_data.data, int_data.length);
     151             : 
     152           0 :                 code_tmp = decode_krb5_padata_sequence(&d, &e_data);
     153           0 :                 if (code_tmp == 0) {
     154           0 :                         *e_data_out = e_data;
     155             :                 }
     156             :         }
     157           0 : done:
     158           0 :         free(realm);
     159           0 :         free(server_name);
     160           0 :         free(client_name);
     161           0 :         free(netbios_name);
     162             : 
     163           0 :         return code;
     164             : }
     165             : 
     166           0 : static krb5_error_code ks_get_pac(krb5_context context,
     167             :                                   uint32_t flags,
     168             :                                   krb5_db_entry *client,
     169             :                                   krb5_db_entry *server,
     170             :                                   krb5_keyblock *client_key,
     171             :                                   krb5_pac *pac)
     172             : {
     173             :         struct mit_samba_context *mit_ctx;
     174             :         krb5_error_code code;
     175             : 
     176           0 :         mit_ctx = ks_get_context(context);
     177           0 :         if (mit_ctx == NULL) {
     178           0 :                 return KRB5_KDB_DBNOTINITED;
     179             :         }
     180             : 
     181           0 :         code = mit_samba_get_pac(mit_ctx,
     182             :                                  context,
     183             :                                  flags,
     184             :                                  client,
     185             :                                  server,
     186             :                                  client_key,
     187             :                                  pac);
     188           0 :         if (code != 0) {
     189           0 :                 return code;
     190             :         }
     191             : 
     192           0 :         return code;
     193             : }
     194             : 
     195             : #if KRB5_KDB_DAL_MAJOR_VERSION < 9
     196           0 : static krb5_error_code ks_verify_pac(krb5_context context,
     197             :                                      unsigned int flags,
     198             :                                      krb5_const_principal client_princ,
     199             :                                      krb5_db_entry *client,
     200             :                                      krb5_db_entry *server,
     201             :                                      krb5_db_entry *krbtgt,
     202             :                                      krb5_keyblock *server_key,
     203             :                                      krb5_keyblock *krbtgt_key,
     204             :                                      krb5_timestamp authtime,
     205             :                                      krb5_authdata **tgt_auth_data,
     206             :                                      krb5_pac *pac)
     207             : {
     208             :         struct mit_samba_context *mit_ctx;
     209           0 :         krb5_authdata **authdata = NULL;
     210           0 :         krb5_pac ipac = NULL;
     211           0 :         DATA_BLOB logon_data = { NULL, 0 };
     212             :         krb5_error_code code;
     213             : 
     214           0 :         mit_ctx = ks_get_context(context);
     215           0 :         if (mit_ctx == NULL) {
     216           0 :                 return KRB5_KDB_DBNOTINITED;
     217             :         }
     218             : 
     219             :         /* find the existing PAC, if present */
     220           0 :         code = krb5_find_authdata(context,
     221             :                                   tgt_auth_data,
     222             :                                   NULL,
     223             :                                   KRB5_AUTHDATA_WIN2K_PAC,
     224             :                                   &authdata);
     225           0 :         if (code != 0) {
     226           0 :                 return code;
     227             :         }
     228             : 
     229             :         /* no pac data */
     230           0 :         if (authdata == NULL) {
     231           0 :                 return 0;
     232             :         }
     233             : 
     234           0 :         SMB_ASSERT(authdata[0] != NULL);
     235             : 
     236           0 :         if (authdata[1] != NULL) {
     237           0 :                 code = KRB5KDC_ERR_BADOPTION; /* XXX */
     238           0 :                 goto done;
     239             :         }
     240             : 
     241           0 :         code = krb5_pac_parse(context,
     242           0 :                               authdata[0]->contents,
     243           0 :                               authdata[0]->length,
     244             :                               &ipac);
     245           0 :         if (code != 0) {
     246           0 :                 goto done;
     247             :         }
     248             : 
     249             :         /* TODO: verify this is correct
     250             :          *
     251             :          * In the constrained delegation case, the PAC is from a service
     252             :          * ticket rather than a TGT; we must verify the server and KDC
     253             :          * signatures to assert that the server did not forge the PAC.
     254             :          */
     255           0 :         if (flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) {
     256           0 :                 code = krb5_pac_verify(context,
     257             :                                        ipac,
     258             :                                        authtime,
     259             :                                        client_princ,
     260             :                                        server_key,
     261             :                                        krbtgt_key);
     262             :         } else {
     263           0 :                 code = krb5_pac_verify(context,
     264             :                                        ipac,
     265             :                                        authtime,
     266             :                                        client_princ,
     267             :                                        krbtgt_key,
     268             :                                        NULL);
     269             :         }
     270           0 :         if (code != 0) {
     271           0 :                 goto done;
     272             :         }
     273             : 
     274             :         /* check and update PAC */
     275           0 :         code = krb5_pac_parse(context,
     276           0 :                               authdata[0]->contents,
     277           0 :                               authdata[0]->length,
     278             :                               pac);
     279           0 :         if (code != 0) {
     280           0 :                 goto done;
     281             :         }
     282             : 
     283           0 :         code = mit_samba_reget_pac(mit_ctx,
     284             :                                    context,
     285             :                                    flags,
     286             :                                    client_princ,
     287             :                                    client,
     288             :                                    server,
     289             :                                    krbtgt,
     290             :                                    krbtgt_key,
     291             :                                    pac);
     292             : 
     293           0 : done:
     294           0 :         krb5_free_authdata(context, authdata);
     295           0 :         krb5_pac_free(context, ipac);
     296           0 :         free(logon_data.data);
     297             : 
     298           0 :         return code;
     299             : }
     300             : 
     301           0 : krb5_error_code kdb_samba_db_sign_auth_data(krb5_context context,
     302             :                                             unsigned int flags,
     303             :                                             krb5_const_principal client_princ,
     304             :                                             krb5_const_principal server_princ,
     305             :                                             krb5_db_entry *client,
     306             :                                             krb5_db_entry *server,
     307             :                                             krb5_db_entry *krbtgt,
     308             :                                             krb5_db_entry *local_krbtgt,
     309             :                                             krb5_keyblock *client_key,
     310             :                                             krb5_keyblock *server_key,
     311             :                                             krb5_keyblock *krbtgt_key,
     312             :                                             krb5_keyblock *local_krbtgt_key,
     313             :                                             krb5_keyblock *session_key,
     314             :                                             krb5_timestamp authtime,
     315             :                                             krb5_authdata **tgt_auth_data,
     316             :                                             void *authdata_info,
     317             :                                             krb5_data ***auth_indicators,
     318             :                                             krb5_authdata ***signed_auth_data)
     319             : {
     320           0 :         krb5_const_principal ks_client_princ = NULL;
     321           0 :         krb5_db_entry *client_entry = NULL;
     322           0 :         krb5_authdata **pac_auth_data = NULL;
     323           0 :         krb5_authdata **authdata = NULL;
     324             :         krb5_boolean is_as_req;
     325             :         krb5_error_code code;
     326           0 :         krb5_pac pac = NULL;
     327             :         krb5_data pac_data;
     328           0 :         bool with_pac = false;
     329           0 :         bool generate_pac = false;
     330           0 :         char *client_name = NULL;
     331             : 
     332             : 
     333           0 :         krbtgt = krbtgt == NULL ? local_krbtgt : krbtgt;
     334           0 :         krbtgt_key = krbtgt_key == NULL ? local_krbtgt_key : krbtgt_key;
     335             : 
     336             :         /* FIXME: We don't support S4U yet */
     337           0 :         if (flags & KRB5_KDB_FLAGS_S4U) {
     338           0 :                 return KRB5_KDB_DBTYPE_NOSUP;
     339             :         }
     340             : 
     341           0 :         is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
     342             : 
     343             :         /*
     344             :          * When using s4u2proxy client_princ actually refers to the proxied user
     345             :          * while client->princ to the proxy service asking for the TGS on behalf
     346             :          * of the proxied user. So always use client_princ in preference.
     347             :          *
     348             :          * Note that when client principal is not NULL, client entry might be
     349             :          * NULL for cross-realm case, so we need to make sure to not
     350             :          * dereference NULL pointer here.
     351             :          */
     352           0 :         if (client_princ != NULL) {
     353           0 :                 ks_client_princ = client_princ;
     354           0 :                 if (!is_as_req) {
     355           0 :                         krb5_boolean is_equal = false;
     356             : 
     357           0 :                         if (client != NULL && client->princ != NULL) {
     358             :                                 is_equal =
     359           0 :                                         krb5_principal_compare(context,
     360             :                                                                client_princ,
     361           0 :                                                                client->princ);
     362             :                         }
     363             : 
     364             :                         /*
     365             :                          * When client principal is the same as supplied client
     366             :                          * entry, don't fetch it.
     367             :                          */
     368           0 :                         if (!is_equal) {
     369           0 :                                 code = ks_get_principal(context,
     370             :                                                         ks_client_princ,
     371             :                                                         0,
     372             :                                                         &client_entry);
     373           0 :                                 if (code != 0) {
     374           0 :                                         (void)krb5_unparse_name(context,
     375             :                                                                 ks_client_princ,
     376             :                                                                 &client_name);
     377             : 
     378           0 :                                         DBG_DEBUG("We didn't find the client "
     379             :                                                   "principal [%s] in our "
     380             :                                                   "database.\n",
     381             :                                                   client_name);
     382           0 :                                         SAFE_FREE(client_name);
     383             : 
     384             :                                         /*
     385             :                                          * If we didn't find client_princ in our
     386             :                                          * database it might be from another
     387             :                                          * realm.
     388             :                                          */
     389           0 :                                         client_entry = NULL;
     390             :                                 }
     391             :                         }
     392             :                 }
     393             :         } else {
     394           0 :                 if (client == NULL) {
     395           0 :                         *signed_auth_data = NULL;
     396           0 :                         return 0;
     397             :                 }
     398           0 :                 ks_client_princ = client->princ;
     399             :         }
     400             : 
     401           0 :         if (client_entry == NULL) {
     402           0 :                 client_entry = client;
     403             :         }
     404             : 
     405           0 :         if (is_as_req) {
     406           0 :                 with_pac = mit_samba_princ_needs_pac(client_entry);
     407             :         } else {
     408           0 :                 with_pac = mit_samba_princ_needs_pac(server);
     409             :         }
     410             : 
     411           0 :         code = krb5_unparse_name(context,
     412             :                                  client_princ,
     413             :                                  &client_name);
     414           0 :         if (code != 0) {
     415           0 :                 goto done;
     416             :         }
     417             : 
     418           0 :         if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC) != 0) {
     419           0 :                 generate_pac = true;
     420             :         }
     421             : 
     422           0 :         DBG_DEBUG("*** Sign data for client principal: %s [%s %s%s]\n",
     423             :                   client_name,
     424             :                   is_as_req ? "AS-REQ" : "TGS_REQ",
     425             :                   with_pac ? is_as_req ? "WITH_PAC" : "FIND_PAC" : "NO_PAC",
     426             :                   generate_pac ? " GENERATE_PAC" : "");
     427             : 
     428             :         /*
     429             :          * Generate PAC for the AS-REQ or check or generate one for the TGS if
     430             :          * needed.
     431             :          */
     432           0 :         if (with_pac && generate_pac) {
     433           0 :                 DBG_DEBUG("Generate PAC for AS-REQ [%s]\n", client_name);
     434             : 
     435           0 :                 code = krb5_pac_init(context, &pac);
     436           0 :                 if (code != 0) {
     437           0 :                         goto done;
     438             :                 }
     439             : 
     440           0 :                 code = ks_get_pac(context,
     441             :                                   flags,
     442             :                                   client_entry,
     443             :                                   server,
     444             :                                   NULL,
     445             :                                   &pac);
     446           0 :                 if (code != 0) {
     447           0 :                         goto done;
     448             :                 }
     449           0 :         } else if (with_pac && !is_as_req) {
     450             :                 /*
     451             :                  * Find the PAC in the TGS, if one exists.
     452             :                  */
     453           0 :                 code = krb5_find_authdata(context,
     454             :                                           tgt_auth_data,
     455             :                                           NULL,
     456             :                                           KRB5_AUTHDATA_WIN2K_PAC,
     457             :                                           &pac_auth_data);
     458           0 :                 if (code != 0) {
     459           0 :                         DBG_ERR("krb5_find_authdata failed: %d\n", code);
     460           0 :                         goto done;
     461             :                 }
     462           0 :                 DBG_DEBUG("Found PAC data for TGS-REQ [%s]\n", client_name);
     463             : 
     464           0 :                 if (pac_auth_data != NULL && pac_auth_data[0] != NULL) {
     465           0 :                         if (pac_auth_data[1] != NULL) {
     466           0 :                                 DBG_ERR("Invalid PAC data!\n");
     467           0 :                                 code = KRB5KDC_ERR_BADOPTION;
     468           0 :                                 goto done;
     469             :                         }
     470             : 
     471           0 :                         DBG_DEBUG("Verify PAC for TGS [%s]\n",
     472             :                                 client_name);
     473             : 
     474           0 :                         code = ks_verify_pac(context,
     475             :                                              flags,
     476             :                                              ks_client_princ,
     477             :                                              client_entry,
     478             :                                              server,
     479             :                                              krbtgt,
     480             :                                              server_key,
     481             :                                              krbtgt_key,
     482             :                                              authtime,
     483             :                                              tgt_auth_data,
     484             :                                              &pac);
     485           0 :                         if (code != 0) {
     486           0 :                                 goto done;
     487             :                         }
     488             :                 } else {
     489           0 :                         if (flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) {
     490           0 :                                 DBG_DEBUG("Generate PAC for constrained"
     491             :                                           "delegation TGS [%s]\n",
     492             :                                           client_name);
     493             : 
     494           0 :                                 code = krb5_pac_init(context, &pac);
     495           0 :                                 if (code != 0) {
     496           0 :                                         goto done;
     497             :                                 }
     498             : 
     499           0 :                                 code = ks_get_pac(context,
     500             :                                                   flags,
     501             :                                                   client_entry,
     502             :                                                   server,
     503             :                                                   NULL,
     504             :                                                   &pac);
     505           0 :                                 if (code != 0 && code != ENOENT) {
     506           0 :                                         goto done;
     507             :                                 }
     508             :                         }
     509             :                 }
     510             :         }
     511             : 
     512           0 :         if (pac == NULL) {
     513           0 :                 DBG_DEBUG("No PAC data - we're done [%s]\n", client_name);
     514           0 :                 *signed_auth_data = NULL;
     515           0 :                 code = 0;
     516           0 :                 goto done;
     517             :         }
     518             : 
     519           0 :         DBG_DEBUG("Signing PAC for %s [%s]\n",
     520             :                   is_as_req ? "AS-REQ" : "TGS-REQ",
     521             :                   client_name);
     522           0 :         code = krb5_pac_sign(context, pac, authtime, ks_client_princ,
     523             :                         server_key, krbtgt_key, &pac_data);
     524           0 :         if (code != 0) {
     525           0 :                 DBG_ERR("krb5_pac_sign failed: %d\n", code);
     526           0 :                 goto done;
     527             :         }
     528             : 
     529           0 :         authdata = calloc(2, sizeof(krb5_authdata *));
     530           0 :         if (authdata == NULL) {
     531           0 :                 goto done;
     532             :         }
     533             : 
     534           0 :         authdata[0] = malloc(sizeof(krb5_authdata));
     535           0 :         if (authdata[0] == NULL) {
     536           0 :                 goto done;
     537             :         }
     538             : 
     539             :         /* put in signed data */
     540           0 :         authdata[0]->magic = KV5M_AUTHDATA;
     541           0 :         authdata[0]->ad_type = KRB5_AUTHDATA_WIN2K_PAC;
     542           0 :         authdata[0]->contents = (krb5_octet *)pac_data.data;
     543           0 :         authdata[0]->length = pac_data.length;
     544             : 
     545           0 :         code = krb5_encode_authdata_container(context,
     546             :                                               KRB5_AUTHDATA_IF_RELEVANT,
     547             :                                               authdata,
     548             :                                               signed_auth_data);
     549           0 :         if (code != 0) {
     550           0 :                 goto done;
     551             :         }
     552             : 
     553           0 :         code = 0;
     554             : 
     555           0 : done:
     556           0 :         if (client_entry != NULL && client_entry != client) {
     557           0 :                 ks_free_principal(context, client_entry);
     558             :         }
     559           0 :         SAFE_FREE(client_name);
     560           0 :         krb5_free_authdata(context, authdata);
     561           0 :         krb5_pac_free(context, pac);
     562             : 
     563           0 :         return code;
     564             : }
     565             : #else /* KRB5_KDB_DAL_MAJOR_VERSION >= 9 */
     566             : static krb5_error_code ks_update_pac(krb5_context context,
     567             :                                      int flags,
     568             :                                      krb5_db_entry *client,
     569             :                                      krb5_db_entry *server,
     570             :                                      krb5_db_entry *signing_krbtgt,
     571             :                                      krb5_pac old_pac,
     572             :                                      krb5_pac new_pac)
     573             : {
     574             :         struct mit_samba_context *mit_ctx = NULL;
     575             :         krb5_error_code code;
     576             : 
     577             :         mit_ctx = ks_get_context(context);
     578             :         if (mit_ctx == NULL) {
     579             :                 return KRB5_KDB_DBNOTINITED;
     580             :         }
     581             : 
     582             :         code = mit_samba_update_pac(mit_ctx,
     583             :                                     context,
     584             :                                     flags,
     585             :                                     client,
     586             :                                     server,
     587             :                                     signing_krbtgt,
     588             :                                     old_pac,
     589             :                                     new_pac);
     590             :         if (code != 0) {
     591             :                 return code;
     592             :         }
     593             : 
     594             :         return code;
     595             : }
     596             : 
     597             : krb5_error_code kdb_samba_db_issue_pac(krb5_context context,
     598             :                                        unsigned int flags,
     599             :                                        krb5_db_entry *client,
     600             :                                        krb5_keyblock *replaced_reply_key,
     601             :                                        krb5_db_entry *server,
     602             :                                        krb5_db_entry *signing_krbtgt,
     603             :                                        krb5_timestamp authtime,
     604             :                                        krb5_pac old_pac,
     605             :                                        krb5_pac new_pac,
     606             :                                        krb5_data ***auth_indicators)
     607             : {
     608             :         char *client_name = NULL;
     609             :         char *server_name = NULL;
     610             :         krb5_error_code code = EINVAL;
     611             : 
     612             :         /* The KDC handles both signing and verification for us. */
     613             : 
     614             :         if (client != NULL) {
     615             :                 code = krb5_unparse_name(context,
     616             :                                          client->princ,
     617             :                                          &client_name);
     618             :                 if (code != 0) {
     619             :                         return code;
     620             :                 }
     621             :         }
     622             : 
     623             :         if (server != NULL) {
     624             :                 code = krb5_unparse_name(context,
     625             :                                          server->princ,
     626             :                                          &server_name);
     627             :                 if (code != 0) {
     628             :                         SAFE_FREE(client_name);
     629             :                         return code;
     630             :                 }
     631             :         }
     632             : 
     633             :         /*
     634             :          * Get a new PAC for AS-REQ or S4U2Self for our realm.
     635             :          *
     636             :          * For a simple cross-realm S4U2Proxy there will be the following TGS
     637             :          * requests after the client realm is identified:
     638             :          *
     639             :          * 1. server@SREALM to SREALM for krbtgt/CREALM@SREALM -- a regular TGS
     640             :          *    request with server's normal TGT and no S4U2Self padata.
     641             :          * 2. server@SREALM to CREALM for server@SREALM (expressed as an
     642             :          *    enterprise principal), with the TGT from #1 as header ticket and
     643             :          *    S4U2Self padata identifying the client.
     644             :          * 3. server@SREALM to SREALM for server@SREALM with S4U2Self padata,
     645             :          *    with the referral TGT from #2 as header ticket
     646             :          *
     647             :          * In request 2 the PROTOCOL_TRANSITION and CROSS_REALM flags are set,
     648             :          * and the request is for a local client (so client != NULL) and we
     649             :          * want to make a new PAC.
     650             :          *
     651             :          * In request 3 the PROTOCOL_TRANSITION and CROSS_REALM flags are also
     652             :          * set, but the request is for a non-local client (so client == NULL)
     653             :          * and we want to copy the subject PAC contained in the referral TGT.
     654             :          */
     655             :         if (old_pac == NULL ||
     656             :             (client != NULL && (flags & KRB5_KDB_FLAG_PROTOCOL_TRANSITION))) {
     657             :                 DBG_NOTICE("Generate PAC for AS-REQ [client=%s, flags=%#08x]\n",
     658             :                            client_name != NULL ? client_name : "<unknown>",
     659             :                            flags);
     660             : 
     661             :                 code = ks_get_pac(context,
     662             :                                   flags,
     663             :                                   client,
     664             :                                   server,
     665             :                                   replaced_reply_key,
     666             :                                   &new_pac);
     667             :         } else {
     668             :                 DBG_NOTICE("Update PAC for TGS-REQ [client=%s, server=%s, "
     669             :                            "flags=%#08x]\n",
     670             :                            client_name != NULL ? client_name : "<unknown>",
     671             :                            server_name != NULL ? server_name : "<unknown>",
     672             :                            flags);
     673             : 
     674             :                 code = ks_update_pac(context,
     675             :                                 flags,
     676             :                                 client,
     677             :                                 server,
     678             :                                 signing_krbtgt,
     679             :                                 old_pac,
     680             :                                 new_pac);
     681             :         }
     682             :         SAFE_FREE(client_name);
     683             :         SAFE_FREE(server_name);
     684             : 
     685             :         return code;
     686             : }
     687             : #endif /* KRB5_KDB_DAL_MAJOR_VERSION */
     688             : 
     689           0 : krb5_error_code kdb_samba_db_check_allowed_to_delegate(krb5_context context,
     690             :                                                        krb5_const_principal client,
     691             :                                                        const krb5_db_entry *server,
     692             :                                                        krb5_const_principal proxy)
     693             : {
     694           0 :         struct mit_samba_context *mit_ctx = NULL;
     695             : 
     696           0 :         mit_ctx = ks_get_context(context);
     697           0 :         if (mit_ctx == NULL) {
     698           0 :                 return KRB5_KDB_DBNOTINITED;
     699             :         }
     700             : 
     701           0 :         return mit_samba_check_s4u2proxy(mit_ctx,
     702             :                                          server,
     703             :                                          proxy);
     704             : 
     705             : }
     706             : 
     707             : 
     708             : #if KRB5_KDB_DAL_MAJOR_VERSION >= 9
     709             : krb5_error_code kdb_samba_db_allowed_to_delegate_from(
     710             :                 krb5_context context,
     711             :                 krb5_const_principal client_principal,
     712             :                 krb5_const_principal server_principal,
     713             :                 krb5_pac header_pac,
     714             :                 const krb5_db_entry *proxy)
     715             : {
     716             :         struct mit_samba_context *mit_ctx = NULL;
     717             :         krb5_error_code code;
     718             : 
     719             :         mit_ctx = ks_get_context(context);
     720             :         if (mit_ctx == NULL) {
     721             :                 return KRB5_KDB_DBNOTINITED;
     722             :         }
     723             : 
     724             :         code = mit_samba_check_allowed_to_delegate_from(mit_ctx,
     725             :                                                         client_principal,
     726             :                                                         server_principal,
     727             :                                                         header_pac,
     728             :                                                         proxy);
     729             : 
     730             :         return code;
     731             : }
     732             : #endif
     733             : 
     734             : 
     735           0 : static void samba_bad_password_count(krb5_db_entry *client,
     736             :                                      krb5_error_code error_code)
     737             : {
     738           0 :         switch (error_code) {
     739           0 :         case 0:
     740           0 :                 mit_samba_zero_bad_password_count(client);
     741           0 :                 break;
     742           0 :         case KRB5KDC_ERR_PREAUTH_FAILED:
     743             :         case KRB5KRB_AP_ERR_BAD_INTEGRITY:
     744           0 :                 mit_samba_update_bad_password_count(client);
     745           0 :                 break;
     746             :         }
     747           0 : }
     748             : 
     749           0 : void kdb_samba_db_audit_as_req(krb5_context context,
     750             :                                krb5_kdc_req *request,
     751             :                                const krb5_address *local_addr,
     752             :                                const krb5_address *remote_addr,
     753             :                                krb5_db_entry *client,
     754             :                                krb5_db_entry *server,
     755             :                                krb5_timestamp authtime,
     756             :                                krb5_error_code error_code)
     757             : {
     758             :         /*
     759             :          * FIXME: This segfaulted with a FAST test
     760             :          * FIND_FAST: <unknown client> for <unknown server>, Unknown FAST armor type 0
     761             :          */
     762           0 :         if (client == NULL) {
     763           0 :                 return;
     764             :         }
     765             : 
     766           0 :         samba_bad_password_count(client, error_code);
     767             : 
     768             :         /* TODO: perform proper audit logging for addresses */
     769             : }

Generated by: LCOV version 1.13