diff options
-rw-r--r-- | daemons/ipa-kdb/Makefile.am | 1 | ||||
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb.c | 2 | ||||
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb.h | 13 | ||||
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb_passwords.c | 102 | ||||
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb_principals.c | 9 | ||||
-rw-r--r-- | util/ipa_krb5.c | 33 | ||||
-rw-r--r-- | util/ipa_krb5.h | 4 |
7 files changed, 153 insertions, 11 deletions
diff --git a/daemons/ipa-kdb/Makefile.am b/daemons/ipa-kdb/Makefile.am index 609372612..c33695933 100644 --- a/daemons/ipa-kdb/Makefile.am +++ b/daemons/ipa-kdb/Makefile.am @@ -29,6 +29,7 @@ ipadb_la_SOURCES = \ ipa_kdb.c \ ipa_kdb_common.c \ ipa_kdb_mkey.c \ + ipa_kdb_passwords.c \ ipa_kdb_principals.c \ ipa_kdb_pwdpolicy.c \ $(KRB5_UTIL_SRCS) \ diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c index d38ce048d..880a7890b 100644 --- a/daemons/ipa-kdb/ipa_kdb.c +++ b/daemons/ipa-kdb/ipa_kdb.c @@ -441,7 +441,7 @@ kdb_vftabl kdb_function_table = { NULL, /* fetch_master_key_list */ ipadb_store_master_key_list, /* store_master_key_list */ NULL, /* dbe_search_enctype */ - NULL, /* change_pwd */ + ipadb_change_pwd, /* change_pwd */ NULL, /* promote_db */ NULL, /* decrypt_key_data */ NULL, /* encrypt_key_data */ diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h index 257145cb6..7dc880527 100644 --- a/daemons/ipa-kdb/ipa_kdb.h +++ b/daemons/ipa-kdb/ipa_kdb.h @@ -66,10 +66,6 @@ #define KMASK_TL_DATA 0x040000 #define KMASK_LOAD 0x200000 -/* MIT Kerberos sanctioned hack to carry private data around. - * In krb5 1.10 this should be superceeded by a better mechanism */ -#define KDB_TL_USER_INFO 0x7ffe - #define IPA_SETUP "ipa-setup-override-restrictions" struct ipadb_context { @@ -161,3 +157,12 @@ krb5_error_code ipadb_store_master_key_list(krb5_context kcontext, char *master_pwd); krb5_error_code ipadb_create_master_key(krb5_context kcontext); + +/* PASSWORD FUNCTIONS */ +krb5_error_code ipadb_change_pwd(krb5_context context, + krb5_keyblock *master_key, + krb5_key_salt_tuple *ks_tuple, + int ks_tuple_count, char *passwd, + int new_kvno, krb5_boolean keepold, + krb5_db_entry *db_entry); + diff --git a/daemons/ipa-kdb/ipa_kdb_passwords.c b/daemons/ipa-kdb/ipa_kdb_passwords.c new file mode 100644 index 000000000..9c927c265 --- /dev/null +++ b/daemons/ipa-kdb/ipa_kdb_passwords.c @@ -0,0 +1,102 @@ +/* + * MIT Kerberos KDC database backend for FreeIPA + * + * Authors: Simo Sorce <ssorce@redhat.com> + * + * Copyright (C) 2011 Simo Sorce, Red Hat + * see file 'COPYING' for use and warranty information + * + * This program is free software you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ipa_kdb.h" + +krb5_error_code ipadb_change_pwd(krb5_context context, + krb5_keyblock *master_key, + krb5_key_salt_tuple *ks_tuple, + int ks_tuple_count, char *passwd, + int new_kvno, krb5_boolean keepold, + krb5_db_entry *db_entry) +{ + krb5_error_code kerr; + krb5_data pwd; + struct ipadb_context *ipactx; + krb5_key_salt_tuple *fks = NULL; + int n_fks; + krb5_key_data *keys = NULL; + int n_keys; + krb5_key_data *tdata; + int t_keys; + int old_kvno; + int i; + + ipactx = ipadb_get_context(context); + if (!ipactx) { + return KRB5_KDB_DBNOTINITED; + } + + old_kvno = krb5_db_get_key_data_kvno(context, db_entry->n_key_data, + db_entry->key_data); + if (old_kvno >= new_kvno) { + new_kvno = old_kvno + 1; + } + + pwd.data = passwd; + pwd.length = strlen(passwd); + + /* 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, + ipactx->supp_encs, ipactx->n_supp_encs, + &fks, &n_fks); + if (kerr) { + return kerr; + } + + kerr = ipa_krb5_generate_key_data(context, db_entry->princ, + pwd, new_kvno, master_key, + n_fks, fks, &n_keys, &keys); + free(fks); + if (kerr) { + return kerr; + } + + if (keepold) { + /* need to add the new keys to the old list */ + t_keys = db_entry->n_key_data; + + tdata = realloc(db_entry->key_data, + sizeof(krb5_key_data) * (t_keys + n_keys)); + if (!tdata) { + ipa_krb5_free_key_data(keys, n_keys); + return ENOMEM; + } + db_entry->key_data = tdata; + db_entry->n_key_data = t_keys + n_keys; + + for (i = 0; i < n_keys; i++) { + db_entry->key_data[t_keys + i] = keys[i]; + } + free(keys); + + } else { + + ipa_krb5_free_key_data(db_entry->key_data, db_entry->n_key_data); + db_entry->key_data = keys; + db_entry->n_key_data = n_keys; + } + + return 0; +} + diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c index 97b240650..993f2981d 100644 --- a/daemons/ipa-kdb/ipa_kdb_principals.c +++ b/daemons/ipa-kdb/ipa_kdb_principals.c @@ -348,7 +348,7 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext, krb5_error_code kerr; krb5_tl_data *res_tl_data; krb5_key_data *res_key_data; - krb5_kvno mkvno; + krb5_kvno mkvno = 0; char *restring; time_t restime; bool resbool; @@ -844,7 +844,6 @@ done: void ipadb_free_principal(krb5_context kcontext, krb5_db_entry *entry) { krb5_tl_data *prev, *next; - int i; if (entry) { free(entry->e_data); @@ -1128,8 +1127,7 @@ static krb5_error_code ipadb_get_ldap_mod_extra_data(struct ipadb_mods *imods, data->tl_data_type == KRB5_TL_KADM_DATA || data->tl_data_type == KRB5_TL_DB_ARGS || data->tl_data_type == KRB5_TL_MKVNO || - data->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK || - data->tl_data_type == KDB_TL_USER_INFO) { + data->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK) { continue; } n++; @@ -1151,8 +1149,7 @@ static krb5_error_code ipadb_get_ldap_mod_extra_data(struct ipadb_mods *imods, data->tl_data_type == KRB5_TL_KADM_DATA || data->tl_data_type == KRB5_TL_DB_ARGS || data->tl_data_type == KRB5_TL_MKVNO || - data->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK || - data->tl_data_type == KDB_TL_USER_INFO) { + data->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK) { continue; } diff --git a/util/ipa_krb5.c b/util/ipa_krb5.c index 96056c769..5b6fc5821 100644 --- a/util/ipa_krb5.c +++ b/util/ipa_krb5.c @@ -452,3 +452,36 @@ fail: return kerr; } +krb5_error_code filter_key_salt_tuples(krb5_context context, + krb5_key_salt_tuple *req, int n_req, + krb5_key_salt_tuple *supp, int n_supp, + krb5_key_salt_tuple **res, int *n_res) +{ + krb5_key_salt_tuple *ks = NULL; + int n_ks; + int i, j; + + ks = calloc(n_req, sizeof(krb5_key_salt_tuple)); + if (!ks) { + return ENOMEM; + } + n_ks = 0; + + for (i = 0; i < n_req; i++) { + for (j = 0; j < n_supp; j++) { + if (req[i].ks_enctype == supp[j].ks_enctype && + req[i].ks_salttype == supp[j].ks_salttype) { + break; + } + } + if (j < n_supp) { + ks[n_ks] = req[i]; + n_ks++; + } + } + + *res = ks; + *n_res = n_ks; + return 0; +} + diff --git a/util/ipa_krb5.h b/util/ipa_krb5.h index 7019e5e63..f0513d109 100644 --- a/util/ipa_krb5.h +++ b/util/ipa_krb5.h @@ -32,4 +32,8 @@ krb5_error_code parse_bval_key_salt_tuples(krb5_context kcontext, krb5_key_salt_tuple **kst, int *n_kst); +krb5_error_code filter_key_salt_tuples(krb5_context context, + krb5_key_salt_tuple *req, int n_req, + krb5_key_salt_tuple *supp, int n_supp, + krb5_key_salt_tuple **res, int *n_res); #endif /* __IPA_KRB5_H_ */ |