Imported Debian patch 4.8.10-2
This commit is contained in:
committed by
Mario Fetka
parent
8bc559c5a1
commit
358acdd85f
@@ -17,7 +17,6 @@ AM_CPPFLAGS = \
|
||||
$(LDAP_CFLAGS) \
|
||||
$(KRB5_CFLAGS) \
|
||||
$(NSPR_CFLAGS) \
|
||||
$(NSS_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
@@ -25,8 +24,6 @@ AM_LDFLAGS = \
|
||||
$(CRYPTO_LIBS) \
|
||||
$(KRB5_LIBS) \
|
||||
$(LDAP_LIBS) \
|
||||
$(NSPR_LIBS) \
|
||||
$(NSS_LIBS) \
|
||||
-avoid-version \
|
||||
-export-symbols-regex ^ipapwd_init$
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.16.2 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -271,6 +271,8 @@ JSLINT = @JSLINT@
|
||||
KRAD_LIBS = @KRAD_LIBS@
|
||||
KRB5KDC_SERVICE = @KRB5KDC_SERVICE@
|
||||
KRB5_CFLAGS = @KRB5_CFLAGS@
|
||||
KRB5_GSSAPI_CFLAGS = @KRB5_GSSAPI_CFLAGS@
|
||||
KRB5_GSSAPI_LIBS = @KRB5_GSSAPI_LIBS@
|
||||
KRB5_LIBS = @KRB5_LIBS@
|
||||
LD = @LD@
|
||||
LDAP_CFLAGS = @LDAP_CFLAGS@
|
||||
@@ -313,11 +315,10 @@ NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
NSPR_CFLAGS = @NSPR_CFLAGS@
|
||||
NSPR_LIBS = @NSPR_LIBS@
|
||||
NSS_CFLAGS = @NSS_CFLAGS@
|
||||
NSS_LIBS = @NSS_LIBS@
|
||||
NUM_VERSION = @NUM_VERSION@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
ODS_GROUP = @ODS_GROUP@
|
||||
ODS_USER = @ODS_USER@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
@@ -338,8 +339,6 @@ POPT_LIBS = @POPT_LIBS@
|
||||
POSUB = @POSUB@
|
||||
PYLINT = @PYLINT@
|
||||
PYTHON = @PYTHON@
|
||||
PYTHON2 = @PYTHON2@
|
||||
PYTHON3 = @PYTHON3@
|
||||
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
|
||||
PYTHON_INSTALL_EXTRA_OPTIONS = @PYTHON_INSTALL_EXTRA_OPTIONS@
|
||||
PYTHON_PLATFORM = @PYTHON_PLATFORM@
|
||||
@@ -427,7 +426,9 @@ program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
pyexecdir = @pyexecdir@
|
||||
pythondir = @pythondir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
selinux_makefile = @selinux_makefile@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
@@ -455,7 +456,6 @@ AM_CPPFLAGS = \
|
||||
$(LDAP_CFLAGS) \
|
||||
$(KRB5_CFLAGS) \
|
||||
$(NSPR_CFLAGS) \
|
||||
$(NSS_CFLAGS) \
|
||||
$(WARN_CFLAGS) \
|
||||
$(NULL)
|
||||
|
||||
@@ -463,8 +463,6 @@ AM_LDFLAGS = \
|
||||
$(CRYPTO_LIBS) \
|
||||
$(KRB5_LIBS) \
|
||||
$(LDAP_LIBS) \
|
||||
$(NSPR_LIBS) \
|
||||
$(NSS_LIBS) \
|
||||
-avoid-version \
|
||||
-export-symbols-regex ^ipapwd_init$
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
||||
Slapi_Entry *config_entry = NULL;
|
||||
Slapi_Attr *a;
|
||||
Slapi_Value *v;
|
||||
Slapi_DN *sdn = NULL;
|
||||
BerElement *be = NULL;
|
||||
ber_tag_t tag, tvno;
|
||||
ber_int_t ttype;
|
||||
@@ -107,7 +108,9 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
||||
}
|
||||
|
||||
/* get the Realm Container entry */
|
||||
ret = ipapwd_getEntry(ipa_realm_dn, &realm_entry, NULL);
|
||||
sdn = slapi_sdn_new_dn_byval(ipa_realm_dn);
|
||||
ret = ipapwd_getEntry(sdn, &realm_entry, NULL);
|
||||
slapi_sdn_free(&sdn);
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
LOG_FATAL("No realm Entry?\n");
|
||||
goto free_and_error;
|
||||
@@ -212,7 +215,9 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
||||
slapi_entry_free(realm_entry);
|
||||
|
||||
/* get the Realm Container entry */
|
||||
ret = ipapwd_getEntry(ipa_pwd_config_dn, &config_entry, NULL);
|
||||
sdn = slapi_sdn_new_dn_byval(ipa_pwd_config_dn);
|
||||
ret = ipapwd_getEntry(sdn, &config_entry, NULL);
|
||||
slapi_sdn_free(&sdn);
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
LOG_FATAL("No config Entry? Impossible!\n");
|
||||
goto free_and_error;
|
||||
@@ -236,7 +241,9 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
||||
if (ipapwd_fips_enabled()) {
|
||||
LOG("FIPS mode is enabled, NT hashes are not allowed.\n");
|
||||
} else {
|
||||
ret = ipapwd_getEntry(ipa_etc_config_dn, &config_entry, NULL);
|
||||
sdn = slapi_sdn_new_dn_byval(ipa_etc_config_dn);
|
||||
ret = ipapwd_getEntry(sdn, &config_entry, NULL);
|
||||
slapi_sdn_free(&sdn);
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
LOG_FATAL("No config Entry?\n");
|
||||
goto free_and_error;
|
||||
@@ -286,8 +293,8 @@ free_and_error:
|
||||
* slapi_pblock_destroy(pb)
|
||||
*/
|
||||
static int pwd_get_values(const Slapi_Entry *ent, const char *attrname,
|
||||
Slapi_ValueSet** results, char** actual_type_name,
|
||||
int *buffer_flags)
|
||||
Slapi_ValueSet** results, char** actual_type_name,
|
||||
int *buffer_flags)
|
||||
{
|
||||
int flags=0;
|
||||
int type_name_disposition = 0;
|
||||
@@ -415,6 +422,7 @@ done:
|
||||
|
||||
int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
|
||||
int *is_root, int *is_krb, int *is_smb, int *is_ipant,
|
||||
int *is_memberof,
|
||||
char *attr, int acc)
|
||||
{
|
||||
Slapi_Value *sval;
|
||||
@@ -433,6 +441,10 @@ int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
|
||||
}
|
||||
}
|
||||
|
||||
/* Default to not setting memberof flag: only set it for non-Kerberos principals
|
||||
* when they have krbPrincipalAux but no krbPrincipalName */
|
||||
*is_memberof = 0;
|
||||
|
||||
/* Check if this is a krbPrincial and therefore needs us to generate other
|
||||
* hashes */
|
||||
sval = slapi_value_new_string("krbPrincipalAux");
|
||||
@@ -443,6 +455,24 @@ int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
|
||||
*is_krb = slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS, sval);
|
||||
slapi_value_free(&sval);
|
||||
|
||||
/* If entry has krbPrincipalAux object class but lacks krbPrincipalName and
|
||||
* memberOf attributes consider this not a Kerberos principal object. In
|
||||
* FreeIPA krbPrincipalAux allows to store krbPwdPolicyReference attribute
|
||||
* which is added by a CoS plugin configuration based on a memberOf
|
||||
* attribute value.
|
||||
* Note that slapi_entry_attr_find() returns 0 if attr exists, -1 for absence
|
||||
*/
|
||||
if (*is_krb) {
|
||||
Slapi_Attr *attr_prname = NULL;
|
||||
Slapi_Attr *attr_memberof = NULL;
|
||||
int has_prname = slapi_entry_attr_find(e, "krbPrincipalName", &attr_prname);
|
||||
int has_memberOf = slapi_entry_attr_find(e, "memberOf", &attr_memberof);
|
||||
if ((has_prname == -1) && (has_memberOf == 0)) {
|
||||
*is_memberof = 1;
|
||||
*is_krb = 0;
|
||||
}
|
||||
}
|
||||
|
||||
sval = slapi_value_new_string("sambaSamAccount");
|
||||
if (!sval) {
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
@@ -560,7 +590,7 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
|
||||
LOG_TRACE("No password policy, use defaults");
|
||||
}
|
||||
break;
|
||||
case IPA_CHANGETYPE_ADMIN:
|
||||
case IPA_CHANGETYPE_ADMIN:
|
||||
/* The expiration date needs to be older than the current time
|
||||
* otherwise the KDC may not immediately register the password
|
||||
* as expired. The last password change needs to match the
|
||||
@@ -636,25 +666,31 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
|
||||
}
|
||||
|
||||
/* Searches the dn in directory,
|
||||
* If found : fills in slapi_entry structure and returns 0
|
||||
* If found : fills in slapi_entry structure and returns 0
|
||||
* If NOT found : returns the search result as LDAP_NO_SUCH_OBJECT
|
||||
*/
|
||||
int ipapwd_getEntry(const char *dn, Slapi_Entry **e2, char **attrlist)
|
||||
int ipapwd_getEntry(Slapi_DN *sdn, Slapi_Entry **e2, char **attrlist)
|
||||
{
|
||||
Slapi_DN *sdn;
|
||||
int search_result = 0;
|
||||
Slapi_DN *local_sdn = NULL;
|
||||
|
||||
LOG_TRACE("=>\n");
|
||||
|
||||
sdn = slapi_sdn_new_dn_byref(dn);
|
||||
search_result = slapi_search_internal_get_entry(sdn, attrlist, e2,
|
||||
ipapwd_plugin_id);
|
||||
if (search_result != LDAP_SUCCESS) {
|
||||
LOG_TRACE("No such entry-(%s), err (%d)\n", dn, search_result);
|
||||
if (sdn == NULL) {
|
||||
LOG_TRACE("No entry to fetch!\n");
|
||||
return LDAP_PARAM_ERROR;
|
||||
}
|
||||
|
||||
local_sdn = slapi_sdn_dup(sdn);
|
||||
search_result = slapi_search_internal_get_entry(local_sdn, attrlist, e2,
|
||||
ipapwd_plugin_id);
|
||||
if (search_result != LDAP_SUCCESS) {
|
||||
LOG_TRACE("No such entry-(%s), err (%d)\n",
|
||||
slapi_sdn_get_dn(sdn), search_result);
|
||||
}
|
||||
|
||||
slapi_sdn_free(&sdn);
|
||||
LOG_TRACE("<= result: %d\n", search_result);
|
||||
slapi_sdn_free(&local_sdn);
|
||||
return search_result;
|
||||
}
|
||||
|
||||
@@ -795,22 +831,21 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
|
||||
slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE,
|
||||
"krbPrincipalKey", svals);
|
||||
|
||||
/* krbLastPwdChange is used to tell whether a host entry has a
|
||||
* keytab so don't set it on hosts.
|
||||
*/
|
||||
/* krbLastPwdChange is used to tell whether a host entry has a
|
||||
* keytab so don't set it on hosts. */
|
||||
if (!is_host) {
|
||||
/* change Last Password Change field with the current date */
|
||||
/* change Last Password Change field with the current date */
|
||||
ret = ipapwd_setdate(data->target, smods, "krbLastPwdChange",
|
||||
data->timeNow, false);
|
||||
if (ret != LDAP_SUCCESS)
|
||||
goto free_and_return;
|
||||
|
||||
/* set Password Expiration date */
|
||||
/* set Password Expiration date */
|
||||
ret = ipapwd_setdate(data->target, smods, "krbPasswordExpiration",
|
||||
data->expireTime, (data->expireTime == 0));
|
||||
if (ret != LDAP_SUCCESS)
|
||||
goto free_and_return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nt && is_smb) {
|
||||
@@ -853,8 +888,8 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
|
||||
slapi_mods_add_string(smods, LDAP_MOD_REPLACE,
|
||||
"userPassword", data->password);
|
||||
|
||||
/* set password history */
|
||||
if (data->policy.history_length > 0) {
|
||||
/* set password history if a Kerberos object */
|
||||
if (data->policy.history_length > 0 && is_krb) {
|
||||
pwvals = ipapwd_setPasswordHistory(smods, data);
|
||||
if (pwvals) {
|
||||
slapi_mods_add_mod_values(smods, LDAP_MOD_REPLACE,
|
||||
@@ -1052,3 +1087,12 @@ void free_ipapwd_krbcfg(struct ipapwd_krbcfg **cfg)
|
||||
*cfg = NULL;
|
||||
};
|
||||
|
||||
int ipapwd_check_max_pwd_len(size_t len, char **errMesg) {
|
||||
if (len > IPAPWD_PASSWORD_MAX_LEN) {
|
||||
LOG("%s\n", ipapwd_password_max_len_errmsg);
|
||||
*errMesg = ipapwd_password_max_len_errmsg;
|
||||
return LDAP_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,8 @@ void *ipapwd_get_plugin_id(void)
|
||||
}
|
||||
|
||||
static void filter_keys(struct ipapwd_krbcfg *krbcfg,
|
||||
struct ipapwd_keyset *kset)
|
||||
struct ipapwd_keyset *kset,
|
||||
bool allow_nthash)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
@@ -108,6 +109,14 @@ static void filter_keys(struct ipapwd_krbcfg *krbcfg,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if requested by the caller, allow arcfour-hmac even
|
||||
* if it is missing in the list of supported enctypes. */
|
||||
if (allow_nthash &&
|
||||
(ENCTYPE_ARCFOUR_HMAC == kset->keys[i].key_data_type[0])) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (j == krbcfg->num_supp_encsalts) { /* not valid */
|
||||
|
||||
/* free key */
|
||||
@@ -130,7 +139,8 @@ static void filter_keys(struct ipapwd_krbcfg *krbcfg,
|
||||
|
||||
static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
|
||||
krb5_key_salt_tuple *kenctypes,
|
||||
int *num_kenctypes)
|
||||
int *num_kenctypes,
|
||||
bool allow_nthash)
|
||||
{
|
||||
/* first filter for duplicates */
|
||||
for (int i = 0; i + 1 < *num_kenctypes; i++) {
|
||||
@@ -158,6 +168,12 @@ static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* if requested by the caller, allow arcfour-hmac even
|
||||
* if it is missing in the list of supported enctypes. */
|
||||
if (allow_nthash &&
|
||||
(ENCTYPE_ARCFOUR_HMAC == kenctypes[i].ks_enctype)) {
|
||||
break;
|
||||
}
|
||||
if (j == krbcfg->num_supp_encsalts) {
|
||||
/* Unsupported, filter out */
|
||||
for (int k = i; k + 1 < *num_kenctypes; k++) {
|
||||
@@ -206,7 +222,7 @@ static int ipapwd_chpwop(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
|
||||
Slapi_Value *objectclass=NULL;
|
||||
char *attrlist[] = {"*", "passwordHistory", NULL };
|
||||
struct ipapwd_data pwdata;
|
||||
int is_krb, is_smb, is_ipant;
|
||||
int is_krb, is_smb, is_ipant, is_memberof;
|
||||
char *principal = NULL;
|
||||
Slapi_PBlock *chpwop_pb = NULL;
|
||||
Slapi_DN *target_sdn = NULL;
|
||||
@@ -318,6 +334,11 @@ parse_req_done:
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
rc = ipapwd_check_max_pwd_len(strlen(newPasswd), &errMesg);
|
||||
if (rc) {
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
if (oldPasswd == NULL || *oldPasswd == '\0') {
|
||||
/* If user is authenticated, they already gave their password during
|
||||
the bind operation (or used sasl or client cert auth or OS creds) */
|
||||
@@ -332,7 +353,7 @@ parse_req_done:
|
||||
/* Determine the target DN for this operation */
|
||||
slapi_pblock_get(pb, SLAPI_TARGET_SDN, &target_sdn);
|
||||
if (target_sdn != NULL) {
|
||||
/* If there is a TARGET_DN we are consuming it */
|
||||
/* If there is a TARGET_SDN we are consuming it */
|
||||
slapi_pblock_set(pb, SLAPI_TARGET_SDN, NULL);
|
||||
target_dn = slapi_sdn_get_ndn(target_sdn);
|
||||
}
|
||||
@@ -356,11 +377,11 @@ parse_req_done:
|
||||
}
|
||||
slapi_sdn_free(&target_sdn);
|
||||
|
||||
if (slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET, dn )) {
|
||||
LOG_FATAL("slapi_pblock_set failed!\n");
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
goto free_and_return;
|
||||
}
|
||||
if (slapi_pblock_set( pb, SLAPI_ORIGINAL_TARGET, dn )) {
|
||||
LOG_FATAL("slapi_pblock_set failed!\n");
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
if (usetxn) {
|
||||
Slapi_DN *sdn = slapi_sdn_new_dn_byref(dn);
|
||||
@@ -382,15 +403,18 @@ parse_req_done:
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we have the DN, look for the entry */
|
||||
ret = ipapwd_getEntry(dn, &targetEntry, attrlist);
|
||||
/* If we can't find the entry, then that's an error */
|
||||
if (ret) {
|
||||
/* Couldn't find the entry, fail */
|
||||
errMesg = "No such Entry exists.\n" ;
|
||||
rc = LDAP_NO_SUCH_OBJECT;
|
||||
goto free_and_return;
|
||||
}
|
||||
/* Now we have the DN, look for the entry */
|
||||
target_sdn = slapi_sdn_new_dn_byval(dn);
|
||||
ret = ipapwd_getEntry(target_sdn, &targetEntry, attrlist);
|
||||
slapi_sdn_free(&target_sdn);
|
||||
|
||||
/* If we can't find the entry, then that's an error */
|
||||
if (ret) {
|
||||
/* Couldn't find the entry, fail */
|
||||
errMesg = "No such Entry exists.\n" ;
|
||||
rc = LDAP_NO_SUCH_OBJECT;
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
if (dn) {
|
||||
Slapi_DN *bind_sdn;
|
||||
@@ -466,6 +490,7 @@ parse_req_done:
|
||||
|
||||
rc = ipapwd_entry_checks(pb, targetEntry,
|
||||
&is_root, &is_krb, &is_smb, &is_ipant,
|
||||
&is_memberof,
|
||||
SLAPI_USERPWD_ATTR, SLAPI_ACL_WRITE);
|
||||
if (rc) {
|
||||
goto free_and_return;
|
||||
@@ -561,16 +586,21 @@ parse_req_done:
|
||||
/* check the policy */
|
||||
ret = ipapwd_CheckPolicy(&pwdata);
|
||||
if (ret) {
|
||||
errMesg = ipapwd_error2string(ret);
|
||||
if (ret == IPAPWD_POLICY_ERROR) {
|
||||
errMesg = "Internal error";
|
||||
rc = ret;
|
||||
} else {
|
||||
goto free_and_return;
|
||||
}
|
||||
/* ipapwd_CheckPolicy happily will try to apply a policy
|
||||
* even if it doesn't need to be applied for Directory Manager
|
||||
* or passsync managers, filter that error out */
|
||||
if (pwdata.changetype != IPA_CHANGETYPE_DSMGR) {
|
||||
errMesg = ipapwd_error2string(ret);
|
||||
ret = ipapwd_to_ldap_pwpolicy_error(ret);
|
||||
slapi_pwpolicy_make_response_control(pb, -1, -1, ret);
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
goto free_and_return;
|
||||
}
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
/* Now we're ready to set the kerberos key material */
|
||||
@@ -1198,6 +1228,7 @@ static int ipapwd_setkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
|
||||
int kvno;
|
||||
char *svcname;
|
||||
bool allowed_access = false;
|
||||
bool is_nthash_allowed = false;
|
||||
struct berval *bvp = NULL;
|
||||
LDAPControl new_ctrl;
|
||||
|
||||
@@ -1270,7 +1301,12 @@ static int ipapwd_setkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
|
||||
for (int i = 0; i < kset->num_keys; i++) {
|
||||
kset->keys[i].key_data_kvno = kvno;
|
||||
}
|
||||
filter_keys(krbcfg, kset);
|
||||
|
||||
/* Only allow generating arcfour-hmac keys for cifs/.. services
|
||||
* unless the enctype is allowed by the IPA configuration for use
|
||||
* by the all principals */
|
||||
is_nthash_allowed = (0 == strncmp("cifs/", serviceName, 5));
|
||||
filter_keys(krbcfg, kset, is_nthash_allowed);
|
||||
|
||||
/* check if we have any left */
|
||||
if (kset->num_keys == 0) {
|
||||
@@ -1579,6 +1615,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
|
||||
struct berval *bvp = NULL;
|
||||
LDAPControl new_ctrl;
|
||||
bool wantold = false;
|
||||
bool is_nthash_allowed = false;
|
||||
|
||||
/* Get Bind DN */
|
||||
slapi_pblock_get(pb, SLAPI_CONN_DN, &bind_dn);
|
||||
@@ -1652,6 +1689,14 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
|
||||
|
||||
} else {
|
||||
|
||||
if (password != NULL) {
|
||||
/* if password was passed-in, check its length */
|
||||
rc = ipapwd_check_max_pwd_len(strlen(password), &err_msg);
|
||||
if (rc) {
|
||||
goto free_and_return;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if we are allowed to *write* keys */
|
||||
acl_ok = is_allowed_to_access_attr(pb, bind_dn, target_entry,
|
||||
WRITEKEYS_OP_CHECK, NULL,
|
||||
@@ -1664,7 +1709,11 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
|
||||
goto free_and_return;
|
||||
}
|
||||
|
||||
filter_enctypes(krbcfg, kenctypes, &num_kenctypes);
|
||||
/* Only allow generating arcfour-hmac keys for cifs/.. services
|
||||
* unless the enctype is allowed by the IPA configuration for use
|
||||
* by the all principals */
|
||||
is_nthash_allowed = (0 == strncmp("cifs/", service_name, 5));
|
||||
filter_enctypes(krbcfg, kenctypes, &num_kenctypes, is_nthash_allowed);
|
||||
|
||||
/* check if we have any left */
|
||||
if (num_kenctypes == 0 && kenctypes != NULL) {
|
||||
@@ -1821,7 +1870,7 @@ static int ipapwd_start( Slapi_PBlock *pb )
|
||||
krb5_context krbctx = NULL;
|
||||
krb5_error_code krberr;
|
||||
char *realm = NULL;
|
||||
char *config_dn;
|
||||
Slapi_DN *config_sdn = NULL;
|
||||
Slapi_Entry *config_entry = NULL;
|
||||
int ret;
|
||||
|
||||
@@ -1834,13 +1883,13 @@ static int ipapwd_start( Slapi_PBlock *pb )
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
if (slapi_pblock_get(pb, SLAPI_TARGET_DN, &config_dn) != 0) {
|
||||
if (slapi_pblock_get(pb, SLAPI_TARGET_SDN, &config_sdn) != 0) {
|
||||
LOG_FATAL("No config DN?\n");
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ipapwd_getEntry(config_dn, &config_entry, NULL) != LDAP_SUCCESS) {
|
||||
if (ipapwd_getEntry(config_sdn, &config_entry, NULL) != LDAP_SUCCESS) {
|
||||
LOG_FATAL("No config Entry extop?\n");
|
||||
ret = LDAP_SUCCESS;
|
||||
goto done;
|
||||
@@ -1869,7 +1918,7 @@ static int ipapwd_start( Slapi_PBlock *pb )
|
||||
goto done;
|
||||
}
|
||||
|
||||
ipa_pwd_config_dn = slapi_ch_strdup(config_dn);
|
||||
ipa_pwd_config_dn = slapi_ch_strdup(slapi_sdn_get_dn(config_sdn));
|
||||
if (!ipa_pwd_config_dn) {
|
||||
LOG_OOM();
|
||||
ret = LDAP_OPERATIONS_ERROR;
|
||||
|
||||
@@ -51,7 +51,6 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include <prio.h>
|
||||
#include <ssl.h>
|
||||
#include <krb5.h>
|
||||
#include <kdb.h>
|
||||
#include <lber.h>
|
||||
@@ -90,6 +89,7 @@ struct ipapwd_operation {
|
||||
struct ipapwd_data pwdata;
|
||||
int pwd_op;
|
||||
int is_krb;
|
||||
int is_memberof;
|
||||
int skip_keys;
|
||||
int skip_history;
|
||||
};
|
||||
@@ -113,11 +113,12 @@ struct ipapwd_krbcfg {
|
||||
|
||||
int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
|
||||
int *is_root, int *is_krb, int *is_smb, int *is_ipant,
|
||||
int *is_memberof,
|
||||
char *attr, int access);
|
||||
int ipapwd_gen_checks(Slapi_PBlock *pb, char **errMesg,
|
||||
struct ipapwd_krbcfg **config, int check_flags);
|
||||
int ipapwd_CheckPolicy(struct ipapwd_data *data);
|
||||
int ipapwd_getEntry(const char *dn, Slapi_Entry **e2, char **attrlist);
|
||||
int ipapwd_getEntry(Slapi_DN *sdn, Slapi_Entry **e2, char **attrlist);
|
||||
int ipapwd_get_cur_kvno(Slapi_Entry *target);
|
||||
int ipapwd_setdate(Slapi_Entry *source, Slapi_Mods *smods, const char *attr,
|
||||
time_t date, bool remove);
|
||||
@@ -131,6 +132,7 @@ int ipapwd_set_extradata(const char *dn,
|
||||
time_t unixtime);
|
||||
void ipapwd_free_slapi_value_array(Slapi_Value ***svals);
|
||||
void free_ipapwd_krbcfg(struct ipapwd_krbcfg **cfg);
|
||||
int ipapwd_check_max_pwd_len(size_t len, char **errMesg);
|
||||
|
||||
/* from encoding.c */
|
||||
struct ipapwd_keyset {
|
||||
|
||||
@@ -80,6 +80,8 @@ struct ipapwd_op_ext {
|
||||
int object_type; /* handle to the extended object */
|
||||
int handle; /* extension handle */
|
||||
};
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* pre/post operations to intercept writes to userPassword
|
||||
****************************************************************************/
|
||||
@@ -129,6 +131,7 @@ static char *ipapwd_getIpaConfigAttr(const char *attr)
|
||||
const char *attrs_list[] = {attr, 0};
|
||||
char *value = NULL;
|
||||
char *dn = NULL;
|
||||
Slapi_DN *sdn = NULL;
|
||||
int ret;
|
||||
|
||||
dn = slapi_ch_smprintf("cn=ipaconfig,cn=etc,%s", ipa_realm_tree);
|
||||
@@ -137,9 +140,12 @@ static char *ipapwd_getIpaConfigAttr(const char *attr)
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = ipapwd_getEntry(dn, &entry, (char **) attrs_list);
|
||||
/* _byref() will take ownership of the dn */
|
||||
sdn = slapi_sdn_new_dn_byref(dn);
|
||||
|
||||
ret = ipapwd_getEntry(sdn, &entry, (char **) attrs_list);
|
||||
if (ret) {
|
||||
LOG("failed to retrieve config entry: %s\n", dn);
|
||||
LOG("failed to retrieve config entry: %s\n", slapi_sdn_get_dn(sdn));
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -147,7 +153,7 @@ static char *ipapwd_getIpaConfigAttr(const char *attr)
|
||||
|
||||
done:
|
||||
slapi_entry_free(entry);
|
||||
slapi_ch_free_string(&dn);
|
||||
slapi_sdn_free(&sdn);
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -210,10 +216,10 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
char *errMesg = "Internal operations error\n";
|
||||
struct slapi_entry *e = NULL;
|
||||
char *userpw = NULL;
|
||||
char *dn = NULL;
|
||||
Slapi_DN *sdn = NULL;
|
||||
struct ipapwd_operation *pwdop = NULL;
|
||||
void *op;
|
||||
int is_repl_op, is_root, is_krb, is_smb, is_ipant;
|
||||
int is_repl_op, is_root, is_krb, is_smb, is_ipant, is_memberof;
|
||||
int ret;
|
||||
int rc = LDAP_SUCCESS;
|
||||
|
||||
@@ -238,8 +244,8 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
/* check this is something interesting for us first */
|
||||
userpw = slapi_entry_attr_get_charptr(e, SLAPI_USERPWD_ATTR);
|
||||
if (!userpw) {
|
||||
/* nothing interesting here */
|
||||
return 0;
|
||||
/* nothing interesting here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ok this is interesting,
|
||||
@@ -272,6 +278,10 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
slapi_ch_free_string(&userpw);
|
||||
} else {
|
||||
rc = ipapwd_check_max_pwd_len(strlen(userpw_clear), &errMesg);
|
||||
if (rc) {
|
||||
goto done;
|
||||
}
|
||||
userpw = slapi_ch_strdup(userpw_clear);
|
||||
}
|
||||
|
||||
@@ -292,8 +302,10 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
* a valid krbPrincipalKey
|
||||
*/
|
||||
if (has_krbprincipalkey(e)) {
|
||||
slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn);
|
||||
LOG("User Life Cycle: %s is a activated stage user (with prehashed password and krb keys)\n", dn ? dn : "unknown");
|
||||
slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
|
||||
LOG("User Life Cycle: %s is a activated stage user "
|
||||
"(with prehashed password and krb keys)\n",
|
||||
sdn ? slapi_sdn_get_dn(sdn) : "unknown");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -306,6 +318,7 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
|
||||
rc = ipapwd_entry_checks(pb, e,
|
||||
&is_root, &is_krb, &is_smb, &is_ipant,
|
||||
&is_memberof,
|
||||
NULL, SLAPI_ACL_ADD);
|
||||
if (rc != LDAP_SUCCESS) {
|
||||
goto done;
|
||||
@@ -317,7 +330,7 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
}
|
||||
|
||||
/* Get target DN */
|
||||
ret = slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn);
|
||||
ret = slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
|
||||
if (ret) {
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
@@ -340,6 +353,7 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
|
||||
pwdop->pwd_op = IPAPWD_OP_ADD;
|
||||
pwdop->pwdata.password = slapi_ch_strdup(userpw);
|
||||
pwdop->is_memberof = is_memberof;
|
||||
|
||||
if (is_root) {
|
||||
pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR;
|
||||
@@ -361,12 +375,15 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
|
||||
}
|
||||
}
|
||||
|
||||
pwdop->pwdata.dn = slapi_ch_strdup(dn);
|
||||
pwdop->pwdata.dn = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
|
||||
pwdop->pwdata.timeNow = time(NULL);
|
||||
pwdop->pwdata.target = e;
|
||||
|
||||
ret = ipapwd_CheckPolicy(&pwdop->pwdata);
|
||||
if (ret) {
|
||||
/* For accounts created by cn=Directory Manager or a passsync
|
||||
* managers, ignore result of a policy check */
|
||||
if ((pwdop->pwdata.changetype != IPA_CHANGETYPE_DSMGR) &&
|
||||
(ret != 0) ) {
|
||||
errMesg = ipapwd_error2string(ret);
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
goto done;
|
||||
@@ -441,7 +458,7 @@ done:
|
||||
#define NTHASH_REGEN_VAL "MagicRegen"
|
||||
#define NTHASH_REGEN_LEN sizeof(NTHASH_REGEN_VAL)
|
||||
static int ipapwd_regen_nthash(Slapi_PBlock *pb, Slapi_Mods *smods,
|
||||
char *dn, struct slapi_entry *entry,
|
||||
const char *dn, struct slapi_entry *entry,
|
||||
struct ipapwd_krbcfg *krbcfg);
|
||||
|
||||
/* PRE MOD Operation:
|
||||
@@ -463,12 +480,12 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
Slapi_Mods *smods = NULL;
|
||||
char *userpw = NULL;
|
||||
char *unhashedpw = NULL;
|
||||
char *dn = NULL;
|
||||
Slapi_DN *tmp_dn;
|
||||
Slapi_DN *sdn = NULL;
|
||||
Slapi_DN *tmp_sdn;
|
||||
struct slapi_entry *e = NULL;
|
||||
struct ipapwd_operation *pwdop = NULL;
|
||||
void *op;
|
||||
int is_repl_op, is_pwd_op, is_root, is_krb, is_smb, is_ipant;
|
||||
int is_repl_op, is_pwd_op, is_root, is_krb, is_smb, is_ipant, is_memberof;
|
||||
int has_krb_keys = 0;
|
||||
int has_history = 0;
|
||||
int gen_krb_keys = 0;
|
||||
@@ -517,6 +534,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
/* check op filtering out LDAP_MOD_BVALUES */
|
||||
switch (lmod->mod_op & 0x0f) {
|
||||
case LDAP_MOD_ADD:
|
||||
case LDAP_MOD_REPLACE:
|
||||
if (!lmod->mod_bvalues ||
|
||||
!lmod->mod_bvalues[0]) {
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
@@ -528,8 +546,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
(strncmp(NTHASH_REGEN_VAL,
|
||||
bv->bv_val, bv->bv_len) == 0)) {
|
||||
is_magic_regen = 1;
|
||||
/* make sure the database will later ignore this mod */
|
||||
slapi_mods_remove(smods);
|
||||
/* We do not remove the mod from the list due to
|
||||
* https://pagure.io/389-ds-base/issue/387#comment-120145 */
|
||||
}
|
||||
default:
|
||||
break;
|
||||
@@ -547,6 +565,11 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
goto done;
|
||||
}
|
||||
bv = lmod->mod_bvalues[0];
|
||||
|
||||
rc = ipapwd_check_max_pwd_len(bv->bv_len, &errMesg);
|
||||
if (rc) {
|
||||
goto done;
|
||||
}
|
||||
slapi_ch_free_string(&unhashedpw);
|
||||
unhashedpw = slapi_ch_malloc(bv->bv_len+1);
|
||||
if (!unhashedpw) {
|
||||
@@ -570,14 +593,14 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
* pre-requisites */
|
||||
|
||||
/* Get target DN */
|
||||
ret = slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn);
|
||||
ret = slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
|
||||
if (ret) {
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
tmp_dn = slapi_sdn_new_dn_byref(dn);
|
||||
if (tmp_dn) {
|
||||
tmp_sdn = slapi_sdn_dup(sdn);
|
||||
if (tmp_sdn) {
|
||||
/* xxxPAR: Ideally SLAPI_MODIFY_EXISTING_ENTRY should be
|
||||
* available but it turns out that is only true if you are
|
||||
* a dbm backend pre-op plugin - lucky dbm backend pre-op
|
||||
@@ -589,8 +612,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
*
|
||||
slapi_pblock_get( pb, SLAPI_MODIFY_EXISTING_ENTRY, &e);
|
||||
*/
|
||||
ret = slapi_search_internal_get_entry(tmp_dn, 0, &e, ipapwd_plugin_id);
|
||||
slapi_sdn_free(&tmp_dn);
|
||||
ret = slapi_search_internal_get_entry(tmp_sdn, 0, &e, ipapwd_plugin_id);
|
||||
slapi_sdn_free(&tmp_sdn);
|
||||
if (ret != LDAP_SUCCESS) {
|
||||
LOG("Failed to retrieve entry?!\n");
|
||||
rc = LDAP_NO_SUCH_OBJECT;
|
||||
@@ -600,6 +623,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
|
||||
rc = ipapwd_entry_checks(pb, e,
|
||||
&is_root, &is_krb, &is_smb, &is_ipant,
|
||||
&is_memberof,
|
||||
is_pwd_op ? SLAPI_USERPWD_ATTR : "ipaNTHash",
|
||||
SLAPI_ACL_WRITE);
|
||||
if (rc) {
|
||||
@@ -617,7 +641,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
/* Make sense to call only if this entry has krb keys to source
|
||||
* the nthash from */
|
||||
if (is_krb) {
|
||||
rc = ipapwd_regen_nthash(pb, smods, dn, e, krbcfg);
|
||||
rc = ipapwd_regen_nthash(pb, smods, slapi_sdn_get_dn(sdn), e, krbcfg);
|
||||
} else {
|
||||
rc = LDAP_UNWILLING_TO_PERFORM;
|
||||
}
|
||||
@@ -768,7 +792,12 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
if (! unhashedpw && (gen_krb_keys || is_smb || is_ipant)) {
|
||||
if ((userpw != NULL) && ('{' == userpw[0])) {
|
||||
if (0 == strncasecmp(userpw, "{CLEAR}", strlen("{CLEAR}"))) {
|
||||
unhashedpw = slapi_ch_strdup(&userpw[strlen("{CLEAR}")]);
|
||||
const char *userpw_clear = &userpw[strlen("{CLEAR}")];
|
||||
rc = ipapwd_check_max_pwd_len(strlen(userpw_clear), &errMesg);
|
||||
if (rc) {
|
||||
goto done;
|
||||
}
|
||||
unhashedpw = slapi_ch_strdup(userpw_clear);
|
||||
if (NULL == unhashedpw) {
|
||||
LOG_OOM();
|
||||
rc = LDAP_OPERATIONS_ERROR;
|
||||
@@ -802,6 +831,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
}
|
||||
|
||||
pwdop->is_krb = is_krb;
|
||||
pwdop->is_memberof = is_memberof;
|
||||
pwdop->pwd_op = IPAPWD_OP_MOD;
|
||||
pwdop->pwdata.password = slapi_ch_strdup(unhashedpw);
|
||||
pwdop->pwdata.changetype = IPA_CHANGETYPE_NORMAL;
|
||||
@@ -818,7 +848,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
/* Check Bind DN */
|
||||
slapi_pblock_get(pb, SLAPI_CONN_DN, &binddn);
|
||||
bdn = slapi_sdn_new_dn_byref(binddn);
|
||||
tdn = slapi_sdn_new_dn_byref(dn);
|
||||
tdn = slapi_sdn_dup(sdn);
|
||||
|
||||
/* if the change is performed by someone else,
|
||||
* it is an admin change that will require a new
|
||||
@@ -841,16 +871,18 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
|
||||
|
||||
}
|
||||
|
||||
pwdop->pwdata.dn = slapi_ch_strdup(dn);
|
||||
pwdop->pwdata.dn = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
|
||||
pwdop->pwdata.timeNow = time(NULL);
|
||||
pwdop->pwdata.target = e;
|
||||
|
||||
/* if krb keys are being set by an external agent we assume password
|
||||
* policies have been properly checked already, so we check them only
|
||||
* if no krb keys are available */
|
||||
* policies have been properly checked already. We check them only if no
|
||||
* krb keys are available and raise error if the change is not done by a
|
||||
* cn=Directory Manager or one of passsync managers */
|
||||
if (has_krb_keys == 0) {
|
||||
ret = ipapwd_CheckPolicy(&pwdop->pwdata);
|
||||
if (ret) {
|
||||
if ((pwdop->pwdata.changetype != IPA_CHANGETYPE_DSMGR) &&
|
||||
(ret != 0)) {
|
||||
errMesg = ipapwd_error2string(ret);
|
||||
rc = LDAP_CONSTRAINT_VIOLATION;
|
||||
goto done;
|
||||
@@ -932,7 +964,7 @@ done:
|
||||
}
|
||||
|
||||
static int ipapwd_regen_nthash(Slapi_PBlock *pb, Slapi_Mods *smods,
|
||||
char *dn, struct slapi_entry *entry,
|
||||
const char *dn, struct slapi_entry *entry,
|
||||
struct ipapwd_krbcfg *krbcfg)
|
||||
{
|
||||
Slapi_Attr *attr;
|
||||
@@ -1009,7 +1041,9 @@ static int ipapwd_regen_nthash(Slapi_PBlock *pb, Slapi_Mods *smods,
|
||||
bval.bv_len = 16;
|
||||
ntvals[0] = &bval;
|
||||
|
||||
slapi_mods_add_modbvps(smods, LDAP_MOD_ADD, "ipaNTHash", ntvals);
|
||||
/* add the change as a replace operation due to
|
||||
* https://pagure.io/389-ds-base/issue/387#comment-120145 */
|
||||
slapi_mods_add_modbvps(smods, LDAP_MOD_REPLACE, "ipaNTHash", ntvals);
|
||||
|
||||
ret = LDAP_SUCCESS;
|
||||
break;
|
||||
@@ -1060,7 +1094,7 @@ static int ipapwd_post_modadd(Slapi_PBlock *pb)
|
||||
if (IPAPWD_OP_NULL == pwdop->pwd_op)
|
||||
return 0;
|
||||
|
||||
if ( ! (pwdop->is_krb)) {
|
||||
if ( !pwdop->is_krb || pwdop->is_memberof) {
|
||||
LOG("Not a kerberos user, ignore krb attributes\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -1331,7 +1365,7 @@ static void ipapwd_write_krb_keys(Slapi_PBlock *pb, char *dn,
|
||||
if (expire) {
|
||||
memset(&expire_tm, 0, sizeof (expire_tm));
|
||||
if (strptime(expire, "%Y%m%d%H%M%SZ", &expire_tm))
|
||||
pwdata.expireTime = mktime(&expire_tm);
|
||||
pwdata.expireTime = timegm(&expire_tm);
|
||||
}
|
||||
|
||||
/* check password policy */
|
||||
@@ -1388,7 +1422,9 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
|
||||
};
|
||||
struct berval *credentials = NULL;
|
||||
Slapi_Entry *entry = NULL;
|
||||
char *dn = NULL;
|
||||
Slapi_DN *target_sdn = NULL;
|
||||
Slapi_DN *sdn = NULL;
|
||||
const char *dn = NULL;
|
||||
int method = 0;
|
||||
bool syncreq;
|
||||
bool otpreq;
|
||||
@@ -1397,9 +1433,11 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
|
||||
time_t expire_time;
|
||||
char *principal_expire = NULL;
|
||||
struct tm expire_tm;
|
||||
int rc = LDAP_INVALID_CREDENTIALS;
|
||||
char *errMesg = NULL;
|
||||
|
||||
/* get BIND parameters */
|
||||
ret |= slapi_pblock_get(pb, SLAPI_BIND_TARGET, &dn);
|
||||
ret |= slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &target_sdn);
|
||||
ret |= slapi_pblock_get(pb, SLAPI_BIND_METHOD, &method);
|
||||
ret |= slapi_pblock_get(pb, SLAPI_BIND_CREDENTIALS, &credentials);
|
||||
if (ret) {
|
||||
@@ -1412,9 +1450,12 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
|
||||
return 0;
|
||||
|
||||
/* Retrieve the user's entry. */
|
||||
ret = ipapwd_getEntry(dn, &entry, (char **) attrs_list);
|
||||
sdn = slapi_sdn_dup(target_sdn);
|
||||
dn = slapi_sdn_get_dn(sdn);
|
||||
ret = ipapwd_getEntry(sdn, &entry, (char **) attrs_list);
|
||||
if (ret) {
|
||||
LOG("failed to retrieve user entry: %s\n", dn);
|
||||
slapi_sdn_free(&sdn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1426,10 +1467,10 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
|
||||
memset(&expire_tm, 0, sizeof (expire_tm));
|
||||
|
||||
if (strptime(principal_expire, "%Y%m%d%H%M%SZ", &expire_tm)) {
|
||||
expire_time = mktime(&expire_tm);
|
||||
expire_time = timegm(&expire_tm);
|
||||
current_time = time(NULL);
|
||||
|
||||
/* mktime returns -1 if the tm struct cannot be represented as
|
||||
/* timegm returns -1 if the tm struct cannot be represented as
|
||||
* as calendar time (seconds since the Epoch). This might
|
||||
* happen with tm structs that are ill-formated or on 32-bit
|
||||
* platforms with dates that would cause overflow
|
||||
@@ -1439,6 +1480,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
|
||||
if (current_time > expire_time && expire_time > 0) {
|
||||
LOG_FATAL("kerberos principal in %s is expired\n", dn);
|
||||
slapi_entry_free(entry);
|
||||
slapi_sdn_free(&sdn);
|
||||
slapi_send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL,
|
||||
"Account (Kerberos principal) is expired",
|
||||
0, NULL);
|
||||
@@ -1454,13 +1496,20 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
|
||||
goto invalid_creds;
|
||||
|
||||
/* Ensure that there is a password. */
|
||||
if (credentials->bv_len == 0)
|
||||
if (credentials->bv_len == 0) {
|
||||
goto invalid_creds;
|
||||
} else {
|
||||
rc = ipapwd_check_max_pwd_len(credentials->bv_len, &errMesg);
|
||||
if (rc) {
|
||||
goto invalid_creds;
|
||||
}
|
||||
}
|
||||
|
||||
/* Authenticate the user. */
|
||||
ret = ipapwd_authenticate(dn, entry, credentials);
|
||||
if (ret) {
|
||||
slapi_entry_free(entry);
|
||||
slapi_sdn_free(&sdn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1469,15 +1518,16 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
|
||||
goto invalid_creds;
|
||||
|
||||
/* Attempt to write out kerberos keys for the user. */
|
||||
ipapwd_write_krb_keys(pb, dn, entry, credentials);
|
||||
ipapwd_write_krb_keys(pb, discard_const(dn), entry, credentials);
|
||||
|
||||
slapi_entry_free(entry);
|
||||
slapi_sdn_free(&sdn);
|
||||
return 0;
|
||||
|
||||
invalid_creds:
|
||||
slapi_entry_free(entry);
|
||||
slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS,
|
||||
NULL, NULL, 0, NULL);
|
||||
slapi_sdn_free(&sdn);
|
||||
slapi_send_ldap_result(pb, rc, NULL, errMesg, 0, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user