Beispiel #1
0
/*
 * Function: kdb_get_entry
 *
 * Purpose: Gets an entry from the kerberos database and breaks
 * it out into a krb5_db_entry and an osa_princ_ent_t.
 *
 * Arguments:
 *
 *		handle		(r) the server_handle
 * 		principal	(r) the principal to get
 * 		kdb		(w) krb5_db_entry to fill in
 * 		adb		(w) osa_princ_ent_rec to fill in
 *
 * when the caller is done with kdb and adb, kdb_free_entry must be
 * called to release them.  The adb record is filled in with the
 * contents of the KRB5_TL_KADM_DATA record; if that record doesn't
 * exist, an empty but valid adb record is returned.
 */
krb5_error_code
kdb_get_entry(kadm5_server_handle_t handle,
	      krb5_principal principal, krb5_db_entry *kdb,
	      osa_princ_ent_rec *adb)
{
    krb5_error_code ret;
    int nprincs;
    krb5_boolean more;
    krb5_tl_data tl_data;
    XDR xdrs;

    ret = krb5_db_get_principal(handle->context, principal, kdb, &nprincs,
				&more);
    if (ret)
	return(ret);

    if (more) {
	krb5_db_free_principal(handle->context, kdb, nprincs);
	return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
    } else if (nprincs != 1) {
	krb5_db_free_principal(handle->context, kdb, nprincs);
	return(KADM5_UNK_PRINC);
    }

    if (adb) {
	memset(adb, 0, sizeof(*adb));

	tl_data.tl_data_type = KRB5_TL_KADM_DATA;
	/*
	 * XXX Currently, lookup_tl_data always returns zero; it sets
	 * tl_data->tl_data_length to zero if the type isn't found.
	 * This should be fixed...
	 */
	if ((ret = krb5_dbe_lookup_tl_data(handle->context, kdb, &tl_data))
	    || (tl_data.tl_data_length == 0)) {
	    /* there's no admin data.  this can happen, if the admin
	       server is put into production after some principals
	       are created.  In this case, return valid admin
	       data (which is all zeros with the hist_kvno filled
	       in), and when the entry is written, the admin
	       data will get stored correctly. */

	    adb->admin_history_kvno = hist_kvno;

	    return(ret);
	}

	/* Solaris Kerberos */
	xdrmem_create(&xdrs, (caddr_t)tl_data.tl_data_contents,
		      tl_data.tl_data_length, XDR_DECODE);
	if (! xdr_osa_princ_ent_rec(&xdrs, adb)) {
	   xdr_destroy(&xdrs);
	   krb5_db_free_principal(handle->context, kdb, 1);
	   return(KADM5_XDR_FAILURE);
	}
	xdr_destroy(&xdrs);
    }

    return(0);
}
Beispiel #2
0
krb5_error_code
krb5_dbe_lookup_mod_princ_data(krb5_context context, krb5_db_entry *entry,
                               krb5_timestamp *mod_time,
                               krb5_principal *mod_princ)
{
    krb5_tl_data        tl_data;
    krb5_error_code     code;

    tl_data.tl_data_type = KRB5_TL_MOD_PRINC;

    if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
        return(code);

    if ((tl_data.tl_data_length < 5) ||
        (tl_data.tl_data_contents[tl_data.tl_data_length-1] != '\0'))
        return(KRB5_KDB_TRUNCATED_RECORD);

    /* Mod Date */
    krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time);

    /* Mod Princ */
    if ((code = krb5_parse_name(context,
                                (const char *) (tl_data.tl_data_contents+4),
                                mod_princ)))
        return(code);

    return(0);
}
Beispiel #3
0
/*
 * Function: kdb_get_entry
 *
 * Purpose: Gets an entry from the kerberos database and breaks
 * it out into a krb5_db_entry and an osa_princ_ent_t.
 *
 * Arguments:
 *
 *              handle          (r) the server_handle
 *              principal       (r) the principal to get
 *              kdb             (w) krb5_db_entry to create
 *              adb             (w) osa_princ_ent_rec to fill in
 *
 * when the caller is done with kdb and adb, kdb_free_entry must be
 * called to release them.  The adb record is filled in with the
 * contents of the KRB5_TL_KADM_DATA record; if that record doesn't
 * exist, an empty but valid adb record is returned.
 */
krb5_error_code
kdb_get_entry(kadm5_server_handle_t handle,
              krb5_principal principal, krb5_db_entry **kdb_ptr,
              osa_princ_ent_rec *adb)
{
    krb5_error_code ret;
    krb5_tl_data tl_data;
    XDR xdrs;
    krb5_db_entry *kdb;

    *kdb_ptr = NULL;

    ret = krb5_db_get_principal(handle->context, principal,
                                KRB5_KDB_FLAG_ALIAS_OK, &kdb);
    if (ret == KRB5_KDB_NOENTRY)
        return(KADM5_UNK_PRINC);
    if (ret)
        return(ret);

    if (adb) {
        memset(adb, 0, sizeof(*adb));

        tl_data.tl_data_type = KRB5_TL_KADM_DATA;
        /*
         * XXX Currently, lookup_tl_data always returns zero; it sets
         * tl_data->tl_data_length to zero if the type isn't found.
         * This should be fixed...
         */
        if ((ret = krb5_dbe_lookup_tl_data(handle->context, kdb, &tl_data))
            || (tl_data.tl_data_length == 0)) {
            /* there's no admin data.  this can happen, if the admin
               server is put into production after some principals
               are created.  In this case, return valid admin
               data (which is all zeros with the hist_kvno filled
               in), and when the entry is written, the admin
               data will get stored correctly. */

            adb->admin_history_kvno = INITIAL_HIST_KVNO;
            *kdb_ptr = kdb;
            return(ret);
        }

        xdrmem_create(&xdrs, (caddr_t)tl_data.tl_data_contents,
                      tl_data.tl_data_length, XDR_DECODE);
        if (! xdr_osa_princ_ent_rec(&xdrs, adb)) {
            xdr_destroy(&xdrs);
            krb5_db_free_principal(handle->context, kdb);
            return(KADM5_XDR_FAILURE);
        }
        xdr_destroy(&xdrs);
    }

    *kdb_ptr = kdb;
    return(0);
}
Beispiel #4
0
static krb5_error_code
lookup_lockout_policy(krb5_context context,
                      krb5_db_entry *entry,
                      krb5_kvno *pw_max_fail,
                      krb5_deltat *pw_failcnt_interval,
                      krb5_deltat *pw_lockout_duration)
{
    krb5_tl_data tl_data;
    krb5_error_code code;
    osa_princ_ent_rec adb;
    XDR xdrs;

    *pw_max_fail = 0;
    *pw_failcnt_interval = 0;
    *pw_lockout_duration = 0;

    tl_data.tl_data_type = KRB5_TL_KADM_DATA;

    code = krb5_dbe_lookup_tl_data(context, entry, &tl_data);
    if (code != 0 || tl_data.tl_data_length == 0)
        return code;

    memset(&adb, 0, sizeof(adb));
    xdrmem_create(&xdrs, (char *)tl_data.tl_data_contents,
                  tl_data.tl_data_length, XDR_DECODE);
    if (!xdr_osa_princ_ent_rec(&xdrs, &adb)) {
        xdr_destroy(&xdrs);
        return KADM5_XDR_FAILURE;
    }

    if (adb.policy != NULL) {
        osa_policy_ent_t policy = NULL;

        code = krb5_db2_get_policy(context, adb.policy, &policy);
        if (code == 0) {
            *pw_max_fail = policy->pw_max_fail;
            *pw_failcnt_interval = policy->pw_failcnt_interval;
            *pw_lockout_duration = policy->pw_lockout_duration;
            krb5_db2_free_policy(context, policy);
        }
    }

    xdr_destroy(&xdrs);

    xdrmem_create(&xdrs, NULL, 0, XDR_FREE);
    xdr_osa_princ_ent_rec(&xdrs, &adb);
    xdr_destroy(&xdrs);

    return 0;
}
Beispiel #5
0
krb5_error_code
krb5_get_linkdn(krb5_context context, krb5_db_entry *entry, char ***link_dn)
{
    krb5_error_code ret;
    krb5_tl_data tl_data;
    void *ptr;

    *link_dn = NULL;
    tl_data.tl_data_type = KDB_TL_USER_INFO;
    ret = krb5_dbe_lookup_tl_data(context, entry, &tl_data);
    if (ret || tl_data.tl_data_length == 0)
        return ret;

    if (decode_tl_data(&tl_data, KDB_TL_LINKDN, &ptr) == 0)
        *link_dn = ptr;

    return 0;
}
Beispiel #6
0
/* Decode the KADM_DATA from a DB entry.*/
static int
get_adb(krb5_db_entry *dbe, osa_princ_ent_rec *adb)
{
    XDR xdrs;
    int success;
    krb5_tl_data tl_data;
    krb5_error_code ret;

    memset(adb, 0, sizeof(*adb));
    tl_data.tl_data_type = KRB5_TL_KADM_DATA;
    ret = krb5_dbe_lookup_tl_data(util_context, dbe, &tl_data);
    if (ret != 0 || tl_data.tl_data_length == 0)
        return 0;
    xdrmem_create(&xdrs, (caddr_t)tl_data.tl_data_contents,
                  tl_data.tl_data_length, XDR_DECODE);
    success = xdr_osa_princ_ent_rec(&xdrs, adb);
    xdr_destroy(&xdrs);
    return success;
}
Beispiel #7
0
static krb5_error_code
get_str_from_tl_data(krb5_context context, krb5_db_entry *entry, int type,
                     char **strval)
{
    krb5_error_code ret;
    krb5_tl_data tl_data;
    void *ptr;

    if (type != KDB_TL_USERDN)
        return EINVAL;

    tl_data.tl_data_type = KDB_TL_USER_INFO;
    ret = krb5_dbe_lookup_tl_data(context, entry, &tl_data);
    if (ret || tl_data.tl_data_length == 0)
        return ret;

    if (decode_tl_data(&tl_data, type, &ptr) == 0)
        *strval = ptr;

    return 0;
}
Beispiel #8
0
/*
 * wrapper routines for decode_tl_data
 */
static krb5_error_code
get_int_from_tl_data(krb5_context context, krb5_db_entry *entry, int type,
                     int *intval)
{
    krb5_error_code ret;
    krb5_tl_data tl_data;
    void *ptr;
    int *intptr;

    tl_data.tl_data_type = KDB_TL_USER_INFO;
    ret = krb5_dbe_lookup_tl_data(context, entry, &tl_data);
    if (ret || tl_data.tl_data_length == 0)
        return ret;

    if (decode_tl_data(&tl_data, type, &ptr) == 0) {
        intptr = ptr;
        *intval = *intptr;
        free(intptr);
    }

    return 0;
}
Beispiel #9
0
/* Compare ent against sample_entry. */
static void
check_entry(krb5_db_entry *ent)
{
    krb5_int16 i, j;
    krb5_key_data *k1, *k2;
    krb5_tl_data *tl, etl;

    CHECK_COND(ent->attributes == sample_entry.attributes);
    CHECK_COND(ent->max_life == sample_entry.max_life);
    CHECK_COND(ent->max_renewable_life == sample_entry.max_renewable_life);
    CHECK_COND(ent->expiration == sample_entry.expiration);
    CHECK_COND(ent->pw_expiration == sample_entry.pw_expiration);
    CHECK_COND(ent->last_success == sample_entry.last_success);
    CHECK_COND(ent->last_failed == sample_entry.last_failed);
    CHECK_COND(ent->fail_auth_count == sample_entry.fail_auth_count);
    CHECK_COND(krb5_principal_compare(ctx, ent->princ, sample_entry.princ));
    CHECK_COND(ent->n_key_data == sample_entry.n_key_data);
    for (i = 0; i < ent->n_key_data; i++) {
        k1 = &ent->key_data[i];
        k2 = &sample_entry.key_data[i];
        CHECK_COND(k1->key_data_ver == k2->key_data_ver);
        CHECK_COND(k1->key_data_kvno == k2->key_data_kvno);
        for (j = 0; j < k1->key_data_ver; j++) {
            CHECK_COND(k1->key_data_type[j] == k2->key_data_type[j]);
            CHECK_COND(k1->key_data_length[j] == k2->key_data_length[j]);
            CHECK_COND(memcmp(k1->key_data_contents[j],
                              k2->key_data_contents[j],
                              k1->key_data_length[j]) == 0);
        }
    }
    for (tl = sample_entry.tl_data; tl != NULL; tl = tl->tl_data_next) {
        etl.tl_data_type = tl->tl_data_type;
        CHECK(krb5_dbe_lookup_tl_data(ctx, ent, &etl));
        CHECK_COND(tl->tl_data_length == etl.tl_data_length);
        CHECK_COND(memcmp(tl->tl_data_contents, etl.tl_data_contents,
                          tl->tl_data_length) == 0);
    }
}
Beispiel #10
0
krb5_error_code
krb5_dbe_lookup_last_pwd_change(krb5_context context, krb5_db_entry *entry,
                                krb5_timestamp *stamp)
{
    krb5_tl_data        tl_data;
    krb5_error_code     code;
    krb5_int32          tmp;

    tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;

    if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
        return(code);

    if (tl_data.tl_data_length != 4) {
        *stamp = 0;
        return(0);
    }

    krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp);

    *stamp = (krb5_timestamp) tmp;

    return(0);
}