Esempio n. 1
0
/*
 * delete a principal from the directory.
 */
krb5_error_code
krb5_ldap_delete_principal(krb5_context context,
                           krb5_const_principal searchfor)
{
    char                      *user=NULL, *DN=NULL, *strval[10] = {NULL};
    LDAPMod                   **mods=NULL;
    LDAP                      *ld=NULL;
    int                       j=0, ptype=0, pcount=0, attrsetmask=0;
    krb5_error_code           st=0;
    krb5_boolean              singleentry=FALSE;
    KEY                       *secretkey=NULL;
    kdb5_dal_handle           *dal_handle=NULL;
    krb5_ldap_context         *ldap_context=NULL;
    krb5_ldap_server_handle   *ldap_server_handle=NULL;
    krb5_db_entry             *entry = NULL;

    /* Clear the global error string */
    krb5_clear_error_message(context);

    SETUP_CONTEXT();
    /* get the principal info */
    if ((st=krb5_ldap_get_principal(context, searchfor, 0, &entry)))
        goto cleanup;

    if (((st=krb5_get_princ_type(context, entry, &(ptype))) != 0) ||
        ((st=krb5_get_attributes_mask(context, entry, &(attrsetmask))) != 0) ||
        ((st=krb5_get_princ_count(context, entry, &(pcount))) != 0) ||
        ((st=krb5_get_userdn(context, entry, &(DN))) != 0))
        goto cleanup;

    if (DN == NULL) {
        st = EINVAL;
        krb5_set_error_message(context, st, "DN information missing");
        goto cleanup;
    }

    GET_HANDLE();

    if (ptype == KDB_STANDALONE_PRINCIPAL_OBJECT) {
        st = ldap_delete_ext_s(ld, DN, NULL, NULL);
        if (st != LDAP_SUCCESS) {
            st = set_ldap_error (context, st, OP_DEL);
            goto cleanup;
        }
    } else {
        if (((st=krb5_unparse_name(context, searchfor, &user)) != 0)
            || ((st=krb5_ldap_unparse_principal_name(user)) != 0))
            goto cleanup;

        memset(strval, 0, sizeof(strval));
        strval[0] = user;
        if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbprincipalname", LDAP_MOD_DELETE,
                                          strval)) != 0)
            goto cleanup;

        singleentry = (pcount == 1) ? TRUE: FALSE;
        if (singleentry == FALSE) {
            if (secretkey != NULL) {
                if ((st=krb5_add_ber_mem_ldap_mod(&mods, "krbprincipalkey", LDAP_MOD_DELETE | LDAP_MOD_BVALUES,
                                                  secretkey->keys)) != 0)
                    goto cleanup;
            }
        } else {
            /*
             * If the Kerberos user principal to be deleted happens to be the last one associated
             * with the directory user object, then it is time to delete the other kerberos
             * specific attributes like krbmaxticketlife, i.e, unkerberize the directory user.
             * From the attrsetmask value, identify the attributes set on the directory user
             * object and delete them.
             * NOTE: krbsecretkey attribute has per principal entries. There can be chances that the
             * other principals' keys are exisiting/left-over. So delete all the values.
             */
            while (attrsetmask) {
                if (attrsetmask & 1) {
                    if ((st=krb5_add_str_mem_ldap_mod(&mods, attributes_set[j], LDAP_MOD_DELETE,
                                                      NULL)) != 0)
                        goto cleanup;
                }
                attrsetmask >>= 1;
                ++j;
            }

            /* the same should be done with the objectclass attributes */
            {
                char *attrvalues[] = {"krbticketpolicyaux", "krbprincipalaux", NULL};
/*              char *attrvalues[] = {"krbpwdpolicyrefaux", "krbticketpolicyaux", "krbprincipalaux", NULL};  */
                int p, q, r=0, amask=0;

                if ((st=checkattributevalue(ld, DN, "objectclass", attrvalues, &amask)) != 0)
                    goto cleanup;
                memset(strval, 0, sizeof(strval));
                for (p=1, q=0; p<=4; p<<=1, ++q)
                    if (p & amask)
                        strval[r++] = attrvalues[q];
                strval[r] = NULL;
                if (r > 0) {
                    if ((st=krb5_add_str_mem_ldap_mod(&mods, "objectclass", LDAP_MOD_DELETE,
                                                      strval)) != 0)
                        goto cleanup;
                }
            }
        }
        st=ldap_modify_ext_s(ld, DN, mods, NULL, NULL);
        if (st != LDAP_SUCCESS) {
            st = set_ldap_error(context, st, OP_MOD);
            goto cleanup;
        }
    }

cleanup:
    if (user)
        free (user);

    if (DN)
        free (DN);

    if (secretkey != NULL) {
        int i=0;
        while (i < secretkey->nkey) {
            free (secretkey->keys[i]->bv_val);
            free (secretkey->keys[i]);
            ++i;
        }
        free (secretkey->keys);
        free (secretkey);
    }

    krb5_ldap_free_principal(context, entry);

    ldap_mods_free(mods, 1);
    krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
    return st;
}
Esempio n. 2
0
krb5_error_code
krb5_ldap_get_principal(krb5_context context, krb5_const_principal searchfor,
                        unsigned int flags, krb5_db_entry **entry_ptr)
{
    char                        *user=NULL, *filter=NULL, *filtuser=NULL;
    unsigned int                tree=0, ntrees=1, princlen=0;
    krb5_error_code             tempst=0, st=0;
    char                        **values=NULL, **subtree=NULL, *cname=NULL;
    LDAP                        *ld=NULL;
    LDAPMessage                 *result=NULL, *ent=NULL;
    krb5_ldap_context           *ldap_context=NULL;
    kdb5_dal_handle             *dal_handle=NULL;
    krb5_ldap_server_handle     *ldap_server_handle=NULL;
    krb5_principal              cprinc=NULL;
    krb5_boolean                found=FALSE;
    krb5_db_entry               *entry = NULL;

    *entry_ptr = NULL;

    /* Clear the global error string */
    krb5_clear_error_message(context);

    if (searchfor == NULL)
        return EINVAL;

    dal_handle = context->dal_handle;
    ldap_context = (krb5_ldap_context *) dal_handle->db_context;

    CHECK_LDAP_HANDLE(ldap_context);

    if (is_principal_in_realm(ldap_context, searchfor) != 0) {
        krb5_set_error_message(context, st,
                               _("Principal does not belong to realm"));
        goto cleanup;
    }

    if ((st=krb5_unparse_name(context, searchfor, &user)) != 0)
        goto cleanup;

    if ((st=krb5_ldap_unparse_principal_name(user)) != 0)
        goto cleanup;

    filtuser = ldap_filter_correct(user);
    if (filtuser == NULL) {
        st = ENOMEM;
        goto cleanup;
    }

    princlen = strlen(FILTER) + strlen(filtuser) + 2 + 1;  /* 2 for closing brackets */
    if ((filter = malloc(princlen)) == NULL) {
        st = ENOMEM;
        goto cleanup;
    }
    snprintf(filter, princlen, FILTER"%s))", filtuser);

    if ((st = krb5_get_subtree_info(ldap_context, &subtree, &ntrees)) != 0)
        goto cleanup;

    GET_HANDLE();
    for (tree=0; tree < ntrees && !found; ++tree) {

        LDAP_SEARCH(subtree[tree], ldap_context->lrparams->search_scope, filter, principal_attributes);
        for (ent=ldap_first_entry(ld, result); ent != NULL && !found; ent=ldap_next_entry(ld, ent)) {

            /* get the associated directory user information */
            if ((values=ldap_get_values(ld, ent, "krbprincipalname")) != NULL) {
                int i;

                /* a wild-card in a principal name can return a list of kerberos principals.
                 * Make sure that the correct principal is returned.
                 * NOTE: a principalname k* in ldap server will return all the principals starting with a k
                 */
                for (i=0; values[i] != NULL; ++i) {
                    if (strcmp(values[i], user) == 0) {
                        found = TRUE;
                        break;
                    }
                }
                ldap_value_free(values);

                if (!found) /* no matching principal found */
                    continue;
            }

            if ((values=ldap_get_values(ld, ent, "krbcanonicalname")) != NULL) {
                if (values[0] && strcmp(values[0], user) != 0) {
                    /* We matched an alias, not the canonical name. */
                    if (flags & KRB5_KDB_FLAG_ALIAS_OK) {
                        st = krb5_ldap_parse_principal_name(values[0], &cname);
                        if (st != 0)
                            goto cleanup;
                        st = krb5_parse_name(context, cname, &cprinc);
                        if (st != 0)
                            goto cleanup;
                    } else /* No canonicalization, so don't return aliases. */
                        found = FALSE;
                }
                ldap_value_free(values);
                if (!found)
                    continue;
            }

            entry = k5alloc(sizeof(*entry), &st);
            if (entry == NULL)
                goto cleanup;
            if ((st = populate_krb5_db_entry(context, ldap_context, ld, ent,
                                             cprinc ? cprinc : searchfor,
                                             entry)) != 0)
                goto cleanup;
        }
        ldap_msgfree(result);
        result = NULL;
    } /* for (tree=0 ... */

    if (found) {
        *entry_ptr = entry;
        entry = NULL;
    } else
        st = KRB5_KDB_NOENTRY;

cleanup:
    ldap_msgfree(result);
    krb5_ldap_free_principal(context, entry);

    if (filter)
        free (filter);

    if (subtree) {
        for (; ntrees; --ntrees)
            if (subtree[ntrees-1])
                free (subtree[ntrees-1]);
        free (subtree);
    }

    if (ldap_server_handle)
        krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);

    if (user)
        free(user);

    if (filtuser)
        free(filtuser);

    if (cname)
        free(cname);

    if (cprinc)
        krb5_free_principal(context, cprinc);

    return st;
}