ipa-kdb: implement change_pwd function

This commit is contained in:
Simo Sorce 2011-06-20 19:35:50 -04:00
parent 49c25dbdf5
commit 452fcdccdc
7 changed files with 153 additions and 11 deletions

View File

@ -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) \

View File

@ -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 */

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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_ */