Import Upstream version 4.12.4
This commit is contained in:
@@ -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.%
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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, ¬okens)) {
|
||||
/* 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);
|
||||
|
||||
Reference in New Issue
Block a user