static kadm5_ret_t kadm5_get_either(int princ, void *server_handle, char *exp, char ***princs, int *count) { struct iter_data data; #ifdef BSD_REGEXPS char *msg; #endif char *regexp; int i, ret; kadm5_server_handle_t handle = server_handle; *count = 0; if (exp == NULL) exp = "*"; CHECK_HANDLE(server_handle); if ((ret = glob_to_regexp(exp, princ ? handle->params.realm : NULL, ®exp)) != KADM5_OK) return ret; if ( #ifdef SOLARIS_REGEXPS ((data.expbuf = compile(regexp, NULL, NULL)) == NULL) #endif #ifdef POSIX_REGEXPS ((regcomp(&data.preg, regexp, REG_NOSUB)) != 0) #endif #ifdef BSD_REGEXPS ((msg = (char *) re_comp(regexp)) != NULL) #endif ) { /* XXX syslog msg or regerr(regerrno) */ free(regexp); return EINVAL; } data.n_names = 0; data.sz_names = 10; data.malloc_failed = 0; data.names = malloc(sizeof(char *) * data.sz_names); if (data.names == NULL) { free(regexp); return ENOMEM; } if (princ) { data.context = handle->context; ret = kdb_iter_entry(handle, exp, get_princs_iter, (void *) &data); } else { ret = krb5_db_iter_policy(handle->context, exp, get_pols_iter, (void *)&data); } free(regexp); #ifdef POSIX_REGEXPS regfree(&data.preg); #endif if ( !ret && data.malloc_failed) ret = ENOMEM; if ( ret ) { for (i = 0; i < data.n_names; i++) free(data.names[i]); free(data.names); return ret; } *princs = data.names; *count = data.n_names; return KADM5_OK; }
int main() { krb5_db_entry *ent; osa_policy_ent_t pol; krb5_pa_data **e_data; const char *status; char *defrealm; int count; CHECK(krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_KDC, &ctx)); /* Currently necessary for krb5_db_open to work. */ CHECK(krb5_get_default_realm(ctx, &defrealm)); /* If we can, revert to requiring all entries match sample_princ in * iter_princ_handler */ CHECK_COND(krb5_db_inited(ctx) != 0); CHECK(krb5_db_create(ctx, NULL)); CHECK(krb5_db_inited(ctx)); CHECK(krb5_db_fini(ctx)); CHECK_COND(krb5_db_inited(ctx) != 0); CHECK_COND(krb5_db_inited(ctx) != 0); CHECK(krb5_db_open(ctx, NULL, KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN)); CHECK(krb5_db_inited(ctx)); /* Manipulate a policy, leaving it in place at the end. */ CHECK_COND(krb5_db_put_policy(ctx, &sample_policy) != 0); CHECK_COND(krb5_db_delete_policy(ctx, polname) != 0); CHECK_COND(krb5_db_get_policy(ctx, polname, &pol) == KRB5_KDB_NOENTRY); CHECK(krb5_db_create_policy(ctx, &sample_policy)); CHECK_COND(krb5_db_create_policy(ctx, &sample_policy) != 0); CHECK(krb5_db_get_policy(ctx, polname, &pol)); check_policy(pol); pol->pw_min_length--; CHECK(krb5_db_put_policy(ctx, pol)); krb5_db_free_policy(ctx, pol); CHECK(krb5_db_get_policy(ctx, polname, &pol)); CHECK_COND(pol->pw_min_length == sample_policy.pw_min_length - 1); krb5_db_free_policy(ctx, pol); CHECK(krb5_db_delete_policy(ctx, polname)); CHECK_COND(krb5_db_put_policy(ctx, &sample_policy) != 0); CHECK_COND(krb5_db_delete_policy(ctx, polname) != 0); CHECK_COND(krb5_db_get_policy(ctx, polname, &pol) == KRB5_KDB_NOENTRY); CHECK(krb5_db_create_policy(ctx, &sample_policy)); count = 0; CHECK(krb5_db_iter_policy(ctx, NULL, iter_pol_handler, &count)); CHECK_COND(count == 1); /* Create a principal. */ CHECK_COND(krb5_db_delete_principal(ctx, &sample_princ) == KRB5_KDB_NOENTRY); CHECK_COND(krb5_db_get_principal(ctx, &xrealm_princ, 0, &ent) == KRB5_KDB_NOENTRY); CHECK(krb5_db_put_principal(ctx, &sample_entry)); /* Putting again will fail with LDAP (due to KADM5_PRINCIPAL in mask) * but succeed with DB2, so don't check the result. */ (void)krb5_db_put_principal(ctx, &sample_entry); /* But it should succeed in both back ends with KADM5_LOAD in mask. */ sample_entry.mask |= KADM5_LOAD; CHECK(krb5_db_put_principal(ctx, &sample_entry)); sample_entry.mask &= ~KADM5_LOAD; /* Fetch and compare the added principal. */ CHECK(krb5_db_get_principal(ctx, &sample_princ, 0, &ent)); check_entry(ent); /* We can't set up a successful allowed-to-delegate check through existing * APIs yet, but we can make a failed check. */ CHECK_COND(krb5_db_check_allowed_to_delegate(ctx, &sample_princ, ent, &sample_princ) != 0); /* Exercise lockout code. */ /* Policy params: max_fail 2, failcnt_interval 60, lockout_duration 120 */ /* Initial state: last_success 1, last_failed 5, fail_auth_count 2, * last admin unlock 6 */ /* Check succeeds due to last admin unlock. */ CHECK(krb5_db_check_policy_as(ctx, NULL, ent, ent, 7, &status, &e_data)); /* Failure count resets to 1 due to last admin unlock. */ sim_preauth(8, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 8); /* Failure count resets to 1 due to failcnt_interval */ sim_preauth(70, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 70); /* Failure count resets to 0 due to successful preauth. */ sim_preauth(75, TRUE, &ent); CHECK_COND(ent->fail_auth_count == 0 && ent->last_success == 75); /* Failure count increments to 2 and stops incrementing. */ sim_preauth(80, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 80); sim_preauth(100, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 2 && ent->last_failed == 100); sim_preauth(110, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 2 && ent->last_failed == 100); /* Check fails due to reaching maximum failure count. */ CHECK_COND(krb5_db_check_policy_as(ctx, NULL, ent, ent, 170, &status, &e_data) == KRB5KDC_ERR_CLIENT_REVOKED); /* Check succeeds after lockout_duration has passed. */ CHECK(krb5_db_check_policy_as(ctx, NULL, ent, ent, 230, &status, &e_data)); /* Failure count resets to 1 on next failure. */ sim_preauth(240, FALSE, &ent); CHECK_COND(ent->fail_auth_count == 1 && ent->last_failed == 240); /* Exercise LDAP code to clear a policy reference and to set the key * data on an existing principal. */ CHECK(krb5_dbe_update_tl_data(ctx, ent, &tl_no_policy)); ent->mask = KADM5_POLICY_CLR | KADM5_KEY_DATA; CHECK(krb5_db_put_principal(ctx, ent)); CHECK(krb5_db_delete_policy(ctx, polname)); /* Put the modified entry again (with KDB_TL_USER_INFO tl-data for LDAP) as * from a load operation. */ ent->mask = (sample_entry.mask & ~KADM5_POLICY) | KADM5_LOAD; CHECK(krb5_db_put_principal(ctx, ent)); /* Exercise LDAP code to create a new principal at a DN from * KDB_TL_USER_INFO tl-data. */ CHECK(krb5_db_delete_principal(ctx, &sample_princ)); CHECK(krb5_db_put_principal(ctx, ent)); krb5_db_free_principal(ctx, ent); /* Exercise principal iteration code. */ count = 0; CHECK(krb5_db_iterate(ctx, "xy*", iter_princ_handler, &count)); CHECK_COND(count == 1); CHECK(krb5_db_fini(ctx)); CHECK_COND(krb5_db_inited(ctx) != 0); /* It might be nice to exercise krb5_db_destroy here, but the LDAP module * doesn't support it. */ krb5_free_default_realm(ctx, defrealm); krb5_free_context(ctx); return 0; }