LCOV - code coverage report
Current view: top level - source4/kdc - wdc-samba4.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 207 310 66.8 %
Date: 2021-09-23 10:06:22 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    PAC Glue between Samba and the KDC
       5             : 
       6             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2009
       7             :    Copyright (C) Simo Sorce <idra@samba.org> 2010
       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             : 
      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 "kdc/kdc-glue.h"
      26             : #include "kdc/pac-glue.h"
      27             : 
      28             : /*
      29             :  * Given the right private pointer from hdb_samba4,
      30             :  * get a PAC from the attached ldb messages.
      31             :  *
      32             :  * For PKINIT we also get pk_reply_key and can add PAC_CREDENTIAL_INFO.
      33             :  */
      34       26965 : static krb5_error_code samba_wdc_get_pac(void *priv, krb5_context context,
      35             :                                          struct hdb_entry_ex *client,
      36             :                                          const krb5_keyblock *pk_reply_key,
      37             :                                          krb5_pac *pac)
      38             : {
      39             :         TALLOC_CTX *mem_ctx;
      40       26965 :         DATA_BLOB *logon_blob = NULL;
      41       26965 :         DATA_BLOB *cred_ndr = NULL;
      42       26965 :         DATA_BLOB **cred_ndr_ptr = NULL;
      43       26965 :         DATA_BLOB _cred_blob = data_blob_null;
      44       26965 :         DATA_BLOB *cred_blob = NULL;
      45       26965 :         DATA_BLOB *upn_blob = NULL;
      46             :         krb5_error_code ret;
      47             :         NTSTATUS nt_status;
      48       26965 :         struct samba_kdc_entry *skdc_entry =
      49       26965 :                 talloc_get_type_abort(client->ctx,
      50             :                 struct samba_kdc_entry);
      51             : 
      52       26965 :         mem_ctx = talloc_named(client->ctx, 0, "samba_get_pac context");
      53       26965 :         if (!mem_ctx) {
      54           0 :                 return ENOMEM;
      55             :         }
      56             : 
      57       26965 :         if (pk_reply_key != NULL) {
      58          26 :                 cred_ndr_ptr = &cred_ndr;
      59             :         }
      60             : 
      61       26965 :         nt_status = samba_kdc_get_pac_blobs(mem_ctx, skdc_entry,
      62             :                                             &logon_blob,
      63             :                                             cred_ndr_ptr,
      64             :                                             &upn_blob);
      65       26965 :         if (!NT_STATUS_IS_OK(nt_status)) {
      66           0 :                 talloc_free(mem_ctx);
      67           0 :                 return EINVAL;
      68             :         }
      69             : 
      70       26965 :         if (pk_reply_key != NULL && cred_ndr != NULL) {
      71          26 :                 ret = samba_kdc_encrypt_pac_credentials(context,
      72             :                                                         pk_reply_key,
      73             :                                                         cred_ndr,
      74             :                                                         mem_ctx,
      75             :                                                         &_cred_blob);
      76          26 :                 if (ret != 0) {
      77           0 :                         talloc_free(mem_ctx);
      78           0 :                         return ret;
      79             :                 }
      80          26 :                 cred_blob = &_cred_blob;
      81             :         }
      82             : 
      83       26965 :         ret = samba_make_krb5_pac(context, logon_blob, cred_blob,
      84             :                                   upn_blob, NULL, pac);
      85             : 
      86       26965 :         talloc_free(mem_ctx);
      87       26965 :         return ret;
      88             : }
      89             : 
      90       26939 : static krb5_error_code samba_wdc_get_pac_compat(void *priv, krb5_context context,
      91             :                                                 struct hdb_entry_ex *client,
      92             :                                                 krb5_pac *pac)
      93             : {
      94       26939 :         return samba_wdc_get_pac(priv, context, client, NULL, pac);
      95             : }
      96             : 
      97             : /* Resign (and reform, including possibly new groups) a PAC */
      98             : 
      99       39896 : static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context,
     100             :                                            const krb5_principal client_principal,
     101             :                                            const krb5_principal delegated_proxy_principal,
     102             :                                            struct hdb_entry_ex *client,
     103             :                                            struct hdb_entry_ex *server,
     104             :                                            struct hdb_entry_ex *krbtgt,
     105             :                                            krb5_pac *pac)
     106             : {
     107       39896 :         struct samba_kdc_entry *p =
     108       39896 :                 talloc_get_type_abort(server->ctx,
     109             :                 struct samba_kdc_entry);
     110       39896 :         struct samba_kdc_entry *krbtgt_skdc_entry =
     111       39896 :                 talloc_get_type_abort(krbtgt->ctx,
     112             :                 struct samba_kdc_entry);
     113       39896 :         TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac context");
     114       39896 :         krb5_pac new_pac = NULL;
     115       39896 :         DATA_BLOB *pac_blob = NULL;
     116       39896 :         DATA_BLOB *upn_blob = NULL;
     117       39896 :         DATA_BLOB *deleg_blob = NULL;
     118             :         krb5_error_code ret;
     119             :         NTSTATUS nt_status;
     120             :         struct PAC_SIGNATURE_DATA *pac_srv_sig;
     121             :         struct PAC_SIGNATURE_DATA *pac_kdc_sig;
     122             :         bool is_in_db, is_untrusted;
     123       39896 :         size_t num_types = 0;
     124       39896 :         uint32_t *types = NULL;
     125       39896 :         uint32_t forced_next_type = 0;
     126       39896 :         size_t i = 0;
     127       39896 :         ssize_t logon_info_idx = -1;
     128       39896 :         ssize_t delegation_idx = -1;
     129       39896 :         ssize_t logon_name_idx = -1;
     130       39896 :         ssize_t upn_dns_info_idx = -1;
     131       39896 :         ssize_t srv_checksum_idx = -1;
     132       39896 :         ssize_t kdc_checksum_idx = -1;
     133             : 
     134       39896 :         if (!mem_ctx) {
     135           0 :                 return ENOMEM;
     136             :         }
     137             : 
     138             :         /* The user account may be set not to want the PAC */
     139       39896 :         if (!samba_princ_needs_pac(p)) {
     140           0 :                 talloc_free(mem_ctx);
     141           0 :                 return EINVAL;
     142             :         }
     143             : 
     144             :         /* If the krbtgt was generated by an RODC, and we are not that
     145             :          * RODC, then we need to regenerate the PAC - we can't trust
     146             :          * it */
     147       39896 :         ret = samba_krbtgt_is_in_db(krbtgt_skdc_entry, &is_in_db, &is_untrusted);
     148       39896 :         if (ret != 0) {
     149           0 :                 talloc_free(mem_ctx);
     150           0 :                 return ret;
     151             :         }
     152             : 
     153       39896 :         if (is_untrusted) {
     154          47 :                 struct samba_kdc_entry *client_skdc_entry = NULL;
     155             : 
     156          47 :                 if (client == NULL) {
     157           0 :                         return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
     158             :                 }
     159             : 
     160          47 :                 client_skdc_entry = talloc_get_type_abort(client->ctx,
     161             :                                                           struct samba_kdc_entry);
     162             : 
     163          47 :                 nt_status = samba_kdc_get_pac_blobs(mem_ctx, client_skdc_entry,
     164             :                                                     &pac_blob, NULL, &upn_blob);
     165          47 :                 if (!NT_STATUS_IS_OK(nt_status)) {
     166           0 :                         talloc_free(mem_ctx);
     167           0 :                         return EINVAL;
     168             :                 }
     169             :         } else {
     170       39849 :                 pac_blob = talloc_zero(mem_ctx, DATA_BLOB);
     171       39849 :                 if (!pac_blob) {
     172           0 :                         talloc_free(mem_ctx);
     173           0 :                         return ENOMEM;
     174             :                 }
     175             : 
     176       39849 :                 pac_srv_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA);
     177       39849 :                 if (!pac_srv_sig) {
     178           0 :                         talloc_free(mem_ctx);
     179           0 :                         return ENOMEM;
     180             :                 }
     181             : 
     182       39849 :                 pac_kdc_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA);
     183       39849 :                 if (!pac_kdc_sig) {
     184           0 :                         talloc_free(mem_ctx);
     185           0 :                         return ENOMEM;
     186             :                 }
     187             : 
     188       39849 :                 nt_status = samba_kdc_update_pac_blob(mem_ctx, context,
     189             :                                                       krbtgt_skdc_entry, p,
     190             :                                                       *pac, pac_blob,
     191             :                                                       pac_srv_sig, pac_kdc_sig);
     192       39849 :                 if (!NT_STATUS_IS_OK(nt_status)) {
     193           0 :                         DEBUG(0, ("Building PAC failed: %s\n",
     194             :                                   nt_errstr(nt_status)));
     195           0 :                         talloc_free(mem_ctx);
     196           0 :                         return EINVAL;
     197             :                 }
     198             :                 
     199       39849 :                 if (is_in_db) {
     200             :                         /* Now check the KDC signature, fetching the correct key based on the enc type */
     201       39792 :                         ret = kdc_check_pac(context, pac_srv_sig->signature, pac_kdc_sig, krbtgt);
     202       39792 :                         if (ret != 0) {
     203           0 :                                 DEBUG(1, ("PAC KDC signature failed to verify\n"));
     204           0 :                                 talloc_free(mem_ctx);
     205           0 :                                 return ret;
     206             :                         }
     207             :                 }
     208             :         }
     209             : 
     210       39896 :         if (delegated_proxy_principal) {
     211          18 :                 deleg_blob = talloc_zero(mem_ctx, DATA_BLOB);
     212          18 :                 if (!deleg_blob) {
     213           0 :                         talloc_free(mem_ctx);
     214           0 :                         return ENOMEM;
     215             :                 }
     216             : 
     217          18 :                 nt_status = samba_kdc_update_delegation_info_blob(mem_ctx,
     218             :                                         context, *pac,
     219          18 :                                         server->entry.principal,
     220             :                                         delegated_proxy_principal,
     221             :                                         deleg_blob);
     222          18 :                 if (!NT_STATUS_IS_OK(nt_status)) {
     223           0 :                         DEBUG(0, ("Building PAC failed: %s\n",
     224             :                                   nt_errstr(nt_status)));
     225           0 :                         talloc_free(mem_ctx);
     226           0 :                         return EINVAL;
     227             :                 }
     228             :         }
     229             : 
     230             :         /* Check the types of the given PAC */
     231       39896 :         ret = krb5_pac_get_types(context, *pac, &num_types, &types);
     232       39896 :         if (ret != 0) {
     233           0 :                 talloc_free(mem_ctx);
     234           0 :                 return ret;
     235             :         }
     236             : 
     237      238367 :         for (i = 0; i < num_types; i++) {
     238      199560 :                 switch (types[i]) {
     239       39896 :                 case PAC_TYPE_LOGON_INFO:
     240       39896 :                         if (logon_info_idx != -1) {
     241           0 :                                 DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n",
     242             :                                           (int)types[i],
     243             :                                           (int)logon_info_idx,
     244             :                                           (int)i));
     245           0 :                                 SAFE_FREE(types);
     246           0 :                                 talloc_free(mem_ctx);
     247           0 :                                 return EINVAL;
     248             :                         }
     249       39896 :                         logon_info_idx = i;
     250       39896 :                         break;
     251           0 :                 case PAC_TYPE_CONSTRAINED_DELEGATION:
     252           0 :                         if (delegation_idx != -1) {
     253           0 :                                 DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n",
     254             :                                           (int)types[i],
     255             :                                           (int)logon_info_idx,
     256             :                                           (int)i));
     257           0 :                                 SAFE_FREE(types);
     258           0 :                                 talloc_free(mem_ctx);
     259           0 :                                 return EINVAL;
     260             :                         }
     261           0 :                         delegation_idx = i;
     262           0 :                         break;
     263       39896 :                 case PAC_TYPE_LOGON_NAME:
     264       39896 :                         if (logon_name_idx != -1) {
     265           0 :                                 DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n",
     266             :                                           (int)types[i],
     267             :                                           (int)logon_info_idx,
     268             :                                           (int)i));
     269           0 :                                 SAFE_FREE(types);
     270           0 :                                 talloc_free(mem_ctx);
     271           0 :                                 return EINVAL;
     272             :                         }
     273       39896 :                         logon_name_idx = i;
     274       39896 :                         break;
     275       39896 :                 case PAC_TYPE_UPN_DNS_INFO:
     276       39896 :                         if (upn_dns_info_idx != -1) {
     277           0 :                                 DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n",
     278             :                                           (int)types[i],
     279             :                                           (int)logon_info_idx,
     280             :                                           (int)i));
     281           0 :                                 SAFE_FREE(types);
     282           0 :                                 talloc_free(mem_ctx);
     283           0 :                                 return EINVAL;
     284             :                         }
     285       39896 :                         upn_dns_info_idx = i;
     286       39896 :                         break;
     287       39896 :                 case PAC_TYPE_SRV_CHECKSUM:
     288       39896 :                         if (srv_checksum_idx != -1) {
     289           0 :                                 DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n",
     290             :                                           (int)types[i],
     291             :                                           (int)logon_info_idx,
     292             :                                           (int)i));
     293           0 :                                 SAFE_FREE(types);
     294           0 :                                 talloc_free(mem_ctx);
     295           0 :                                 return EINVAL;
     296             :                         }
     297       39896 :                         srv_checksum_idx = i;
     298       39896 :                         break;
     299       39896 :                 case PAC_TYPE_KDC_CHECKSUM:
     300       39896 :                         if (kdc_checksum_idx != -1) {
     301           0 :                                 DEBUG(1, ("logon type[%d] twice [%d] and [%d]: \n",
     302             :                                           (int)types[i],
     303             :                                           (int)logon_info_idx,
     304             :                                           (int)i));
     305           0 :                                 SAFE_FREE(types);
     306           0 :                                 talloc_free(mem_ctx);
     307           0 :                                 return EINVAL;
     308             :                         }
     309       39896 :                         kdc_checksum_idx = i;
     310       39896 :                         break;
     311          80 :                 default:
     312          80 :                         continue;
     313             :                 }
     314             :         }
     315             : 
     316       39896 :         if (logon_info_idx == -1) {
     317           0 :                 DEBUG(1, ("PAC_TYPE_LOGON_INFO missing\n"));
     318           0 :                 SAFE_FREE(types);
     319           0 :                 talloc_free(mem_ctx);
     320           0 :                 return EINVAL;
     321             :         }
     322       39896 :         if (logon_name_idx == -1) {
     323           0 :                 DEBUG(1, ("PAC_TYPE_LOGON_NAME missing\n"));
     324           0 :                 SAFE_FREE(types);
     325           0 :                 talloc_free(mem_ctx);
     326           0 :                 return EINVAL;
     327             :         }
     328       39896 :         if (srv_checksum_idx == -1) {
     329           0 :                 DEBUG(1, ("PAC_TYPE_SRV_CHECKSUM missing\n"));
     330           0 :                 SAFE_FREE(types);
     331           0 :                 talloc_free(mem_ctx);
     332           0 :                 return EINVAL;
     333             :         }
     334       39896 :         if (kdc_checksum_idx == -1) {
     335           0 :                 DEBUG(1, ("PAC_TYPE_KDC_CHECKSUM missing\n"));
     336           0 :                 SAFE_FREE(types);
     337           0 :                 talloc_free(mem_ctx);
     338           0 :                 return EINVAL;
     339             :         }
     340             : 
     341             :         /* Build an updated PAC */
     342       39896 :         ret = krb5_pac_init(context, &new_pac);
     343       39896 :         if (ret != 0) {
     344           0 :                 SAFE_FREE(types);
     345           0 :                 talloc_free(mem_ctx);
     346           0 :                 return ret;
     347             :         }
     348             : 
     349      238385 :         for (i = 0;;) {
     350      239474 :                 const uint8_t zero_byte = 0;
     351             :                 krb5_data type_data;
     352      239474 :                 DATA_BLOB type_blob = data_blob_null;
     353             :                 uint32_t type;
     354             : 
     355      239474 :                 if (forced_next_type != 0) {
     356             :                         /*
     357             :                          * We need to inject possible missing types
     358             :                          */
     359          18 :                         type = forced_next_type;
     360          18 :                         forced_next_type = 0;
     361      239456 :                 } else if (i < num_types) {
     362      199560 :                         type = types[i];
     363      199560 :                         i++;
     364             :                 } else {
     365       38807 :                         break;
     366             :                 }
     367             : 
     368      199578 :                 switch (type) {
     369       39896 :                 case PAC_TYPE_LOGON_INFO:
     370       39896 :                         type_blob = *pac_blob;
     371             : 
     372       39896 :                         if (delegation_idx == -1 && deleg_blob != NULL) {
     373             :                                 /* inject CONSTRAINED_DELEGATION behind */
     374          18 :                                 forced_next_type = PAC_TYPE_CONSTRAINED_DELEGATION;
     375             :                         }
     376       38807 :                         break;
     377          18 :                 case PAC_TYPE_CONSTRAINED_DELEGATION:
     378          18 :                         if (deleg_blob != NULL) {
     379          18 :                                 type_blob = *deleg_blob;
     380             :                         }
     381          18 :                         break;
     382          80 :                 case PAC_TYPE_CREDENTIAL_INFO:
     383             :                         /*
     384             :                          * Note that we copy the credential blob,
     385             :                          * as it's only usable with the PKINIT based
     386             :                          * AS-REP reply key, it's only available on the
     387             :                          * host which did the AS-REQ/AS-REP exchange.
     388             :                          *
     389             :                          * This matches Windows 2008R2...
     390             :                          */
     391          80 :                         break;
     392       39896 :                 case PAC_TYPE_LOGON_NAME:
     393             :                         /*
     394             :                          * this is generated in the main KDC code
     395             :                          * we just add a place holder here.
     396             :                          */
     397       39896 :                         type_blob = data_blob_const(&zero_byte, 1);
     398             : 
     399       39896 :                         if (upn_dns_info_idx == -1 && upn_blob != NULL) {
     400             :                                 /* inject UPN_DNS_INFO behind */
     401           0 :                                 forced_next_type = PAC_TYPE_UPN_DNS_INFO;
     402             :                         }
     403       38807 :                         break;
     404       39896 :                 case PAC_TYPE_UPN_DNS_INFO:
     405             :                         /*
     406             :                          * Replace in the RODC case, otherwise
     407             :                          * upn_blob is NULL and we just copy.
     408             :                          */
     409       39896 :                         if (upn_blob != NULL) {
     410          47 :                                 type_blob = *upn_blob;
     411             :                         }
     412       38807 :                         break;
     413       39896 :                 case PAC_TYPE_SRV_CHECKSUM:
     414             :                         /*
     415             :                          * this are generated in the main KDC code
     416             :                          * we just add a place holder here.
     417             :                          */
     418       39896 :                         type_blob = data_blob_const(&zero_byte, 1);
     419       39896 :                         break;
     420       39896 :                 case PAC_TYPE_KDC_CHECKSUM:
     421             :                         /*
     422             :                          * this are generated in the main KDC code
     423             :                          * we just add a place holders here.
     424             :                          */
     425       39896 :                         type_blob = data_blob_const(&zero_byte, 1);
     426       39896 :                         break;
     427           0 :                 default:
     428             :                         /* just copy... */
     429           0 :                         break;
     430             :                 }
     431             : 
     432      199578 :                 if (type_blob.length != 0) {
     433      314942 :                         ret = smb_krb5_copy_data_contents(&type_data,
     434      155293 :                                                           type_blob.data,
     435             :                                                           type_blob.length);
     436      159649 :                         if (ret != 0) {
     437           0 :                                 SAFE_FREE(types);
     438           0 :                                 krb5_pac_free(context, new_pac);
     439           0 :                                 talloc_free(mem_ctx);
     440           0 :                                 return ret;
     441             :                         }
     442             :                 } else {
     443       39929 :                         ret = krb5_pac_get_buffer(context, *pac,
     444             :                                                   type, &type_data);
     445       39929 :                         if (ret != 0) {
     446           0 :                                 SAFE_FREE(types);
     447           0 :                                 krb5_pac_free(context, new_pac);
     448           0 :                                 talloc_free(mem_ctx);
     449           0 :                                 return ret;
     450             :                         }
     451             :                 }
     452             : 
     453      199578 :                 ret = krb5_pac_add_buffer(context, new_pac,
     454             :                                           type, &type_data);
     455      199578 :                 smb_krb5_free_data_contents(context, &type_data);
     456      199578 :                 if (ret != 0) {
     457           0 :                         SAFE_FREE(types);
     458           0 :                         krb5_pac_free(context, new_pac);
     459           0 :                         talloc_free(mem_ctx);
     460           0 :                         return ret;
     461             :                 }
     462             :         }
     463             : 
     464       79792 :         SAFE_FREE(types);
     465             : 
     466             :         /* We now replace the pac */
     467       39896 :         krb5_pac_free(context, *pac);
     468       39896 :         *pac = new_pac;
     469             : 
     470       39896 :         talloc_free(mem_ctx);
     471       39896 :         return ret;
     472             : }
     473             : 
     474       26353 : static char *get_netbios_name(TALLOC_CTX *mem_ctx, HostAddresses *addrs)
     475             : {
     476       26353 :         char *nb_name = NULL;
     477             :         size_t len;
     478             :         unsigned int i;
     479             : 
     480       26353 :         for (i = 0; addrs && i < addrs->len; i++) {
     481          98 :                 if (addrs->val[i].addr_type != KRB5_ADDRESS_NETBIOS) {
     482           0 :                         continue;
     483             :                 }
     484          98 :                 len = MIN(addrs->val[i].address.length, 15);
     485          98 :                 nb_name = talloc_strndup(mem_ctx,
     486          98 :                                          addrs->val[i].address.data, len);
     487          98 :                 if (nb_name) {
     488          98 :                         break;
     489             :                 }
     490             :         }
     491             : 
     492       26353 :         if ((nb_name == NULL) || (nb_name[0] == '\0')) {
     493       25665 :                 return NULL;
     494             :         }
     495             : 
     496             :         /* Strip space padding */
     497         614 :         for (len = strlen(nb_name) - 1;
     498         516 :              (len > 0) && (nb_name[len] == ' ');
     499         418 :              --len) {
     500         418 :                 nb_name[len] = '\0';
     501             :         }
     502             : 
     503          98 :         return nb_name;
     504             : }
     505             : 
     506          10 : static krb5_data fill_krb5_data(void *data, size_t length)
     507             : {
     508             :         krb5_data kdata;
     509             : 
     510          10 :         kdata.data = data;
     511          10 :         kdata.length = length;
     512             : 
     513          10 :         return kdata;
     514             : }
     515             : 
     516             : /* this function allocates 'data' using malloc.
     517             :  * The caller is responsible for freeing it */
     518          10 : static void samba_kdc_build_edata_reply(NTSTATUS nt_status, DATA_BLOB *e_data)
     519             : {
     520          10 :         krb5_error_code ret = 0;
     521             :         PA_DATA pa;
     522             :         unsigned char *buf;
     523             :         size_t len;
     524             : 
     525          10 :         if (!e_data)
     526           0 :                 return;
     527             : 
     528          10 :         e_data->data   = NULL;
     529          10 :         e_data->length = 0;
     530             : 
     531          10 :         pa.padata_type          = KRB5_PADATA_PW_SALT;
     532          10 :         pa.padata_value.length  = 12;
     533          10 :         pa.padata_value.data    = malloc(pa.padata_value.length);
     534          10 :         if (!pa.padata_value.data) {
     535           0 :                 e_data->length = 0;
     536           0 :                 e_data->data = NULL;
     537           0 :                 return;
     538             :         }
     539             : 
     540          10 :         SIVAL(pa.padata_value.data, 0, NT_STATUS_V(nt_status));
     541          10 :         SIVAL(pa.padata_value.data, 4, 0);
     542          10 :         SIVAL(pa.padata_value.data, 8, 1);
     543             : 
     544          10 :         ASN1_MALLOC_ENCODE(PA_DATA, buf, len, &pa, &len, ret);
     545          10 :         free(pa.padata_value.data);
     546          10 :         if (ret) {
     547           0 :                 return;
     548             :         }
     549             : 
     550          10 :         e_data->data   = buf;
     551          10 :         e_data->length = len;
     552             : 
     553          10 :         return;
     554             : }
     555             : 
     556             : 
     557       26353 : static krb5_error_code samba_wdc_check_client_access(void *priv,
     558             :                                                      krb5_context context,
     559             :                                                      krb5_kdc_configuration *config,
     560             :                                                      hdb_entry_ex *client_ex, const char *client_name,
     561             :                                                      hdb_entry_ex *server_ex, const char *server_name,
     562             :                                                      KDC_REQ *req,
     563             :                                                      krb5_data *e_data)
     564             : {
     565             :         struct samba_kdc_entry *kdc_entry;
     566             :         bool password_change;
     567             :         char *workstation;
     568             :         NTSTATUS nt_status;
     569             : 
     570       26353 :         kdc_entry = talloc_get_type(client_ex->ctx, struct samba_kdc_entry);
     571       26353 :         password_change = (server_ex && server_ex->entry.flags.change_pw);
     572       26353 :         workstation = get_netbios_name((TALLOC_CTX *)client_ex->ctx,
     573             :                                         req->req_body.addresses);
     574             : 
     575       26353 :         nt_status = samba_kdc_check_client_access(kdc_entry,
     576             :                                                   client_name,
     577             :                                                   workstation,
     578             :                                                   password_change);
     579             : 
     580       26353 :         if (!NT_STATUS_IS_OK(nt_status)) {
     581          10 :                 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MEMORY)) {
     582           0 :                         return ENOMEM;
     583             :                 }
     584             : 
     585          10 :                 if (e_data) {
     586             :                         DATA_BLOB data;
     587             : 
     588          10 :                         samba_kdc_build_edata_reply(nt_status, &data);
     589          10 :                         *e_data = fill_krb5_data(data.data, data.length);
     590             :                 }
     591             : 
     592          10 :                 return samba_kdc_map_policy_err(nt_status);
     593             :         }
     594             : 
     595             :         /* Now do the standard Heimdal check */
     596       26343 :         return kdc_check_flags(context, config,
     597             :                                client_ex, client_name,
     598             :                                server_ex, server_name,
     599       26343 :                                req->msg_type == krb_as_req);
     600             : }
     601             : 
     602          92 : static krb5_error_code samba_wdc_plugin_init(krb5_context context, void **ptr)
     603             : {
     604          92 :         *ptr = NULL;
     605          92 :         return 0;
     606             : }
     607             : 
     608           0 : static void samba_wdc_plugin_fini(void *ptr)
     609             : {
     610           0 :         return;
     611             : }
     612             : 
     613             : struct krb5plugin_windc_ftable windc_plugin_table = {
     614             :         .minor_version = KRB5_WINDC_PLUGIN_MINOR,
     615             :         .init = samba_wdc_plugin_init,
     616             :         .fini = samba_wdc_plugin_fini,
     617             :         .pac_generate = samba_wdc_get_pac_compat,
     618             :         .pac_verify = samba_wdc_reget_pac,
     619             :         .client_access = samba_wdc_check_client_access,
     620             :         .pac_pk_generate = samba_wdc_get_pac,
     621             : };
     622             : 
     623             : 

Generated by: LCOV version 1.13