diff options
Diffstat (limited to 'daemons/ipa-kdb')
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb.c | 38 | ||||
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb.h | 2 | ||||
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb_passwords.c | 16 | ||||
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb_principals.c | 80 | ||||
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb_pwdpolicy.c | 8 |
5 files changed, 144 insertions, 0 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c index d20b6a1f4..fff35c9c9 100644 --- a/daemons/ipa-kdb/ipa_kdb.c +++ b/daemons/ipa-kdb/ipa_kdb.c @@ -56,6 +56,7 @@ static void ipadb_context_free(krb5_context kcontext, ldap_unbind_ext_s((*ctx)->lcontext, NULL, NULL); } free((*ctx)->supp_encs); + free((*ctx)->def_encs); ipadb_mspac_struct_free(&(*ctx)->mspac); krb5_free_default_realm(kcontext, (*ctx)->realm); @@ -383,6 +384,43 @@ int ipadb_get_connection(struct ipadb_context *ipactx) goto done; } + /* defaults first, this is used to tell what default enc:salts to use + * for kadmin password changes */ + vals = ldap_get_values_len(ipactx->lcontext, first, + "krbDefaultEncSaltTypes"); + if (!vals || !vals[0]) { + goto done; + } + + for (c = 0; vals[c]; c++) /* count */ ; + cvals = calloc(c, sizeof(char *)); + if (!cvals) { + ret = ENOMEM; + goto done; + } + for (i = 0; i < c; i++) { + cvals[i] = strndup(vals[i]->bv_val, vals[i]->bv_len); + if (!cvals[i]) { + ret = ENOMEM; + goto done; + } + } + + ret = parse_bval_key_salt_tuples(ipactx->kcontext, + (const char * const *)cvals, c, + &kst, &n_kst); + if (ret) { + goto done; + } + + if (ipactx->def_encs) { + free(ipactx->def_encs); + } + ipactx->def_encs = kst; + ipactx->n_def_encs = n_kst; + + /* supported enc salt types, use to tell kadmin what to accept + * but also to detect if kadmin is requesting the default set */ vals = ldap_get_values_len(ipactx->lcontext, first, "krbSupportedEncSaltTypes"); if (!vals || !vals[0]) { diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h index ba9968bce..3c6138599 100644 --- a/daemons/ipa-kdb/ipa_kdb.h +++ b/daemons/ipa-kdb/ipa_kdb.h @@ -106,6 +106,8 @@ struct ipadb_context { bool override_restrictions; krb5_key_salt_tuple *supp_encs; int n_supp_encs; + krb5_key_salt_tuple *def_encs; + int n_def_encs; struct ipadb_mspac *mspac; /* Don't access this directly, use ipadb_get_global_config(). */ diff --git a/daemons/ipa-kdb/ipa_kdb_passwords.c b/daemons/ipa-kdb/ipa_kdb_passwords.c index 974ae8fc8..ad57181d5 100644 --- a/daemons/ipa-kdb/ipa_kdb_passwords.c +++ b/daemons/ipa-kdb/ipa_kdb_passwords.c @@ -159,6 +159,22 @@ krb5_error_code ipadb_change_pwd(krb5_context context, pwd.data = passwd; pwd.length = strlen(passwd); + /* detect if kadmin is just passing along the default set */ + if (ks_tuple_count == ipactx->n_supp_encs) { + for (i = 0; i < ks_tuple_count; i++) { + if (ks_tuple[i].ks_enctype != ipactx->supp_encs[i].ks_enctype) + break; + if (ks_tuple[i].ks_salttype != ipactx->supp_encs[i].ks_salttype) + break; + } + if (i == ks_tuple_count) { + /* we got passed the default supported enctypes, replace with + * the actual default enctypes to use */ + ks_tuple = ipactx->def_encs; + ks_tuple_count = ipactx->n_def_encs; + } + } + /* We further filter supported enctypes to restrict to the list * we have in ldap */ kerr = filter_key_salt_tuples(context, ks_tuple, ks_tuple_count, diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c index d0fd3e291..b3f8b1ad7 100644 --- a/daemons/ipa-kdb/ipa_kdb_principals.c +++ b/daemons/ipa-kdb/ipa_kdb_principals.c @@ -349,6 +349,83 @@ static enum ipadb_user_auth ipadb_get_user_auth(struct ipadb_context *ipactx, return ua; } +#define OSA_ADB_PRINC_VERSION_1 0x12345C01 +/* The XDR encoding of OSA_PRINC_ENC is as follows: + version: int (signed 32 bit integer) + name: nullstring (null terminated variable string) + aux_attributes: long (signed 32 bit integer) + old_key_next: u_int (unsigned 32 bit integer) + adm_hist_kvno: u_char (unisgned char) + old_keys: array of keys, we do not care so alway u_int of 0 +*/ +#define OSA_PRINC_ENC_BASE_SIZE 20 + +static krb5_error_code ipadb_policydn_to_kdam_tl_data(const char *policydn, + krb5_db_entry *entry) +{ + krb5_error_code kerr; + uint32_t tmp; + char *policy_name = NULL; + char *p; + uint8_t *buf = NULL; + size_t buf_len; + int slen; + int plen; + int cur; + + /* policy objects must use cn as the RDN */ + if (strncmp(policydn, "cn=", 3) != 0) { + return KRB5_KDB_INTERNAL_ERROR; + } + + /* Should we try to consider the case where a ',' is part of the polict + * name ? */ + policy_name = strdup(&policydn[3]); + if (!policy_name) { + kerr = ENOMEM; + goto done; + } + p = strchr(policy_name, ','); + if (p) *p = '\0'; + + /* Now we open code a basic KRB5_TL_KADM_DATA which is a XDR encoded + * structure in MIT code */ + + slen = strlen(policy_name) + 1; + /* A xdr varstring is preceeded by a 32bit len field and is always 32 + * bit aligned */ + plen = slen + 4; + plen = (((plen + 3) / 4) * 4); + + buf_len = OSA_PRINC_ENC_BASE_SIZE + plen; + buf = calloc(1, buf_len); + if (!buf) { + kerr = ENOMEM; + goto done; + } + + /* version */ + cur = 0; + tmp = htobe32(OSA_ADB_PRINC_VERSION_1); + memcpy(&buf[cur], &tmp, 4); + cur += 4; + + /* name */ + tmp = htobe32(slen); + memcpy(&buf[cur], &tmp, 4); + memcpy(&buf[cur + 4], policy_name, slen); + cur += plen; + + /* All the other fileds are left empty */ + + kerr = ipadb_set_tl_data(entry, KRB5_TL_KADM_DATA, buf_len, buf); + +done: + free(policy_name); + free(buf); + return kerr; +} + static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext, char *principal, LDAPMessage *lentry, @@ -617,6 +694,9 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext, } ied->pw_policy_dn = restring; + kerr = ipadb_policydn_to_kdam_tl_data(restring, entry); + if (kerr) goto done; + ret = ipadb_ldap_attr_to_strlist(lcontext, lentry, "passwordHistory", &restrlist); if (ret != 0 && ret != ENOENT) { diff --git a/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c b/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c index 6f3992be6..076314a12 100644 --- a/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c +++ b/daemons/ipa-kdb/ipa_kdb_pwdpolicy.c @@ -237,6 +237,13 @@ krb5_error_code ipadb_get_pwd_policy(krb5_context kcontext, char *name, pentry->pw_lockout_duration = result; } + ret = ipa_kstuples_to_string(ipactx->supp_encs, ipactx->n_supp_encs, + &pentry->allowed_keysalts); + if (ret != 0) { + kerr = KRB5_KDB_INTERNAL_ERROR; + goto done; + } + *policy = pentry; done: @@ -274,6 +281,7 @@ void ipadb_free_pwd_policy(krb5_context kcontext, osa_policy_ent_t val) { if (val) { free(val->name); + free(val->allowed_keysalts); free(val); } } |