mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
ipa-kdb: add password policy support
Use default policy for new principals created by kadmin
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
NULL =
|
NULL =
|
||||||
|
|
||||||
KRB5_UTIL_DIR = ../../util
|
KRB5_UTIL_DIR = ../../util
|
||||||
KRB5_UTIL_SRCS = $(KRB5_UTIL_DIR)/ipa_krb5.c
|
KRB5_UTIL_SRCS = $(KRB5_UTIL_DIR)/ipa_krb5.c \
|
||||||
|
$(KRB5_UTIL_DIR)/ipa_pwd.c
|
||||||
|
|
||||||
INCLUDES = \
|
INCLUDES = \
|
||||||
-I. \
|
-I. \
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
|
|
||||||
#include "ipa_krb5.h"
|
#include "ipa_krb5.h"
|
||||||
|
#include "ipa_pwd.h"
|
||||||
|
|
||||||
/* easier to copy the defines here than to mess with kadm5/admin.h
|
/* easier to copy the defines here than to mess with kadm5/admin.h
|
||||||
* for now */
|
* for now */
|
||||||
@@ -80,6 +81,17 @@ struct ipadb_context {
|
|||||||
int n_supp_encs;
|
int n_supp_encs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define IPA_E_DATA_MAGIC 0x0eda7a
|
||||||
|
struct ipadb_e_data {
|
||||||
|
int magic;
|
||||||
|
bool ipa_user;
|
||||||
|
char *passwd;
|
||||||
|
time_t last_pwd_change;
|
||||||
|
char *pw_policy_dn;
|
||||||
|
char **pw_history;
|
||||||
|
struct ipapwd_policy pol;
|
||||||
|
};
|
||||||
|
|
||||||
struct ipadb_context *ipadb_get_context(krb5_context kcontext);
|
struct ipadb_context *ipadb_get_context(krb5_context kcontext);
|
||||||
int ipadb_get_connection(struct ipadb_context *ipactx);
|
int ipadb_get_connection(struct ipadb_context *ipactx);
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,147 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ipa_kdb.h"
|
#include "ipa_kdb.h"
|
||||||
|
#include "ipa_pwd.h"
|
||||||
|
#include <kadm5/kadm_err.h>
|
||||||
|
|
||||||
|
static char *pw_policy_attrs[] = {
|
||||||
|
"krbmaxpwdlife",
|
||||||
|
"krbminpwdlife",
|
||||||
|
"krbpwdmindiffchars",
|
||||||
|
"krbpwdminlength",
|
||||||
|
"krbpwdhistorylength",
|
||||||
|
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static krb5_error_code ipadb_get_pw_policy(struct ipadb_context *ipactx,
|
||||||
|
char *pw_policy_dn,
|
||||||
|
struct ipapwd_policy *pol)
|
||||||
|
{
|
||||||
|
krb5_error_code kerr;
|
||||||
|
LDAPMessage *res = NULL;
|
||||||
|
LDAPMessage *lentry;
|
||||||
|
uint32_t result;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
kerr = ipadb_simple_search(ipactx, pw_policy_dn, LDAP_SCOPE_BASE,
|
||||||
|
"(objectClass=*)", pw_policy_attrs, &res);
|
||||||
|
if (kerr) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
lentry = ldap_first_entry(ipactx->lcontext, res);
|
||||||
|
if (!lentry) {
|
||||||
|
kerr = KRB5_KDB_INTERNAL_ERROR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
|
||||||
|
"krbMinPwdLife", &result);
|
||||||
|
if (ret == 0) {
|
||||||
|
pol->min_pwd_life = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
|
||||||
|
"krbMaxPwdLife", &result);
|
||||||
|
if (ret == 0) {
|
||||||
|
pol->max_pwd_life = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
|
||||||
|
"krbPwdMinLength", &result);
|
||||||
|
if (ret == 0) {
|
||||||
|
pol->min_pwd_length = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
|
||||||
|
"krbPwdHistoryLength", &result);
|
||||||
|
if (ret == 0) {
|
||||||
|
pol->history_length = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
|
||||||
|
"krbPwdMinDiffChars", &result);
|
||||||
|
if (ret == 0) {
|
||||||
|
pol->min_complexity = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
ldap_msgfree(res);
|
||||||
|
return kerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code ipapwd_error_to_kerr(krb5_context context,
|
||||||
|
enum ipapwd_error err)
|
||||||
|
{
|
||||||
|
krb5_error_code kerr;
|
||||||
|
|
||||||
|
switch(err) {
|
||||||
|
case IPAPWD_POLICY_OK:
|
||||||
|
kerr = 0;
|
||||||
|
break;
|
||||||
|
case IPAPWD_POLICY_ACCOUNT_EXPIRED:
|
||||||
|
kerr = KADM5_BAD_PRINCIPAL;
|
||||||
|
krb5_set_error_message(context, kerr, "Account expired");
|
||||||
|
break;
|
||||||
|
case IPAPWD_POLICY_PWD_TOO_YOUNG:
|
||||||
|
kerr = KADM5_PASS_TOOSOON;
|
||||||
|
krb5_set_error_message(context, kerr, "Too soon to change password");
|
||||||
|
break;
|
||||||
|
case IPAPWD_POLICY_PWD_TOO_SHORT:
|
||||||
|
kerr = KADM5_PASS_Q_TOOSHORT;
|
||||||
|
krb5_set_error_message(context, kerr, "Password is too short");
|
||||||
|
break;
|
||||||
|
case IPAPWD_POLICY_PWD_IN_HISTORY:
|
||||||
|
kerr = KADM5_PASS_REUSE;
|
||||||
|
krb5_set_error_message(context, kerr, "Password reuse not permitted");
|
||||||
|
break;
|
||||||
|
case IPAPWD_POLICY_PWD_COMPLEXITY:
|
||||||
|
kerr = KADM5_PASS_Q_CLASS;
|
||||||
|
krb5_set_error_message(context, kerr, "Password is too simple");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
kerr = KADM5_PASS_Q_GENERIC;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static krb5_error_code ipadb_check_pw_policy(krb5_context context,
|
||||||
|
char *passwd,
|
||||||
|
krb5_db_entry *db_entry)
|
||||||
|
{
|
||||||
|
krb5_error_code kerr;
|
||||||
|
struct ipadb_e_data *ied;
|
||||||
|
struct ipadb_context *ipactx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ipactx = ipadb_get_context(context);
|
||||||
|
|
||||||
|
ied = (struct ipadb_e_data *)db_entry->e_data;
|
||||||
|
if (ied->magic != IPA_E_DATA_MAGIC) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ied->passwd = strdup(passwd);
|
||||||
|
if (!ied->passwd) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
ied->pol.max_pwd_life = IPAPWD_DEFAULT_PWDLIFE;
|
||||||
|
ied->pol.min_pwd_length = IPAPWD_DEFAULT_MINLEN;
|
||||||
|
kerr = ipadb_get_pw_policy(ipactx, ied->pw_policy_dn, &ied->pol);
|
||||||
|
if (kerr != 0) {
|
||||||
|
return kerr;
|
||||||
|
}
|
||||||
|
ret = ipapwd_check_policy(&ied->pol, passwd, time(NULL),
|
||||||
|
db_entry->expiration,
|
||||||
|
db_entry->pw_expiration,
|
||||||
|
ied->last_pwd_change,
|
||||||
|
ied->pw_history);
|
||||||
|
return ipapwd_error_to_kerr(context, ret);
|
||||||
|
}
|
||||||
|
|
||||||
krb5_error_code ipadb_change_pwd(krb5_context context,
|
krb5_error_code ipadb_change_pwd(krb5_context context,
|
||||||
krb5_keyblock *master_key,
|
krb5_keyblock *master_key,
|
||||||
@@ -32,6 +173,7 @@ krb5_error_code ipadb_change_pwd(krb5_context context,
|
|||||||
krb5_error_code kerr;
|
krb5_error_code kerr;
|
||||||
krb5_data pwd;
|
krb5_data pwd;
|
||||||
struct ipadb_context *ipactx;
|
struct ipadb_context *ipactx;
|
||||||
|
struct ipadb_e_data *ied;
|
||||||
krb5_key_salt_tuple *fks = NULL;
|
krb5_key_salt_tuple *fks = NULL;
|
||||||
int n_fks;
|
int n_fks;
|
||||||
krb5_key_data *keys = NULL;
|
krb5_key_data *keys = NULL;
|
||||||
@@ -39,6 +181,7 @@ krb5_error_code ipadb_change_pwd(krb5_context context,
|
|||||||
krb5_key_data *tdata;
|
krb5_key_data *tdata;
|
||||||
int t_keys;
|
int t_keys;
|
||||||
int old_kvno;
|
int old_kvno;
|
||||||
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ipactx = ipadb_get_context(context);
|
ipactx = ipadb_get_context(context);
|
||||||
@@ -46,6 +189,32 @@ krb5_error_code ipadb_change_pwd(krb5_context context,
|
|||||||
return KRB5_KDB_DBNOTINITED;
|
return KRB5_KDB_DBNOTINITED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!db_entry->e_data) {
|
||||||
|
if (!ipactx->override_restrictions) {
|
||||||
|
return EINVAL;
|
||||||
|
} else {
|
||||||
|
/* kadmin is creating a new principal */
|
||||||
|
ied = calloc(1, sizeof(struct ipadb_e_data));
|
||||||
|
if (!ied) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
ied->magic = IPA_E_DATA_MAGIC;
|
||||||
|
/* set the default policy on new entries */
|
||||||
|
ret = asprintf(&ied->pw_policy_dn,
|
||||||
|
"cn=global_policy,%s", ipactx->realm_base);
|
||||||
|
if (ret == -1) {
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
db_entry->e_data = (krb5_octet *)ied;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check pwd policy before doing any other work */
|
||||||
|
kerr = ipadb_check_pw_policy(context, passwd, db_entry);
|
||||||
|
if (kerr) {
|
||||||
|
return kerr;
|
||||||
|
}
|
||||||
|
|
||||||
old_kvno = krb5_db_get_key_data_kvno(context, db_entry->n_key_data,
|
old_kvno = krb5_db_get_key_data_kvno(context, db_entry->n_key_data,
|
||||||
db_entry->key_data);
|
db_entry->key_data);
|
||||||
if (old_kvno >= new_kvno) {
|
if (old_kvno >= new_kvno) {
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ static char *std_principal_attrs[] = {
|
|||||||
"krbMaxTicketLife",
|
"krbMaxTicketLife",
|
||||||
"krbMaxRenewableAge",
|
"krbMaxRenewableAge",
|
||||||
|
|
||||||
|
/* IPA SPECIFIC ATTRIBUTES */
|
||||||
"nsaccountlock",
|
"nsaccountlock",
|
||||||
|
"passwordHistory",
|
||||||
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
@@ -343,12 +345,15 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
|
|||||||
krb5_db_entry **kentry,
|
krb5_db_entry **kentry,
|
||||||
uint32_t *polmask)
|
uint32_t *polmask)
|
||||||
{
|
{
|
||||||
|
struct ipadb_context *ipactx;
|
||||||
LDAP *lcontext;
|
LDAP *lcontext;
|
||||||
krb5_db_entry *entry;
|
krb5_db_entry *entry;
|
||||||
|
struct ipadb_e_data *ied;
|
||||||
krb5_error_code kerr;
|
krb5_error_code kerr;
|
||||||
krb5_tl_data *res_tl_data;
|
krb5_tl_data *res_tl_data;
|
||||||
krb5_key_data *res_key_data;
|
krb5_key_data *res_key_data;
|
||||||
krb5_kvno mkvno = 0;
|
krb5_kvno mkvno = 0;
|
||||||
|
char **restrlist;
|
||||||
char *restring;
|
char *restring;
|
||||||
time_t restime;
|
time_t restime;
|
||||||
bool resbool;
|
bool resbool;
|
||||||
@@ -363,7 +368,8 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
|
|||||||
|
|
||||||
/* proceed to fill in attributes in the order they are defined in
|
/* proceed to fill in attributes in the order they are defined in
|
||||||
* krb5_db_entry in kdb.h */
|
* krb5_db_entry in kdb.h */
|
||||||
lcontext = (ipadb_get_context(kcontext))->lcontext;
|
ipactx = ipadb_get_context(kcontext);
|
||||||
|
lcontext = ipactx->lcontext;
|
||||||
|
|
||||||
entry->magic = KRB5_KDB_MAGIC_NUMBER;
|
entry->magic = KRB5_KDB_MAGIC_NUMBER;
|
||||||
entry->len = KRB5_KDB_V1_BASE_LENGTH;
|
entry->len = KRB5_KDB_V1_BASE_LENGTH;
|
||||||
@@ -524,20 +530,6 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
|
|||||||
entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
|
entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ipadb_ldap_attr_to_time_t(lcontext, lentry,
|
|
||||||
"krbLastPwdChange", &restime);
|
|
||||||
if (ret == 0) {
|
|
||||||
krb5_int32 time32le = htole32((krb5_int32)restime);
|
|
||||||
|
|
||||||
kerr = ipadb_set_tl_data(entry,
|
|
||||||
KRB5_TL_LAST_PWD_CHANGE,
|
|
||||||
sizeof(time32le),
|
|
||||||
(krb5_octet *)&time32le);
|
|
||||||
if (kerr) {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ipadb_ldap_attr_to_time_t(lcontext, lentry,
|
ret = ipadb_ldap_attr_to_time_t(lcontext, lentry,
|
||||||
"krbLastAdminUnlock", &restime);
|
"krbLastAdminUnlock", &restime);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
@@ -552,7 +544,70 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: fetch and se policy via krbpwdpolicyreference or fallback */
|
ied = calloc(1, sizeof(struct ipadb_e_data));
|
||||||
|
if (!ied) {
|
||||||
|
kerr = ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
ied->magic = IPA_E_DATA_MAGIC;
|
||||||
|
|
||||||
|
/* mark this as an ipa_user if it has the posixaccount objectclass */
|
||||||
|
ret = ipadb_ldap_attr_has_value(lcontext, lentry,
|
||||||
|
"objectClass", "posixAccount");
|
||||||
|
if (ret != 0 && ret != ENOENT) {
|
||||||
|
kerr = ret;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ied->ipa_user = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipadb_ldap_attr_to_str(lcontext, lentry,
|
||||||
|
"krbPwdPolicyReference", &restring);
|
||||||
|
switch (ret) {
|
||||||
|
case ENOENT:
|
||||||
|
/* use the default policy if ref. is not available */
|
||||||
|
ret = asprintf(&restring,
|
||||||
|
"cn=global_policy,%s", ipactx->realm_base);
|
||||||
|
if (ret == -1) {
|
||||||
|
kerr = ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
kerr = KRB5_KDB_INTERNAL_ERROR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
ied->pw_policy_dn = restring;
|
||||||
|
|
||||||
|
ret = ipadb_ldap_attr_to_strlist(lcontext, lentry,
|
||||||
|
"passwordHistory", &restrlist);
|
||||||
|
if (ret != 0 && ret != ENOENT) {
|
||||||
|
kerr = KRB5_KDB_INTERNAL_ERROR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
ied->pw_history = restrlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ipadb_ldap_attr_to_time_t(lcontext, lentry,
|
||||||
|
"krbLastPwdChange", &restime);
|
||||||
|
if (ret == 0) {
|
||||||
|
krb5_int32 time32le = htole32((krb5_int32)restime);
|
||||||
|
|
||||||
|
kerr = ipadb_set_tl_data(entry,
|
||||||
|
KRB5_TL_LAST_PWD_CHANGE,
|
||||||
|
sizeof(time32le),
|
||||||
|
(krb5_octet *)&time32le);
|
||||||
|
if (kerr) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
ied->last_pwd_change = restime;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->e_data = (krb5_octet *)ied;
|
||||||
|
|
||||||
kerr = 0;
|
kerr = 0;
|
||||||
|
|
||||||
@@ -843,10 +898,11 @@ done:
|
|||||||
|
|
||||||
void ipadb_free_principal(krb5_context kcontext, krb5_db_entry *entry)
|
void ipadb_free_principal(krb5_context kcontext, krb5_db_entry *entry)
|
||||||
{
|
{
|
||||||
|
struct ipadb_e_data *ied;
|
||||||
krb5_tl_data *prev, *next;
|
krb5_tl_data *prev, *next;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (entry) {
|
if (entry) {
|
||||||
free(entry->e_data);
|
|
||||||
krb5_free_principal(kcontext, entry->princ);
|
krb5_free_principal(kcontext, entry->princ);
|
||||||
prev = entry->tl_data;
|
prev = entry->tl_data;
|
||||||
while(prev) {
|
while(prev) {
|
||||||
@@ -856,6 +912,20 @@ void ipadb_free_principal(krb5_context kcontext, krb5_db_entry *entry)
|
|||||||
prev = next;
|
prev = next;
|
||||||
}
|
}
|
||||||
ipa_krb5_free_key_data(entry->key_data, entry->n_key_data);
|
ipa_krb5_free_key_data(entry->key_data, entry->n_key_data);
|
||||||
|
|
||||||
|
if (entry->e_data) {
|
||||||
|
ied = (struct ipadb_e_data *)entry->e_data;
|
||||||
|
if (ied->magic == IPA_E_DATA_MAGIC) {
|
||||||
|
free(ied->passwd);
|
||||||
|
free(ied->pw_policy_dn);
|
||||||
|
for (i = 0; ied->pw_history && ied->pw_history[i]; i++) {
|
||||||
|
free(ied->pw_history[i]);
|
||||||
|
}
|
||||||
|
free(ied->pw_history);
|
||||||
|
free(ied);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
free(entry);
|
free(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1249,6 +1319,49 @@ done:
|
|||||||
return kerr;
|
return kerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static krb5_error_code ipadb_get_ldap_mod_str_list(struct ipadb_mods *imods,
|
||||||
|
char *attrname,
|
||||||
|
char **strlist, int len,
|
||||||
|
int mod_op)
|
||||||
|
{
|
||||||
|
krb5_error_code kerr;
|
||||||
|
struct berval **bvs = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
bvs = calloc(len + 1, sizeof(struct berval *));
|
||||||
|
if (!bvs) {
|
||||||
|
kerr = ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
bvs[i] = calloc(1, sizeof(struct berval));
|
||||||
|
if (!bvs[i]) {
|
||||||
|
kerr = ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
bvs[i]->bv_val = strdup(strlist[i]);
|
||||||
|
if (!bvs[i]->bv_val) {
|
||||||
|
kerr = ENOMEM;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
bvs[i]->bv_len = strlen(strlist[i]) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
kerr = ipadb_get_ldap_mod_bvalues(imods, attrname, bvs, len, mod_op);
|
||||||
|
|
||||||
|
done:
|
||||||
|
if (kerr) {
|
||||||
|
for (i = 0; bvs && bvs[i]; i++) {
|
||||||
|
free(bvs[i]->bv_val);
|
||||||
|
free(bvs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(bvs);
|
||||||
|
return kerr;
|
||||||
|
}
|
||||||
|
|
||||||
static krb5_error_code ipadb_entry_to_mods(struct ipadb_mods *imods,
|
static krb5_error_code ipadb_entry_to_mods(struct ipadb_mods *imods,
|
||||||
krb5_db_entry *entry,
|
krb5_db_entry *entry,
|
||||||
char *principal,
|
char *principal,
|
||||||
@@ -1448,6 +1561,50 @@ static krb5_error_code ipadb_entry_to_mods(struct ipadb_mods *imods,
|
|||||||
|
|
||||||
/* KADM5_LOAD */
|
/* KADM5_LOAD */
|
||||||
|
|
||||||
|
/* Store saved password if any and password history */
|
||||||
|
if (entry->e_data) {
|
||||||
|
struct ipadb_e_data *ied;
|
||||||
|
time_t now = time(NULL);
|
||||||
|
char **new_history;
|
||||||
|
int nh_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ied = (struct ipadb_e_data *)entry->e_data;
|
||||||
|
if (ied->magic != IPA_E_DATA_MAGIC) {
|
||||||
|
kerr = EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to set userPassword and history only if this is
|
||||||
|
* a IPA User, we don't do that for simple service principals
|
||||||
|
*/
|
||||||
|
if (ied->ipa_user && ied->passwd) {
|
||||||
|
kerr = ipadb_get_ldap_mod_str(imods, "userPassword",
|
||||||
|
ied->passwd, mod_op);
|
||||||
|
if (kerr) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ied->ipa_user && ied->passwd && ied->pol.history_length) {
|
||||||
|
ret = ipapwd_generate_new_history(ied->passwd, now,
|
||||||
|
ied->pol.history_length,
|
||||||
|
ied->pw_history,
|
||||||
|
&new_history, &nh_len);
|
||||||
|
if (ret) {
|
||||||
|
kerr = ret;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
kerr = ipadb_get_ldap_mod_str_list(imods, "passwordHistory",
|
||||||
|
new_history, nh_len, mod_op);
|
||||||
|
if (kerr) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
kerr = 0;
|
kerr = 0;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|||||||
Reference in New Issue
Block a user