Import Upstream version 4.12.4

This commit is contained in:
geos_one
2025-08-12 22:28:56 +02:00
parent 03a8170b15
commit 9181ee2487
1629 changed files with 874094 additions and 554378 deletions

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# Makefile.in generated by automake 1.17 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -71,6 +71,8 @@ am__make_running_with_option = \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
am__rm_f = rm -f $(am__rm_f_notfound)
am__rm_rf = rm -rf $(am__rm_f_notfound)
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -129,10 +131,9 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
}
am__installdirs = "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(appdir)"
LTLIBRARIES = $(plugin_LTLIBRARIES)
@@ -210,8 +211,6 @@ am__define_uniq_tagged_files = \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp README
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
@@ -233,6 +232,8 @@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CRYPTO_CFLAGS = @CRYPTO_CFLAGS@
CRYPTO_LIBS = @CRYPTO_LIBS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DATA_VERSION = @DATA_VERSION@
DEFS = @DEFS@
@@ -246,8 +247,10 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILECMD = @FILECMD@
GETTEXT_DOMAIN = @GETTEXT_DOMAIN@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GIT_BRANCH = @GIT_BRANCH@
@@ -255,6 +258,7 @@ GIT_VERSION = @GIT_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GREP = @GREP@
HTTPD_GROUP = @HTTPD_GROUP@
INI_CFLAGS = @INI_CFLAGS@
INI_LIBS = @INI_LIBS@
INSTALL = @INSTALL@
@@ -267,9 +271,12 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
IPAPLATFORM = @IPAPLATFORM@
IPA_DATA_DIR = @IPA_DATA_DIR@
IPA_SYSCONF_DIR = @IPA_SYSCONF_DIR@
JANSSON_CFLAGS = @JANSSON_CFLAGS@
JANSSON_LIBS = @JANSSON_LIBS@
JSLINT = @JSLINT@
KRAD_LIBS = @KRAD_LIBS@
KRB5KDC_SERVICE = @KRB5KDC_SERVICE@
KRB5_BUILD_VERSION = @KRB5_BUILD_VERSION@
KRB5_CFLAGS = @KRB5_CFLAGS@
KRB5_GSSAPI_CFLAGS = @KRB5_GSSAPI_CFLAGS@
KRB5_GSSAPI_LIBS = @KRB5_GSSAPI_LIBS@
@@ -278,6 +285,8 @@ LD = @LD@
LDAP_CFLAGS = @LDAP_CFLAGS@
LDAP_LIBS = @LDAP_LIBS@
LDFLAGS = @LDFLAGS@
LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
LIBCURL_LIBS = @LIBCURL_LIBS@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBINTL_LIBS = @LIBINTL_LIBS@
@@ -337,6 +346,8 @@ PLATFORM_PYTHON = @PLATFORM_PYTHON@
POPT_CFLAGS = @POPT_CFLAGS@
POPT_LIBS = @POPT_LIBS@
POSUB = @POSUB@
PWQUALITY_CFLAGS = @PWQUALITY_CFLAGS@
PWQUALITY_LIBS = @PWQUALITY_LIBS@
PYLINT = @PYLINT@
PYTHON = @PYTHON@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
@@ -345,9 +356,12 @@ PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
RESOLV_LIBS = @RESOLV_LIBS@
RPMLINT = @RPMLINT@
SAMBA40EXTRA_LIBPATH = @SAMBA40EXTRA_LIBPATH@
SAMBAUTIL_CFLAGS = @SAMBAUTIL_CFLAGS@
SAMBAUTIL_LIBS = @SAMBAUTIL_LIBS@
SAMBA_SECURITY_LIBS = @SAMBA_SECURITY_LIBS@
SASL_CFLAGS = @SASL_CFLAGS@
SASL_LIBS = @SASL_LIBS@
SED = @SED@
@@ -386,8 +400,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -433,6 +449,7 @@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
sysconfenvdir = @sysconfenvdir@
systemdcatalogdir = @systemdcatalogdir@
systemdsystemunitdir = @systemdsystemunitdir@
systemdtmpfilesdir = @systemdtmpfilesdir@
target_alias = @target_alias@
@@ -556,15 +573,13 @@ uninstall-pluginLTLIBRARIES:
done
clean-pluginLTLIBRARIES:
-test -z "$(plugin_LTLIBRARIES)" || rm -f $(plugin_LTLIBRARIES)
-$(am__rm_f) $(plugin_LTLIBRARIES)
@list='$(plugin_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
echo rm -f $${locs}; \
$(am__rm_f) $${locs}
libipa_pwd_extop.la: $(libipa_pwd_extop_la_OBJECTS) $(libipa_pwd_extop_la_DEPENDENCIES) $(EXTRA_libipa_pwd_extop_la_DEPENDENCIES)
$(AM_V_CCLD)$(LINK) -rpath $(plugindir) $(libipa_pwd_extop_la_OBJECTS) $(libipa_pwd_extop_la_LIBADD) $(LIBS)
@@ -583,7 +598,7 @@ distclean-compile:
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@echo '# dummy' >$@-t && $(am__mv) $@-t $@
@: >>$@
am--depfiles: $(am__depfiles_remade)
@@ -686,7 +701,6 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -751,8 +765,8 @@ mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -763,7 +777,7 @@ clean-am: clean-generic clean-libtool clean-pluginLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -f ./$(DEPDIR)/common.Plo
-rm -f ./$(DEPDIR)/common.Plo
-rm -f ./$(DEPDIR)/encoding.Plo
-rm -f ./$(DEPDIR)/ipa_pwd_extop.Plo
-rm -f ./$(DEPDIR)/otpctrl.Plo
@@ -813,7 +827,7 @@ install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/common.Plo
-rm -f ./$(DEPDIR)/common.Plo
-rm -f ./$(DEPDIR)/encoding.Plo
-rm -f ./$(DEPDIR)/ipa_pwd_extop.Plo
-rm -f ./$(DEPDIR)/otpctrl.Plo
@@ -860,3 +874,10 @@ uninstall-am: uninstall-appDATA uninstall-pluginLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%

View File

@@ -33,7 +33,7 @@
* Authors:
* Simo Sorce <ssorce@redhat.com>
*
* Copyright (C) 2007-2010 Red Hat, Inc.
* Copyright (C) 2007-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -81,7 +81,9 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
char **encsalts;
char **tmparray;
char *tmpstr;
int i, ret;
int ret;
size_t i;
bool fips_enabled = false;
config = calloc(1, sizeof(struct ipapwd_krbcfg));
if (!config) {
@@ -240,28 +242,35 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
config->allow_nt_hash = false;
if (ipapwd_fips_enabled()) {
LOG("FIPS mode is enabled, NT hashes are not allowed.\n");
fips_enabled = true;
}
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;
} else {
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;
} else {
tmparray = slapi_entry_attr_get_charray(config_entry,
"ipaConfigString");
for (i = 0; tmparray && tmparray[i]; i++) {
tmparray = slapi_entry_attr_get_charray(config_entry,
"ipaConfigString");
for (i = 0; tmparray && tmparray[i]; i++) {
if (strcasecmp(tmparray[i], "EnforceLDAPOTP") == 0) {
config->enforce_ldap_otp = true;
continue;
}
if (!fips_enabled) {
if (strcasecmp(tmparray[i], "AllowNThash") == 0) {
config->allow_nt_hash = true;
continue;
}
}
if (tmparray) slapi_ch_array_free(tmparray);
}
slapi_entry_free(config_entry);
if (tmparray) slapi_ch_array_free(tmparray);
}
slapi_entry_free(config_entry);
return config;
free_and_error:
@@ -322,10 +331,13 @@ int ipapwd_getPolicy(const char *dn,
Slapi_PBlock *pb = NULL;
char *attrs[] = { "krbMaxPwdLife", "krbMinPwdLife",
"krbPwdMinDiffChars", "krbPwdMinLength",
"krbPwdHistoryLength", NULL};
"krbPwdHistoryLength", "ipaPwdMaxRepeat",
"ipaPwdMaxSequence", "ipaPwdDictCheck",
"ipaPwdUserCheck", NULL};
Slapi_Entry **es = NULL;
Slapi_Entry *pe = NULL;
int ret, res, scope, i;
int ret, res, scope;
size_t i;
int buffer_flags=0;
Slapi_ValueSet* results = NULL;
char *actual_type_name = NULL;
@@ -402,6 +414,10 @@ int ipapwd_getPolicy(const char *dn,
policy->min_complexity = slapi_entry_attr_get_int(pe,
"krbPwdMinDiffChars");
policy->max_repeat = slapi_entry_attr_get_int(pe, "ipaPwdMaxRepeat");
policy->max_sequence = slapi_entry_attr_get_int(pe, "ipaPwdMaxSequence");
policy->dictcheck = slapi_entry_attr_get_bool(pe, "ipaPwdDictCheck");
policy->usercheck = slapi_entry_attr_get_bool(pe, "ipaPwdUserCheck");
ret = 0;
@@ -539,7 +555,7 @@ int ipapwd_gen_checks(Slapi_PBlock *pb, char **errMesg,
}
sdn = slapi_sdn_new_dn_byref(dn);
if (!sdn) {
LOG_FATAL("Unable to convert dn to sdn %s", dn ? dn : "<NULL>");
LOG_FATAL("Unable to convert dn to sdn %s\n", dn ? dn : "<NULL>");
*errMesg = "Internal Error";
rc = LDAP_OPERATIONS_ERROR;
goto done;
@@ -558,11 +574,18 @@ int ipapwd_gen_checks(Slapi_PBlock *pb, char **errMesg,
/* get the kerberos context and master key */
*config = ipapwd_getConfig();
if (NULL == *config) {
LOG_FATAL("Error Retrieving Master Key");
LOG_FATAL("Error Retrieving Master Key\n");
*errMesg = "Fatal Internal Error";
rc = LDAP_OPERATIONS_ERROR;
}
/* do not return the master key if asked */
if (check_flags & IPAPWD_CHECK_ONLY_CONFIG) {
free((*config)->kmkey->contents);
free((*config)->kmkey);
(*config)->kmkey = NULL;
}
done:
return rc;
}
@@ -576,6 +599,7 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
time_t pwd_expiration;
time_t last_pwd_change;
char **pwd_history;
char *uid;
char *tmpstr;
int ret;
@@ -587,7 +611,7 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
/* Find the entry with the password policy */
ret = ipapwd_getPolicy(data->dn, data->target, &pol);
if (ret) {
LOG_TRACE("No password policy, use defaults");
LOG_TRACE("No password policy, use defaults\n");
}
break;
case IPA_CHANGETYPE_ADMIN:
@@ -613,14 +637,14 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
*/
ret = ipapwd_getPolicy(data->dn, data->target, &tmppol);
if (ret) {
LOG_TRACE("No password policy, use defaults");
LOG_TRACE("No password policy, use defaults\n");
} else {
pol.max_pwd_life = tmppol.max_pwd_life;
pol.history_length = tmppol.history_length;
}
break;
default:
LOG_TRACE("Unknown password change type, use defaults");
LOG_TRACE("Unknown password change type, use defaults\n");
break;
}
@@ -641,9 +665,11 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
pwd_history = slapi_entry_attr_get_charray(data->target,
"passwordHistory");
uid = slapi_entry_attr_get_charptr(data->target, "uid");
/* check policy */
ret = ipapwd_check_policy(&pol, data->password,
uid,
data->timeNow,
acct_expiration,
pwd_expiration,
@@ -651,6 +677,7 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
pwd_history);
slapi_ch_array_free(pwd_history);
slapi_ch_free_string(&uid);
if (data->expireTime == 0) {
if (pol.max_pwd_life > 0) {
@@ -845,6 +872,20 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
data->expireTime, (data->expireTime == 0));
if (ret != LDAP_SUCCESS)
goto free_and_return;
switch(data->changetype) {
case IPA_CHANGETYPE_DSMGR:
case IPA_CHANGETYPE_ADMIN:
/* Mark as administratively reset which will unlock acct */
ret = ipapwd_setdate(data->target, smods,
"krbLastAdminUnlock",
data->timeNow, false);
if (ret != LDAP_SUCCESS)
goto free_and_return;
break;
default:
break;
}
}
}
@@ -927,7 +968,7 @@ Slapi_Value **ipapwd_setPasswordHistory(Slapi_Mods *smods,
char **new_pwd_history = NULL;
int n = 0;
int ret;
int i;
size_t i;
pwd_history = slapi_entry_attr_get_charray(data->target,
"passwordHistory");
@@ -1059,10 +1100,9 @@ int ipapwd_set_extradata(const char *dn,
void ipapwd_free_slapi_value_array(Slapi_Value ***svals)
{
Slapi_Value **sv = *svals;
int i;
if (sv) {
for (i = 0; sv[i]; i++) {
for (size_t i = 0; sv[i]; i++) {
slapi_value_free(&sv[i]);
}
}
@@ -1078,8 +1118,10 @@ void free_ipapwd_krbcfg(struct ipapwd_krbcfg **cfg)
krb5_free_default_realm(c->krbctx, c->realm);
krb5_free_context(c->krbctx);
free(c->kmkey->contents);
free(c->kmkey);
if (c->kmkey) {
free(c->kmkey->contents);
free(c->kmkey);
}
free(c->supp_encsalts);
free(c->pref_encsalts);
slapi_ch_array_free(c->passsync_mgrs);
@@ -1090,7 +1132,7 @@ void free_ipapwd_krbcfg(struct ipapwd_krbcfg **cfg)
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;
*errMesg = (char *)ipapwd_password_max_len_errmsg;
return LDAP_CONSTRAINT_VIOLATION;
}
return 0;

View File

@@ -33,7 +33,7 @@
* Authors:
* Simo Sorce <ssorce@redhat.com>
*
* Copyright (C) 2007-2010 Red Hat, Inc.
* Copyright (C) 2007-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -231,7 +231,7 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
if (!*svals) {
/* errMesg should have been set in encrypt_encode_key() */
LOG_FATAL("key encryption/encoding failed\n");
LOG_FATAL("key encryption/encoding failed (%s)\n", *errMesg);
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
@@ -267,6 +267,7 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
}
(*ntvals)[0] = slapi_value_new();
if (slapi_value_set((*ntvals)[0], nt_key, 16) == NULL) {
LOG("Failed to set value for nt_key");
rc = LDAP_OPERATIONS_ERROR;
goto done;
}

View File

@@ -33,7 +33,7 @@
* Authors:
* Simo Sorce <ssorce@redhat.com>
*
* Copyright (C) 2007-2010 Red Hat, Inc.
* Copyright (C) 2007-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -96,11 +96,19 @@ void *ipapwd_get_plugin_id(void)
return ipapwd_plugin_id;
}
static bool is_nthash_allowed(const char *service_name, const char *bind_dn)
{
#define CIFS_PRINCIPAL_PREFIX "krbprincipalname=cifs/"
return (0 == strncmp("cifs/", service_name, 5)) ||
(0 == strncmp(CIFS_PRINCIPAL_PREFIX, bind_dn,
sizeof(CIFS_PRINCIPAL_PREFIX) - 1));
}
static void filter_keys(struct ipapwd_krbcfg *krbcfg,
struct ipapwd_keyset *kset,
bool allow_nthash)
{
int i, j;
size_t i, j;
for (i = 0; i < kset->num_keys; i++) {
for (j = 0; j < krbcfg->num_supp_encsalts; j++) {
@@ -143,11 +151,11 @@ static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
bool allow_nthash)
{
/* first filter for duplicates */
for (int i = 0; i + 1 < *num_kenctypes; i++) {
for (int j = i + 1; j < *num_kenctypes; j++) {
for (size_t i = 0; i + 1 < *num_kenctypes; i++) {
for (size_t j = i + 1; j < *num_kenctypes; j++) {
if (kenctypes[i].ks_enctype == kenctypes[j].ks_enctype) {
/* duplicate, filter out */
for (int k = j; k + 1 < *num_kenctypes; k++) {
for (size_t k = j; k + 1 < *num_kenctypes; k++) {
kenctypes[k].ks_enctype = kenctypes[k + 1].ks_enctype;
kenctypes[k].ks_salttype = kenctypes[k + 1].ks_salttype;
}
@@ -158,8 +166,8 @@ static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
}
/* then filter for supported */
for (int i = 0; i < *num_kenctypes; i++) {
int j;
for (size_t i = 0; i < *num_kenctypes; i++) {
size_t j;
/* Check if supported */
for (j = 0; j < krbcfg->num_supp_encsalts; j++) {
@@ -176,7 +184,7 @@ static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
}
if (j == krbcfg->num_supp_encsalts) {
/* Unsupported, filter out */
for (int k = i; k + 1 < *num_kenctypes; k++) {
for (size_t k = i; k + 1 < *num_kenctypes; k++) {
kenctypes[k].ks_enctype = kenctypes[k + 1].ks_enctype;
kenctypes[k].ks_salttype = kenctypes[k + 1].ks_salttype;
}
@@ -336,6 +344,8 @@ parse_req_done:
rc = ipapwd_check_max_pwd_len(strlen(newPasswd), &errMesg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
bindDN, errMesg);
goto free_and_return;
}
@@ -343,7 +353,7 @@ parse_req_done:
/* If user is authenticated, they already gave their password during
the bind operation (or used sasl or client cert auth or OS creds) */
slapi_pblock_get(pb, SLAPI_CONN_AUTHMETHOD, &authmethod);
if (!authmethod || !strcmp(authmethod, SLAPD_AUTH_NONE)) {
if (!authmethod || strcmp(authmethod, SLAPD_AUTH_NONE) == 0) {
errMesg = "User must be authenticated to the directory server.\n";
rc = LDAP_INSUFFICIENT_ACCESS;
goto free_and_return;
@@ -448,7 +458,7 @@ parse_req_done:
char *cur_pw;
if (oldPasswd == NULL || *oldPasswd == '\0') {
LOG_FATAL("Old password was not provided!\n");
LOG_FATAL("Old password was not provided for '%s'!\n", dn);
rc = LDAP_INVALID_CREDENTIALS;
goto free_and_return;
}
@@ -458,7 +468,7 @@ parse_req_done:
cur_pw = slapi_entry_attr_get_charptr(targetEntry,
"userPassword");
if (!cur_pw) {
LOG_FATAL("User has no current password?\n");
LOG_FATAL("User '%s' does not have a current password?\n", dn);
rc = LDAP_UNWILLING_TO_PERFORM;
goto free_and_return;
}
@@ -477,7 +487,7 @@ parse_req_done:
slapi_value_free(&pw);
if (ret != 0) {
LOG_TRACE("Invalid password!\n");
LOG_TRACE("Invalid password for '%s'!\n", dn);
rc = LDAP_INVALID_CREDENTIALS;
goto free_and_return;
}
@@ -571,11 +581,9 @@ parse_req_done:
/* special cases */
if ((strcasecmp(dn, bindDN) != 0) &&
(strcasecmp(ipa_changepw_principal_dn, bindDN) != 0)) {
int i;
pwdata.changetype = IPA_CHANGETYPE_ADMIN;
for (i = 0; i < krbcfg->num_passsync_mgrs; i++) {
for (size_t i = 0; i < krbcfg->num_passsync_mgrs; i++) {
if (strcasecmp(krbcfg->passsync_mgrs[i], bindDN) == 0) {
pwdata.changetype = IPA_CHANGETYPE_DSMGR;
break;
@@ -598,6 +606,8 @@ parse_req_done:
errMesg = ipapwd_error2string(ret);
ret = ipapwd_to_ldap_pwpolicy_error(ret);
slapi_pwpolicy_make_response_control(pb, -1, -1, ret);
LOG_PWDPOLICY("Failed to set password credentials for"
" '%s': %s\n", dn, errMesg);
rc = LDAP_CONSTRAINT_VIOLATION;
goto free_and_return;
}
@@ -658,7 +668,7 @@ free_and_return:
if (targetEntry) slapi_entry_free(targetEntry);
if (ber) ber_free(ber, 1);
LOG("%s", errMesg ? errMesg : "success");
LOG("%s\n", errMesg ? errMesg : "success");
slapi_send_ldap_result(pb, rc, NULL, errMesg, 0, NULL);
return SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
@@ -724,7 +734,8 @@ static Slapi_Entry *get_entry_by_principal(const char *principal)
"krbCanonicalName",
"enrolledBy", NULL };
Slapi_Entry **es = NULL;
int res, ret, i;
int res, ret;
size_t i;
Slapi_Entry *entry = NULL;
/* Find ancestor base DN */
@@ -766,7 +777,7 @@ static Slapi_Entry *get_entry_by_principal(const char *principal)
/* if there is none or more than one, freak out */
if (i != 1) {
LOG_TRACE("Too many entries, or entry no found (%d)", i);
LOG_TRACE("Too many entries, or entry no found (%ld)\n", i);
goto free_and_return;
}
entry = slapi_entry_dup(es[0]);
@@ -801,7 +812,7 @@ static bool is_allowed_to_access_attr(Slapi_PBlock *pb, char *bindDN,
*/
be = get_realm_backend();
if (!be) {
LOG_FATAL("Could not fetch REALM backend!");
LOG_FATAL("Could not fetch REALM backend!\n");
return false;
}
if (slapi_pblock_set(pb, SLAPI_BACKEND, be)) {
@@ -860,7 +871,8 @@ static void remove_user_password(Slapi_Mods *smods,
if ((NULL != pw) && (NULL == krbLastPwdChange)) {
slapi_mods_add_mod_values(smods, LDAP_MOD_DELETE,
"userPassword", NULL);
LOG_TRACE("Removing userPassword from host entry\n");
LOG_TRACE("Removing userPassword from host entry '%s'\n",
slapi_entry_get_dn_const(targetEntry));
}
}
if (krbLastPwdChange) slapi_ch_free_string(&krbLastPwdChange);
@@ -883,8 +895,9 @@ static int store_new_keys(Slapi_Entry *target, char *svcname, char *bind_dn,
rc = set_krbLastPwdChange(smods, time_now);
if (rc) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to set krbLastPwdChange");
err_msg = "Internal error while storing keytab data\n";
LOG_FATAL("Failed to set krbLastPwdChange for target '%s'\n",
slapi_entry_get_dn_const(target));
err_msg = "Internal error while storing keytab data";
goto done;
}
@@ -897,8 +910,9 @@ static int store_new_keys(Slapi_Entry *target, char *svcname, char *bind_dn,
rc = ipapwd_apply_mods(slapi_entry_get_dn_const(target), smods);
if (rc != LDAP_SUCCESS) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to apply mods");
err_msg = "Internal error while saving keys\n";
LOG_FATAL("Failed to apply mods to target '%s'\n",
slapi_entry_get_dn_const(target));
err_msg = "Internal error while saving keys";
goto done;
}
@@ -906,8 +920,9 @@ static int store_new_keys(Slapi_Entry *target, char *svcname, char *bind_dn,
svcname, time_now);
if (rc != LDAP_SUCCESS) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to set extradata");
err_msg = "Internal error while saving keytab extradata\n";
LOG_FATAL("Failed to set extradata for target '%s'\n",
slapi_entry_get_dn_const(target));
err_msg = "Internal error while saving keytab extradata";
goto done;
}
@@ -995,7 +1010,7 @@ static int decode_setkeytab_request(krb5_context krbctx,
kset->mkvno = mkvno;
rtag = ber_peek_tag(ber, &tlen);
for (int i = 0; rtag == LBER_SEQUENCE; i++) {
for (size_t i = 0; rtag == LBER_SEQUENCE; i++) {
krb5_key_data *newset;
ber_tag_t ctag;
ber_int_t type;
@@ -1173,29 +1188,29 @@ static int encode_setkeytab_reply(struct ipapwd_keyset *kset,
rc = ber_printf(ber, "{i{", (ber_int_t)kset->keys[0].key_data_kvno);
if (rc == -1) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to ber_printf the kvno");
LOG_FATAL("Failed to ber_printf the kvno\n");
goto done;
}
for (int i = 0; i < kset->num_keys; i++) {
for (size_t i = 0; i < kset->num_keys; i++) {
rc = ber_printf(ber, "{i}", (ber_int_t)kset->keys[i].key_data_type[0]);
if (rc == -1) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to ber_printf the enctype");
LOG_FATAL("Failed to ber_printf the enctype\n");
goto done;
}
}
rc = ber_printf(ber, "}}");
if (rc == -1) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to ber_printf the termination");
LOG_FATAL("Failed to ber_printf the termination\n");
goto done;
}
rc = ber_flatten(ber, &bvp);
if (rc == -1) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to ber_flatten the buffer");
LOG_FATAL("Failed to ber_flatten the buffer\n");
goto done;
}
@@ -1228,7 +1243,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;
bool nthash_allowed = false;
struct berval *bvp = NULL;
LDAPControl new_ctrl;
@@ -1298,15 +1313,15 @@ static int ipapwd_setkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
/* get next kvno for entry (will be 1 if this is new) and fix keyset */
kvno = ipapwd_get_cur_kvno(targetEntry) + 1;
for (int i = 0; i < kset->num_keys; i++) {
for (size_t i = 0; i < kset->num_keys; i++) {
kset->keys[i].key_data_kvno = kvno;
}
/* 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);
nthash_allowed = is_nthash_allowed(serviceName, bindDN);
filter_keys(krbcfg, kset, nthash_allowed);
/* check if we have any left */
if (kset->num_keys == 0) {
@@ -1344,7 +1359,7 @@ static int ipapwd_setkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
rc = encode_setkeytab_reply(kset, &bvp);
if (rc) {
errMesg = "Internal Error.\n";
errMesg = "Internal Error.";
goto free_and_return;
}
@@ -1364,7 +1379,7 @@ free_and_return:
if (targetEntry) slapi_entry_free(targetEntry);
if (svals) {
for (int i = 0; svals[i]; i++) {
for (size_t i = 0; svals[i]; i++) {
slapi_value_free(&svals[i]);
}
free(svals);
@@ -1374,7 +1389,7 @@ free_and_return:
if (rc == LDAP_SUCCESS)
errMesg = NULL;
LOG("%s", errMesg ? errMesg : "success");
LOG("%s\n", errMesg ? errMesg : "success");
slapi_send_ldap_result(pb, rc, NULL, errMesg, 0, NULL);
return SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
@@ -1395,7 +1410,6 @@ static int decode_getkeytab_request(struct berval *extop, bool *wantold,
krb5_key_salt_tuple *enctypes = NULL;
bool newkt;
bool ret;
int i;
ret = ipaasn1_dec_getkt(extop->bv_val, extop->bv_len, &newkt,
&svcname, &password, &etypes, &numtypes);
@@ -1415,7 +1429,7 @@ static int decode_getkeytab_request(struct berval *extop, bool *wantold,
goto done;
}
for (i = 0; i < numtypes; i++) {
for (size_t i = 0; i < numtypes; i++) {
enctypes[i].ks_enctype = etypes[i];
enctypes[i].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL;
}
@@ -1458,7 +1472,7 @@ static int encode_getkeytab_reply(krb5_context krbctx,
/* uses last key kvno */
kvno = keys[num_keys-1].key_data_kvno;
for (int i = 0; i < num_keys; i++) {
for (size_t i = 0; i < num_keys; i++) {
krb5_enc_data cipher = { 0 };
krb5_data plain = { 0 };
krb5_int16 plen;
@@ -1508,7 +1522,7 @@ static int encode_getkeytab_reply(krb5_context krbctx,
rc = LDAP_SUCCESS;
done:
for (int i = 0; i < ksc.nkeys; i ++) {
for (size_t i = 0; i < ksc.nkeys; i++) {
free(ksc.ksdata[i].key.contents);
}
if (rc != LDAP_SUCCESS) {
@@ -1615,7 +1629,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;
bool nthash_allowed = false;
/* Get Bind DN */
slapi_pblock_get(pb, SLAPI_CONN_DN, &bind_dn);
@@ -1624,7 +1638,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
* this operation. */
if (bind_dn == NULL || *bind_dn == '\0') {
/* Refuse the operation because they're bound anonymously */
err_msg = "Anonymous Binds are not allowed.\n";
err_msg = "Anonymous Binds are not allowed.";
rc = LDAP_INSUFFICIENT_ACCESS;
goto free_and_return;
}
@@ -1640,7 +1654,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value);
if (!extop_value) {
LOG_FATAL("Failed to retrieve extended op value from pblock\n");
err_msg = "Failed to retrieve extended operation value\n";
err_msg = "Failed to retrieve extended operation value";
rc = LDAP_OPERATIONS_ERROR;
goto free_and_return;
}
@@ -1666,7 +1680,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
/* get Entry by krbPrincipalName */
target_entry = get_entry_by_principal(service_name);
if (!target_entry) {
err_msg = "PrincipalName not found.\n";
err_msg = "PrincipalName not found.";
rc = LDAP_NO_SUCH_OBJECT;
goto free_and_return;
}
@@ -1682,7 +1696,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
if (!acl_ok) {
LOG_FATAL("Not allowed to retrieve keytab on [%s] as user [%s]!\n",
service_name, bind_dn);
err_msg = "Insufficient access rights\n";
err_msg = "Insufficient access rights";
rc = LDAP_INSUFFICIENT_ACCESS;
goto free_and_return;
}
@@ -1693,6 +1707,8 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
/* if password was passed-in, check its length */
rc = ipapwd_check_max_pwd_len(strlen(password), &err_msg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
bind_dn, err_msg);
goto free_and_return;
}
}
@@ -1704,7 +1720,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
if (!acl_ok) {
LOG_FATAL("Not allowed to set keytab on [%s]!\n",
service_name);
err_msg = "Insufficient access rights\n";
err_msg = "Insufficient access rights";
rc = LDAP_INSUFFICIENT_ACCESS;
goto free_and_return;
}
@@ -1712,8 +1728,8 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
/* 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);
nthash_allowed = is_nthash_allowed(service_name, bind_dn);
filter_enctypes(krbcfg, kenctypes, &num_kenctypes, nthash_allowed);
/* check if we have any left */
if (num_kenctypes == 0 && kenctypes != NULL) {
@@ -1737,7 +1753,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
if (!svals) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("encrypt_encode_keys failed!\n");
err_msg = "Internal error while encrypting keys\n";
err_msg = "Internal error while encrypting keys";
goto free_and_return;
}
@@ -1757,7 +1773,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
rc = encode_getkeytab_reply(krbctx, krbcfg->kmkey, mkvno,
keys, num_keys, &bvp);
if (rc != LDAP_SUCCESS) {
err_msg = "Internal Error.\n";
err_msg = "Internal Error.";
goto free_and_return;
}
@@ -1768,7 +1784,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
free_and_return:
if (rc == LDAP_SUCCESS) err_msg = NULL;
LOG("%s", err_msg ? err_msg : "success");
LOG("%s\n", err_msg ? err_msg : "success");
slapi_send_ldap_result(pb, rc, NULL, err_msg, 0, NULL);
/* Free anything that we allocated above */
@@ -1779,7 +1795,7 @@ free_and_return:
if (target_entry) slapi_entry_free(target_entry);
if (keys) ipa_krb5_free_key_data(keys, num_keys);
if (svals) {
for (int i = 0; svals[i]; i++) {
for (size_t i = 0; svals[i]; i++) {
slapi_value_free(&svals[i]);
}
free(svals);
@@ -2023,7 +2039,7 @@ int ipapwd_init( Slapi_PBlock *pb )
"ipapwd_post_init_betxn", ipapwd_post_init_betxn,
"IPA pwd post ops betxn", NULL,
ipapwd_plugin_id);
}
}
slapi_register_plugin("preoperation", 1,
"ipapwd_pre_init", ipapwd_pre_init,

View File

@@ -70,6 +70,7 @@
#define IPAPWD_CHECK_CONN_SECURE 0x00000001
#define IPAPWD_CHECK_DN 0x00000002
#define IPAPWD_CHECK_ONLY_CONFIG 0x00000004
#define IPA_CHANGETYPE_NORMAL 0
#define IPA_CHANGETYPE_ADMIN 1
@@ -109,6 +110,7 @@ struct ipapwd_krbcfg {
char **passsync_mgrs;
int num_passsync_mgrs;
bool allow_nt_hash;
bool enforce_ldap_otp;
};
int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,

View File

@@ -33,7 +33,7 @@
* Authors:
* Simo Sorce <ssorce@redhat.com>
*
* Copyright (C) 2007-2010 Red Hat, Inc.
* Copyright (C) 2007-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -248,6 +248,13 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
return 0;
}
/* Get target DN */
ret = slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
if (ret) {
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
/* Ok this is interesting,
* Check this is a clear text password, or refuse operation */
if ('{' == userpw[0]) {
@@ -280,6 +287,8 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
} else {
rc = ipapwd_check_max_pwd_len(strlen(userpw_clear), &errMesg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
slapi_sdn_get_dn(sdn), errMesg);
goto done;
}
userpw = slapi_ch_strdup(userpw_clear);
@@ -329,13 +338,6 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
goto done;
}
/* Get target DN */
ret = slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
if (ret) {
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
/* time to get the operation handler */
ret = slapi_pblock_get(pb, SLAPI_OPERATION, &op);
if (ret != 0) {
@@ -359,7 +361,6 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR;
} else {
char *binddn;
int i;
pwdop->pwdata.changetype = IPA_CHANGETYPE_ADMIN;
@@ -367,7 +368,7 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
slapi_pblock_get(pb, SLAPI_CONN_DN, &binddn);
/* if it is a passsync manager we also need to skip resets */
for (i = 0; i < krbcfg->num_passsync_mgrs; i++) {
for (size_t i = 0; i < krbcfg->num_passsync_mgrs; i++) {
if (strcasecmp(krbcfg->passsync_mgrs[i], binddn) == 0) {
pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR;
break;
@@ -385,6 +386,8 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
if ((pwdop->pwdata.changetype != IPA_CHANGETYPE_DSMGR) &&
(ret != 0) ) {
errMesg = ipapwd_error2string(ret);
LOG_PWDPOLICY("Failed to add password credentials for '%s': %s\n",
slapi_sdn_get_dn(sdn), errMesg);
rc = LDAP_CONSTRAINT_VIOLATION;
goto done;
}
@@ -507,6 +510,13 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
goto done;
}
/* Get target DN */
ret = slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
if (ret) {
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
/* grab the mods - we'll put them back later with
* our modifications appended
*/
@@ -568,6 +578,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
rc = ipapwd_check_max_pwd_len(bv->bv_len, &errMesg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
slapi_sdn_get_dn(sdn), errMesg);
goto done;
}
slapi_ch_free_string(&unhashedpw);
@@ -591,14 +603,6 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
/* OK we have something interesting here, start checking for
* pre-requisites */
/* Get target DN */
ret = slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
if (ret) {
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
tmp_sdn = slapi_sdn_dup(sdn);
if (tmp_sdn) {
/* xxxPAR: Ideally SLAPI_MODIFY_EXISTING_ENTRY should be
@@ -795,6 +799,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
const char *userpw_clear = &userpw[strlen("{CLEAR}")];
rc = ipapwd_check_max_pwd_len(strlen(userpw_clear), &errMesg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
slapi_sdn_get_dn(sdn), errMesg);
goto done;
}
unhashedpw = slapi_ch_strdup(userpw_clear);
@@ -806,9 +812,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
slapi_ch_free_string(&userpw);
} else if (slapi_is_encoded(userpw)) {
LOG("Pre-Encoded passwords are not valid\n");
errMesg = "Pre-Encoded passwords are not valid\n";
errMesg = "Pre-Encoded passwords are not valid";
LOG("%s (%s)\n", errMesg, slapi_sdn_get_dn(sdn));
rc = LDAP_CONSTRAINT_VIOLATION;
goto done;
}
@@ -843,7 +848,6 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
} else {
char *binddn;
Slapi_DN *bdn, *tdn;
int i;
/* Check Bind DN */
slapi_pblock_get(pb, SLAPI_CONN_DN, &binddn);
@@ -857,18 +861,16 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
pwdop->pwdata.changetype = IPA_CHANGETYPE_ADMIN;
/* if it is a passsync manager we also need to skip resets */
for (i = 0; i < krbcfg->num_passsync_mgrs; i++) {
for (size_t i = 0; i < krbcfg->num_passsync_mgrs; i++) {
if (strcasecmp(krbcfg->passsync_mgrs[i], binddn) == 0) {
pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR;
break;
}
}
}
slapi_sdn_free(&bdn);
slapi_sdn_free(&tdn);
}
pwdop->pwdata.dn = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
@@ -884,6 +886,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
if ((pwdop->pwdata.changetype != IPA_CHANGETYPE_DSMGR) &&
(ret != 0)) {
errMesg = ipapwd_error2string(ret);
LOG_PWDPOLICY("Check Password Policy failed for (%s) - %s/n",
pwdop->pwdata.dn, errMesg);
rc = LDAP_CONSTRAINT_VIOLATION;
goto done;
}
@@ -976,7 +980,6 @@ static int ipapwd_regen_nthash(Slapi_PBlock *pb, Slapi_Mods *smods,
int num_keys;
int mkvno;
int ret;
int i;
ret = slapi_entry_attr_find(entry, "ipaNTHash", &attr);
if (ret == 0) {
@@ -1008,7 +1011,7 @@ static int ipapwd_regen_nthash(Slapi_PBlock *pb, Slapi_Mods *smods,
ret = LDAP_UNWILLING_TO_PERFORM;
for (i = 0; i < num_keys; i++) {
for (size_t i = 0; i < num_keys; i++) {
char nthash[16];
krb5_enc_data cipher;
krb5_data plain;
@@ -1071,6 +1074,7 @@ static int ipapwd_post_modadd(Slapi_PBlock *pb)
struct ipapwd_krbcfg *krbcfg = NULL;
char *principal = NULL;
Slapi_Value *ipahost;
Slapi_Value *zero;
LOG_TRACE("=>\n");
@@ -1167,6 +1171,13 @@ static int ipapwd_post_modadd(Slapi_PBlock *pb)
}
slapi_value_free(&ipahost);
}
zero = slapi_value_new_string("0");
if (!slapi_entry_attr_has_syntax_value(pwdop->pwdata.target,
"passwordgraceusertime", zero)) {
/* Clear the passwordgraceusertime from the user entry */
slapi_mods_add_string(smods, LDAP_MOD_REPLACE, "passwordgraceusertime", "0");
}
slapi_value_free(&zero);
ret = ipapwd_apply_mods(pwdop->pwdata.dn, smods);
if (ret)
@@ -1201,13 +1212,20 @@ done:
* value at the end. This leaves only the password in creds for later
* validation.
*/
typedef enum {
OTP_IS_NOT_REQUIRED = 0,
OTP_IS_REQUIRED_EXPLICITLY,
OTP_IS_REQUIRED_IMPLICITLY
} otp_req_enum;
static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
struct berval *creds, bool otpreq)
struct berval *creds, otp_req_enum otpreq,
bool *notokens)
{
uint32_t auth_types;
/* Get the configured authentication types. */
auth_types = otp_config_auth_types(otp_config, entry);
*notokens = false;
/*
* IMPORTANT SECTION!
@@ -1237,7 +1255,11 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
/* With no tokens, succeed if tokens aren't required. */
if (tokens[0] == NULL) {
otp_token_free_array(tokens);
return !otpreq;
*notokens = true;
if (otpreq != OTP_IS_NOT_REQUIRED)
/* DENY: OTP is required, either explicitly or implicitly */
return false;
return true;
}
if (otp_token_validate_berval(tokens, creds, NULL)) {
@@ -1248,7 +1270,8 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
otp_token_free_array(tokens);
}
return (auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) && !otpreq;
return (auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) &&
(otpreq == OTP_IS_NOT_REQUIRED);
}
static int ipapwd_authenticate(const char *dn, Slapi_Entry *entry,
@@ -1403,6 +1426,11 @@ done:
}
#ifdef USE_OP_NOTE_MFA_AUTH
/* defined in ldap/servers/slapd/pblock.c in 389-ds but not exposed via slapi-plugin.h */
extern void slapi_pblock_set_flag_operation_notes(Slapi_PBlock *pb, uint32_t opflag);
#endif
/* PRE BIND Operation
*
* Used for:
@@ -1420,12 +1448,13 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
"krbPasswordExpiration", "krblastpwchange",
NULL
};
struct ipapwd_krbcfg *krbcfg = NULL;
struct berval *credentials = NULL;
Slapi_Entry *entry = NULL;
Slapi_DN *target_sdn = NULL;
Slapi_DN *sdn = NULL;
const char *dn = NULL;
int method = 0;
ber_tag_t method = 0;
bool syncreq;
bool otpreq;
int ret = 0;
@@ -1435,6 +1464,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
struct tm expire_tm;
int rc = LDAP_INVALID_CREDENTIALS;
char *errMesg = NULL;
bool notokens = false;
/* get BIND parameters */
ret |= slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &target_sdn);
@@ -1446,8 +1476,10 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
}
/* We're only interested in simple authentication. */
if (method != LDAP_AUTH_SIMPLE || credentials->bv_len == 0)
if (method != LDAP_AUTH_SIMPLE || credentials->bv_len == 0) {
LOG("Not handled (not simple bind or NULL dn/credentials)\n");
return 0;
}
/* Retrieve the user's entry. */
sdn = slapi_sdn_dup(target_sdn);
@@ -1491,9 +1523,28 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
/* Try to do OTP first. */
syncreq = otpctrl_present(pb, OTP_SYNC_REQUEST_OID);
otpreq = otpctrl_present(pb, OTP_REQUIRED_OID);
if (!syncreq && !ipapwd_pre_bind_otp(dn, entry, credentials, otpreq))
goto invalid_creds;
otpreq = otpctrl_present(pb, OTP_REQUIRED_OID) ?
OTP_IS_REQUIRED_EXPLICITLY : OTP_IS_NOT_REQUIRED;
if (!syncreq && (otpreq == OTP_IS_NOT_REQUIRED)) {
ret = ipapwd_gen_checks(pb, &errMesg, &krbcfg, IPAPWD_CHECK_ONLY_CONFIG);
if (ret != 0) {
LOG_FATAL("ipapwd_gen_checks failed!?\n");
slapi_entry_free(entry);
slapi_sdn_free(&sdn);
return 0;
}
if (krbcfg->enforce_ldap_otp) {
otpreq = OTP_IS_REQUIRED_IMPLICITLY;
}
}
if (!syncreq && !ipapwd_pre_bind_otp(dn, entry,
credentials, otpreq, &notokens)) {
/* We got here because ipapwd_pre_bind_otp() returned false,
* it means that either token verification failed or
* a rule for empty tokens failed current policy. */
if (!(notokens || (otpreq == OTP_IS_NOT_REQUIRED)))
goto invalid_creds;
}
/* Ensure that there is a password. */
if (credentials->bv_len == 0) {
@@ -1501,10 +1552,15 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
} else {
rc = ipapwd_check_max_pwd_len(credentials->bv_len, &errMesg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
slapi_sdn_get_dn(sdn), errMesg);
goto invalid_creds;
}
}
/* Reset rc to make sure errors are reported*/
rc = LDAP_INVALID_CREDENTIALS;
/* Authenticate the user. */
ret = ipapwd_authenticate(dn, entry, credentials);
if (ret) {
@@ -1520,11 +1576,23 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
/* Attempt to write out kerberos keys for the user. */
ipapwd_write_krb_keys(pb, discard_const(dn), entry, credentials);
#ifdef USE_OP_NOTE_MFA_AUTH
/* If it was a successful authentication with OTP required, mark it
* for access log to notice multi-factor authentication has happened
* https://www.port389.org/docs/389ds/design/mfa-operation-note-design.html
*/
if (!syncreq &&
((otpreq != OTP_IS_NOT_REQUIRED) && !notokens)) {
slapi_pblock_set_flag_operation_notes(pb, SLAPI_OP_NOTE_MFA_AUTH);
}
#endif
slapi_entry_free(entry);
slapi_sdn_free(&sdn);
return 0;
invalid_creds:
free_ipapwd_krbcfg(&krbcfg);
slapi_entry_free(entry);
slapi_sdn_free(&sdn);
slapi_send_ldap_result(pb, rc, NULL, errMesg, 0, NULL);