Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

Location:
vendor/current/source4/kdc
Files:
7 added
2 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/kdc/db-glue.c

    r740 r988  
    3333#include "system/kerberos.h"
    3434#include "auth/kerberos/kerberos.h"
    35 #include <hdb.h>
     35#include "kdc/sdb.h"
    3636#include "kdc/samba_kdc.h"
    37 #include "kdc/kdc-policy.h"
     37#include "kdc/db-glue.h"
    3838
    3939#define SAMBA_KVNO_GET_KRBTGT(kvno) \
     
    6666};
    6767
    68 static KerberosTime ldb_msg_find_krb5time_ldap_time(struct ldb_message *msg, const char *attr, KerberosTime default_val)
     68
     69static time_t ldb_msg_find_krb5time_ldap_time(struct ldb_message *msg, const char *attr, time_t default_val)
    6970{
    7071    const char *tmp;
     
    8485}
    8586
    86 static HDBFlags uf2HDBFlags(krb5_context context, uint32_t userAccountControl, enum samba_kdc_ent_type ent_type)
     87static struct SDBFlags uf2SDBFlags(krb5_context context, uint32_t userAccountControl, enum samba_kdc_ent_type ent_type)
    8788{
    88         HDBFlags flags = int2HDBFlags(0);
     89        struct SDBFlags flags = int2SDBFlags(0);
    8990
    9091        /* we don't allow kadmin deletes */
     
    131132        }
    132133        if (userAccountControl & UF_LOCKOUT) {
    133                 flags.invalid = 1;
     134                flags.locked_out = 1;
    134135        }
    135136/*
     
    158159                flags.ok_as_delegate = 1;
    159160        }
     161        if (userAccountControl & UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION) {
     162                /*
     163                 * this is confusing...
     164                 *
     165                 * UF_TRUSTED_FOR_DELEGATION
     166                 * => ok_as_delegate
     167                 *
     168                 * and
     169                 *
     170                 * UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
     171                 * => trusted_for_delegation
     172                 */
     173                flags.trusted_for_delegation = 1;
     174        }
    160175        if (!(userAccountControl & UF_NOT_DELEGATED)) {
    161176                flags.forwardable = 1;
     
    174189static int samba_kdc_entry_destructor(struct samba_kdc_entry *p)
    175190{
    176     hdb_entry_ex *entry_ex = p->entry_ex;
    177     free_hdb_entry(&entry_ex->entry);
    178     return 0;
    179 }
    180 
    181 static void samba_kdc_free_entry(krb5_context context, hdb_entry_ex *entry_ex)
    182 {
    183         /* this function is called only from hdb_free_entry().
    184          * Make sure we neutralize the destructor or we will
    185          * get a double free later when hdb_free_entry() will
    186          * try to call free_hdb_entry() */
    187         talloc_set_destructor(entry_ex->ctx, NULL);
    188 
    189         /* now proceed to free the talloc part */
    190         talloc_free(entry_ex->ctx);
     191        if (p->entry_ex != NULL) {
     192                struct sdb_entry_ex *entry_ex = p->entry_ex;
     193                free_sdb_entry(&entry_ex->entry);
     194        }
     195
     196        return 0;
    191197}
    192198
     
    199205                                                    uint32_t userAccountControl,
    200206                                                    enum samba_kdc_ent_type ent_type,
    201                                                     hdb_entry_ex *entry_ex)
     207                                                    struct sdb_entry_ex *entry_ex)
    202208{
    203209        krb5_error_code ret = 0;
     
    359365                if (kdc_db_ctx->rodc) {
    360366                        /* We are on an RODC, but don't have keys for this account.  Signal this to the caller */
    361                         return HDB_ERR_NOT_FOUND_HERE;
     367                        /* TODO:  We need to call a generalised version of auth_sam_trigger_repl_secret from here */
     368                        return SDB_ERR_NOT_FOUND_HERE;
    362369                }
    363370
     
    370377        /* allocate space to decode into */
    371378        entry_ex->entry.keys.len = 0;
    372         entry_ex->entry.keys.val = calloc(allocated_keys, sizeof(Key));
     379        entry_ex->entry.keys.val = calloc(allocated_keys, sizeof(struct sdb_key));
    373380        if (entry_ex->entry.keys.val == NULL) {
    374381                ret = ENOMEM;
     
    377384
    378385        if (hash && (supported_enctypes & ENC_RC4_HMAC_MD5)) {
    379                 Key key;
    380 
    381                 key.mkvno = 0;
    382                 key.salt = NULL; /* No salt for this enc type */
    383 
    384                 ret = krb5_keyblock_init(context,
    385                                          ENCTYPE_ARCFOUR_HMAC,
    386                                          hash->hash, sizeof(hash->hash),
    387                                          &key.key);
     386                struct sdb_key key = {};
     387
     388                ret = smb_krb5_keyblock_init_contents(context,
     389                                                      ENCTYPE_ARCFOUR_HMAC,
     390                                                      hash->hash,
     391                                                      sizeof(hash->hash),
     392                                                      &key.key);
    388393                if (ret) {
    389394                        goto out;
     
    396401        if (pkb4) {
    397402                for (i=0; i < pkb4->num_keys; i++) {
    398                         Key key;
     403                        struct sdb_key key = {};
    399404
    400405                        if (!pkb4->keys[i].value) continue;
     
    403408                                continue;
    404409                        }
    405 
    406                         key.mkvno = 0;
    407                         key.salt = NULL;
    408410
    409411                        if (pkb4->salt.string) {
     
    418420                                }
    419421
    420                                 key.salt->type = hdb_pw_salt;
    421 
    422                                 ret = krb5_data_copy(&key.salt->salt, salt.data, salt.length);
     422                                key.salt->type = KRB5_PW_SALT;
     423
     424                                ret = krb5_copy_data_contents(&key.salt->salt,
     425                                                              salt.data,
     426                                                              salt.length);
    423427                                if (ret) {
    424428                                        free(key.salt);
     
    430434                        /* TODO: maybe pass the iteration_count somehow... */
    431435
    432                         ret = krb5_keyblock_init(context,
    433                                                 pkb4->keys[i].keytype,
    434                                                 pkb4->keys[i].value->data,
    435                                                 pkb4->keys[i].value->length,
    436                                                 &key.key);
     436                        ret = smb_krb5_keyblock_init_contents(context,
     437                                                              pkb4->keys[i].keytype,
     438                                                              pkb4->keys[i].value->data,
     439                                                              pkb4->keys[i].value->length,
     440                                                              &key.key);
    437441                        if (ret == KRB5_PROG_ETYPE_NOSUPP) {
    438442                                DEBUG(2,("Unsupported keytype ignored - type %u\n",
     
    443447                        if (ret) {
    444448                                if (key.salt) {
    445                                         free_Salt(key.salt);
     449                                        kerberos_free_data_contents(context, &key.salt->salt);
    446450                                        free(key.salt);
    447451                                        key.salt = NULL;
     
    455459        } else if (pkb3) {
    456460                for (i=0; i < pkb3->num_keys; i++) {
    457                         Key key;
     461                        struct sdb_key key = {};
    458462
    459463                        if (!pkb3->keys[i].value) continue;
     
    462466                                continue;
    463467                        }
    464 
    465                         key.mkvno = 0;
    466                         key.salt = NULL;
    467468
    468469                        if (pkb3->salt.string) {
     
    477478                                }
    478479
    479                                 key.salt->type = hdb_pw_salt;
    480 
    481                                 ret = krb5_data_copy(&key.salt->salt, salt.data, salt.length);
     480                                key.salt->type = KRB5_PW_SALT;
     481
     482                                ret = krb5_copy_data_contents(&key.salt->salt,
     483                                                              salt.data,
     484                                                              salt.length);
    482485                                if (ret) {
    483486                                        free(key.salt);
     
    487490                        }
    488491
    489                         ret = krb5_keyblock_init(context,
    490                                                 pkb3->keys[i].keytype,
    491                                                 pkb3->keys[i].value->data,
    492                                                 pkb3->keys[i].value->length,
    493                                                 &key.key);
     492                        ret = smb_krb5_keyblock_init_contents(context,
     493                                                              pkb3->keys[i].keytype,
     494                                                              pkb3->keys[i].value->data,
     495                                                              pkb3->keys[i].value->length,
     496                                                              &key.key);
    494497                        if (ret) {
    495498                                if (key.salt) {
    496                                         free_Salt(key.salt);
     499                                        kerberos_free_data_contents(context, &key.salt->salt);
    497500                                        free(key.salt);
    498501                                        key.salt = NULL;
     
    515518        }
    516519        return ret;
     520}
     521
     522static int principal_comp_strcmp_int(krb5_context context,
     523                                     krb5_const_principal principal,
     524                                     unsigned int component,
     525                                     const char *string,
     526                                     bool do_strcasecmp)
     527{
     528        const char *p;
     529        size_t len;
     530
     531#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING)
     532        p = krb5_principal_get_comp_string(context, principal, component);
     533        if (p == NULL) {
     534                return -1;
     535        }
     536        len = strlen(p);
     537#else
     538        krb5_data *d;
     539        if (component >= krb5_princ_size(context, principal)) {
     540                return -1;
     541        }
     542
     543        d = krb5_princ_component(context, principal, component);
     544        if (d == NULL) {
     545                return -1;
     546        }
     547
     548        p = d->data;
     549        len = d->length;
     550#endif
     551        if (do_strcasecmp) {
     552                return strncasecmp(p, string, len);
     553        } else {
     554                return strncmp(p, string, len);
     555        }
     556}
     557
     558static int principal_comp_strcasecmp(krb5_context context,
     559                                     krb5_const_principal principal,
     560                                     unsigned int component,
     561                                     const char *string)
     562{
     563        return principal_comp_strcmp_int(context, principal,
     564                                         component, string, true);
     565}
     566
     567static int principal_comp_strcmp(krb5_context context,
     568                                 krb5_const_principal principal,
     569                                 unsigned int component,
     570                                 const char *string)
     571{
     572        return principal_comp_strcmp_int(context, principal,
     573                                         component, string, false);
    517574}
    518575
     
    522579static krb5_error_code samba_kdc_message2entry(krb5_context context,
    523580                                               struct samba_kdc_db_context *kdc_db_ctx,
    524                                                TALLOC_CTX *mem_ctx, krb5_const_principal principal,
     581                                               TALLOC_CTX *mem_ctx,
     582                                               krb5_const_principal principal,
    525583                                               enum samba_kdc_ent_type ent_type,
    526584                                               unsigned flags,
    527585                                               struct ldb_dn *realm_dn,
    528586                                               struct ldb_message *msg,
    529                                                hdb_entry_ex *entry_ex)
     587                                               struct sdb_entry_ex *entry_ex)
    530588{
    531589        struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx;
    532590        uint32_t userAccountControl;
     591        uint32_t msDS_User_Account_Control_Computed;
    533592        unsigned int i;
    534593        krb5_error_code ret = 0;
     
    563622        }
    564623
    565         memset(entry_ex, 0, sizeof(*entry_ex));
    566 
    567         p = talloc(mem_ctx, struct samba_kdc_entry);
     624        ZERO_STRUCTP(entry_ex);
     625
     626        p = talloc_zero(mem_ctx, struct samba_kdc_entry);
    568627        if (!p) {
    569628                ret = ENOMEM;
     
    572631
    573632        p->kdc_db_ctx = kdc_db_ctx;
    574         p->entry_ex = entry_ex;
    575633        p->realm_dn = talloc_reference(p, realm_dn);
    576634        if (!p->realm_dn) {
     
    581639        talloc_set_destructor(p, samba_kdc_entry_destructor);
    582640
    583         /* make sure we do not have bogus data in there */
    584         memset(&entry_ex->entry, 0, sizeof(hdb_entry));
    585 
    586641        entry_ex->ctx = p;
    587         entry_ex->free_entry = samba_kdc_free_entry;
    588642
    589643        userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
    590644
    591 
    592         entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal)));
    593         if (ent_type == SAMBA_KDC_ENT_TYPE_ANY && principal == NULL) {
    594                 krb5_make_principal(context, &entry_ex->entry.principal, lpcfg_realm(lp_ctx), samAccountName, NULL);
     645        msDS_User_Account_Control_Computed
     646                = ldb_msg_find_attr_as_uint(msg,
     647                                            "msDS-User-Account-Control-Computed",
     648                                            UF_ACCOUNTDISABLE);
     649
     650        /*
     651         * This brings in the lockout flag, block the account if not
     652         * found.  We need the weird UF_ACCOUNTDISABLE check because
     653         * we do not want to fail open if the value is not returned,
     654         * but 0 is a valid value (all OK)
     655         */
     656        if (msDS_User_Account_Control_Computed == UF_ACCOUNTDISABLE) {
     657                ret = EINVAL;
     658                krb5_set_error_message(context, ret, "samba_kdc_message2entry: "
     659                                "no msDS-User-Account-Control-Computed present");
     660                goto out;
    595661        } else {
    596                 ret = copy_Principal(principal, entry_ex->entry.principal);
     662                userAccountControl |= msDS_User_Account_Control_Computed;
     663        }
     664
     665        /*
     666         * If we are set to canonicalize, we get back the fixed UPPER
     667         * case realm, and the real username (ie matching LDAP
     668         * samAccountName)
     669         *
     670         * Otherwise, if we are set to enterprise, we
     671         * get back the whole principal as-sent
     672         *
     673         * Finally, if we are not set to canonicalize, we get back the
     674         * fixed UPPER case realm, but the as-sent username
     675         */
     676
     677        if (ent_type == SAMBA_KDC_ENT_TYPE_KRBTGT) {
     678                if (flags & (SDB_F_CANON)) {
     679                        /*
     680                         * When requested to do so, ensure that the
     681                         * both realm values in the principal are set
     682                         * to the upper case, canonical realm
     683                         */
     684                        ret = smb_krb5_make_principal(context, &entry_ex->entry.principal,
     685                                                      lpcfg_realm(lp_ctx), "krbtgt",
     686                                                      lpcfg_realm(lp_ctx), NULL);
     687                        if (ret) {
     688                                krb5_clear_error_message(context);
     689                                goto out;
     690                        }
     691                        smb_krb5_principal_set_type(context, entry_ex->entry.principal, KRB5_NT_SRV_INST);
     692                } else {
     693                        ret = krb5_copy_principal(context, principal, &entry_ex->entry.principal);
     694                        if (ret) {
     695                                krb5_clear_error_message(context);
     696                                goto out;
     697                        }
     698                        /*
     699                         * this appears to be required regardless of
     700                         * the canonicalize flag from the client
     701                         */
     702                        ret = smb_krb5_principal_set_realm(context, entry_ex->entry.principal, lpcfg_realm(lp_ctx));
     703                        if (ret) {
     704                                krb5_clear_error_message(context);
     705                                goto out;
     706                        }
     707                }
     708
     709        } else if (ent_type == SAMBA_KDC_ENT_TYPE_ANY && principal == NULL) {
     710                ret = smb_krb5_make_principal(context, &entry_ex->entry.principal, lpcfg_realm(lp_ctx), samAccountName, NULL);
    597711                if (ret) {
    598712                        krb5_clear_error_message(context);
    599713                        goto out;
    600714                }
    601 
    602                 /* While we have copied the client principal, tests
    603                  * show that Win2k3 returns the 'corrected' realm, not
    604                  * the client-specified realm.  This code attempts to
    605                  * replace the client principal's realm with the one
    606                  * we determine from our records */
    607 
    608                 /* this has to be with malloc() */
    609                 krb5_principal_set_realm(context, entry_ex->entry.principal, lpcfg_realm(lp_ctx));
     715        } else if (flags & SDB_F_CANON && flags & SDB_F_FOR_AS_REQ) {
     716                /*
     717                 * SDB_F_CANON maps from the canonicalize flag in the
     718                 * packet, and has a different meaning between AS-REQ
     719                 * and TGS-REQ.  We only change the principal in the AS-REQ case
     720                 */
     721                ret = smb_krb5_make_principal(context, &entry_ex->entry.principal, lpcfg_realm(lp_ctx), samAccountName, NULL);
     722                if (ret) {
     723                        krb5_clear_error_message(context);
     724                        goto out;
     725                }
     726        } else {
     727                ret = krb5_copy_principal(context, principal, &entry_ex->entry.principal);
     728                if (ret) {
     729                        krb5_clear_error_message(context);
     730                        goto out;
     731                }
     732
     733                if (smb_krb5_principal_get_type(context, principal) != KRB5_NT_ENTERPRISE_PRINCIPAL) {
     734                        /* While we have copied the client principal, tests
     735                         * show that Win2k3 returns the 'corrected' realm, not
     736                         * the client-specified realm.  This code attempts to
     737                         * replace the client principal's realm with the one
     738                         * we determine from our records */
     739                       
     740                        /* this has to be with malloc() */
     741                        ret = smb_krb5_principal_set_realm(context, entry_ex->entry.principal, lpcfg_realm(lp_ctx));
     742                        if (ret) {
     743                                krb5_clear_error_message(context);
     744                                goto out;
     745                        }
     746                }
    610747        }
    611748
    612749        /* First try and figure out the flags based on the userAccountControl */
    613         entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type);
     750        entry_ex->entry.flags = uf2SDBFlags(context, userAccountControl, ent_type);
    614751
    615752        /* Windows 2008 seems to enforce this (very sensible) rule by
     
    624761                }
    625762        }
    626 
    627         if (flags & HDB_F_ADMIN_DATA) {
     763        /*
     764         * To give the correct type of error to the client, we must
     765         * not just return the entry without .server set, we must
     766         * pretend the principal does not exist.  Otherwise we may
     767         * return ERR_POLICY instead of
     768         * KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
     769         */
     770        if (ent_type == SAMBA_KDC_ENT_TYPE_SERVER && entry_ex->entry.flags.server == 0) {
     771                ret = SDB_ERR_NOENTRY;
     772                krb5_set_error_message(context, ret, "samba_kdc_message2entry: no servicePrincipalName present for this server, refusing with no-such-entry");
     773                goto out;
     774        }
     775        if (flags & SDB_F_ADMIN_DATA) {
    628776                /* These (created_by, modified_by) parts of the entry are not relevant for Samba4's use
    629777                 * of the Heimdal KDC.  They are stored in a the traditional
     
    634782                entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0);
    635783                /* use 'kadmin' for now (needed by mit_samba) */
    636                 krb5_make_principal(context,
    637                                     &entry_ex->entry.created_by.principal,
    638                                     lpcfg_realm(lp_ctx), "kadmin", NULL);
    639 
    640                 entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event));
     784
     785                ret = smb_krb5_make_principal(context,
     786                                              &entry_ex->entry.created_by.principal,
     787                                              lpcfg_realm(lp_ctx), "kadmin", NULL);
     788                if (ret) {
     789                        krb5_clear_error_message(context);
     790                        goto out;
     791                }
     792
     793                entry_ex->entry.modified_by = (struct sdb_event *) malloc(sizeof(struct sdb_event));
    641794                if (entry_ex->entry.modified_by == NULL) {
    642795                        ret = ENOMEM;
     
    648801                entry_ex->entry.modified_by->time = ldb_msg_find_krb5time_ldap_time(msg, "whenChanged", 0);
    649802                /* use 'kadmin' for now (needed by mit_samba) */
    650                 krb5_make_principal(context,
    651                                     &entry_ex->entry.modified_by->principal,
    652                                     lpcfg_realm(lp_ctx), "kadmin", NULL);
     803                ret = smb_krb5_make_principal(context,
     804                                              &entry_ex->entry.modified_by->principal,
     805                                              lpcfg_realm(lp_ctx), "kadmin", NULL);
     806                if (ret) {
     807                        krb5_clear_error_message(context);
     808                        goto out;
     809                }
    653810        }
    654811
     
    664821
    665822        if (rid == DOMAIN_RID_KRBTGT) {
     823                char *realm = NULL;
     824
    666825                entry_ex->entry.valid_end = NULL;
    667826                entry_ex->entry.pw_end = NULL;
     
    669828                entry_ex->entry.flags.invalid = 0;
    670829                entry_ex->entry.flags.server = 1;
     830
     831                realm = smb_krb5_principal_get_realm(context, principal);
     832                if (realm == NULL) {
     833                        ret = ENOMEM;
     834                        goto out;
     835                }
    671836
    672837                /* Don't mark all requests for the krbtgt/realm as
     
    675840                 * Instead, only do it when request is for the kpasswd service */
    676841                if (ent_type == SAMBA_KDC_ENT_TYPE_SERVER
    677                     && principal->name.name_string.len == 2
    678                     && (strcmp(principal->name.name_string.val[0], "kadmin") == 0)
    679                     && (strcmp(principal->name.name_string.val[1], "changepw") == 0)
    680                     && lpcfg_is_my_domain_or_realm(lp_ctx, principal->realm)) {
     842                    && krb5_princ_size(context, principal) == 2
     843                    && (principal_comp_strcmp(context, principal, 0, "kadmin") == 0)
     844                    && (principal_comp_strcmp(context, principal, 1, "changepw") == 0)
     845                    && lpcfg_is_my_domain_or_realm(lp_ctx, realm)) {
    681846                        entry_ex->entry.flags.change_pw = 1;
    682847                }
     848
     849                SAFE_FREE(realm);
     850
    683851                entry_ex->entry.flags.client = 0;
    684852                entry_ex->entry.flags.forwardable = 1;
     
    748916
    749917        if (ent_type == SAMBA_KDC_ENT_TYPE_SERVER) {
    750                 *entry_ex->entry.max_life = nt_time_to_unix(kdc_db_ctx->policy.service_tkt_lifetime);
     918                *entry_ex->entry.max_life = kdc_db_ctx->policy.svc_tkt_lifetime;
    751919        } else if (ent_type == SAMBA_KDC_ENT_TYPE_KRBTGT || ent_type == SAMBA_KDC_ENT_TYPE_CLIENT) {
    752                 *entry_ex->entry.max_life = nt_time_to_unix(kdc_db_ctx->policy.user_tkt_lifetime);
     920                *entry_ex->entry.max_life = kdc_db_ctx->policy.usr_tkt_lifetime;
    753921        } else {
    754                 *entry_ex->entry.max_life = MIN(nt_time_to_unix(kdc_db_ctx->policy.service_tkt_lifetime),
    755                                                nt_time_to_unix(kdc_db_ctx->policy.user_tkt_lifetime));
     922                *entry_ex->entry.max_life = MIN(kdc_db_ctx->policy.svc_tkt_lifetime,
     923                                                kdc_db_ctx->policy.usr_tkt_lifetime);
    756924        }
    757925
     
    762930        }
    763931
    764         *entry_ex->entry.max_renew = nt_time_to_unix(kdc_db_ctx->policy.user_tkt_renewaltime);
    765 
    766         entry_ex->entry.generation = NULL;
     932        *entry_ex->entry.max_renew = kdc_db_ctx->policy.renewal_lifetime;
    767933
    768934        /* Get keys from the db */
     
    771937                                           ent_type, entry_ex);
    772938        if (ret) {
    773                 /* Could be bougus data in the entry, or out of memory */
     939                /* Could be bogus data in the entry, or out of memory */
    774940                goto out;
    775941        }
     
    789955        }
    790956        for (i=0; i < entry_ex->entry.etypes->len; i++) {
    791                 entry_ex->entry.etypes->val[i] = entry_ex->entry.keys.val[i].key.keytype;
     957                entry_ex->entry.etypes->val[i] = KRB5_KEY_TYPE(&entry_ex->entry.keys.val[i].key);
    792958        }
    793959
     
    798964        if (ret != 0) {
    799965                /* This doesn't free ent itself, that is for the eventual caller to do */
    800                 hdb_free_entry(context, entry_ex);
     966                sdb_free_entry(entry_ex);
     967                ZERO_STRUCTP(entry_ex);
    801968        } else {
    802969                talloc_steal(kdc_db_ctx, entry_ex->ctx);
     
    808975/*
    809976 * Construct an hdb_entry from a directory entry.
     977 * The kvno is what the remote client asked for
    810978 */
    811979static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
     
    814982                                               enum trust_direction direction,
    815983                                               struct ldb_dn *realm_dn,
     984                                               unsigned flags,
     985                                               uint32_t kvno,
    816986                                               struct ldb_message *msg,
    817                                                hdb_entry_ex *entry_ex)
     987                                               struct sdb_entry_ex *entry_ex)
    818988{
    819989        struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx;
    820         const char *dnsdomain;
    821         const char *realm = lpcfg_realm(lp_ctx);
    822         DATA_BLOB password_utf16;
    823         struct samr_Password password_hash;
     990        const char *our_realm = lpcfg_realm(lp_ctx);
     991        const char *dnsdomain = NULL;
     992        char *partner_realm = NULL;
     993        const char *realm = NULL;
     994        const char *krbtgt_realm = NULL;
     995        DATA_BLOB password_utf16 = data_blob_null;
     996        DATA_BLOB password_utf8 = data_blob_null;
     997        struct samr_Password _password_hash;
     998        const struct samr_Password *password_hash = NULL;
    824999        const struct ldb_val *password_val;
    8251000        struct trustAuthInOutBlob password_blob;
    8261001        struct samba_kdc_entry *p;
    827 
     1002        bool use_previous = false;
     1003        uint32_t current_kvno;
     1004        uint32_t previous_kvno;
     1005        uint32_t num_keys = 0;
    8281006        enum ndr_err_code ndr_err;
    8291007        int ret, trust_direction_flags;
    8301008        unsigned int i;
     1009        struct AuthenticationInformationArray *auth_array;
     1010        struct timeval tv;
     1011        NTTIME an_hour_ago;
     1012        uint32_t *auth_kvno;
     1013        bool preferr_current = false;
     1014        uint32_t supported_enctypes = ENC_RC4_HMAC_MD5;
     1015
     1016        if (dsdb_functional_level(kdc_db_ctx->samdb) >= DS_DOMAIN_FUNCTION_2008) {
     1017                supported_enctypes = ldb_msg_find_attr_as_uint(msg,
     1018                                        "msDS-SupportedEncryptionTypes",
     1019                                        supported_enctypes);
     1020        }
     1021
     1022        trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
     1023        if (!(trust_direction_flags & direction)) {
     1024                krb5_clear_error_message(context);
     1025                ret = SDB_ERR_NOENTRY;
     1026                goto out;
     1027        }
     1028
     1029        dnsdomain = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
     1030        if (dnsdomain == NULL) {
     1031                krb5_clear_error_message(context);
     1032                ret = SDB_ERR_NOENTRY;
     1033                goto out;
     1034        }
     1035        partner_realm = strupper_talloc(mem_ctx, dnsdomain);
     1036        if (partner_realm == NULL) {
     1037                krb5_clear_error_message(context);
     1038                ret = ENOMEM;
     1039                goto out;
     1040        }
     1041
     1042        if (direction == INBOUND) {
     1043                realm = our_realm;
     1044                krbtgt_realm = partner_realm;
     1045
     1046                password_val = ldb_msg_find_ldb_val(msg, "trustAuthIncoming");
     1047        } else { /* OUTBOUND */
     1048                realm = partner_realm;
     1049                krbtgt_realm = our_realm;
     1050
     1051                password_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing");
     1052        }
     1053
     1054        if (password_val == NULL) {
     1055                krb5_clear_error_message(context);
     1056                ret = SDB_ERR_NOENTRY;
     1057                goto out;
     1058        }
     1059
     1060        ndr_err = ndr_pull_struct_blob(password_val, mem_ctx, &password_blob,
     1061                                       (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
     1062        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     1063                krb5_clear_error_message(context);
     1064                ret = EINVAL;
     1065                goto out;
     1066        }
    8311067
    8321068        p = talloc(mem_ctx, struct samba_kdc_entry);
     
    8371073
    8381074        p->kdc_db_ctx = kdc_db_ctx;
    839         p->entry_ex = entry_ex;
    8401075        p->realm_dn = realm_dn;
    8411076
     
    8431078
    8441079        /* make sure we do not have bogus data in there */
    845         memset(&entry_ex->entry, 0, sizeof(hdb_entry));
     1080        memset(&entry_ex->entry, 0, sizeof(struct sdb_entry));
    8461081
    8471082        entry_ex->ctx = p;
    848         entry_ex->free_entry = samba_kdc_free_entry;
    8491083
    8501084        /* use 'whenCreated' */
    8511085        entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0);
    8521086        /* use 'kadmin' for now (needed by mit_samba) */
    853         krb5_make_principal(context,
    854                             &entry_ex->entry.created_by.principal,
    855                             realm, "kadmin", NULL);
    856 
    857         entry_ex->entry.valid_start = NULL;
    858 
    859         trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
    860 
    861         if (direction == INBOUND) {
    862                 password_val = ldb_msg_find_ldb_val(msg, "trustAuthIncoming");
    863 
    864         } else { /* OUTBOUND */
    865                 dnsdomain = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
    866                 /* replace realm */
    867                 realm = strupper_talloc(mem_ctx, dnsdomain);
    868                 password_val = ldb_msg_find_ldb_val(msg, "trustAuthOutgoing");
    869         }
    870 
    871         if (!password_val || !(trust_direction_flags & direction)) {
    872                 ret = ENOENT;
    873                 goto out;
    874         }
    875 
    876         ndr_err = ndr_pull_struct_blob(password_val, mem_ctx, &password_blob,
    877                                            (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
    878         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    879                 ret = EINVAL;
    880                 goto out;
    881         }
    882 
    883         entry_ex->entry.kvno = -1;
    884         for (i=0; i < password_blob.count; i++) {
    885                 if (password_blob.current.array[i].AuthType == TRUST_AUTH_TYPE_VERSION) {
    886                         entry_ex->entry.kvno = password_blob.current.array[i].AuthInfo.version.version;
    887                 }
    888         }
    889 
    890         for (i=0; i < password_blob.count; i++) {
    891                 if (password_blob.current.array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) {
    892                         password_utf16 = data_blob_const(password_blob.current.array[i].AuthInfo.clear.password,
    893                                                          password_blob.current.array[i].AuthInfo.clear.size);
    894                         /* In the future, generate all sorts of
    895                          * hashes, but for now we can't safely convert
    896                          * the random strings windows uses into
    897                          * utf8 */
    898 
    899                         /* but as it is utf16 already, we can get the NT password/arcfour-hmac-md5 key */
    900                         mdfour(password_hash.hash, password_utf16.data, password_utf16.length);
    901                         break;
    902                 } else if (password_blob.current.array[i].AuthType == TRUST_AUTH_TYPE_NT4OWF) {
    903                         password_hash = password_blob.current.array[i].AuthInfo.nt4owf.password;
    904                         break;
    905                 }
    906         }
    907 
    908         if (i < password_blob.count) {
    909                 Key key;
    910                 /* Must have found a cleartext or MD4 password */
    911                 entry_ex->entry.keys.val = calloc(1, sizeof(Key));
    912 
    913                 key.mkvno = 0;
    914                 key.salt = NULL; /* No salt for this enc type */
    915 
    916                 if (entry_ex->entry.keys.val == NULL) {
    917                         ret = ENOMEM;
    918                         goto out;
    919                 }
    920 
    921                 ret = krb5_keyblock_init(context,
    922                                          ENCTYPE_ARCFOUR_HMAC,
    923                                          password_hash.hash, sizeof(password_hash.hash),
    924                                          &key.key);
    925 
    926                 entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
    927                 entry_ex->entry.keys.len++;
    928         }
    929 
    930         entry_ex->entry.principal = malloc(sizeof(*(entry_ex->entry.principal)));
    931 
    932         ret = copy_Principal(principal, entry_ex->entry.principal);
     1087        ret = smb_krb5_make_principal(context,
     1088                                      &entry_ex->entry.created_by.principal,
     1089                                      realm, "kadmin", NULL);
    9331090        if (ret) {
    9341091                krb5_clear_error_message(context);
     
    9361093        }
    9371094
    938         /* While we have copied the client principal, tests
    939          * show that Win2k3 returns the 'corrected' realm, not
    940          * the client-specified realm.  This code attempts to
    941          * replace the client principal's realm with the one
    942          * we determine from our records */
    943 
    944         krb5_principal_set_realm(context, entry_ex->entry.principal, realm);
    945         entry_ex->entry.flags = int2HDBFlags(0);
     1095        /*
     1096         * We always need to generate the canonicalized principal
     1097         * with the values of our database.
     1098         */
     1099        ret = smb_krb5_make_principal(context, &entry_ex->entry.principal, realm,
     1100                                      "krbtgt", krbtgt_realm, NULL);
     1101        if (ret) {
     1102                krb5_clear_error_message(context);
     1103                goto out;
     1104        }
     1105        smb_krb5_principal_set_type(context, entry_ex->entry.principal,
     1106                                    KRB5_NT_SRV_INST);
     1107
     1108        entry_ex->entry.valid_start = NULL;
     1109
     1110        /* we need to work out if we are going to use the current or
     1111         * the previous password hash.
     1112         * We base this on the kvno the client passes in. If the kvno
     1113         * passed in is equal to the current kvno in our database then
     1114         * we use the current structure. If it is the current kvno-1,
     1115         * then we use the previous substrucure.
     1116         */
     1117
     1118        /*
     1119         * Windows preferrs the previous key for one hour.
     1120         */
     1121        tv = timeval_current();
     1122        if (tv.tv_sec > 3600) {
     1123                tv.tv_sec -= 3600;
     1124        }
     1125        an_hour_ago = timeval_to_nttime(&tv);
     1126
     1127        /* first work out the current kvno */
     1128        current_kvno = 0;
     1129        for (i=0; i < password_blob.count; i++) {
     1130                struct AuthenticationInformation *a =
     1131                        &password_blob.current.array[i];
     1132
     1133                if (a->LastUpdateTime <= an_hour_ago) {
     1134                        preferr_current = true;
     1135                }
     1136
     1137                if (a->AuthType == TRUST_AUTH_TYPE_VERSION) {
     1138                        current_kvno = a->AuthInfo.version.version;
     1139                }
     1140        }
     1141        if (current_kvno == 0) {
     1142                previous_kvno = 255;
     1143        } else {
     1144                previous_kvno = current_kvno - 1;
     1145        }
     1146        for (i=0; i < password_blob.count; i++) {
     1147                struct AuthenticationInformation *a =
     1148                        &password_blob.previous.array[i];
     1149
     1150                if (a->AuthType == TRUST_AUTH_TYPE_VERSION) {
     1151                        previous_kvno = a->AuthInfo.version.version;
     1152                }
     1153        }
     1154
     1155        /* work out whether we will use the previous or current
     1156           password */
     1157        if (password_blob.previous.count == 0) {
     1158                /* there is no previous password */
     1159                use_previous = false;
     1160        } else if (!(flags & SDB_F_KVNO_SPECIFIED)) {
     1161                /*
     1162                 * If not specified we use the lowest kvno
     1163                 * for the first hour after an update.
     1164                 */
     1165                if (preferr_current) {
     1166                        use_previous = false;
     1167                } else if (previous_kvno < current_kvno) {
     1168                        use_previous = true;
     1169                } else {
     1170                        use_previous = false;
     1171                }
     1172        } else if (kvno == current_kvno) {
     1173                /*
     1174                 * Exact match ...
     1175                 */
     1176                use_previous = false;
     1177        } else if (kvno == previous_kvno) {
     1178                /*
     1179                 * Exact match ...
     1180                 */
     1181                use_previous = true;
     1182        } else {
     1183                /*
     1184                 * Fallback to the current one for anything else
     1185                 */
     1186                use_previous = false;
     1187        }
     1188
     1189        if (use_previous) {
     1190                auth_array = &password_blob.previous;
     1191                auth_kvno = &previous_kvno;
     1192        } else {
     1193                auth_array = &password_blob.current;
     1194                auth_kvno = &current_kvno;
     1195        }
     1196
     1197        /* use the kvno the client specified, if available */
     1198        if (flags & SDB_F_KVNO_SPECIFIED) {
     1199                entry_ex->entry.kvno = kvno;
     1200        } else {
     1201                entry_ex->entry.kvno = *auth_kvno;
     1202        }
     1203
     1204        for (i=0; i < auth_array->count; i++) {
     1205                if (auth_array->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) {
     1206                        bool ok;
     1207
     1208                        password_utf16 = data_blob_const(auth_array->array[i].AuthInfo.clear.password,
     1209                                                         auth_array->array[i].AuthInfo.clear.size);
     1210                        if (password_utf16.length == 0) {
     1211                                break;
     1212                        }
     1213
     1214                        if (supported_enctypes & ENC_RC4_HMAC_MD5) {
     1215                                mdfour(_password_hash.hash, password_utf16.data, password_utf16.length);
     1216                                if (password_hash == NULL) {
     1217                                        num_keys += 1;
     1218                                }
     1219                                password_hash = &_password_hash;
     1220                        }
     1221
     1222                        if (!(supported_enctypes & (ENC_HMAC_SHA1_96_AES128|ENC_HMAC_SHA1_96_AES256))) {
     1223                                break;
     1224                        }
     1225
     1226                        ok = convert_string_talloc(mem_ctx,
     1227                                                   CH_UTF16MUNGED, CH_UTF8,
     1228                                                   password_utf16.data,
     1229                                                   password_utf16.length,
     1230                                                   (void *)&password_utf8.data,
     1231                                                   &password_utf8.length);
     1232                        if (!ok) {
     1233                                krb5_clear_error_message(context);
     1234                                ret = ENOMEM;
     1235                                goto out;
     1236                        }
     1237
     1238                        if (supported_enctypes & ENC_HMAC_SHA1_96_AES128) {
     1239                                num_keys += 1;
     1240                        }
     1241                        if (supported_enctypes & ENC_HMAC_SHA1_96_AES256) {
     1242                                num_keys += 1;
     1243                        }
     1244                        break;
     1245                } else if (auth_array->array[i].AuthType == TRUST_AUTH_TYPE_NT4OWF) {
     1246                        if (supported_enctypes & ENC_RC4_HMAC_MD5) {
     1247                                password_hash = &auth_array->array[i].AuthInfo.nt4owf.password;
     1248                                num_keys += 1;
     1249                        }
     1250                }
     1251        }
     1252
     1253        /* Must have found a cleartext or MD4 password */
     1254        if (num_keys == 0) {
     1255                DEBUG(1,(__location__ ": no usable key found\n"));
     1256                krb5_clear_error_message(context);
     1257                ret = SDB_ERR_NOENTRY;
     1258                goto out;
     1259        }
     1260
     1261        entry_ex->entry.keys.val = calloc(num_keys, sizeof(struct sdb_key));
     1262        if (entry_ex->entry.keys.val == NULL) {
     1263                krb5_clear_error_message(context);
     1264                ret = ENOMEM;
     1265                goto out;
     1266        }
     1267
     1268        if (password_utf8.length != 0) {
     1269                struct sdb_key key = {};
     1270                krb5_const_principal salt_principal = entry_ex->entry.principal;
     1271                krb5_data salt;
     1272                krb5_data cleartext_data;
     1273
     1274                cleartext_data.data = discard_const_p(char, password_utf8.data);
     1275                cleartext_data.length = password_utf8.length;
     1276
     1277                ret = smb_krb5_get_pw_salt(context,
     1278                                           salt_principal,
     1279                                           &salt);
     1280                if (ret != 0) {
     1281                        goto out;
     1282                }
     1283
     1284                if (supported_enctypes & ENC_HMAC_SHA1_96_AES256) {
     1285                        ret = smb_krb5_create_key_from_string(context,
     1286                                                              salt_principal,
     1287                                                              &salt,
     1288                                                              &cleartext_data,
     1289                                                              ENCTYPE_AES256_CTS_HMAC_SHA1_96,
     1290                                                              &key.key);
     1291                        if (ret != 0) {
     1292                                kerberos_free_data_contents(context, &salt);
     1293                                goto out;
     1294                        }
     1295
     1296                        entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
     1297                        entry_ex->entry.keys.len++;
     1298                }
     1299
     1300                if (supported_enctypes & ENC_HMAC_SHA1_96_AES128) {
     1301                        ret = smb_krb5_create_key_from_string(context,
     1302                                                              salt_principal,
     1303                                                              &salt,
     1304                                                              &cleartext_data,
     1305                                                              ENCTYPE_AES128_CTS_HMAC_SHA1_96,
     1306                                                              &key.key);
     1307                        if (ret != 0) {
     1308                                kerberos_free_data_contents(context, &salt);
     1309                                goto out;
     1310                        }
     1311
     1312                        entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
     1313                        entry_ex->entry.keys.len++;
     1314                }
     1315
     1316                kerberos_free_data_contents(context, &salt);
     1317        }
     1318
     1319        if (password_hash != NULL) {
     1320                struct sdb_key key = {};
     1321
     1322                ret = smb_krb5_keyblock_init_contents(context,
     1323                                                      ENCTYPE_ARCFOUR_HMAC,
     1324                                                      password_hash->hash,
     1325                                                      sizeof(password_hash->hash),
     1326                                                      &key.key);
     1327                if (ret != 0) {
     1328                        goto out;
     1329                }
     1330
     1331                entry_ex->entry.keys.val[entry_ex->entry.keys.len] = key;
     1332                entry_ex->entry.keys.len++;
     1333        }
     1334
     1335        entry_ex->entry.flags = int2SDBFlags(0);
    9461336        entry_ex->entry.flags.immutable = 1;
    9471337        entry_ex->entry.flags.invalid = 0;
     
    9541344
    9551345        entry_ex->entry.max_renew = NULL;
    956 
    957         entry_ex->entry.generation = NULL;
    9581346
    9591347        entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes)));
     
    9711359        }
    9721360        for (i=0; i < entry_ex->entry.etypes->len; i++) {
    973                 entry_ex->entry.etypes->val[i] = entry_ex->entry.keys.val[i].key.keytype;
    974         }
    975 
     1361                entry_ex->entry.etypes->val[i] = KRB5_KEY_TYPE(&entry_ex->entry.keys.val[i].key);
     1362        }
    9761363
    9771364        p->msg = talloc_steal(p, msg);
    9781365
    9791366out:
     1367        TALLOC_FREE(partner_realm);
     1368
    9801369        if (ret != 0) {
    9811370                /* This doesn't free ent itself, that is for the eventual caller to do */
    982                 hdb_free_entry(context, entry_ex);
     1371                sdb_free_entry(entry_ex);
    9831372        } else {
    9841373                talloc_steal(kdc_db_ctx, entry_ex->ctx);
     
    9951384                                        struct ldb_message **pmsg)
    9961385{
    997         int lret;
    998         krb5_error_code ret;
    999         char *filter = NULL;
     1386        NTSTATUS status;
    10001387        const char * const *attrs = trust_attrs;
    10011388
    1002         struct ldb_result *res = NULL;
    1003         filter = talloc_asprintf(mem_ctx, "(&(objectClass=trustedDomain)(|(flatname=%s)(trustPartner=%s)))", realm, realm);
    1004 
    1005         if (!filter) {
    1006                 ret = ENOMEM;
    1007                 krb5_set_error_message(context, ret, "talloc_asprintf: out of memory");
     1389        status = dsdb_trust_search_tdo(ldb_ctx, realm, realm,
     1390                                       attrs, mem_ctx, pmsg);
     1391        if (NT_STATUS_IS_OK(status)) {
     1392                return 0;
     1393        } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     1394                return SDB_ERR_NOENTRY;
     1395        } else if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
     1396                int ret = ENOMEM;
     1397                krb5_set_error_message(context, ret, "get_sam_result_trust: out of memory");
    10081398                return ret;
    1009         }
    1010 
    1011         lret = ldb_search(ldb_ctx, mem_ctx, &res,
    1012                           ldb_get_default_basedn(ldb_ctx),
    1013                           LDB_SCOPE_SUBTREE, attrs, "%s", filter);
    1014         if (lret != LDB_SUCCESS) {
    1015                 DEBUG(3, ("Failed to search for %s: %s\n", filter, ldb_errstring(ldb_ctx)));
    1016                 return HDB_ERR_NOENTRY;
    1017         } else if (res->count == 0 || res->count > 1) {
    1018                 DEBUG(3, ("Failed find a single entry for %s: got %d\n", filter, res->count));
    1019                 talloc_free(res);
    1020                 return HDB_ERR_NOENTRY;
    1021         }
    1022         talloc_steal(mem_ctx, res->msgs);
    1023         *pmsg = res->msgs[0];
    1024         talloc_free(res);
    1025         return 0;
     1399        } else {
     1400                int ret = EINVAL;
     1401                krb5_set_error_message(context, ret, "get_sam_result_trust: %s", nt_errstr(status));
     1402                return ret;
     1403        }
    10261404}
    10271405
     
    10321410                                                const char **attrs,
    10331411                                                struct ldb_dn **realm_dn,
    1034                                                 struct ldb_message **msg) {
     1412                                                struct ldb_message **msg)
     1413{
    10351414        NTSTATUS nt_status;
    1036         char *principal_string;
    1037         krb5_error_code ret;
    1038 
    1039         ret = krb5_unparse_name(context, principal, &principal_string);
    1040 
    1041         if (ret != 0) {
    1042                 return ret;
     1415        char *principal_string = NULL;
     1416
     1417        if (smb_krb5_principal_get_type(context, principal) == KRB5_NT_ENTERPRISE_PRINCIPAL) {
     1418                principal_string = smb_krb5_principal_get_comp_string(mem_ctx, context,
     1419                                                                      principal, 0);
     1420                if (principal_string == NULL) {
     1421                        return ENOMEM;
     1422                }
     1423        } else {
     1424                char *principal_string_m = NULL;
     1425                krb5_error_code ret;
     1426
     1427                ret = krb5_unparse_name(context, principal, &principal_string_m);
     1428                if (ret != 0) {
     1429                        return ret;
     1430                }
     1431
     1432                principal_string = talloc_strdup(mem_ctx, principal_string_m);
     1433                SAFE_FREE(principal_string_m);
     1434                if (principal_string == NULL) {
     1435                        return ENOMEM;
     1436                }
    10431437        }
    10441438
     
    10461440                                              mem_ctx, principal_string, attrs,
    10471441                                              realm_dn, msg);
    1048         free(principal_string);
    10491442        if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
    1050                 return HDB_ERR_NOENTRY;
     1443                krb5_principal fallback_principal = NULL;
     1444                unsigned int num_comp;
     1445                char *fallback_realm = NULL;
     1446                char *fallback_account = NULL;
     1447                krb5_error_code ret;
     1448
     1449                ret = krb5_parse_name(context, principal_string,
     1450                                      &fallback_principal);
     1451                TALLOC_FREE(principal_string);
     1452                if (ret != 0) {
     1453                        return ret;
     1454                }
     1455
     1456                num_comp = krb5_princ_size(context, fallback_principal);
     1457                fallback_realm = smb_krb5_principal_get_realm(context,
     1458                                                              fallback_principal);
     1459                if (fallback_realm == NULL) {
     1460                        krb5_free_principal(context, fallback_principal);
     1461                        return ENOMEM;
     1462                }
     1463
     1464                if (num_comp == 1) {
     1465                        size_t len;
     1466
     1467                        fallback_account = smb_krb5_principal_get_comp_string(mem_ctx,
     1468                                                context, fallback_principal, 0);
     1469                        if (fallback_account == NULL) {
     1470                                krb5_free_principal(context, fallback_principal);
     1471                                SAFE_FREE(fallback_realm);
     1472                                return ENOMEM;
     1473                        }
     1474
     1475                        len = strlen(fallback_account);
     1476                        if (len >= 2 && fallback_account[len - 1] == '$') {
     1477                                TALLOC_FREE(fallback_account);
     1478                        }
     1479                }
     1480                krb5_free_principal(context, fallback_principal);
     1481                fallback_principal = NULL;
     1482
     1483                if (fallback_account != NULL) {
     1484                        char *with_dollar;
     1485
     1486                        with_dollar = talloc_asprintf(mem_ctx, "%s$",
     1487                                                     fallback_account);
     1488                        if (with_dollar == NULL) {
     1489                                SAFE_FREE(fallback_realm);
     1490                                return ENOMEM;
     1491                        }
     1492                        TALLOC_FREE(fallback_account);
     1493
     1494                        ret = smb_krb5_make_principal(context,
     1495                                                      &fallback_principal,
     1496                                                      fallback_realm,
     1497                                                      with_dollar, NULL);
     1498                        TALLOC_FREE(with_dollar);
     1499                        if (ret != 0) {
     1500                                SAFE_FREE(fallback_realm);
     1501                                return ret;
     1502                        }
     1503                }
     1504                SAFE_FREE(fallback_realm);
     1505
     1506                if (fallback_principal != NULL) {
     1507                        char *fallback_string = NULL;
     1508
     1509                        ret = krb5_unparse_name(context,
     1510                                                fallback_principal,
     1511                                                &fallback_string);
     1512                        if (ret != 0) {
     1513                                krb5_free_principal(context, fallback_principal);
     1514                                return ret;
     1515                        }
     1516
     1517                        nt_status = sam_get_results_principal(kdc_db_ctx->samdb,
     1518                                                              mem_ctx,
     1519                                                              fallback_string,
     1520                                                              attrs,
     1521                                                              realm_dn, msg);
     1522                        SAFE_FREE(fallback_string);
     1523                }
     1524                krb5_free_principal(context, fallback_principal);
     1525                fallback_principal = NULL;
     1526        }
     1527        TALLOC_FREE(principal_string);
     1528
     1529        if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
     1530                return SDB_ERR_NOENTRY;
    10511531        } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MEMORY)) {
    10521532                return ENOMEM;
     
    10551535        }
    10561536
    1057         return ret;
     1537        return 0;
    10581538}
    10591539
     
    10631543                                               krb5_const_principal principal,
    10641544                                               unsigned flags,
    1065                                                hdb_entry_ex *entry_ex) {
     1545                                               struct sdb_entry_ex *entry_ex) {
    10661546        struct ldb_dn *realm_dn;
    10671547        krb5_error_code ret;
     
    10691549
    10701550        ret = samba_kdc_lookup_client(context, kdc_db_ctx,
    1071                                        mem_ctx, principal, user_attrs,
    1072                                        &realm_dn, &msg);
     1551                                      mem_ctx, principal, user_attrs,
     1552                                      &realm_dn, &msg);
    10731553        if (ret != 0) {
    10741554                return ret;
     
    10871567                                              krb5_const_principal principal,
    10881568                                              unsigned flags,
    1089                                               uint32_t krbtgt_number,
    1090                                               hdb_entry_ex *entry_ex)
     1569                                              uint32_t kvno,
     1570                                              struct sdb_entry_ex *entry_ex)
    10911571{
    10921572        struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx;
     
    10941574        struct ldb_message *msg = NULL;
    10951575        struct ldb_dn *realm_dn = ldb_get_default_basedn(kdc_db_ctx->samdb);
    1096 
    1097         krb5_principal alloc_principal = NULL;
    1098         if (principal->name.name_string.len != 2
    1099             || (strcmp(principal->name.name_string.val[0], KRB5_TGS_NAME) != 0)) {
     1576        char *realm_from_princ, *realm_from_princ_malloc;
     1577        char *realm_princ_comp = smb_krb5_principal_get_comp_string(mem_ctx, context, principal, 1);
     1578
     1579        realm_from_princ_malloc = smb_krb5_principal_get_realm(context, principal);
     1580        if (realm_from_princ_malloc == NULL) {
     1581                /* can't happen */
     1582                return SDB_ERR_NOENTRY;
     1583        }
     1584        realm_from_princ = talloc_strdup(mem_ctx, realm_from_princ_malloc);
     1585        free(realm_from_princ_malloc);
     1586        if (realm_from_princ == NULL) {
     1587                return SDB_ERR_NOENTRY;
     1588        }
     1589
     1590        if (krb5_princ_size(context, principal) != 2
     1591            || (principal_comp_strcmp(context, principal, 0, KRB5_TGS_NAME) != 0)) {
    11001592                /* Not a krbtgt */
    1101                 return HDB_ERR_NOENTRY;
     1593                return SDB_ERR_NOENTRY;
    11021594        }
    11031595
    11041596        /* krbtgt case.  Either us or a trusted realm */
    11051597
    1106         if (lpcfg_is_my_domain_or_realm(lp_ctx, principal->realm)
    1107             && lpcfg_is_my_domain_or_realm(lp_ctx, principal->name.name_string.val[1])) {
     1598        if (lpcfg_is_my_domain_or_realm(lp_ctx, realm_from_princ)
     1599            && lpcfg_is_my_domain_or_realm(lp_ctx, realm_princ_comp)) {
    11081600                /* us, or someone quite like us */
    11091601                /* Cludge, cludge cludge.  If the realm part of krbtgt/realm,
     
    11121604
    11131605                int lret;
     1606                unsigned int krbtgt_number;
     1607                /* w2k8r2 sometimes gives us a kvno of 255 for inter-domain
     1608                   trust tickets. We don't yet know what this means, but we do
     1609                   seem to need to treat it as unspecified */
     1610                if (flags & SDB_F_KVNO_SPECIFIED) {
     1611                        krbtgt_number = SAMBA_KVNO_GET_KRBTGT(kvno);
     1612                        if (kdc_db_ctx->rodc) {
     1613                                if (krbtgt_number != kdc_db_ctx->my_krbtgt_number) {
     1614                                        return SDB_ERR_NOT_FOUND_HERE;
     1615                                }
     1616                        }
     1617                } else {
     1618                        krbtgt_number = kdc_db_ctx->my_krbtgt_number;
     1619                }
    11141620
    11151621                if (krbtgt_number == kdc_db_ctx->my_krbtgt_number) {
    11161622                        lret = dsdb_search_one(kdc_db_ctx->samdb, mem_ctx,
    11171623                                               &msg, kdc_db_ctx->krbtgt_dn, LDB_SCOPE_BASE,
    1118                                                krbtgt_attrs, 0,
     1624                                               krbtgt_attrs, DSDB_SEARCH_NO_GLOBAL_CATALOG,
    11191625                                               "(objectClass=user)");
    11201626                } else {
     
    11251631                                               &msg, realm_dn, LDB_SCOPE_SUBTREE,
    11261632                                               krbtgt_attrs,
    1127                                                DSDB_SEARCH_SHOW_EXTENDED_DN,
     1633                                               DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_NO_GLOBAL_CATALOG,
    11281634                                               "(&(objectClass=user)(msDS-SecondaryKrbTgtNumber=%u))", (unsigned)(krbtgt_number));
    11291635                }
     
    11321638                        krb5_warnx(context, "samba_kdc_fetch: could not find KRBTGT number %u in DB!",
    11331639                                   (unsigned)(krbtgt_number));
    1134                         krb5_set_error_message(context, HDB_ERR_NOENTRY,
     1640                        krb5_set_error_message(context, SDB_ERR_NOENTRY,
    11351641                                               "samba_kdc_fetch: could not find KRBTGT number %u in DB!",
    11361642                                               (unsigned)(krbtgt_number));
    1137                         return HDB_ERR_NOENTRY;
     1643                        return SDB_ERR_NOENTRY;
    11381644                } else if (lret != LDB_SUCCESS) {
    11391645                        krb5_warnx(context, "samba_kdc_fetch: could not find KRBTGT number %u in DB!",
    11401646                                   (unsigned)(krbtgt_number));
    1141                         krb5_set_error_message(context, HDB_ERR_NOENTRY,
     1647                        krb5_set_error_message(context, SDB_ERR_NOENTRY,
    11421648                                               "samba_kdc_fetch: could not find KRBTGT number %u in DB!",
    11431649                                               (unsigned)(krbtgt_number));
    1144                         return HDB_ERR_NOENTRY;
    1145                 }
    1146 
    1147                 if (flags & HDB_F_CANON) {
    1148                         ret = krb5_copy_principal(context, principal, &alloc_principal);
    1149                         if (ret) {
    1150                                 return ret;
    1151                         }
    1152 
    1153                         /* When requested to do so, ensure that the
    1154                          * both realm values in the principal are set
    1155                          * to the upper case, canonical realm */
    1156                         free(alloc_principal->name.name_string.val[1]);
    1157                         alloc_principal->name.name_string.val[1] = strdup(lpcfg_realm(lp_ctx));
    1158                         if (!alloc_principal->name.name_string.val[1]) {
    1159                                 ret = ENOMEM;
    1160                                 krb5_set_error_message(context, ret, "samba_kdc_fetch: strdup() failed!");
    1161                                 return ret;
    1162                         }
    1163                         principal = alloc_principal;
     1650                        return SDB_ERR_NOENTRY;
    11641651                }
    11651652
     
    11671654                                              principal, SAMBA_KDC_ENT_TYPE_KRBTGT,
    11681655                                              flags, realm_dn, msg, entry_ex);
    1169                 if (flags & HDB_F_CANON) {
    1170                         /* This is again copied in the message2entry call */
    1171                         krb5_free_principal(context, alloc_principal);
    1172                 }
    11731656                if (ret != 0) {
    11741657                        krb5_warnx(context, "samba_kdc_fetch: self krbtgt message2entry failed");
     
    11821665                /* Either an inbound or outbound trust */
    11831666
    1184                 if (strcasecmp(lpcfg_realm(lp_ctx), principal->realm) == 0) {
     1667                if (strcasecmp(lpcfg_realm(lp_ctx), realm_from_princ) == 0) {
    11851668                        /* look for inbound trust */
    11861669                        direction = INBOUND;
    1187                         realm = principal->name.name_string.val[1];
    1188                 } else if (strcasecmp(lpcfg_realm(lp_ctx), principal->name.name_string.val[1]) == 0) {
     1670                        realm = realm_princ_comp;
     1671                } else if (principal_comp_strcasecmp(context, principal, 1, lpcfg_realm(lp_ctx)) == 0) {
    11891672                        /* look for outbound trust */
    11901673                        direction = OUTBOUND;
    1191                         realm = principal->realm;
     1674                        realm = realm_from_princ;
    11921675                } else {
    11931676                        krb5_warnx(context, "samba_kdc_fetch: not our realm for trusts ('%s', '%s')",
    1194                                    principal->realm, principal->name.name_string.val[1]);
    1195                         krb5_set_error_message(context, HDB_ERR_NOENTRY, "samba_kdc_fetch: not our realm for trusts ('%s', '%s')",
    1196                                                principal->realm, principal->name.name_string.val[1]);
    1197                         return HDB_ERR_NOENTRY;
     1677                                   realm_from_princ,
     1678                                   realm_princ_comp);
     1679                        krb5_set_error_message(context, SDB_ERR_NOENTRY, "samba_kdc_fetch: not our realm for trusts ('%s', '%s')",
     1680                                               realm_from_princ,
     1681                                               realm_princ_comp);
     1682                        return SDB_ERR_NOENTRY;
    11981683                }
    11991684
     
    12111696
    12121697                ret = samba_kdc_trust_message2entry(context, kdc_db_ctx, mem_ctx,
    1213                                               principal, direction,
    1214                                               realm_dn, msg, entry_ex);
     1698                                                    principal, direction,
     1699                                                    realm_dn, flags, kvno, msg, entry_ex);
    12151700                if (ret != 0) {
    1216                         krb5_warnx(context, "samba_kdc_fetch: trust_message2entry failed");
     1701                        krb5_warnx(context, "samba_kdc_fetch: trust_message2entry failed for %s",
     1702                                   ldb_dn_get_linearized(msg->dn));
     1703                        krb5_set_error_message(context, ret, "samba_kdc_fetch: "
     1704                                               "trust_message2entry failed for %s",
     1705                                               ldb_dn_get_linearized(msg->dn));
    12171706                }
    12181707                return ret;
     
    12221711
    12231712static krb5_error_code samba_kdc_lookup_server(krb5_context context,
    1224                                                 struct samba_kdc_db_context *kdc_db_ctx,
    1225                                                 TALLOC_CTX *mem_ctx,
    1226                                                 krb5_const_principal principal,
    1227                                                 const char **attrs,
    1228                                                 struct ldb_dn **realm_dn,
    1229                                                 struct ldb_message **msg)
     1713                                               struct samba_kdc_db_context *kdc_db_ctx,
     1714                                               TALLOC_CTX *mem_ctx,
     1715                                               krb5_const_principal principal,
     1716                                               unsigned flags,
     1717                                               const char **attrs,
     1718                                               struct ldb_dn **realm_dn,
     1719                                               struct ldb_message **msg)
    12301720{
    12311721        krb5_error_code ret;
    1232         if (principal->name.name_string.len >= 2) {
     1722        if ((smb_krb5_principal_get_type(context, principal) != KRB5_NT_ENTERPRISE_PRINCIPAL)
     1723            && krb5_princ_size(context, principal) >= 2) {
    12331724                /* 'normal server' case */
    12341725                int ldb_ret;
     
    12531744
    12541745                if (!NT_STATUS_IS_OK(nt_status)) {
    1255                         return HDB_ERR_NOENTRY;
     1746                        return SDB_ERR_NOENTRY;
    12561747                }
    12571748
     
    12591750                                          mem_ctx,
    12601751                                          msg, user_dn, LDB_SCOPE_BASE,
    1261                                           attrs, DSDB_SEARCH_SHOW_EXTENDED_DN, "(objectClass=*)");
     1752                                          attrs,
     1753                                          DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_NO_GLOBAL_CATALOG,
     1754                                          "(objectClass=*)");
    12621755                if (ldb_ret != LDB_SUCCESS) {
    1263                         return HDB_ERR_NOENTRY;
    1264                 }
    1265 
     1756                        return SDB_ERR_NOENTRY;
     1757                }
     1758                return 0;
     1759        } else if (!(flags & SDB_F_FOR_AS_REQ)
     1760                   && smb_krb5_principal_get_type(context, principal) == KRB5_NT_ENTERPRISE_PRINCIPAL) {
     1761                /*
     1762                 * The behaviour of accepting an
     1763                 * KRB5_NT_ENTERPRISE_PRINCIPAL server principal
     1764                 * containing a UPN only applies to TGS-REQ packets,
     1765                 * not AS-REQ packets.
     1766                 */
     1767                return samba_kdc_lookup_client(context, kdc_db_ctx,
     1768                                               mem_ctx, principal, attrs,
     1769                                               realm_dn, msg);
    12661770        } else {
     1771                /*
     1772                 * This case is for:
     1773                 *  - the AS-REQ, where we only accept
     1774                 *    samAccountName based lookups for the server, no
     1775                 *    matter if the name is an
     1776                 *    KRB5_NT_ENTERPRISE_PRINCIPAL or not
     1777                 *  - for the TGS-REQ when we are not given an
     1778                 *    KRB5_NT_ENTERPRISE_PRINCIPAL, which also must
     1779                 *    only lookup samAccountName based names.
     1780                 */
    12671781                int lret;
     1782                char *short_princ;
     1783                krb5_principal enterprise_principal = NULL;
     1784                krb5_const_principal used_principal = NULL;
     1785                char *name1 = NULL;
     1786                size_t len1 = 0;
    12681787                char *filter = NULL;
    1269                 char *short_princ;
    1270                 const char *realm;
     1788
     1789                if (smb_krb5_principal_get_type(context, principal) == KRB5_NT_ENTERPRISE_PRINCIPAL) {
     1790                        char *str = NULL;
     1791                        /* Need to reparse the enterprise principal to find the real target */
     1792                        if (krb5_princ_size(context, principal) != 1) {
     1793                                ret = KRB5_PARSE_MALFORMED;
     1794                                krb5_set_error_message(context, ret, "samba_kdc_lookup_server: request for an "
     1795                                                       "enterprise principal with wrong (%d) number of components",
     1796                                                       krb5_princ_size(context, principal));
     1797                                return ret;
     1798                        }
     1799                        str = smb_krb5_principal_get_comp_string(mem_ctx, context, principal, 0);
     1800                        if (str == NULL) {
     1801                                return KRB5_PARSE_MALFORMED;
     1802                        }
     1803                        ret = krb5_parse_name(context, str,
     1804                                              &enterprise_principal);
     1805                        talloc_free(str);
     1806                        if (ret) {
     1807                                return ret;
     1808                        }
     1809                        used_principal = enterprise_principal;
     1810                } else {
     1811                        used_principal = principal;
     1812                }
     1813
    12711814                /* server as client principal case, but we must not lookup userPrincipalNames */
    12721815                *realm_dn = ldb_get_default_basedn(kdc_db_ctx->samdb);
    1273                 realm = krb5_principal_get_realm(context, principal);
    1274 
    1275                 /* TODO: Check if it is our realm, otherwise give referall */
    1276 
    1277                 ret = krb5_unparse_name_flags(context, principal,  KRB5_PRINCIPAL_UNPARSE_NO_REALM, &short_princ);
     1816
     1817                /* TODO: Check if it is our realm, otherwise give referral */
     1818
     1819                ret = krb5_unparse_name_flags(context, used_principal,
     1820                                              KRB5_PRINCIPAL_UNPARSE_NO_REALM |
     1821                                              KRB5_PRINCIPAL_UNPARSE_DISPLAY,
     1822                                              &short_princ);
     1823                used_principal = NULL;
     1824                krb5_free_principal(context, enterprise_principal);
     1825                enterprise_principal = NULL;
    12781826
    12791827                if (ret != 0) {
     
    12831831                }
    12841832
     1833                name1 = ldb_binary_encode_string(mem_ctx, short_princ);
     1834                SAFE_FREE(short_princ);
     1835                if (name1 == NULL) {
     1836                        return ENOMEM;
     1837                }
     1838                len1 = strlen(name1);
     1839                if (len1 >= 1 && name1[len1 - 1] != '$') {
     1840                        filter = talloc_asprintf(mem_ctx,
     1841                                        "(&(objectClass=user)(|(samAccountName=%s)(samAccountName=%s$)))",
     1842                                        name1, name1);
     1843                        if (filter == NULL) {
     1844                                return ENOMEM;
     1845                        }
     1846                } else {
     1847                        filter = talloc_asprintf(mem_ctx,
     1848                                        "(&(objectClass=user)(samAccountName=%s))",
     1849                                        name1);
     1850                        if (filter == NULL) {
     1851                                return ENOMEM;
     1852                        }
     1853                }
     1854
    12851855                lret = dsdb_search_one(kdc_db_ctx->samdb, mem_ctx, msg,
    12861856                                       *realm_dn, LDB_SCOPE_SUBTREE,
    12871857                                       attrs,
    1288                                        DSDB_SEARCH_SHOW_EXTENDED_DN,
    1289                                        "(&(objectClass=user)(samAccountName=%s))",
    1290                                        ldb_binary_encode_string(mem_ctx, short_princ));
    1291                 free(short_princ);
     1858                                       DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_NO_GLOBAL_CATALOG,
     1859                                       "%s", filter);
    12921860                if (lret == LDB_ERR_NO_SUCH_OBJECT) {
    1293                         DEBUG(3, ("Failed find a entry for %s\n", filter));
    1294                         return HDB_ERR_NOENTRY;
     1861                        DEBUG(10, ("Failed to find an entry for %s filter:%s\n",
     1862                                  name1, filter));
     1863                        return SDB_ERR_NOENTRY;
     1864                }
     1865                if (lret == LDB_ERR_CONSTRAINT_VIOLATION) {
     1866                        DEBUG(10, ("Failed to find unique entry for %s filter:%s\n",
     1867                                  name1, filter));
     1868                        return SDB_ERR_NOENTRY;
    12951869                }
    12961870                if (lret != LDB_SUCCESS) {
    1297                         DEBUG(3, ("Failed single search for for %s - %s\n",
    1298                                   filter, ldb_errstring(kdc_db_ctx->samdb)));
    1299                         return HDB_ERR_NOENTRY;
    1300                 }
    1301         }
    1302 
    1303         return 0;
     1871                        DEBUG(0, ("Failed single search for %s - %s\n",
     1872                                  name1, ldb_errstring(kdc_db_ctx->samdb)));
     1873                        return SDB_ERR_NOENTRY;
     1874                }
     1875                return 0;
     1876        }
     1877        return SDB_ERR_NOENTRY;
    13041878}
     1879
     1880
    13051881
    13061882static krb5_error_code samba_kdc_fetch_server(krb5_context context,
     
    13091885                                              krb5_const_principal principal,
    13101886                                              unsigned flags,
    1311                                               hdb_entry_ex *entry_ex)
     1887                                              struct sdb_entry_ex *entry_ex)
    13121888{
    13131889        krb5_error_code ret;
     
    13161892
    13171893        ret = samba_kdc_lookup_server(context, kdc_db_ctx, mem_ctx, principal,
    1318                                       server_attrs, &realm_dn, &msg);
     1894                                      flags, server_attrs, &realm_dn, &msg);
    13191895        if (ret != 0) {
    13201896                return ret;
     
    13321908}
    13331909
     1910static krb5_error_code samba_kdc_lookup_realm(krb5_context context,
     1911                                              struct samba_kdc_db_context *kdc_db_ctx,
     1912                                              TALLOC_CTX *mem_ctx,
     1913                                              krb5_const_principal principal,
     1914                                              unsigned flags,
     1915                                              struct sdb_entry_ex *entry_ex)
     1916{
     1917        TALLOC_CTX *frame = talloc_stackframe();
     1918        NTSTATUS status;
     1919        krb5_error_code ret;
     1920        char *_realm = NULL;
     1921        bool check_realm = false;
     1922        const char *realm = NULL;
     1923        struct dsdb_trust_routing_table *trt = NULL;
     1924        const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
     1925        unsigned int num_comp;
     1926        bool ok;
     1927        char *upper = NULL;
     1928
     1929        num_comp = krb5_princ_size(context, principal);
     1930
     1931        if (flags & SDB_F_GET_CLIENT) {
     1932                if (flags & SDB_F_FOR_AS_REQ) {
     1933                        check_realm = true;
     1934                }
     1935        }
     1936        if (flags & SDB_F_GET_SERVER) {
     1937                if (flags & SDB_F_FOR_TGS_REQ) {
     1938                        check_realm = true;
     1939                }
     1940        }
     1941
     1942        if (!check_realm) {
     1943                TALLOC_FREE(frame);
     1944                return 0;
     1945        }
     1946
     1947        _realm = smb_krb5_principal_get_realm(context, principal);
     1948        if (_realm == NULL) {
     1949                TALLOC_FREE(frame);
     1950                return ENOMEM;
     1951        }
     1952
     1953        /*
     1954         * The requested realm needs to be our own
     1955         */
     1956        ok = lpcfg_is_my_domain_or_realm(kdc_db_ctx->lp_ctx, _realm);
     1957        if (!ok) {
     1958                /*
     1959                 * The request is not for us...
     1960                 */
     1961                SAFE_FREE(_realm);
     1962                TALLOC_FREE(frame);
     1963                return SDB_ERR_NOENTRY;
     1964        }
     1965
     1966        realm = talloc_strdup(frame, _realm);
     1967        SAFE_FREE(_realm);
     1968        if (realm == NULL) {
     1969                TALLOC_FREE(frame);
     1970                return ENOMEM;
     1971        }
     1972
     1973        if (smb_krb5_principal_get_type(context, principal) == KRB5_NT_ENTERPRISE_PRINCIPAL) {
     1974                char *principal_string = NULL;
     1975                krb5_principal enterprise_principal = NULL;
     1976                char *enterprise_realm = NULL;
     1977
     1978                if (num_comp != 1) {
     1979                        TALLOC_FREE(frame);
     1980                        return SDB_ERR_NOENTRY;
     1981                }
     1982
     1983                principal_string = smb_krb5_principal_get_comp_string(frame, context,
     1984                                                                      principal, 0);
     1985                if (principal_string == NULL) {
     1986                        TALLOC_FREE(frame);
     1987                        return ENOMEM;
     1988                }
     1989
     1990                ret = krb5_parse_name(context, principal_string,
     1991                                      &enterprise_principal);
     1992                TALLOC_FREE(principal_string);
     1993                if (ret) {
     1994                        TALLOC_FREE(frame);
     1995                        return ret;
     1996                }
     1997
     1998                enterprise_realm = smb_krb5_principal_get_realm(context,
     1999                                                        enterprise_principal);
     2000                krb5_free_principal(context, enterprise_principal);
     2001                if (enterprise_realm != NULL) {
     2002                        realm = talloc_strdup(frame, enterprise_realm);
     2003                        SAFE_FREE(enterprise_realm);
     2004                        if (realm == NULL) {
     2005                                TALLOC_FREE(frame);
     2006                                return ENOMEM;
     2007                        }
     2008                }
     2009        }
     2010
     2011        if (flags & SDB_F_GET_SERVER) {
     2012                char *service_realm = NULL;
     2013
     2014                ret = principal_comp_strcmp(context, principal, 0, KRB5_TGS_NAME);
     2015                if (ret == 0) {
     2016                        /*
     2017                         * we need to search krbtgt/ locally
     2018                         */
     2019                        TALLOC_FREE(frame);
     2020                        return 0;
     2021                }
     2022
     2023                /*
     2024                 * We need to check the last component against the routing table.
     2025                 *
     2026                 * Note this works only with 2 or 3 component principals, e.g:
     2027                 *
     2028                 * servicePrincipalName: ldap/W2K8R2-219.bla.base
     2029                 * servicePrincipalName: ldap/W2K8R2-219.bla.base/bla.base
     2030                 * servicePrincipalName: ldap/W2K8R2-219.bla.base/ForestDnsZones.bla.base
     2031                 * servicePrincipalName: ldap/W2K8R2-219.bla.base/DomainDnsZones.bla.base
     2032                 */
     2033
     2034                if (num_comp == 2 || num_comp == 3) {
     2035                        service_realm = smb_krb5_principal_get_comp_string(frame,
     2036                                                                           context,
     2037                                                                           principal,
     2038                                                                           num_comp - 1);
     2039                }
     2040
     2041                if (service_realm != NULL) {
     2042                        realm = service_realm;
     2043                }
     2044        }
     2045
     2046        ok = lpcfg_is_my_domain_or_realm(kdc_db_ctx->lp_ctx, realm);
     2047        if (ok) {
     2048                /*
     2049                 * skip the expensive routing lookup
     2050                 */
     2051                TALLOC_FREE(frame);
     2052                return 0;
     2053        }
     2054
     2055        status = dsdb_trust_routing_table_load(kdc_db_ctx->samdb,
     2056                                               frame, &trt);
     2057        if (!NT_STATUS_IS_OK(status)) {
     2058                TALLOC_FREE(frame);
     2059                return EINVAL;
     2060        }
     2061
     2062        tdo = dsdb_trust_routing_by_name(trt, realm);
     2063        if (tdo == NULL) {
     2064                /*
     2065                 * This principal has to be local
     2066                 */
     2067                TALLOC_FREE(frame);
     2068                return 0;
     2069        }
     2070
     2071        if (tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) {
     2072                /*
     2073                 * TODO: handle the routing within the forest
     2074                 *
     2075                 * This should likely be handled in
     2076                 * samba_kdc_message2entry() in case we're
     2077                 * a global catalog. We'd need to check
     2078                 * if realm_dn is our own domain and derive
     2079                 * the dns domain name from realm_dn and check that
     2080                 * against the routing table or fallback to
     2081                 * the tdo we found here.
     2082                 *
     2083                 * But for now we don't support multiple domains
     2084                 * in our forest correctly anyway.
     2085                 *
     2086                 * Just search in our local database.
     2087                 */
     2088                TALLOC_FREE(frame);
     2089                return 0;
     2090        }
     2091
     2092        ZERO_STRUCT(entry_ex->entry);
     2093
     2094        ret = krb5_copy_principal(context, principal,
     2095                                  &entry_ex->entry.principal);
     2096        if (ret) {
     2097                TALLOC_FREE(frame);
     2098                return ret;
     2099        }
     2100
     2101        upper = strupper_talloc(frame, tdo->domain_name.string);
     2102        if (upper == NULL) {
     2103                TALLOC_FREE(frame);
     2104                return ENOMEM;
     2105        }
     2106
     2107        ret = smb_krb5_principal_set_realm(context,
     2108                                           entry_ex->entry.principal,
     2109                                           upper);
     2110        if (ret) {
     2111                TALLOC_FREE(frame);
     2112                return ret;
     2113        }
     2114
     2115        TALLOC_FREE(frame);
     2116        return SDB_ERR_WRONG_REALM;
     2117}
     2118
    13342119krb5_error_code samba_kdc_fetch(krb5_context context,
    13352120                                struct samba_kdc_db_context *kdc_db_ctx,
     
    13372122                                unsigned flags,
    13382123                                krb5_kvno kvno,
    1339                                 hdb_entry_ex *entry_ex)
     2124                                struct sdb_entry_ex *entry_ex)
    13402125{
    1341         krb5_error_code ret = HDB_ERR_NOENTRY;
     2126        krb5_error_code ret = SDB_ERR_NOENTRY;
    13422127        TALLOC_CTX *mem_ctx;
    1343         unsigned int krbtgt_number;
    1344         if (flags & HDB_F_KVNO_SPECIFIED) {
    1345                 krbtgt_number = SAMBA_KVNO_GET_KRBTGT(kvno);
    1346                 if (kdc_db_ctx->rodc) {
    1347                         if (krbtgt_number != kdc_db_ctx->my_krbtgt_number) {
    1348                                 return HDB_ERR_NOT_FOUND_HERE;
    1349                         }
    1350                 }
    1351         } else {
    1352                 krbtgt_number = kdc_db_ctx->my_krbtgt_number;
    1353         }
    13542128
    13552129        mem_ctx = talloc_named(kdc_db_ctx, 0, "samba_kdc_fetch context");
     
    13602134        }
    13612135
    1362         if (flags & HDB_F_GET_CLIENT) {
     2136        ret = samba_kdc_lookup_realm(context, kdc_db_ctx, mem_ctx,
     2137                                     principal, flags, entry_ex);
     2138        if (ret != 0) {
     2139                goto done;
     2140        }
     2141
     2142        ret = SDB_ERR_NOENTRY;
     2143
     2144        if (flags & SDB_F_GET_CLIENT) {
    13632145                ret = samba_kdc_fetch_client(context, kdc_db_ctx, mem_ctx, principal, flags, entry_ex);
    1364                 if (ret != HDB_ERR_NOENTRY) goto done;
    1365         }
    1366         if (flags & HDB_F_GET_SERVER) {
     2146                if (ret != SDB_ERR_NOENTRY) goto done;
     2147        }
     2148        if (flags & SDB_F_GET_SERVER) {
    13672149                /* krbtgt fits into this situation for trusted realms, and for resolving different versions of our own realm name */
    1368                 ret = samba_kdc_fetch_krbtgt(context, kdc_db_ctx, mem_ctx, principal, flags, krbtgt_number, entry_ex);
    1369                 if (ret != HDB_ERR_NOENTRY) goto done;
     2150                ret = samba_kdc_fetch_krbtgt(context, kdc_db_ctx, mem_ctx, principal, flags, kvno, entry_ex);
     2151                if (ret != SDB_ERR_NOENTRY) goto done;
    13702152
    13712153                /* We return 'no entry' if it does not start with krbtgt/, so move to the common case quickly */
    13722154                ret = samba_kdc_fetch_server(context, kdc_db_ctx, mem_ctx, principal, flags, entry_ex);
    1373                 if (ret != HDB_ERR_NOENTRY) goto done;
    1374         }
    1375         if (flags & HDB_F_GET_KRBTGT) {
    1376                 ret = samba_kdc_fetch_krbtgt(context, kdc_db_ctx, mem_ctx, principal, flags, krbtgt_number, entry_ex);
    1377                 if (ret != HDB_ERR_NOENTRY) goto done;
     2155                if (ret != SDB_ERR_NOENTRY) goto done;
     2156        }
     2157        if (flags & SDB_F_GET_KRBTGT) {
     2158                ret = samba_kdc_fetch_krbtgt(context, kdc_db_ctx, mem_ctx, principal, flags, kvno, entry_ex);
     2159                if (ret != SDB_ERR_NOENTRY) goto done;
    13782160        }
    13792161
     
    13922174static krb5_error_code samba_kdc_seq(krb5_context context,
    13932175                                     struct samba_kdc_db_context *kdc_db_ctx,
    1394                                      hdb_entry_ex *entry)
     2176                                     struct sdb_entry_ex *entry)
    13952177{
    13962178        krb5_error_code ret;
    13972179        struct samba_kdc_seq *priv = kdc_db_ctx->seq_ctx;
     2180        const char *realm = lpcfg_realm(kdc_db_ctx->lp_ctx);
     2181        struct ldb_message *msg = NULL;
     2182        const char *sAMAccountName = NULL;
     2183        krb5_principal principal = NULL;
    13982184        TALLOC_CTX *mem_ctx;
    1399         hdb_entry_ex entry_ex;
    1400         memset(&entry_ex, '\0', sizeof(entry_ex));
    14012185
    14022186        if (!priv) {
    1403                 return HDB_ERR_NOENTRY;
     2187                return SDB_ERR_NOENTRY;
    14042188        }
    14052189
     
    14122196        }
    14132197
    1414         if (priv->index < priv->count) {
    1415                 ret = samba_kdc_message2entry(context, kdc_db_ctx, mem_ctx,
    1416                                               NULL, SAMBA_KDC_ENT_TYPE_ANY,
    1417                                               HDB_F_ADMIN_DATA|HDB_F_GET_ANY,
    1418                                               priv->realm_dn, priv->msgs[priv->index++], entry);
    1419         } else {
    1420                 ret = HDB_ERR_NOENTRY;
     2198        while (priv->index < priv->count) {
     2199                msg = priv->msgs[priv->index++];
     2200
     2201                sAMAccountName = ldb_msg_find_attr_as_string(msg, "sAMAccountName", NULL);
     2202                if (sAMAccountName != NULL) {
     2203                        break;
     2204                }
     2205        }
     2206
     2207        if (sAMAccountName == NULL) {
     2208                ret = SDB_ERR_NOENTRY;
     2209                goto out;
     2210        }
     2211
     2212        ret = smb_krb5_make_principal(context, &principal,
     2213                                      realm, sAMAccountName, NULL);
     2214        if (ret != 0) {
     2215                goto out;
     2216        }
     2217
     2218        ret = samba_kdc_message2entry(context, kdc_db_ctx, mem_ctx,
     2219                                      principal, SAMBA_KDC_ENT_TYPE_ANY,
     2220                                      SDB_F_ADMIN_DATA|SDB_F_GET_ANY,
     2221                                      priv->realm_dn, msg, entry);
     2222
     2223out:
     2224        if (principal != NULL) {
     2225                krb5_free_principal(context, principal);
    14212226        }
    14222227
     
    14332238krb5_error_code samba_kdc_firstkey(krb5_context context,
    14342239                                   struct samba_kdc_db_context *kdc_db_ctx,
    1435                                    hdb_entry_ex *entry)
     2240                                   struct sdb_entry_ex *entry)
    14362241{
    14372242        struct ldb_context *ldb_ctx = kdc_db_ctx->samdb;
     
    14732278                return ret;
    14742279        }
    1475 
    1476         lret = ldb_search(ldb_ctx, priv, &res,
    1477                           priv->realm_dn, LDB_SCOPE_SUBTREE, user_attrs,
    1478                           "(objectClass=user)");
     2280        krb5_free_default_realm(context, realm);
     2281
     2282        lret = dsdb_search(ldb_ctx, priv, &res,
     2283                           priv->realm_dn, LDB_SCOPE_SUBTREE, user_attrs,
     2284                           DSDB_SEARCH_NO_GLOBAL_CATALOG,
     2285                           "(objectClass=user)");
    14792286
    14802287        if (lret != LDB_SUCCESS) {
    14812288                TALLOC_FREE(priv);
    1482                 return HDB_ERR_NOENTRY;
     2289                return SDB_ERR_NOENTRY;
    14832290        }
    14842291
     
    15022309krb5_error_code samba_kdc_nextkey(krb5_context context,
    15032310                                  struct samba_kdc_db_context *kdc_db_ctx,
    1504                                   hdb_entry_ex *entry)
     2311                                  struct sdb_entry_ex *entry)
    15052312{
    15062313        return samba_kdc_seq(context, kdc_db_ctx, entry);
     
    15102317 *
    15112318 * This is currently a very nasty hack - allowing only delegation to itself.
    1512  *
    1513  * This is shared between the constrained delegation and S4U2Self code.
    15142319 */
    15152320krb5_error_code
    1516 samba_kdc_check_identical_client_and_server(krb5_context context,
    1517                                             struct samba_kdc_db_context *kdc_db_ctx,
    1518                                             hdb_entry_ex *entry,
    1519                                             krb5_const_principal target_principal)
     2321samba_kdc_check_s4u2self(krb5_context context,
     2322                        struct samba_kdc_db_context *kdc_db_ctx,
     2323                         struct samba_kdc_entry *skdc_entry,
     2324                        krb5_const_principal target_principal)
    15202325{
    15212326        krb5_error_code ret;
    1522         krb5_principal enterprise_prinicpal = NULL;
    15232327        struct ldb_dn *realm_dn;
    15242328        struct ldb_message *msg;
    15252329        struct dom_sid *orig_sid;
    15262330        struct dom_sid *target_sid;
    1527         struct samba_kdc_entry *p = talloc_get_type(entry->ctx, struct samba_kdc_entry);
    15282331        const char *delegation_check_attrs[] = {
    15292332                "objectSid", NULL
    15302333        };
    15312334
    1532         TALLOC_CTX *mem_ctx = talloc_named(kdc_db_ctx, 0, "samba_kdc_check_constrained_delegation");
     2335        TALLOC_CTX *mem_ctx = talloc_named(kdc_db_ctx, 0, "samba_kdc_check_s4u2self");
    15332336
    15342337        if (!mem_ctx) {
    15352338                ret = ENOMEM;
    1536                 krb5_set_error_message(context, ret, "samba_kdc_fetch: talloc_named() failed!");
     2339                krb5_set_error_message(context, ret, "samba_kdc_check_s4u2self: talloc_named() failed!");
    15372340                return ret;
    15382341        }
    15392342
    1540         if (target_principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) {
    1541                 /* Need to reparse the enterprise principal to find the real target */
    1542                 if (target_principal->name.name_string.len != 1) {
    1543                         ret = KRB5_PARSE_MALFORMED;
    1544                         krb5_set_error_message(context, ret, "samba_kdc_check_constrained_delegation: request for delegation to enterprise principal with wrong (%d) number of components",
    1545                                                target_principal->name.name_string.len);
    1546                         talloc_free(mem_ctx);
    1547                         return ret;
    1548                 }
    1549                 ret = krb5_parse_name(context, target_principal->name.name_string.val[0],
    1550                                       &enterprise_prinicpal);
    1551                 if (ret) {
    1552                         talloc_free(mem_ctx);
    1553                         return ret;
    1554                 }
    1555                 target_principal = enterprise_prinicpal;
    1556         }
    1557 
    15582343        ret = samba_kdc_lookup_server(context, kdc_db_ctx, mem_ctx, target_principal,
    1559                                        delegation_check_attrs, &realm_dn, &msg);
    1560 
    1561         krb5_free_principal(context, enterprise_prinicpal);
     2344                                      SDB_F_GET_CLIENT|SDB_F_GET_SERVER,
     2345                                      delegation_check_attrs, &realm_dn, &msg);
    15622346
    15632347        if (ret != 0) {
     
    15662350        }
    15672351
    1568         orig_sid = samdb_result_dom_sid(mem_ctx, p->msg, "objectSid");
     2352        orig_sid = samdb_result_dom_sid(mem_ctx, skdc_entry->msg, "objectSid");
    15692353        target_sid = samdb_result_dom_sid(mem_ctx, msg, "objectSid");
    15702354
     
    15892373samba_kdc_check_pkinit_ms_upn_match(krb5_context context,
    15902374                                    struct samba_kdc_db_context *kdc_db_ctx,
    1591                                      hdb_entry_ex *entry,
     2375                                    struct samba_kdc_entry *skdc_entry,
    15922376                                     krb5_const_principal certificate_principal)
    15932377{
     
    15972381        struct dom_sid *orig_sid;
    15982382        struct dom_sid *target_sid;
    1599         struct samba_kdc_entry *p = talloc_get_type(entry->ctx, struct samba_kdc_entry);
    16002383        const char *ms_upn_check_attrs[] = {
    16012384                "objectSid", NULL
     
    16112394
    16122395        ret = samba_kdc_lookup_client(context, kdc_db_ctx,
    1613                                        mem_ctx, certificate_principal,
    1614                                        ms_upn_check_attrs, &realm_dn, &msg);
     2396                                      mem_ctx, certificate_principal,
     2397                                      ms_upn_check_attrs, &realm_dn, &msg);
    16152398
    16162399        if (ret != 0) {
     
    16192402        }
    16202403
    1621         orig_sid = samdb_result_dom_sid(mem_ctx, p->msg, "objectSid");
     2404        orig_sid = samdb_result_dom_sid(mem_ctx, skdc_entry->msg, "objectSid");
    16222405        target_sid = samdb_result_dom_sid(mem_ctx, msg, "objectSid");
    16232406
     
    16272410        if (!(orig_sid && target_sid && dom_sid_equal(orig_sid, target_sid))) {
    16282411                talloc_free(mem_ctx);
     2412#ifdef KRB5_KDC_ERR_CLIENT_NAME_MISMATCH /* Heimdal */
    16292413                return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
     2414#elif defined(KRB5KDC_ERR_CLIENT_NAME_MISMATCH) /* MIT */
     2415                return KRB5KDC_ERR_CLIENT_NAME_MISMATCH;
     2416#endif
    16302417        }
    16312418
    16322419        talloc_free(mem_ctx);
    16332420        return ret;
     2421}
     2422
     2423/*
     2424 * Check if a given entry may delegate to this target principal
     2425 * with S4U2Proxy.
     2426 */
     2427krb5_error_code
     2428samba_kdc_check_s4u2proxy(krb5_context context,
     2429                          struct samba_kdc_db_context *kdc_db_ctx,
     2430                          struct samba_kdc_entry *skdc_entry,
     2431                          krb5_const_principal target_principal)
     2432{
     2433        krb5_error_code ret;
     2434        char *tmp = NULL;
     2435        const char *client_dn = NULL;
     2436        const char *target_principal_name = NULL;
     2437        struct ldb_message_element *el;
     2438        struct ldb_val val;
     2439        unsigned int i;
     2440        bool found = false;
     2441
     2442        TALLOC_CTX *mem_ctx = talloc_named(kdc_db_ctx, 0, "samba_kdc_check_s4u2proxy");
     2443
     2444        if (!mem_ctx) {
     2445                ret = ENOMEM;
     2446                krb5_set_error_message(context, ret,
     2447                                       "samba_kdc_check_s4u2proxy:"
     2448                                       " talloc_named() failed!");
     2449                return ret;
     2450        }
     2451
     2452        client_dn = ldb_dn_get_linearized(skdc_entry->msg->dn);
     2453        if (!client_dn) {
     2454                if (errno == 0) {
     2455                        errno = ENOMEM;
     2456                }
     2457                ret = errno;
     2458                krb5_set_error_message(context, ret,
     2459                                       "samba_kdc_check_s4u2proxy:"
     2460                                       " ldb_dn_get_linearized() failed!");
     2461                return ret;
     2462        }
     2463
     2464        /*
     2465         * The main heimdal code already checked that the target_principal
     2466         * belongs to the same realm as the client.
     2467         *
     2468         * So we just need the principal without the realm,
     2469         * as that is what is configured in the "msDS-AllowedToDelegateTo"
     2470         * attribute.
     2471         */
     2472        ret = krb5_unparse_name_flags(context, target_principal,
     2473                                      KRB5_PRINCIPAL_UNPARSE_NO_REALM, &tmp);
     2474        if (ret) {
     2475                talloc_free(mem_ctx);
     2476                krb5_set_error_message(context, ret,
     2477                                       "samba_kdc_check_s4u2proxy:"
     2478                                       " krb5_unparse_name() failed!");
     2479                return ret;
     2480        }
     2481        DEBUG(10,("samba_kdc_check_s4u2proxy: client[%s] for target[%s]\n",
     2482                 client_dn, tmp));
     2483
     2484        target_principal_name = talloc_strdup(mem_ctx, tmp);
     2485        SAFE_FREE(tmp);
     2486        if (target_principal_name == NULL) {
     2487                ret = ENOMEM;
     2488                krb5_set_error_message(context, ret,
     2489                                       "samba_kdc_check_s4u2proxy:"
     2490                                       " talloc_strdup() failed!");
     2491                return ret;
     2492        }
     2493
     2494        el = ldb_msg_find_element(skdc_entry->msg, "msDS-AllowedToDelegateTo");
     2495        if (el == NULL) {
     2496                goto bad_option;
     2497        }
     2498
     2499        val = data_blob_string_const(target_principal_name);
     2500
     2501        for (i=0; i<el->num_values; i++) {
     2502                struct ldb_val *val1 = &val;
     2503                struct ldb_val *val2 = &el->values[i];
     2504                int cmp;
     2505
     2506                if (val1->length != val2->length) {
     2507                        continue;
     2508                }
     2509
     2510                cmp = strncasecmp((const char *)val1->data,
     2511                                  (const char *)val2->data,
     2512                                  val1->length);
     2513                if (cmp != 0) {
     2514                        continue;
     2515                }
     2516
     2517                found = true;
     2518                break;
     2519        }
     2520
     2521        if (!found) {
     2522                goto bad_option;
     2523        }
     2524
     2525        DEBUG(10,("samba_kdc_check_s4u2proxy: client[%s] allowed target[%s]\n",
     2526                 client_dn, tmp));
     2527        talloc_free(mem_ctx);
     2528        return 0;
     2529
     2530bad_option:
     2531        krb5_set_error_message(context, ret,
     2532                               "samba_kdc_check_s4u2proxy: client[%s] "
     2533                               "not allowed for delegation to target[%s]",
     2534                               client_dn,
     2535                               target_principal_name);
     2536        talloc_free(mem_ctx);
     2537        return KRB5KDC_ERR_BADOPTION;
    16342538}
    16352539
     
    16562560        kdc_db_ctx->lp_ctx = base_ctx->lp_ctx;
    16572561
    1658         kdc_get_policy(base_ctx->lp_ctx, NULL, &kdc_db_ctx->policy);
     2562        /* get default kdc policy */
     2563        lpcfg_default_kdc_policy(base_ctx->lp_ctx,
     2564                                 &kdc_db_ctx->policy.svc_tkt_lifetime,
     2565                                 &kdc_db_ctx->policy.usr_tkt_lifetime,
     2566                                 &kdc_db_ctx->policy.renewal_lifetime);
    16592567
    16602568        session_info = system_session(kdc_db_ctx->lp_ctx);
     
    16672575                                          base_ctx->lp_ctx, session_info, 0);
    16682576        if (kdc_db_ctx->samdb == NULL) {
    1669                 DEBUG(1, ("hdb_samba4_create: Cannot open samdb for KDC backend!"));
     2577                DEBUG(1, ("samba_kdc_setup_db_ctx: Cannot open samdb for KDC backend!"));
    16702578                talloc_free(kdc_db_ctx);
    16712579                return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     
    16752583        ldb_ret = samdb_rodc(kdc_db_ctx->samdb, &kdc_db_ctx->rodc);
    16762584        if (ldb_ret != LDB_SUCCESS) {
    1677                 DEBUG(1, ("hdb_samba4_create: Cannot determine if we are an RODC in KDC backend: %s\n",
     2585                DEBUG(1, ("samba_kdc_setup_db_ctx: Cannot determine if we are an RODC in KDC backend: %s\n",
    16782586                          ldb_errstring(kdc_db_ctx->samdb)));
    16792587                talloc_free(kdc_db_ctx);
     
    16862594                struct ldb_dn *server_dn = samdb_server_dn(kdc_db_ctx->samdb, kdc_db_ctx);
    16872595                if (!server_dn) {
    1688                         DEBUG(1, ("hdb_samba4_create: Cannot determine server DN in KDC backend: %s\n",
     2596                        DEBUG(1, ("samba_kdc_setup_db_ctx: Cannot determine server DN in KDC backend: %s\n",
    16892597                                  ldb_errstring(kdc_db_ctx->samdb)));
    16902598                        talloc_free(kdc_db_ctx);
     
    16952603                                             "serverReference", &account_dn);
    16962604                if (ldb_ret != LDB_SUCCESS) {
    1697                         DEBUG(1, ("hdb_samba4_create: Cannot determine server account in KDC backend: %s\n",
     2605                        DEBUG(1, ("samba_kdc_setup_db_ctx: Cannot determine server account in KDC backend: %s\n",
    16982606                                  ldb_errstring(kdc_db_ctx->samdb)));
    16992607                        talloc_free(kdc_db_ctx);
     
    17052613                talloc_free(account_dn);
    17062614                if (ldb_ret != LDB_SUCCESS) {
    1707                         DEBUG(1, ("hdb_samba4_create: Cannot determine RODC krbtgt account in KDC backend: %s\n",
     2615                        DEBUG(1, ("samba_kdc_setup_db_ctx: Cannot determine RODC krbtgt account in KDC backend: %s\n",
    17082616                                  ldb_errstring(kdc_db_ctx->samdb)));
    17092617                        talloc_free(kdc_db_ctx);
     
    17142622                                          &msg, kdc_db_ctx->krbtgt_dn, LDB_SCOPE_BASE,
    17152623                                          secondary_keytab,
    1716                                           0,
     2624                                          DSDB_SEARCH_NO_GLOBAL_CATALOG,
    17172625                                          "(&(objectClass=user)(msDS-SecondaryKrbTgtNumber=*))");
    17182626                if (ldb_ret != LDB_SUCCESS) {
    1719                         DEBUG(1, ("hdb_samba4_create: Cannot read krbtgt account %s in KDC backend to get msDS-SecondaryKrbTgtNumber: %s: %s\n",
     2627                        DEBUG(1, ("samba_kdc_setup_db_ctx: Cannot read krbtgt account %s in KDC backend to get msDS-SecondaryKrbTgtNumber: %s: %s\n",
    17202628                                  ldb_dn_get_linearized(kdc_db_ctx->krbtgt_dn),
    17212629                                  ldb_errstring(kdc_db_ctx->samdb),
     
    17262634                my_krbtgt_number = ldb_msg_find_attr_as_int(msg, "msDS-SecondaryKrbTgtNumber", -1);
    17272635                if (my_krbtgt_number == -1) {
    1728                         DEBUG(1, ("hdb_samba4_create: Cannot read msDS-SecondaryKrbTgtNumber from krbtgt account %s in KDC backend: got %d\n",
     2636                        DEBUG(1, ("samba_kdc_setup_db_ctx: Cannot read msDS-SecondaryKrbTgtNumber from krbtgt account %s in KDC backend: got %d\n",
    17292637                                  ldb_dn_get_linearized(kdc_db_ctx->krbtgt_dn),
    17302638                                  my_krbtgt_number));
     
    17372645                kdc_db_ctx->my_krbtgt_number = 0;
    17382646                ldb_ret = dsdb_search_one(kdc_db_ctx->samdb, kdc_db_ctx,
    1739                                           &msg, NULL, LDB_SCOPE_SUBTREE,
     2647                                          &msg,
     2648                                          ldb_get_default_basedn(kdc_db_ctx->samdb),
     2649                                          LDB_SCOPE_SUBTREE,
    17402650                                          krbtgt_attrs,
    1741                                           0,
     2651                                          DSDB_SEARCH_NO_GLOBAL_CATALOG,
    17422652                                          "(&(objectClass=user)(samAccountName=krbtgt))");
    17432653
  • vendor/current/source4/kdc/db-glue.h

    r740 r988  
    2222*/
    2323
     24struct sdb_entry_ex;
     25
    2426krb5_error_code samba_kdc_fetch(krb5_context context,
    2527                                struct samba_kdc_db_context *kdc_db_ctx,
     
    2729                                unsigned flags,
    2830                                krb5_kvno kvno,
    29                                 hdb_entry_ex *entry_ex);
     31                                struct sdb_entry_ex *entry_ex);
    3032
    3133krb5_error_code samba_kdc_firstkey(krb5_context context,
    3234                                   struct samba_kdc_db_context *kdc_db_ctx,
    33                                    hdb_entry_ex *entry);
     35                                   struct sdb_entry_ex *entry);
    3436
    3537krb5_error_code samba_kdc_nextkey(krb5_context context,
    3638                                  struct samba_kdc_db_context *kdc_db_ctx,
    37                                   hdb_entry_ex *entry);
     39                                  struct sdb_entry_ex *entry);
    3840
    3941krb5_error_code
    40 samba_kdc_check_identical_client_and_server(krb5_context context,
    41                                             struct samba_kdc_db_context *kdc_db_ctx,
    42                                             hdb_entry_ex *entry,
    43                                             krb5_const_principal target_principal);
     42samba_kdc_check_s4u2self(krb5_context context,
     43                        struct samba_kdc_db_context *kdc_db_ctx,
     44                         struct samba_kdc_entry *skdc_entry,
     45                        krb5_const_principal target_principal);
    4446
    4547krb5_error_code
    4648samba_kdc_check_pkinit_ms_upn_match(krb5_context context,
    4749                                    struct samba_kdc_db_context *kdc_db_ctx,
    48                                     hdb_entry_ex *entry,
     50                                    struct samba_kdc_entry *skdc_entry,
    4951                                    krb5_const_principal certificate_principal);
     52
     53krb5_error_code
     54samba_kdc_check_s4u2proxy(krb5_context context,
     55                          struct samba_kdc_db_context *kdc_db_ctx,
     56                          struct samba_kdc_entry *skdc_entry,
     57                          krb5_const_principal target_principal);
    5058
    5159NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_context *base_ctx,
  • vendor/current/source4/kdc/hdb-samba4.c

    r740 r988  
    3636#include "kdc/kdc-glue.h"
    3737#include "kdc/db-glue.h"
     38#include "auth/auth_sam.h"
     39#include <ldb.h>
     40#include "sdb.h"
     41#include "sdb_hdb.h"
    3842
    3943static krb5_error_code hdb_samba4_open(krb5_context context, HDB *db, int flags, mode_t mode)
     
    8690{
    8791        struct samba_kdc_db_context *kdc_db_ctx;
    88 
    89         kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
    90                                            struct samba_kdc_db_context);
    91 
    92         return samba_kdc_fetch(context, kdc_db_ctx, principal, flags, kvno, entry_ex);
     92        struct sdb_entry_ex sdb_entry_ex = {};
     93        krb5_error_code code, ret;
     94
     95        kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
     96                                           struct samba_kdc_db_context);
     97
     98        ret = samba_kdc_fetch(context,
     99                              kdc_db_ctx,
     100                              principal,
     101                              flags,
     102                              kvno,
     103                              &sdb_entry_ex);
     104        switch (ret) {
     105        case 0:
     106                code = 0;
     107                break;
     108        case SDB_ERR_WRONG_REALM:
     109                /*
     110                 * If SDB_ERR_WRONG_REALM is returned we need to process the
     111                 * sdb_entry to fill the principal in the HDB entry.
     112                 */
     113                code = HDB_ERR_WRONG_REALM;
     114                break;
     115        case SDB_ERR_NOENTRY:
     116                return HDB_ERR_NOENTRY;
     117        default:
     118                return HDB_ERR_NOT_FOUND_HERE;
     119        }
     120
     121        ret = sdb_entry_ex_to_hdb_entry_ex(context, &sdb_entry_ex, entry_ex);
     122        sdb_free_entry(&sdb_entry_ex);
     123
     124        if (code != 0 && ret != 0) {
     125                code = ret;
     126        }
     127
     128        return code;
    93129}
    94130
     
    97133{
    98134        struct samba_kdc_db_context *kdc_db_ctx;
    99 
    100         kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
    101                                            struct samba_kdc_db_context);
    102 
    103         return samba_kdc_firstkey(context, kdc_db_ctx, entry);
     135        struct sdb_entry_ex sdb_entry_ex = {};
     136        krb5_error_code ret;
     137
     138        kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
     139                                           struct samba_kdc_db_context);
     140
     141        ret = samba_kdc_firstkey(context, kdc_db_ctx, &sdb_entry_ex);
     142        switch (ret) {
     143        case 0:
     144                break;
     145        case SDB_ERR_WRONG_REALM:
     146                return HDB_ERR_WRONG_REALM;
     147        case SDB_ERR_NOENTRY:
     148                return HDB_ERR_NOENTRY;
     149        default:
     150                return HDB_ERR_NOT_FOUND_HERE;
     151        }
     152
     153        ret = sdb_entry_ex_to_hdb_entry_ex(context, &sdb_entry_ex, entry);
     154        sdb_free_entry(&sdb_entry_ex);
     155        return ret;
    104156}
    105157
     
    108160{
    109161        struct samba_kdc_db_context *kdc_db_ctx;
    110 
    111         kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
    112                                            struct samba_kdc_db_context);
    113 
    114         return samba_kdc_nextkey(context, kdc_db_ctx, entry);
     162        struct sdb_entry_ex sdb_entry_ex = {};
     163        krb5_error_code ret;
     164
     165        kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
     166                                           struct samba_kdc_db_context);
     167
     168        ret = samba_kdc_nextkey(context, kdc_db_ctx, &sdb_entry_ex);
     169        switch (ret) {
     170        case 0:
     171                break;
     172        case SDB_ERR_WRONG_REALM:
     173                return HDB_ERR_WRONG_REALM;
     174        case SDB_ERR_NOENTRY:
     175                return HDB_ERR_NOENTRY;
     176        default:
     177                return HDB_ERR_NOT_FOUND_HERE;
     178        }
     179
     180        ret = sdb_entry_ex_to_hdb_entry_ex(context, &sdb_entry_ex, entry);
     181        sdb_free_entry(&sdb_entry_ex);
     182        return ret;
    115183}
    116184
     
    122190
    123191static krb5_error_code
    124 hdb_samba4_check_identical_client_and_server(krb5_context context, HDB *db,
     192hdb_samba4_check_constrained_delegation(krb5_context context, HDB *db,
    125193                                        hdb_entry_ex *entry,
    126194                                        krb5_const_principal target_principal)
    127195{
    128196        struct samba_kdc_db_context *kdc_db_ctx;
    129 
    130         kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
    131                                            struct samba_kdc_db_context);
    132 
    133         return samba_kdc_check_identical_client_and_server(context, kdc_db_ctx,
    134                                                            entry,
    135                                                            target_principal);
     197        struct samba_kdc_entry *skdc_entry;
     198        krb5_error_code ret;
     199
     200        kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
     201                                           struct samba_kdc_db_context);
     202        skdc_entry = talloc_get_type_abort(entry->ctx,
     203                                           struct samba_kdc_entry);
     204
     205        ret = samba_kdc_check_s4u2proxy(context, kdc_db_ctx,
     206                                        skdc_entry,
     207                                        target_principal);
     208        switch (ret) {
     209        case 0:
     210                break;
     211        case SDB_ERR_WRONG_REALM:
     212                ret = HDB_ERR_WRONG_REALM;
     213                break;
     214        case SDB_ERR_NOENTRY:
     215                ret = HDB_ERR_NOENTRY;
     216                break;
     217        default:
     218                ret = HDB_ERR_NOT_FOUND_HERE;
     219                break;
     220        }
     221
     222        return ret;
    136223}
    137224
     
    142229{
    143230        struct samba_kdc_db_context *kdc_db_ctx;
    144 
    145         kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
    146                                            struct samba_kdc_db_context);
    147 
    148         return samba_kdc_check_pkinit_ms_upn_match(context, kdc_db_ctx,
    149                                                    entry,
    150                                                    certificate_principal);
     231        struct samba_kdc_entry *skdc_entry;
     232        krb5_error_code ret;
     233
     234        kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
     235                                           struct samba_kdc_db_context);
     236        skdc_entry = talloc_get_type_abort(entry->ctx,
     237                                           struct samba_kdc_entry);
     238
     239        ret = samba_kdc_check_pkinit_ms_upn_match(context, kdc_db_ctx,
     240                                                  skdc_entry,
     241                                                  certificate_principal);
     242        switch (ret) {
     243        case 0:
     244                break;
     245        case SDB_ERR_WRONG_REALM:
     246                ret = HDB_ERR_WRONG_REALM;
     247                break;
     248        case SDB_ERR_NOENTRY:
     249                ret = HDB_ERR_NOENTRY;
     250                break;
     251        default:
     252                ret = HDB_ERR_NOT_FOUND_HERE;
     253                break;
     254        }
     255
     256        return ret;
     257}
     258
     259static krb5_error_code
     260hdb_samba4_check_s4u2self(krb5_context context, HDB *db,
     261                          hdb_entry_ex *entry,
     262                          krb5_const_principal target_principal)
     263{
     264        struct samba_kdc_db_context *kdc_db_ctx;
     265        struct samba_kdc_entry *skdc_entry;
     266        krb5_error_code ret;
     267
     268        kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
     269                                           struct samba_kdc_db_context);
     270        skdc_entry = talloc_get_type_abort(entry->ctx,
     271                                           struct samba_kdc_entry);
     272
     273        ret = samba_kdc_check_s4u2self(context, kdc_db_ctx,
     274                                       skdc_entry,
     275                                       target_principal);
     276        switch (ret) {
     277        case 0:
     278                break;
     279        case SDB_ERR_WRONG_REALM:
     280                ret = HDB_ERR_WRONG_REALM;
     281                break;
     282        case SDB_ERR_NOENTRY:
     283                ret = HDB_ERR_NOENTRY;
     284                break;
     285        default:
     286                ret = HDB_ERR_NOT_FOUND_HERE;
     287                break;
     288        }
     289
     290        return ret;
     291}
     292
     293static krb5_error_code hdb_samba4_auth_status(krb5_context context, HDB *db,
     294                                              hdb_entry_ex *entry,
     295                                              int hdb_auth_status)
     296{
     297        struct samba_kdc_db_context *kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
     298                                                                        struct samba_kdc_db_context);
     299        struct samba_kdc_entry *p = talloc_get_type(entry->ctx, struct samba_kdc_entry);
     300
     301        struct ldb_dn *domain_dn = ldb_get_default_basedn(kdc_db_ctx->samdb);
     302
     303        if (hdb_auth_status == HDB_AUTH_WRONG_PASSWORD) {
     304                authsam_update_bad_pwd_count(kdc_db_ctx->samdb, p->msg, domain_dn);
     305        } else if (hdb_auth_status == HDB_AUTH_SUCCESS) {
     306                authsam_logon_success_accounting(kdc_db_ctx->samdb, p->msg,
     307                                                 domain_dn, true);
     308        }
     309        return 0;
    151310}
    152311
     
    162321        NTSTATUS nt_status;
    163322
     323        if (hdb_interface_version != HDB_INTERFACE_VERSION) {
     324                krb5_set_error_message(context, EINVAL, "Heimdal HDB interface version mismatch between build-time and run-time libraries!");
     325                return NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION;
     326        }
     327
    164328        *db = talloc(base_ctx, HDB);
    165329        if (!*db) {
     
    170334        (*db)->hdb_master_key_set = 0;
    171335        (*db)->hdb_db = NULL;
    172         (*db)->hdb_capability_flags = 0;
     336        (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL;
    173337
    174338        nt_status = samba_kdc_setup_db_ctx(*db, base_ctx, &kdc_db_ctx);
     
    197361        (*db)->hdb_destroy = hdb_samba4_destroy;
    198362
    199         (*db)->hdb_auth_status = NULL;
    200         (*db)->hdb_check_constrained_delegation = hdb_samba4_check_identical_client_and_server;
     363        (*db)->hdb_auth_status = hdb_samba4_auth_status;
     364        (*db)->hdb_check_constrained_delegation = hdb_samba4_check_constrained_delegation;
    201365        (*db)->hdb_check_pkinit_ms_upn_match = hdb_samba4_check_pkinit_ms_upn_match;
    202         (*db)->hdb_check_s4u2self = hdb_samba4_check_identical_client_and_server;
     366        (*db)->hdb_check_s4u2self = hdb_samba4_check_s4u2self;
    203367
    204368        return NT_STATUS_OK;
    205369}
    206 
    207 static krb5_error_code hdb_samba4_create(krb5_context context, struct HDB **db, const char *arg)
    208 {
    209         NTSTATUS nt_status;
    210         void *ptr;
    211         struct samba_kdc_base_context *base_ctx;
    212 
    213         if (sscanf(arg, "&%p", &ptr) != 1) {
    214                 return EINVAL;
    215         }
    216         base_ctx = talloc_get_type_abort(ptr, struct samba_kdc_base_context);
    217         /* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */
    218         nt_status = hdb_samba4_create_kdc(base_ctx, context, db);
    219 
    220         if (NT_STATUS_IS_OK(nt_status)) {
    221                 return 0;
    222         }
    223         return EINVAL;
    224 }
    225 
    226 /* Only used in the hdb-backed keytab code
    227  * for a keytab of 'samba4&<address>', to find
    228  * kpasswd's key in the main DB, and to
    229  * copy all the keys into a file (libnet_keytab_export)
    230  *
    231  * The <address> is the string form of a pointer to a talloced struct hdb_samba_context
    232  */
    233 struct hdb_method hdb_samba4 = {
    234         .interface_version = HDB_INTERFACE_VERSION,
    235         .prefix = "samba4",
    236         .create = hdb_samba4_create
    237 };
  • vendor/current/source4/kdc/kdc-glue.h

    r740 r988  
    8282                            DATA_BLOB *out);
    8383
     84/* from kdc-glue.c */
     85int kdc_check_pac(krb5_context krb5_context,
     86                  DATA_BLOB server_sig,
     87                  struct PAC_SIGNATURE_DATA *kdc_sig,
     88                  hdb_entry_ex *ent);
    8489#endif
  • vendor/current/source4/kdc/kdc.c

    r740 r988  
    3333#include "param/param.h"
    3434#include "kdc/kdc-glue.h"
     35#include "kdc/pac-glue.h"
    3536#include "dsdb/samdb/samdb.h"
    3637#include "auth/session.h"
     38#include "libds/common/roles.h"
     39
     40NTSTATUS server_service_kdc_init(void);
    3741
    3842extern struct krb5plugin_windc_ftable windc_plugin_table;
    39 extern struct hdb_method hdb_samba4;
    4043
    4144static NTSTATUS kdc_proxy_unavailable_error(struct kdc_server *kdc,
     
    616619        struct kdc_udp_call *call = tevent_req_callback_data(subreq,
    617620                                       struct kdc_udp_call);
    618         ssize_t ret;
    619621        int sys_errno;
    620622
    621         ret = tdgram_sendto_queue_recv(subreq, &sys_errno);
     623        tdgram_sendto_queue_recv(subreq, &sys_errno);
    622624
    623625        /* We don't care about errors */
     
    653655                                                &kdc_socket->local_address);
    654656        if (ret != 0) {
    655                 status = map_nt_error_from_unix(errno);
     657                status = map_nt_error_from_unix_common(errno);
    656658                return status;
    657659        }
     
    684686                                     &kdc_udp_socket->dgram);
    685687        if (ret != 0) {
    686                 status = map_nt_error_from_unix(errno);
     688                status = map_nt_error_from_unix_common(errno);
    687689                DEBUG(0,("Failed to bind to %s:%u UDP - %s\n",
    688690                         address, port, nt_errstr(status)));
     
    728730        }
    729731
    730         num_interfaces = iface_count(ifaces);
     732        num_interfaces = iface_list_count(ifaces);
    731733
    732734        /* if we are allowing incoming packets from any address, then
    733735           we need to bind to the wildcard address */
    734736        if (!lpcfg_bind_interfaces_only(lp_ctx)) {
    735                 if (kdc_port) {
    736                         status = kdc_add_socket(kdc, model_ops,
    737                                                 "kdc", "0.0.0.0", kdc_port,
    738                                                 kdc_process, false);
    739                         NT_STATUS_NOT_OK_RETURN(status);
    740                 }
    741 
    742                 if (kpasswd_port) {
    743                         status = kdc_add_socket(kdc, model_ops,
    744                                                 "kpasswd", "0.0.0.0", kpasswd_port,
    745                                                 kpasswdd_process, false);
    746                         NT_STATUS_NOT_OK_RETURN(status);
     737                int num_binds = 0;
     738                char **wcard = iface_list_wildcard(kdc);
     739                NT_STATUS_HAVE_NO_MEMORY(wcard);
     740                for (i=0; wcard[i]; i++) {
     741                        if (kdc_port) {
     742                                status = kdc_add_socket(kdc, model_ops,
     743                                                        "kdc", wcard[i], kdc_port,
     744                                                        kdc_process, false);
     745                                if (NT_STATUS_IS_OK(status)) {
     746                                        num_binds++;
     747                                }
     748                        }
     749
     750                        if (kpasswd_port) {
     751                                status = kdc_add_socket(kdc, model_ops,
     752                                                        "kpasswd", wcard[i], kpasswd_port,
     753                                                        kpasswdd_process, false);
     754                                if (NT_STATUS_IS_OK(status)) {
     755                                        num_binds++;
     756                                }
     757                        }
     758                }
     759                talloc_free(wcard);
     760                if (num_binds == 0) {
     761                        return NT_STATUS_INVALID_PARAMETER_MIX;
    747762                }
    748763                done_wildcard = true;
     
    750765
    751766        for (i=0; i<num_interfaces; i++) {
    752                 const char *address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i));
     767                const char *address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i));
    753768
    754769                if (kdc_port) {
     
    772787}
    773788
    774 
    775789static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
    776790                                 struct kdc_check_generic_kerberos *r)
     
    781795        struct kdc_server *kdc = talloc_get_type(msg->private_data, struct kdc_server);
    782796        enum ndr_err_code ndr_err;
    783         krb5_enctype etype;
    784797        int ret;
    785798        hdb_entry_ex ent;
    786799        krb5_principal principal;
    787         krb5_keyblock keyblock;
    788         Key *key;
    789800
    790801        /* There is no reply to this request */
     
    797808        }
    798809
    799         if (pac_validate.MessageType != 3) {
     810        if (pac_validate.MessageType != NETLOGON_GENERIC_KRB5_PAC_VALIDATE) {
    800811                /* We don't implement any other message types - such as certificate validation - yet */
    801812                return NT_STATUS_INVALID_PARAMETER;
     
    810821        srv_sig = data_blob_const(pac_validate.ChecksumAndSignature.data,
    811822                                  pac_validate.ChecksumLength);
    812 
    813         if (pac_validate.SignatureType == CKSUMTYPE_HMAC_MD5) {
    814                 etype = ETYPE_ARCFOUR_HMAC_MD5;
    815         } else {
    816                 ret = krb5_cksumtype_to_enctype(kdc->smb_krb5_context->krb5_context, pac_validate.SignatureType,
    817                                                 &etype);
    818                 if (ret != 0) {
    819                         return NT_STATUS_LOGON_FAILURE;
    820                 }
    821         }
    822823
    823824        ret = krb5_make_principal(kdc->smb_krb5_context->krb5_context, &principal,
     
    844845        }
    845846
    846         ret = hdb_enctype2key(kdc->smb_krb5_context->krb5_context, &ent.entry, etype, &key);
    847 
    848         if (ret != 0) {
    849                 hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
    850                 krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
    851                 return NT_STATUS_LOGON_FAILURE;
    852         }
    853 
    854         keyblock = key->key;
    855 
    856847        kdc_sig.type = pac_validate.SignatureType;
    857848        kdc_sig.signature = data_blob_const(&pac_validate.ChecksumAndSignature.data[pac_validate.ChecksumLength],
    858849                                            pac_validate.SignatureLength);
    859         ret = check_pac_checksum(msg, srv_sig, &kdc_sig,
    860                            kdc->smb_krb5_context->krb5_context, &keyblock);
     850
     851        ret = kdc_check_pac(kdc->smb_krb5_context->krb5_context, srv_sig, &kdc_sig, &ent);
    861852
    862853        hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
     
    889880                task_server_terminate(task, "kdc: no KDC required in member server configuration", false);
    890881                return;
    891         case ROLE_DOMAIN_CONTROLLER:
     882        case ROLE_DOMAIN_PDC:
     883        case ROLE_DOMAIN_BDC:
     884                task_server_terminate(task, "Cannot start KDC as a 'classic Samba' DC", true);
     885                return;
     886        case ROLE_ACTIVE_DIRECTORY_DC:
    892887                /* Yes, we want a KDC */
    893888                break;
    894889        }
    895890
    896         load_interfaces(task, lpcfg_interfaces(task->lp_ctx), &ifaces);
    897 
    898         if (iface_count(ifaces) == 0) {
     891        load_interface_list(task, task->lp_ctx, &ifaces);
     892
     893        if (iface_list_count(ifaces) == 0) {
    899894                task_server_terminate(task, "kdc: no network interfaces configured", false);
    900895                return;
     
    933928        initialize_krb5_error_table();
    934929
    935         ret = smb_krb5_init_context(kdc, task->event_ctx, task->lp_ctx, &kdc->smb_krb5_context);
     930        ret = smb_krb5_init_context(kdc, task->lp_ctx, &kdc->smb_krb5_context);
    936931        if (ret) {
    937932                DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
     
    950945        }
    951946
    952         kdc->config->logf = kdc->smb_krb5_context->logf;
     947        kdc->config->logf = (krb5_log_facility *)kdc->smb_krb5_context->pvt_log_data;
    953948        kdc->config->db = talloc(kdc, struct HDB *);
    954949        if (!kdc->config->db) {
     
    957952        }
    958953        kdc->config->num_db = 1;
     954
     955        /*
     956         * This restores the behavior before
     957         * commit 255e3e18e00f717d99f3bc57c8a8895ff624f3c3
     958         * s4:heimdal: import lorikeet-heimdal-201107150856
     959         * (commit 48936803fae4a2fb362c79365d31f420c917b85b)
     960         *
     961         * as_use_strongest_session_key,preauth_use_strongest_session_key
     962         * and tgs_use_strongest_session_key are input to the
     963         * _kdc_find_etype() function. The old bahavior is in
     964         * the use_strongest_session_key=FALSE code path.
     965         * (The only remaining difference in _kdc_find_etype()
     966         *  is the is_preauth parameter.)
     967         *
     968         * The old behavior in the _kdc_get_preferred_key()
     969         * function is use_strongest_server_key=TRUE.
     970         */
     971        kdc->config->as_use_strongest_session_key = false;
     972        kdc->config->preauth_use_strongest_session_key = false;
     973        kdc->config->tgs_use_strongest_session_key = false;
     974        kdc->config->use_strongest_server_key = true;
    959975
    960976        /* Register hdb-samba4 hooks for use as a keytab */
     
    979995        ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
    980996                                   PLUGIN_TYPE_DATA, "hdb",
    981                                    &hdb_samba4);
     997                                   &hdb_samba4_interface);
    982998        if(ret) {
    983999                task_server_terminate(task, "kdc: failed to register hdb plugin", true);
  • vendor/current/source4/kdc/kpasswdd.c

    r740 r988  
    3131#include "param/param.h"
    3232#include "kdc/kdc-glue.h"
     33#include "dsdb/common/util.h"
     34#include "kdc/kpasswd_glue.h"
    3335
    3436/* Return true if there is a valid error packet formed in the error_blob */
     
    112114                switch (reject_reason) {
    113115                case SAM_PWD_CHANGE_PASSWORD_TOO_SHORT:
    114                         reject_string = talloc_asprintf(mem_ctx, "Password too short, password must be at least %d characters long",
     116                        reject_string = talloc_asprintf(mem_ctx, "Password too short, password must be at least %d characters long.",
    115117                                                        dominfo->min_password_length);
    116118                        break;
     
    119121                        break;
    120122                case SAM_PWD_CHANGE_PWD_IN_HISTORY:
    121                         reject_string = "Password is already in password history";
     123                        reject_string = talloc_asprintf(mem_ctx, "Password is already in password history.  New password must not match any of your %d previous passwords.",
     124                                                        dominfo->password_history_length);
    122125                        break;
    123126                default:
    124                         reject_string = talloc_asprintf(mem_ctx, "Password must be at least %d characters long, and cannot match any of your %d previous passwords",
    125                                                         dominfo->min_password_length, dominfo->password_history_length);
     127                        reject_string = "Password change rejected, password changes may not be permitted on this account, or the minimum password age may not have elapsed.";
    126128                        break;
    127129                }
     
    156158{
    157159        NTSTATUS status;
     160        NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
    158161        enum samPwdChangeReason reject_reason;
    159162        struct samr_DomInfo1 *dominfo;
    160         struct samr_Password *oldLmHash, *oldNtHash;
    161         struct ldb_context *samdb;
    162         const char * const attrs[] = { "dBCSPwd", "unicodePwd", NULL };
    163         struct ldb_message **res;
    164         int ret;
    165 
    166         /* Fetch the old hashes to get the old password in order to perform
    167          * the password change operation. Naturally it would be much better to
    168          * have a password hash from an authentication around but this doesn't
    169          * seem to be the case here. */
    170         ret = gendb_search(kdc->samdb, mem_ctx, NULL, &res, attrs,
    171                            "(&(objectClass=user)(sAMAccountName=%s))",
    172                            session_info->info->account_name);
    173         if (ret != 1) {
    174                 return kpasswdd_make_error_reply(kdc, mem_ctx,
    175                                                 KRB5_KPASSWD_ACCESSDENIED,
    176                                                 "No such user when changing password",
    177                                                 reply);
    178         }
    179 
    180         status = samdb_result_passwords(mem_ctx, kdc->task->lp_ctx, res[0],
    181                                         &oldLmHash, &oldNtHash);
     163        const char *error_string;
     164
     165        status = samdb_kpasswd_change_password(mem_ctx,
     166                                               kdc->task->lp_ctx,
     167                                               kdc->task->event_ctx,
     168                                               kdc->samdb,
     169                                               session_info,
     170                                               password,
     171                                               &reject_reason,
     172                                               &dominfo,
     173                                               &error_string,
     174                                               &result);
    182175        if (!NT_STATUS_IS_OK(status)) {
    183                 return kpasswdd_make_error_reply(kdc, mem_ctx,
    184                                                 KRB5_KPASSWD_ACCESSDENIED,
    185                                                 "Not permitted to change password",
    186                                                 reply);
    187         }
    188 
    189         /* Start a SAM with user privileges for the password change */
    190         samdb = samdb_connect(mem_ctx, kdc->task->event_ctx, kdc->task->lp_ctx,
    191                               session_info, 0);
    192         if (!samdb) {
    193                 return kpasswdd_make_error_reply(kdc, mem_ctx,
    194                                                 KRB5_KPASSWD_HARDERROR,
    195                                                 "Failed to open samdb",
    196                                                 reply);
    197         }
    198 
    199         DEBUG(3, ("Changing password of %s\\%s (%s)\n",
    200                   session_info->info->domain_name,
    201                   session_info->info->account_name,
    202                   dom_sid_string(mem_ctx, &session_info->security_token->sids[PRIMARY_USER_SID_INDEX])));
    203 
    204         /* Performs the password change */
    205         status = samdb_set_password_sid(samdb, mem_ctx,
    206                                         &session_info->security_token->sids[PRIMARY_USER_SID_INDEX],
    207                                         password, NULL, NULL,
    208                                         oldLmHash, oldNtHash, /* this is a user password change */
    209                                         &reject_reason,
    210                                         &dominfo);
    211         return kpasswd_make_pwchange_reply(kdc, mem_ctx,
    212                                            status,
     176                return kpasswdd_make_error_reply(kdc,
     177                                                 mem_ctx,
     178                                                 KRB5_KPASSWD_ACCESSDENIED,
     179                                                 error_string,
     180                                                 reply);
     181        }
     182
     183        return kpasswd_make_pwchange_reply(kdc,
     184                                           mem_ctx,
     185                                           result,
    213186                                           reject_reason,
    214187                                           dominfo,
    215188                                           reply);
    216 
    217189}
    218190
     
    228200
    229201        if (!NT_STATUS_IS_OK(gensec_session_info(gensec_security,
     202                                                 mem_ctx,
    230203                                                 &session_info))) {
    231204                return kpasswdd_make_error_reply(kdc, mem_ctx,
     
    239212        {
    240213                DATA_BLOB password;
    241                 if (!convert_string_talloc_convenience(mem_ctx, lpcfg_iconv_convenience(kdc->task->lp_ctx),
     214                if (!convert_string_talloc_handle(mem_ctx, lpcfg_iconv_handle(kdc->task->lp_ctx),
    242215                                               CH_UTF8, CH_UTF16,
    243216                                               (const char *)input->data,
    244217                                               input->length,
    245                                                (void **)&password.data, &pw_len, false)) {
     218                                               (void **)&password.data, &pw_len)) {
    246219                        return false;
    247220                }
     
    279252                }
    280253
    281                 if (!convert_string_talloc_convenience(mem_ctx, lpcfg_iconv_convenience(kdc->task->lp_ctx),
     254                if (!convert_string_talloc_handle(mem_ctx, lpcfg_iconv_handle(kdc->task->lp_ctx),
    282255                                               CH_UTF8, CH_UTF16,
    283256                                               (const char *)chpw.newpasswd.data,
    284257                                               chpw.newpasswd.length,
    285                                                (void **)&password.data, &pw_len, false)) {
     258                                               (void **)&password.data, &pw_len)) {
    286259                        free_ChangePasswdDataMS(&chpw);
    287260                        return false;
     
    544517         * complex code */
    545518
    546         nt_status = gensec_set_local_address(gensec_security, peer_addr);
     519        nt_status = gensec_set_remote_address(gensec_security, peer_addr);
    547520        if (!NT_STATUS_IS_OK(nt_status)) {
    548521                talloc_free(tmp_ctx);
     
    567540
    568541        /* Accept the AP-REQ and generate teh AP-REP we need for the reply */
    569         nt_status = gensec_update(gensec_security, tmp_ctx, ap_req, &ap_rep);
     542        nt_status = gensec_update_ev(gensec_security, tmp_ctx, kdc->task->event_ctx, ap_req, &ap_rep);
    570543        if (!NT_STATUS_IS_OK(nt_status) && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    571544
  • vendor/current/source4/kdc/mit_samba.c

    r740 r988  
    196196        DATA_BLOB *pac_blob;
    197197        NTSTATUS nt_status;
     198        struct samba_kdc_entry *skdc_entry;
     199
     200        skdc_entry = talloc_get_type_abort(client->ctx,
     201                                           struct samba_kdc_entry);
    198202
    199203        tmp_ctx = talloc_named(ctx, 0, "mit_samba_get_pac_data context");
     
    202206        }
    203207
    204         nt_status = samba_kdc_get_pac_blob(tmp_ctx, client, &pac_blob);
     208        nt_status = samba_kdc_get_pac_blob(tmp_ctx, skdc_entry, &pac_blob);
    205209        if (!NT_STATUS_IS_OK(nt_status)) {
    206210                talloc_free(tmp_ctx);
     
    231235        krb5_pac pac = NULL;
    232236        int ret;
     237        struct samba_kdc_entry *skdc_entry = NULL;
     238
     239        if (client) {
     240                skdc_entry = talloc_get_type_abort(client->ctx,
     241                                                   struct samba_kdc_entry);
     242        }
    233243
    234244        /* The user account may be set not to want the PAC */
    235         if (client && !samba_princ_needs_pac(client)) {
     245        if (client && !samba_princ_needs_pac(skdc_entry)) {
    236246                return EINVAL;
    237247        }
     
    255265        }
    256266
     267        /* TODO: An implementation-specific decision will need to be
     268         * made as to when to check the KDC pac signature, and how to
     269         * untrust untrusted RODCs */
    257270        nt_status = samba_kdc_update_pac_blob(tmp_ctx, ctx->context,
    258                                               &pac, logon_blob);
     271                                              pac, logon_blob, NULL, NULL);
    259272        if (!NT_STATUS_IS_OK(nt_status)) {
    260273                DEBUG(0, ("Building PAC failed: %s\n",
     
    278291        talloc_free(tmp_ctx);
    279292        return ret;
     293}
     294
     295/* provide header, function is exported but there are no public headers */
     296
     297krb5_error_code encode_krb5_padata_sequence(krb5_pa_data *const *rep, krb5_data **code);
     298
     299/* this function allocates 'data' using malloc.
     300 * The caller is responsible for freeing it */
     301static void samba_kdc_build_edata_reply(NTSTATUS nt_status, DATA_BLOB *e_data)
     302{
     303        krb5_error_code ret = 0;
     304        krb5_pa_data pa, *ppa = NULL;
     305        krb5_data *d = NULL;
     306
     307        if (!e_data)
     308                return;
     309
     310        e_data->data   = NULL;
     311        e_data->length = 0;
     312
     313        pa.magic                = KV5M_PA_DATA;
     314        pa.pa_type              = KRB5_PADATA_PW_SALT;
     315        pa.length               = 12;
     316        pa.contents             = malloc(pa.length);
     317        if (!pa.contents) {
     318                return;
     319        }
     320
     321        SIVAL(pa.contents, 0, NT_STATUS_V(nt_status));
     322        SIVAL(pa.contents, 4, 0);
     323        SIVAL(pa.contents, 8, 1);
     324
     325        ppa = &pa;
     326
     327        ret = encode_krb5_padata_sequence(&ppa, &d);
     328        free(pa.contents);
     329        if (ret) {
     330                return;
     331        }
     332
     333        e_data->data   = (uint8_t *)d->data;
     334        e_data->length = d->length;
     335
     336        /* free d, not d->data - gd */
     337        free(d);
     338
     339        return;
    280340}
    281341
     
    317377                                     bool is_nt_enterprise_name)
    318378{
     379#if 1
     380        /*
     381         * This is disabled because mit_samba_update_pac_data() does not handle
     382         * S4U_DELEGATION_INFO
     383         */
     384
     385        return KRB5KDC_ERR_BADOPTION;
     386#else
    319387        krb5_principal target_principal;
    320388        int flags = 0;
     
    331399        }
    332400
    333         ret = samba_kdc_check_identical_client_and_server(ctx->context,
    334                                                           ctx->db_ctx,
    335                                                           entry,
    336                                                           target_principal);
     401        ret = samba_kdc_check_s4u2proxy(ctx->context,
     402                                        ctx->db_ctx,
     403                                        skdc_entry,
     404                                        target_principal);
    337405
    338406        krb5_free_principal(ctx->context, target_principal);
    339407
    340408        return ret;
     409#endif
    341410}
    342411
  • vendor/current/source4/kdc/pac-glue.c

    r740 r988  
    2727#include "auth/auth.h"
    2828#include "auth/auth_sam_reply.h"
    29 #include "kdc/kdc-glue.h"
     29#include "system/kerberos.h"
     30#include "auth/kerberos/kerberos.h"
     31#include "kdc/samba_kdc.h"
     32#include "kdc/pac-glue.h"
    3033#include "param/param.h"
    3134#include "librpc/gen_ndr/ndr_krb5pac.h"
     35#include "libcli/security/security.h"
     36#include "dsdb/samdb/samdb.h"
     37#include "auth/kerberos/pac_utils.h"
    3238
    3339static
     
    5157
    5258        pac_info.logon_info.info = talloc_zero(mem_ctx, struct PAC_LOGON_INFO);
    53         if (!mem_ctx) {
     59        if (!pac_info.logon_info.info) {
    5460                return NT_STATUS_NO_MEMORY;
    5561        }
     
    7278krb5_error_code samba_make_krb5_pac(krb5_context context,
    7379                                    DATA_BLOB *pac_blob,
     80                                    DATA_BLOB *deleg_blob,
    7481                                    krb5_pac *pac)
    7582{
    7683        krb5_data pac_data;
     84        krb5_data deleg_data;
    7785        krb5_error_code ret;
    7886
     
    8290        }
    8391
    84         ret = krb5_data_copy(&pac_data, pac_blob->data, pac_blob->length);
     92        ret = krb5_copy_data_contents(&pac_data,
     93                                      pac_blob->data,
     94                                      pac_blob->length);
    8595        if (ret != 0) {
    8696                return ret;
    8797        }
    8898
     99        ZERO_STRUCT(deleg_data);
     100        if (deleg_blob) {
     101                ret = krb5_copy_data_contents(&deleg_data,
     102                                              deleg_blob->data,
     103                                              deleg_blob->length);
     104                if (ret != 0) {
     105                        kerberos_free_data_contents(context, &pac_data);
     106                        return ret;
     107                }
     108        }
     109
    89110        ret = krb5_pac_init(context, pac);
    90111        if (ret != 0) {
    91                 krb5_data_free(&pac_data);
     112                kerberos_free_data_contents(context, &pac_data);
     113                kerberos_free_data_contents(context, &deleg_data);
    92114                return ret;
    93115        }
    94116
    95117        ret = krb5_pac_add_buffer(context, *pac, PAC_TYPE_LOGON_INFO, &pac_data);
    96         krb5_data_free(&pac_data);
     118        kerberos_free_data_contents(context, &pac_data);
    97119        if (ret != 0) {
     120                kerberos_free_data_contents(context, &deleg_data);
    98121                return ret;
    99122        }
    100123
     124        if (deleg_blob) {
     125                ret = krb5_pac_add_buffer(context, *pac,
     126                                          PAC_TYPE_CONSTRAINED_DELEGATION,
     127                                          &deleg_data);
     128                kerberos_free_data_contents(context, &deleg_data);
     129                if (ret != 0) {
     130                        return ret;
     131                }
     132        }
     133
    101134        return ret;
    102135}
    103136
    104 bool samba_princ_needs_pac(struct hdb_entry_ex *princ)
    105 {
    106 
    107         struct samba_kdc_entry *p = talloc_get_type(princ->ctx, struct samba_kdc_entry);
     137bool samba_princ_needs_pac(struct samba_kdc_entry *skdc_entry)
     138{
     139
    108140        uint32_t userAccountControl;
    109141
    110 
    111142        /* The service account may be set not to want the PAC */
    112         userAccountControl = ldb_msg_find_attr_as_uint(p->msg, "userAccountControl", 0);
     143        userAccountControl = ldb_msg_find_attr_as_uint(skdc_entry->msg, "userAccountControl", 0);
    113144        if (userAccountControl & UF_NO_AUTH_DATA_REQUIRED) {
    114145                return false;
     
    118149}
    119150
    120 /* Was the krbtgt an RODC (and we are not) */
    121 bool samba_krbtgt_was_untrusted_rodc(struct hdb_entry_ex *princ)
    122 {
    123 
    124         struct samba_kdc_entry *p = talloc_get_type(princ->ctx, struct samba_kdc_entry);
    125         int rodc_krbtgt_number;
    126 
    127         /* Determine if this was printed by an RODC */
     151/* Was the krbtgt in this DB (ie, should we check the incoming signature) and was it an RODC */
     152int samba_krbtgt_is_in_db(struct samba_kdc_entry *p,
     153                          bool *is_in_db,
     154                          bool *is_untrusted)
     155{
     156        NTSTATUS status;
     157        int rodc_krbtgt_number, trust_direction;
     158        uint32_t rid;
     159
     160        TALLOC_CTX *mem_ctx = talloc_new(NULL);
     161        if (!mem_ctx) {
     162                return ENOMEM;
     163        }
     164       
     165        trust_direction = ldb_msg_find_attr_as_int(p->msg, "trustDirection", 0);
     166
     167        if (trust_direction != 0) {
     168                /* Domain trust - we cannot check the sig, but we trust it for a correct PAC
     169                   
     170                   This is exactly where we should flag for SID
     171                   validation when we do inter-foreest trusts
     172                 */
     173                talloc_free(mem_ctx);
     174                *is_untrusted = false;
     175                *is_in_db = false;
     176                return 0;
     177        }
     178
     179        /* The lack of password controls etc applies to krbtgt by
     180         * virtue of being that particular RID */
     181        status = dom_sid_split_rid(NULL, samdb_result_dom_sid(mem_ctx, p->msg, "objectSid"), NULL, &rid);
     182
     183        if (!NT_STATUS_IS_OK(status)) {
     184                talloc_free(mem_ctx);
     185                return EINVAL;
     186        }
     187
    128188        rodc_krbtgt_number = ldb_msg_find_attr_as_int(p->msg, "msDS-SecondaryKrbTgtNumber", -1);
    129         if (rodc_krbtgt_number == -1) {
    130                 return false;
    131         } else if (rodc_krbtgt_number != p->kdc_db_ctx->my_krbtgt_number) {
    132                 return true;
    133         }
    134 
    135         return false;
     189
     190        if (p->kdc_db_ctx->my_krbtgt_number == 0) {
     191                if (rid == DOMAIN_RID_KRBTGT) {
     192                        *is_untrusted = false;
     193                        *is_in_db = true;
     194                        talloc_free(mem_ctx);
     195                        return 0;
     196                } else if (rodc_krbtgt_number != -1) {
     197                        *is_in_db = true;
     198                        *is_untrusted = true;
     199                        talloc_free(mem_ctx);
     200                        return 0;
     201                }
     202        } else if ((rid != DOMAIN_RID_KRBTGT) && (rodc_krbtgt_number == p->kdc_db_ctx->my_krbtgt_number)) {
     203                talloc_free(mem_ctx);
     204                *is_untrusted = false;
     205                *is_in_db = true;
     206                return 0;
     207        } else if (rid == DOMAIN_RID_KRBTGT) {
     208                /* krbtgt viewed from an RODC */
     209                talloc_free(mem_ctx);
     210                *is_untrusted = false;
     211                *is_in_db = false;
     212                return 0;
     213        }
     214
     215        /* Another RODC */
     216        talloc_free(mem_ctx);
     217        *is_untrusted = true;
     218        *is_in_db = false;
     219        return 0;
    136220}
    137221
    138222NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx,
    139                                 struct hdb_entry_ex *client,
     223                                struct samba_kdc_entry *p,
    140224                                DATA_BLOB **_pac_blob)
    141225{
    142         struct samba_kdc_entry *p = talloc_get_type(client->ctx, struct samba_kdc_entry);
    143226        struct auth_user_info_dc *user_info_dc;
    144227        DATA_BLOB *pac_blob;
     
    146229
    147230        /* The user account may be set not to want the PAC */
    148         if ( ! samba_princ_needs_pac(client)) {
     231        if ( ! samba_princ_needs_pac(p)) {
    149232                *_pac_blob = NULL;
    150233                return NT_STATUS_OK;
     
    183266NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx,
    184267                                   krb5_context context,
    185                                    krb5_pac *pac, DATA_BLOB *pac_blob)
     268                                   const krb5_pac pac, DATA_BLOB *pac_blob,
     269                                   struct PAC_SIGNATURE_DATA *pac_srv_sig,
     270                                   struct PAC_SIGNATURE_DATA *pac_kdc_sig)
    186271{
    187272        struct auth_user_info_dc *user_info_dc;
     
    189274        NTSTATUS nt_status;
    190275
    191         ret = kerberos_pac_to_user_info_dc(mem_ctx, *pac,
    192                                            context, &user_info_dc, NULL, NULL);
     276        ret = kerberos_pac_to_user_info_dc(mem_ctx, pac,
     277                                           context, &user_info_dc, pac_srv_sig, pac_kdc_sig);
    193278        if (ret) {
    194279                return NT_STATUS_UNSUCCESSFUL;
     
    201286}
    202287
    203 /* this function allocates 'data' using malloc.
    204  * The caller is responsible for freeing it */
    205 void samba_kdc_build_edata_reply(NTSTATUS nt_status, DATA_BLOB *e_data)
    206 {
    207         PA_DATA pa;
    208         unsigned char *buf;
    209         size_t len;
    210         krb5_error_code ret = 0;
    211 
    212         if (!e_data)
    213                 return;
    214 
    215         pa.padata_type          = KRB5_PADATA_PW_SALT;
    216         pa.padata_value.length  = 12;
    217         pa.padata_value.data    = malloc(pa.padata_value.length);
    218         if (!pa.padata_value.data) {
    219                 e_data->length = 0;
    220                 e_data->data = NULL;
    221                 return;
    222         }
    223 
    224         SIVAL(pa.padata_value.data, 0, NT_STATUS_V(nt_status));
    225         SIVAL(pa.padata_value.data, 4, 0);
    226         SIVAL(pa.padata_value.data, 8, 1);
    227 
    228         ASN1_MALLOC_ENCODE(PA_DATA, buf, len, &pa, &len, ret);
    229         free(pa.padata_value.data);
    230 
    231         e_data->data   = buf;
    232         e_data->length = len;
    233 
    234         return;
     288NTSTATUS samba_kdc_update_delegation_info_blob(TALLOC_CTX *mem_ctx,
     289                                krb5_context context,
     290                                const krb5_pac pac,
     291                                const krb5_principal server_principal,
     292                                const krb5_principal proxy_principal,
     293                                DATA_BLOB *new_blob)
     294{
     295        krb5_data old_data;
     296        DATA_BLOB old_blob;
     297        krb5_error_code ret;
     298        NTSTATUS nt_status;
     299        enum ndr_err_code ndr_err;
     300        union PAC_INFO info;
     301        struct PAC_CONSTRAINED_DELEGATION _d;
     302        struct PAC_CONSTRAINED_DELEGATION *d = NULL;
     303        char *server = NULL;
     304        char *proxy = NULL;
     305        uint32_t i;
     306        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     307
     308        if (tmp_ctx == NULL) {
     309                return NT_STATUS_NO_MEMORY;
     310        }
     311
     312        ret = krb5_pac_get_buffer(context, pac, PAC_TYPE_CONSTRAINED_DELEGATION, &old_data);
     313        if (ret == ENOENT) {
     314                ZERO_STRUCT(old_data);
     315        } else if (ret) {
     316                talloc_free(tmp_ctx);
     317                return NT_STATUS_UNSUCCESSFUL;
     318        }
     319
     320        old_blob.length = old_data.length;
     321        old_blob.data = (uint8_t *)old_data.data;
     322
     323        ZERO_STRUCT(info);
     324        if (old_blob.length > 0) {
     325                ndr_err = ndr_pull_union_blob(&old_blob, mem_ctx,
     326                                &info, PAC_TYPE_CONSTRAINED_DELEGATION,
     327                                (ndr_pull_flags_fn_t)ndr_pull_PAC_INFO);
     328                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     329                        kerberos_free_data_contents(context, &old_data);
     330                        nt_status = ndr_map_error2ntstatus(ndr_err);
     331                        DEBUG(0,("can't parse the PAC LOGON_INFO: %s\n", nt_errstr(nt_status)));
     332                        talloc_free(tmp_ctx);
     333                        return nt_status;
     334                }
     335        } else {
     336                ZERO_STRUCT(_d);
     337                info.constrained_delegation.info = &_d;
     338        }
     339        kerberos_free_data_contents(context, &old_data);
     340
     341        ret = krb5_unparse_name(context, server_principal, &server);
     342        if (ret) {
     343                talloc_free(tmp_ctx);
     344                return NT_STATUS_INTERNAL_ERROR;
     345        }
     346
     347        ret = krb5_unparse_name_flags(context, proxy_principal,
     348                                      KRB5_PRINCIPAL_UNPARSE_NO_REALM, &proxy);
     349        if (ret) {
     350                SAFE_FREE(server);
     351                talloc_free(tmp_ctx);
     352                return NT_STATUS_INTERNAL_ERROR;
     353        }
     354
     355        d = info.constrained_delegation.info;
     356        i = d->num_transited_services;
     357        d->proxy_target.string = server;
     358        d->transited_services = talloc_realloc(mem_ctx, d->transited_services,
     359                                               struct lsa_String, i + 1);
     360        d->transited_services[i].string = proxy;
     361        d->num_transited_services = i + 1;
     362
     363        ndr_err = ndr_push_union_blob(new_blob, mem_ctx,
     364                                &info, PAC_TYPE_CONSTRAINED_DELEGATION,
     365                                (ndr_push_flags_fn_t)ndr_push_PAC_INFO);
     366        SAFE_FREE(server);
     367        SAFE_FREE(proxy);
     368        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     369                kerberos_free_data_contents(context, &old_data);
     370                nt_status = ndr_map_error2ntstatus(ndr_err);
     371                DEBUG(0,("can't parse the PAC LOGON_INFO: %s\n", nt_errstr(nt_status)));
     372                talloc_free(tmp_ctx);
     373                return nt_status;
     374        }
     375
     376        talloc_free(tmp_ctx);
     377        return NT_STATUS_OK;
    235378}
    236379
     
    241384
    242385        if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_MUST_CHANGE))
    243                 ret = KRB5KDC_ERR_KEY_EXPIRED;
     386                ret = KRB5KDC_ERR_KEY_EXP;
    244387        else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_EXPIRED))
    245                 ret = KRB5KDC_ERR_KEY_EXPIRED;
     388                ret = KRB5KDC_ERR_KEY_EXP;
    246389        else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_EXPIRED))
    247390                ret = KRB5KDC_ERR_CLIENT_REVOKED;
     
    287430        return nt_status;
    288431}
    289 
  • vendor/current/source4/kdc/pac-glue.h

    r740 r988  
    2424krb5_error_code samba_make_krb5_pac(krb5_context context,
    2525                                    DATA_BLOB *pac_blob,
     26                                    DATA_BLOB *deleg_blob,
    2627                                    krb5_pac *pac);
    2728
    28 bool samba_princ_needs_pac(struct hdb_entry_ex *princ);
     29bool samba_princ_needs_pac(struct samba_kdc_entry *skdc_entry);
    2930
    30 bool samba_krbtgt_was_untrusted_rodc(struct hdb_entry_ex *princ);
     31int samba_krbtgt_is_in_db(struct samba_kdc_entry *skdc_entry,
     32                          bool *is_in_db,
     33                          bool *is_untrusted);
    3134
    3235NTSTATUS samba_kdc_get_pac_blob(TALLOC_CTX *mem_ctx,
    33                                 struct hdb_entry_ex *client,
     36                                struct samba_kdc_entry *skdc_entry,
    3437                                DATA_BLOB **_pac_blob);
    3538
    3639NTSTATUS samba_kdc_update_pac_blob(TALLOC_CTX *mem_ctx,
    3740                                   krb5_context context,
    38                                    krb5_pac *pac, DATA_BLOB *pac_blob);
     41                                   const krb5_pac pac, DATA_BLOB *pac_blob,
     42                                   struct PAC_SIGNATURE_DATA *pac_srv_sig,
     43                                   struct PAC_SIGNATURE_DATA *pac_kdc_sig);
    3944
    40 void samba_kdc_build_edata_reply(NTSTATUS nt_status, DATA_BLOB *e_data);
     45NTSTATUS samba_kdc_update_delegation_info_blob(TALLOC_CTX *mem_ctx,
     46                                krb5_context context,
     47                                const krb5_pac pac,
     48                                const krb5_principal server_principal,
     49                                const krb5_principal proxy_principal,
     50                                DATA_BLOB *pac_blob);
    4151
    4252krb5_error_code samba_kdc_map_policy_err(NTSTATUS nt_status);
  • vendor/current/source4/kdc/proxy.c

    r740 r988  
    557557        state->out = data_blob_talloc(state, raw.data + 4, raw.length - 4);
    558558        if (state->out.length != raw.length - 4) {
    559                 tevent_req_nomem(NULL, req);
     559                tevent_req_oom(req);
    560560                return;
    561561        }
  • vendor/current/source4/kdc/samba_kdc.h

    r740 r988  
    2222*/
    2323
     24#ifndef _SAMBA_KDC_H_
     25#define _SAMBA_KDC_H_
     26
     27struct samba_kdc_policy {
     28        time_t svc_tkt_lifetime;
     29        time_t usr_tkt_lifetime;
     30        time_t renewal_lifetime;
     31};
     32
    2433struct samba_kdc_base_context {
    2534        struct tevent_context *ev_ctx;
     
    3746        unsigned int my_krbtgt_number;
    3847        struct ldb_dn *krbtgt_dn;
    39         struct lsa_DomainInfoKerberos policy;
     48        struct samba_kdc_policy policy;
    4049};
    4150
     
    4453        struct ldb_message *msg;
    4554        struct ldb_dn *realm_dn;
    46         hdb_entry_ex *entry_ex;
     55        void *entry_ex;
    4756};
     57
     58extern struct hdb_method hdb_samba4_interface;
     59
     60#endif /* _SAMBA_KDC_H_ */
  • vendor/current/source4/kdc/wdc-samba4.c

    r740 r988  
    3535        krb5_error_code ret;
    3636        NTSTATUS nt_status;
     37        struct samba_kdc_entry *skdc_entry =
     38                talloc_get_type_abort(client->ctx,
     39                struct samba_kdc_entry);
    3740
    3841        mem_ctx = talloc_named(client->ctx, 0, "samba_get_pac context");
     
    4144        }
    4245
    43         nt_status = samba_kdc_get_pac_blob(mem_ctx, client, &pac_blob);
     46        nt_status = samba_kdc_get_pac_blob(mem_ctx, skdc_entry, &pac_blob);
    4447        if (!NT_STATUS_IS_OK(nt_status)) {
    4548                talloc_free(mem_ctx);
     
    4750        }
    4851
    49         ret = samba_make_krb5_pac(context, pac_blob, pac);
     52        ret = samba_make_krb5_pac(context, pac_blob, NULL, pac);
    5053
    5154        talloc_free(mem_ctx);
     
    5760static krb5_error_code samba_wdc_reget_pac(void *priv, krb5_context context,
    5861                                           const krb5_principal client_principal,
     62                                           const krb5_principal delegated_proxy_principal,
    5963                                           struct hdb_entry_ex *client,
    6064                                           struct hdb_entry_ex *server,
     
    6266                                           krb5_pac *pac)
    6367{
    64         struct samba_kdc_entry *p = talloc_get_type(server->ctx, struct samba_kdc_entry);
     68        struct samba_kdc_entry *p =
     69                talloc_get_type_abort(server->ctx,
     70                struct samba_kdc_entry);
     71        struct samba_kdc_entry *krbtgt_skdc_entry =
     72                talloc_get_type_abort(krbtgt->ctx,
     73                struct samba_kdc_entry);
    6574        TALLOC_CTX *mem_ctx = talloc_named(p, 0, "samba_kdc_reget_pac context");
    6675        DATA_BLOB *pac_blob;
     76        DATA_BLOB *deleg_blob = NULL;
    6777        krb5_error_code ret;
    6878        NTSTATUS nt_status;
     79        struct PAC_SIGNATURE_DATA *pac_srv_sig;
     80        struct PAC_SIGNATURE_DATA *pac_kdc_sig;
     81        bool is_in_db, is_untrusted;
    6982
    7083        if (!mem_ctx) {
     
    7386
    7487        /* The user account may be set not to want the PAC */
    75         if (!samba_princ_needs_pac(server)) {
     88        if (!samba_princ_needs_pac(p)) {
    7689                talloc_free(mem_ctx);
    7790                return EINVAL;
     
    8194         * RODC, then we need to regenerate the PAC - we can't trust
    8295         * it */
    83         if (samba_krbtgt_was_untrusted_rodc(krbtgt)) {
     96        ret = samba_krbtgt_is_in_db(krbtgt_skdc_entry, &is_in_db, &is_untrusted);
     97        if (ret != 0) {
     98                talloc_free(mem_ctx);
     99                return ret;
     100        }
     101
     102        if (is_untrusted) {
     103                struct samba_kdc_entry *client_skdc_entry = NULL;
     104
    84105                if (client == NULL) {
    85106                        return KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
    86107                }
    87                 nt_status = samba_kdc_get_pac_blob(mem_ctx, client, &pac_blob);
     108
     109                client_skdc_entry = talloc_get_type_abort(client->ctx,
     110                                                          struct samba_kdc_entry);
     111
     112                nt_status = samba_kdc_get_pac_blob(mem_ctx, client_skdc_entry, &pac_blob);
    88113                if (!NT_STATUS_IS_OK(nt_status)) {
    89114                        talloc_free(mem_ctx);
     
    97122                }
    98123
     124                pac_srv_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA);
     125                if (!pac_srv_sig) {
     126                        talloc_free(mem_ctx);
     127                        return ENOMEM;
     128                }
     129
     130                pac_kdc_sig = talloc_zero(mem_ctx, struct PAC_SIGNATURE_DATA);
     131                if (!pac_kdc_sig) {
     132                        talloc_free(mem_ctx);
     133                        return ENOMEM;
     134                }
     135
    99136                nt_status = samba_kdc_update_pac_blob(mem_ctx, context,
    100                                                       pac, pac_blob);
     137                                                      *pac, pac_blob,
     138                                                      pac_srv_sig, pac_kdc_sig);
    101139                if (!NT_STATUS_IS_OK(nt_status)) {
    102140                        DEBUG(0, ("Building PAC failed: %s\n",
     
    105143                        return EINVAL;
    106144                }
    107         }
     145               
     146                if (is_in_db) {
     147                        /* Now check the KDC signature, fetching the correct key based on the enc type */
     148                        ret = kdc_check_pac(context, pac_srv_sig->signature, pac_kdc_sig, krbtgt);
     149                        if (ret != 0) {
     150                                DEBUG(1, ("PAC KDC signature failed to verify\n"));
     151                                talloc_free(mem_ctx);
     152                                return ret;
     153                        }
     154                }
     155        }
     156
     157        if (delegated_proxy_principal) {
     158                deleg_blob = talloc_zero(mem_ctx, DATA_BLOB);
     159                if (!deleg_blob) {
     160                        talloc_free(mem_ctx);
     161                        return ENOMEM;
     162                }
     163
     164                nt_status = samba_kdc_update_delegation_info_blob(mem_ctx,
     165                                        context, *pac,
     166                                        server->entry.principal,
     167                                        delegated_proxy_principal,
     168                                        deleg_blob);
     169                if (!NT_STATUS_IS_OK(nt_status)) {
     170                        DEBUG(0, ("Building PAC failed: %s\n",
     171                                  nt_errstr(nt_status)));
     172                        talloc_free(mem_ctx);
     173                        return EINVAL;
     174                }
     175        }
     176
    108177        /* We now completely regenerate this pac */
    109178        krb5_pac_free(context, *pac);
    110179
    111         ret = samba_make_krb5_pac(context, pac_blob, pac);
     180        ret = samba_make_krb5_pac(context, pac_blob, deleg_blob, pac);
    112181
    113182        talloc_free(mem_ctx);
     
    133202        }
    134203
    135         if (nb_name == NULL) {
     204        if ((nb_name == NULL) || (nb_name[0] == '\0')) {
    136205                return NULL;
    137206        }
    138207
    139208        /* Strip space padding */
    140         i = strlen(nb_name) - 1;
    141         while (i > 0 && nb_name[i] == ' ') {
    142                 nb_name[i] = '\0';
     209        for (len = strlen(nb_name) - 1;
     210             (len > 0) && (nb_name[len] == ' ');
     211             --len) {
     212                nb_name[len] = '\0';
    143213        }
    144214
     
    155225        return kdata;
    156226}
     227
     228/* this function allocates 'data' using malloc.
     229 * The caller is responsible for freeing it */
     230static void samba_kdc_build_edata_reply(NTSTATUS nt_status, DATA_BLOB *e_data)
     231{
     232        krb5_error_code ret = 0;
     233        PA_DATA pa;
     234        unsigned char *buf;
     235        size_t len;
     236
     237        if (!e_data)
     238                return;
     239
     240        e_data->data   = NULL;
     241        e_data->length = 0;
     242
     243        pa.padata_type          = KRB5_PADATA_PW_SALT;
     244        pa.padata_value.length  = 12;
     245        pa.padata_value.data    = malloc(pa.padata_value.length);
     246        if (!pa.padata_value.data) {
     247                e_data->length = 0;
     248                e_data->data = NULL;
     249                return;
     250        }
     251
     252        SIVAL(pa.padata_value.data, 0, NT_STATUS_V(nt_status));
     253        SIVAL(pa.padata_value.data, 4, 0);
     254        SIVAL(pa.padata_value.data, 8, 1);
     255
     256        ASN1_MALLOC_ENCODE(PA_DATA, buf, len, &pa, &len, ret);
     257        free(pa.padata_value.data);
     258        if (ret) {
     259                return;
     260        }
     261
     262        e_data->data   = buf;
     263        e_data->length = len;
     264
     265        return;
     266}
     267
    157268
    158269static krb5_error_code samba_wdc_check_client_access(void *priv,
     
    213324
    214325struct krb5plugin_windc_ftable windc_plugin_table = {
    215         .minor_version = KRB5_WINDC_PLUGING_MINOR,
     326        .minor_version = KRB5_WINDC_PLUGIN_MINOR,
    216327        .init = samba_wdc_plugin_init,
    217328        .fini = samba_wdc_plugin_fini,
  • vendor/current/source4/kdc/wscript_build

    r740 r988  
    11#!/usr/bin/env python
    22
     3# We do this because we do not want to depend on the KDC, only find and use it's header files.  We do not want
     4if not bld.CONFIG_SET("USING_SYSTEM_KDC"):
     5    kdc_include = "../heimdal/kdc"
     6else:
     7    kdc_include = getattr(bld.env, "CPPPATH_KDC")
     8
    39bld.SAMBA_MODULE('service_kdc',
    4         source='kdc.c kpasswdd.c proxy.c',
    5         subsystem='service',
    6         init_function='server_service_kdc_init',
    7         deps='kdc HDB_SAMBA4 WDC_SAMBA4 samba-hostconfig LIBTSOCKET LIBSAMBA_TSOCKET com_err samba_server_gensec',
    8         internal_module=False,
     10                 source='kdc.c kpasswdd.c proxy.c',
     11                 subsystem='service',
     12                 init_function='server_service_kdc_init',
     13                 deps='''
     14                      kdc
     15                      HDB_SAMBA4
     16                      WDC_SAMBA4
     17                      samba-hostconfig
     18                      LIBTSOCKET
     19                      LIBSAMBA_TSOCKET
     20                      com_err
     21                      samba_server_gensec
     22                      PAC_GLUE
     23                      KDC-GLUE
     24                      KPASSWD_GLUE
     25                 ''',
     26                 internal_module=False)
     27
     28bld.SAMBA_LIBRARY('HDB_SAMBA4',
     29                  source='hdb-samba4.c hdb-samba4-plugin.c',
     30                  deps='ldb auth4_sam auth_sam_reply samba-credentials hdb db-glue samba-hostconfig com_err sdb_hdb',
     31                  includes=kdc_include,
     32                  private_library=True,
     33                  enabled=bld.CONFIG_SET('SAMBA4_USES_HEIMDAL')
     34                  )
     35
     36# A plugin for Heimdal's kadmin for users who need to operate that tool
     37bld.SAMBA_LIBRARY('HDB_SAMBA4_PLUGIN',
     38                  source='hdb-samba4-plugin.c',
     39                  deps='hdb HDB_SAMBA4 samba-util samba-hostconfig ',
     40                  includes=kdc_include,
     41                  link_name='modules/hdb/hdb_samba4.so',
     42                  realname='hdb_samba4.so',
     43                  install_path='${MODULESDIR}/hdb',
     44                  enabled = (bld.CONFIG_SET("USING_SYSTEM_KRB5") and bld.CONFIG_SET("USING_SYSTEM_HDB"))
     45                  )
     46
     47bld.SAMBA_SUBSYSTEM('KDC-GLUE',
     48        source='kdc-glue.c',
     49        includes=kdc_include,
     50        deps='hdb PAC_GLUE',
     51        enabled=bld.CONFIG_SET('SAMBA4_USES_HEIMDAL')
    952        )
    10 
    11 
    12 bld.SAMBA_SUBSYSTEM('HDB_SAMBA4',
    13         source='hdb-samba4.c',
    14         deps='ldb auth4_sam auth_sam_reply credentials hdb db-glue samba-hostconfig com_err',
    15         includes='../heimdal/kdc',
    16         )
    17 
    1853
    1954bld.SAMBA_SUBSYSTEM('WDC_SAMBA4',
    2055        source='wdc-samba4.c',
    21         includes='../heimdal/kdc',
    22         deps='ldb auth4_sam auth_sam_reply credentials hdb PAC_GLUE samba-hostconfig com_err'
     56        includes=kdc_include,
     57        deps='ldb auth4_sam auth_sam_reply samba-credentials hdb PAC_GLUE samba-hostconfig com_err KDC-GLUE',
     58        enabled=bld.CONFIG_SET('SAMBA4_USES_HEIMDAL')
    2359        )
    2460
     61bld.SAMBA_SUBSYSTEM('sdb',
     62        source='sdb.c',
     63        includes=kdc_include,
     64        deps='talloc krb5',
     65        )
     66
     67bld.SAMBA_SUBSYSTEM('sdb_hdb',
     68        source='sdb_to_hdb.c',
     69        includes=kdc_include,
     70        deps='talloc sdb hdb',
     71        autoproto='sdb_hdb.h',
     72        enabled=bld.CONFIG_SET('SAMBA4_USES_HEIMDAL')
     73        )
    2574
    2675bld.SAMBA_SUBSYSTEM('PAC_GLUE',
    2776        source='pac-glue.c',
    28         includes='../heimdal/kdc',
    29         deps='ldb auth4_sam auth_sam_reply credentials hdb samba-hostconfig com_err'
     77        includes=kdc_include,
     78        deps='ldb auth4_sam auth_sam_reply samba-credentials samba-hostconfig com_err'
    3079        )
    3180
     
    3988bld.SAMBA_LIBRARY('db-glue',
    4089        source='db-glue.c',
    41         deps='ldb auth4_sam auth_sam_reply credentials hdb samba-hostconfig com_err kdc-policy',
    42         private_library=True
     90        deps='ldb auth4_sam auth_sam_reply samba-credentials sdb samba-hostconfig com_err',
     91        private_library=True,
     92        includes=kdc_include,
    4393        )
    4494
    45 bld.SAMBA_LIBRARY('kdc-policy',
    46         source='policy.c',
    47         deps='samba-hostconfig authkrb5',
    48         private_library=True,
    49         autoproto = 'kdc-policy-proto.h'
    50         )
    51 
     95bld.SAMBA_SUBSYSTEM('KPASSWD_GLUE',
     96        source='kpasswd_glue.c',
     97        includes=kdc_include,
     98        deps='ldb com_err')
    5299
    53100bld.SAMBA_SUBSYSTEM('MIT_SAMBA',
    54         source='mit_samba.c',
    55         deps='ldb auth4_sam auth_sam_reply credentials hdb db-glue PAC_GLUE samba-hostconfig com_err'
    56         )
    57 
    58 
    59 bld.SAMBA_LIBRARY('mit-samba',
    60         source='',
    61         deps='MIT_SAMBA',
    62         external_library=True,
    63         realname='mit_samba.so'
    64         )
    65 
     101                    source='mit_samba.c',
     102                    deps='''
     103                         ldb
     104                         auth4_sam
     105                         auth_sam_reply
     106                         samba-credentials
     107                         hdb
     108                         db-glue
     109                         PAC_GLUE
     110                         samba-hostconfig
     111                         com_err
     112                         ''',
     113                    enabled=not bld.CONFIG_SET('SAMBA4_USES_HEIMDAL'))
Note: See TracChangeset for help on using the changeset viewer.