コード例 #1
0
ファイル: ldap_misc.c プロジェクト: Akasurde/krb5
/*
 * Fill out a krb5_db_entry princ entry struct given a LDAP message containing
 * the results of a principal search of the directory.
 */
krb5_error_code
populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context,
                       LDAP *ld, LDAPMessage *ent, krb5_const_principal princ,
                       krb5_db_entry *entry)
{
    krb5_error_code ret;
    unsigned int mask = 0;
    int val, i, pcount, objtype;
    krb5_boolean attr_present;
    krb5_kvno mkvno = 0;
    krb5_timestamp lastpwdchange, unlock_time;
    char *policydn = NULL, *pwdpolicydn = NULL, *polname = NULL, *user = NULL;
    char *tktpolname = NULL, *dn = NULL, **link_references = NULL;
    char **pnvalues = NULL, **ocvalues = NULL, **a2d2 = NULL;
    struct berval **ber_key_data = NULL, **ber_tl_data = NULL;
    krb5_tl_data userinfo_tl_data = { NULL }, **endp, *tl;
    osa_princ_ent_rec princ_ent;

    memset(&princ_ent, 0, sizeof(princ_ent));

    ret = krb5_copy_principal(context, princ, &entry->princ);
    if (ret)
        goto cleanup;

    /* get the associated directory user information */
    pnvalues = ldap_get_values(ld, ent, "krbprincipalname");
    if (pnvalues != NULL) {
        ret = krb5_unparse_name(context, princ, &user);
        if (ret)
            goto cleanup;

        pcount = 0;
        for (i = 0; pnvalues[i] != NULL; i++) {
            if (strcasecmp(pnvalues[i], user) == 0) {
                pcount = ldap_count_values(pnvalues);
                break;
            }
        }

        dn = ldap_get_dn(ld, ent);
        if (dn == NULL) {
            ldap_get_option(ld, LDAP_OPT_RESULT_CODE, &ret);
            ret = set_ldap_error(context, ret, 0);
            goto cleanup;
        }

        ocvalues = ldap_get_values(ld, ent, "objectclass");
        if (ocvalues != NULL) {
            for (i = 0; ocvalues[i] != NULL; i++) {
                if (strcasecmp(ocvalues[i], "krbprincipal") == 0) {
                    objtype = KDB_STANDALONE_PRINCIPAL_OBJECT;
                    ret = store_tl_data(&userinfo_tl_data, KDB_TL_PRINCTYPE,
                                        &objtype);
                    if (ret)
                        goto cleanup;
                    break;
                }
            }
        }

        /* Add principalcount, DN and principaltype user information to
         * tl_data */
        ret = store_tl_data(&userinfo_tl_data, KDB_TL_PRINCCOUNT, &pcount);
        if (ret)
            goto cleanup;
        ret = store_tl_data(&userinfo_tl_data, KDB_TL_USERDN, dn);
        if (ret)
            goto cleanup;
    }

    ret = get_time(ld, ent, "krbLastSuccessfulAuth", &entry->last_success,
                   &attr_present);
    if (ret)
        goto cleanup;
    if (attr_present)
        mask |= KDB_LAST_SUCCESS_ATTR;

    ret = get_time(ld, ent, "krbLastFailedAuth", &entry->last_failed,
                   &attr_present);
    if (ret)
        goto cleanup;
    if (attr_present)
        mask |= KDB_LAST_FAILED_ATTR;

    if (krb5_ldap_get_value(ld, ent, "krbLoginFailedCount", &val) == 0) {
        entry->fail_auth_count = val;
        mask |= KDB_FAIL_AUTH_COUNT_ATTR;
    }
    if (krb5_ldap_get_value(ld, ent, "krbmaxticketlife", &val) == 0) {
        entry->max_life = val;
        mask |= KDB_MAX_LIFE_ATTR;
    }
    if (krb5_ldap_get_value(ld, ent, "krbmaxrenewableage", &val) == 0) {
        entry->max_renewable_life = val;
        mask |= KDB_MAX_RLIFE_ATTR;
    }
    if (krb5_ldap_get_value(ld, ent, "krbticketflags", &val) == 0) {
        entry->attributes = val;
        mask |= KDB_TKT_FLAGS_ATTR;
    }
    ret = get_time(ld, ent, "krbprincipalexpiration", &entry->expiration,
                   &attr_present);
    if (ret)
        goto cleanup;
    if (attr_present)
        mask |= KDB_PRINC_EXPIRE_TIME_ATTR;

    ret = get_time(ld, ent, "krbpasswordexpiration", &entry->pw_expiration,
                   &attr_present);
    if (ret)
        goto cleanup;
    if (attr_present)
        mask |= KDB_PWD_EXPIRE_TIME_ATTR;

    ret = krb5_ldap_get_string(ld, ent, "krbticketpolicyreference", &policydn,
                               &attr_present);
    if (ret)
        goto cleanup;
    if (attr_present) {
        mask |= KDB_POL_REF_ATTR;
        /* Ensure that the policy is inside the realm container. */
        ret = krb5_ldap_policydn_to_name(context, policydn, &tktpolname);
        if (ret)
            goto cleanup;
    }

    ret = krb5_ldap_get_string(ld, ent, "krbpwdpolicyreference", &pwdpolicydn,
                               &attr_present);
    if (ret)
        goto cleanup;
    if (attr_present) {
        mask |= KDB_PWD_POL_REF_ATTR;

        /* Ensure that the policy is inside the realm container. */
        ret = krb5_ldap_policydn_to_name(context, pwdpolicydn, &polname);
        if (ret)
            goto cleanup;
        princ_ent.policy = polname;
        princ_ent.aux_attributes |= KADM5_POLICY;
    }

    ber_key_data = ldap_get_values_len(ld, ent, "krbpwdhistory");
    if (ber_key_data != NULL) {
        mask |= KDB_PWD_HISTORY_ATTR;
        ret = krb5_decode_histkey(context, ber_key_data, &princ_ent);
        if (ret)
            goto cleanup;
        ldap_value_free_len(ber_key_data);
    }

    if (princ_ent.aux_attributes) {
        ret = krb5_update_tl_kadm_data(context, entry, &princ_ent);
        if (ret)
            goto cleanup;
    }

    ber_key_data = ldap_get_values_len(ld, ent, "krbprincipalkey");
    if (ber_key_data != NULL) {
        mask |= KDB_SECRET_KEY_ATTR;
        ret = krb5_decode_krbsecretkey(context, entry, ber_key_data, &mkvno);
        if (ret)
            goto cleanup;
        if (mkvno != 0) {
            ret = krb5_dbe_update_mkvno(context, entry, mkvno);
            if (ret)
                goto cleanup;
        }
    }

    ret = get_time(ld, ent, "krbLastPwdChange", &lastpwdchange, &attr_present);
    if (ret)
        goto cleanup;
    if (attr_present) {
        ret = krb5_dbe_update_last_pwd_change(context, entry, lastpwdchange);
        if (ret)
            goto cleanup;
        mask |= KDB_LAST_PWD_CHANGE_ATTR;
    }

    ret = get_time(ld, ent, "krbLastAdminUnlock", &unlock_time, &attr_present);
    if (ret)
        goto cleanup;
    if (attr_present) {
        ret = krb5_dbe_update_last_admin_unlock(context, entry, unlock_time);
        if (ret)
            goto cleanup;
        mask |= KDB_LAST_ADMIN_UNLOCK_ATTR;
    }

    a2d2 = ldap_get_values(ld, ent, "krbAllowedToDelegateTo");
    if (a2d2 != NULL) {
        for (endp = &entry->tl_data; *endp; endp = &(*endp)->tl_data_next);
        for (i = 0; a2d2[i] != NULL; i++) {
            tl = k5alloc(sizeof(*tl), &ret);
            if (tl == NULL)
                goto cleanup;
            tl->tl_data_type = KRB5_TL_CONSTRAINED_DELEGATION_ACL;
            tl->tl_data_length = strlen(a2d2[i]);
            tl->tl_data_contents = (unsigned char *)strdup(a2d2[i]);
            if (tl->tl_data_contents == NULL) {
                ret = ENOMEM;
                free(tl);
                goto cleanup;
            }
            tl->tl_data_next = NULL;
            *endp = tl;
            endp = &tl->tl_data_next;
        }
    }

    link_references = ldap_get_values(ld, ent, "krbobjectreferences");
    if (link_references != NULL) {
        for (i = 0; link_references[i] != NULL; i++) {
            ret = store_tl_data(&userinfo_tl_data, KDB_TL_LINKDN,
                                link_references[i]);
            if (ret)
                goto cleanup;
        }
    }

    ber_tl_data = ldap_get_values_len(ld, ent, "krbExtraData");
    if (ber_tl_data != NULL) {
        for (i = 0; ber_tl_data[i] != NULL; i++) {
            ret = berval2tl_data(ber_tl_data[i], &tl);
            if (ret)
                goto cleanup;
            ret = krb5_dbe_update_tl_data(context, entry, tl);
            free(tl->tl_data_contents);
            free(tl);
            if (ret)
                goto cleanup;
        }
        mask |= KDB_EXTRA_DATA_ATTR;
    }

    /* Auth indicators from krbPrincipalAuthInd will replace those from
     * krbExtraData. */
    ret = get_ldap_auth_ind(context, ld, ent, entry, &mask);
    if (ret)
        goto cleanup;

    /* Update the mask of attributes present on the directory object to the
     * tl_data. */
    ret = store_tl_data(&userinfo_tl_data, KDB_TL_MASK, &mask);
    if (ret)
        goto cleanup;
    ret = krb5_dbe_update_tl_data(context, entry, &userinfo_tl_data);
    if (ret)
        goto cleanup;

    ret = krb5_read_tkt_policy(context, ldap_context, entry, tktpolname);
    if (ret)
        goto cleanup;

    /* For compatibility with DB2 principals. */
    entry->len = KRB5_KDB_V1_BASE_LENGTH;

cleanup:
    ldap_memfree(dn);
    ldap_value_free_len(ber_key_data);
    ldap_value_free_len(ber_tl_data);
    ldap_value_free(pnvalues);
    ldap_value_free(ocvalues);
    ldap_value_free(link_references);
    ldap_value_free(a2d2);
    free(userinfo_tl_data.tl_data_contents);
    free(pwdpolicydn);
    free(polname);
    free(tktpolname);
    free(policydn);
    krb5_free_unparsed_name(context, user);
    free_princ_ent_contents(&princ_ent);
    return ret;
}
コード例 #2
0
ファイル: ldap_realm.c プロジェクト: b055man/krb5
krb5_error_code
krb5_ldap_read_realm_params(krb5_context context, char *lrealm,
                            krb5_ldap_realm_params **rlparamp, int *mask)
{
    char                   **values=NULL;
    krb5_error_code        st=0, tempst=0;
    LDAP                   *ld=NULL;
    LDAPMessage            *result=NULL,*ent=NULL;
    krb5_ldap_realm_params *rlparams=NULL;
    kdb5_dal_handle        *dal_handle=NULL;
    krb5_ldap_context      *ldap_context=NULL;
    krb5_ldap_server_handle *ldap_server_handle=NULL;
    int x=0;

    SETUP_CONTEXT ();

    /* validate the input parameter */
    if (lrealm == NULL || ldap_context->container_dn == NULL) {
        st = EINVAL;
        goto cleanup;
    }

    /* get ldap handle */
    GET_HANDLE ();

    /* Initialize realm container structure */
    rlparams =(krb5_ldap_realm_params *) malloc(sizeof(krb5_ldap_realm_params));
    CHECK_NULL(rlparams);
    memset(rlparams, 0, sizeof(krb5_ldap_realm_params));

    /* allocate tl_data structure to store MASK information */
    rlparams->tl_data = malloc (sizeof(krb5_tl_data));
    if (rlparams->tl_data == NULL) {
        st = ENOMEM;
        goto cleanup;
    }
    memset(rlparams->tl_data, 0, sizeof(krb5_tl_data));
    rlparams->tl_data->tl_data_type = KDB_TL_USER_INFO;

    /* set the mask parameter to 0 */
    *mask = 0;

    /* set default values */
    rlparams->search_scope = LDAP_SCOPE_SUBTREE;

    if (asprintf(&rlparams->realmdn, "cn=%s,%s", lrealm,
                 ldap_context->container_dn) < 0) {
        rlparams->realmdn = NULL;
        st = ENOMEM;
        goto cleanup;
    }

    /* populate the realm name in the structure */
    rlparams->realm_name = strdup(lrealm);
    CHECK_NULL(rlparams->realm_name);

    LDAP_SEARCH(rlparams->realmdn, LDAP_SCOPE_BASE, "(objectclass=krbRealmContainer)", realm_attributes);

    if ((st = ldap_count_entries(ld, result)) <= 0) {
        /* This could happen when the DN used to bind and read the realm object
         * does not have sufficient rights to read its attributes
         */
        st = KRB5_KDB_ACCESS_ERROR; /* return some other error ? */
        goto cleanup;
    }

    ent = ldap_first_entry (ld, result);
    if (ent == NULL) {
        ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, (void *) &st);
#if 0
        st = translate_ldap_error(st, OP_SEARCH);
#endif
        goto cleanup;
    }

    /* Read the attributes */
    {
        if ((values=ldap_get_values(ld, ent, "krbSubTrees")) != NULL) {
            rlparams->subtreecount = ldap_count_values(values);
            rlparams->subtree = (char **) malloc(sizeof(char *) * (rlparams->subtreecount + 1));
            if (rlparams->subtree == NULL) {
                st = ENOMEM;
                goto cleanup;
            }
            for (x=0; x<rlparams->subtreecount; x++) {
                rlparams->subtree[x] = strdup(values[x]);
                if (rlparams->subtree[x] == NULL) {
                    st = ENOMEM;
                    goto cleanup;
                }
            }
            rlparams->subtree[rlparams->subtreecount] = NULL;
            *mask |= LDAP_REALM_SUBTREE;
            ldap_value_free(values);
        }

        if((values=ldap_get_values(ld, ent, "krbPrincContainerRef")) != NULL) {
            rlparams->containerref = strdup(values[0]);
            if(rlparams->containerref == NULL) {
                st = ENOMEM;
                goto cleanup;
            }
            *mask |= LDAP_REALM_CONTREF;
            ldap_value_free(values);
        }

        if ((values=ldap_get_values(ld, ent, "krbSearchScope")) != NULL) {
            rlparams->search_scope=atoi(values[0]);
            /* searchscope can be ONE-LEVEL or SUBTREE, else default to SUBTREE */
            if (!(rlparams->search_scope==1 || rlparams->search_scope==2))
                rlparams->search_scope = LDAP_SCOPE_SUBTREE;
            *mask |= LDAP_REALM_SEARCHSCOPE;
            ldap_value_free(values);
        }

        if ((values=ldap_get_values(ld, ent, "krbMaxTicketLife")) != NULL) {
            rlparams->max_life = atoi(values[0]);
            *mask |= LDAP_REALM_MAXTICKETLIFE;
            ldap_value_free(values);
        }

        if ((values=ldap_get_values(ld, ent, "krbMaxRenewableAge")) != NULL) {
            rlparams->max_renewable_life = atoi(values[0]);
            *mask |= LDAP_REALM_MAXRENEWLIFE;
            ldap_value_free(values);
        }

        if ((values=ldap_get_values(ld, ent, "krbTicketFlags")) != NULL) {
            rlparams->tktflags = atoi(values[0]);
            *mask |= LDAP_REALM_KRBTICKETFLAGS;
            ldap_value_free(values);
        }

    }

    rlparams->mask = *mask;
    *rlparamp = rlparams;
    st = store_tl_data(rlparams->tl_data, KDB_TL_MASK, mask);

cleanup:

    /* if there is an error, free allocated structures */
    if (st != 0) {
        krb5_ldap_free_realm_params(rlparams);
        *rlparamp=NULL;
    }
    ldap_msgfree(result);
    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
    return st;
}