Imported Debian patch 4.0.5-6~numeezy

This commit is contained in:
Alexandre Ellert
2016-02-17 15:07:45 +01:00
committed by Mario Fetka
parent c44de33144
commit 10dfc9587b
1203 changed files with 53869 additions and 241462 deletions

View File

@@ -6,14 +6,14 @@ KRB5_UTIL_DIR = ../../../util
KRB5_UTIL_SRCS = $(KRB5_UTIL_DIR)/ipa_krb5.c \
$(KRB5_UTIL_DIR)/ipa_pwd.c \
$(KRB5_UTIL_DIR)/ipa_pwd_ntlm.c
ASN1_UTIL_DIR=../../../asn1
AM_CPPFLAGS = \
-I. \
-I$(srcdir) \
-I$(srcdir)/../libotp \
-I$(PLUGIN_COMMON_DIR) \
-I$(KRB5_UTIL_DIR) \
-I$(ASN1_UTIL_DIR) \
-I$(COMMON_BER_DIR) \
-DPREFIX=\""$(prefix)"\" \
-DBINDIR=\""$(bindir)"\" \
-DLIBDIR=\""$(libdir)"\" \
@@ -38,11 +38,9 @@ AM_LDFLAGS = \
# Plugin Binary
plugindir = $(libdir)/dirsrv/plugins
plugin_LTLIBRARIES = libipa_pwd_extop.la
libipa_pwd_extop_la_LIBADD = \
$(builddir)/../libotp/libotp.la \
$(ASN1_UTIL_DIR)/libipaasn1.la \
$(NULL)
libipa_pwd_extop_la_LIBADD = $(builddir)/../libotp/libotp.la
libipa_pwd_extop_la_SOURCES = \
authcfg.c \
common.c \
encoding.c \
prepost.c \

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.15 from Makefile.am.
# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -16,17 +16,7 @@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
@@ -90,12 +80,13 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = ipa-slapi-plugins/ipa-pwd-extop
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp README
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../version.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
@@ -129,13 +120,12 @@ am__uninstall_files_from_dir = { \
}
am__installdirs = "$(DESTDIR)$(plugindir)" "$(DESTDIR)$(appdir)"
LTLIBRARIES = $(plugin_LTLIBRARIES)
am__DEPENDENCIES_1 =
libipa_pwd_extop_la_DEPENDENCIES = $(builddir)/../libotp/libotp.la \
$(ASN1_UTIL_DIR)/libipaasn1.la $(am__DEPENDENCIES_1)
libipa_pwd_extop_la_DEPENDENCIES = $(builddir)/../libotp/libotp.la
am__objects_1 = ipa_krb5.lo ipa_pwd.lo ipa_pwd_ntlm.lo
am__objects_2 =
am_libipa_pwd_extop_la_OBJECTS = common.lo encoding.lo prepost.lo \
ipa_pwd_extop.lo syncreq.lo $(am__objects_1) $(am__objects_2)
am_libipa_pwd_extop_la_OBJECTS = authcfg.lo common.lo encoding.lo \
prepost.lo ipa_pwd_extop.lo syncreq.lo $(am__objects_1) \
$(am__objects_2)
libipa_pwd_extop_la_OBJECTS = $(am_libipa_pwd_extop_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -202,7 +192,6 @@ am__define_uniq_tagged_files = \
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@
AMTAR = @AMTAR@
@@ -249,7 +238,6 @@ LDAP_CFLAGS = @LDAP_CFLAGS@
LDAP_LIBS = @LDAP_LIBS@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBPDB_NAME = @LIBPDB_NAME@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBVERTO_CFLAGS = @LIBVERTO_CFLAGS@
@@ -257,7 +245,6 @@ LIBVERTO_LIBS = @LIBVERTO_LIBS@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
@@ -369,7 +356,6 @@ pythondir = @pythondir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
subdirs = @subdirs@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
target_alias = @target_alias@
@@ -384,13 +370,13 @@ KRB5_UTIL_SRCS = $(KRB5_UTIL_DIR)/ipa_krb5.c \
$(KRB5_UTIL_DIR)/ipa_pwd.c \
$(KRB5_UTIL_DIR)/ipa_pwd_ntlm.c
ASN1_UTIL_DIR = ../../../asn1
AM_CPPFLAGS = \
-I. \
-I$(srcdir) \
-I$(srcdir)/../libotp \
-I$(PLUGIN_COMMON_DIR) \
-I$(KRB5_UTIL_DIR) \
-I$(ASN1_UTIL_DIR) \
-I$(COMMON_BER_DIR) \
-DPREFIX=\""$(prefix)"\" \
-DBINDIR=\""$(bindir)"\" \
-DLIBDIR=\""$(libdir)"\" \
@@ -416,12 +402,9 @@ AM_LDFLAGS = \
# Plugin Binary
plugindir = $(libdir)/dirsrv/plugins
plugin_LTLIBRARIES = libipa_pwd_extop.la
libipa_pwd_extop_la_LIBADD = \
$(builddir)/../libotp/libotp.la \
$(ASN1_UTIL_DIR)/libipaasn1.la \
$(NULL)
libipa_pwd_extop_la_LIBADD = $(builddir)/../libotp/libotp.la
libipa_pwd_extop_la_SOURCES = \
authcfg.c \
common.c \
encoding.c \
prepost.c \
@@ -456,6 +439,7 @@ $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__confi
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ipa-slapi-plugins/ipa-pwd-extop/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign ipa-slapi-plugins/ipa-pwd-extop/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
@@ -518,6 +502,7 @@ mostlyclean-compile:
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/authcfg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encoding.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipa_krb5.Plo@am__quote@
@@ -804,8 +789,6 @@ uninstall-am: uninstall-appDATA uninstall-pluginLTLIBRARIES
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am uninstall-appDATA uninstall-pluginLTLIBRARIES
.PRECIOUS: Makefile
# 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.

View File

@@ -0,0 +1,280 @@
/** BEGIN COPYRIGHT BLOCK
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional permission under GPLv3 section 7:
*
* In the following paragraph, "GPL" means the GNU General Public
* License, version 3 or any later version, and "Non-GPL Code" means
* code that is governed neither by the GPL nor a license
* compatible with the GPL.
*
* You may link the code of this Program with Non-GPL Code and convey
* linked combinations including the two, provided that such Non-GPL
* Code only links to the code of this Program through those well
* defined interfaces identified in the file named EXCEPTION found in
* the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline
* functions from the Approved Interfaces without causing the resulting
* work to be covered by the GPL. Only the copyright holders of this
* Program may make changes or additions to the list of Approved
* Interfaces.
*
* Authors:
* Nathaniel McCallum <npmccallum@redhat.com>
*
* Copyright (C) 2014 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
#include "authcfg.h"
#include "ipapwd.h"
#include "pratom.h"
static struct config {
struct config *next;
Slapi_DN *suffix;
uint32_t config;
} *config;
static uint32_t string_to_config(const char *str)
{
static const struct {
const char *string;
uint32_t config;
} map[] = {
{ "disabled", AUTHCFG_AUTH_TYPE_DISABLED },
{ "password", AUTHCFG_AUTH_TYPE_PASSWORD },
{ "otp", AUTHCFG_AUTH_TYPE_OTP },
{ "pkinit", AUTHCFG_AUTH_TYPE_PKINIT },
{ "radius", AUTHCFG_AUTH_TYPE_RADIUS },
{}
};
for (uint32_t i = 0; map[i].string != NULL; i++) {
if (strcasecmp(map[i].string, str) == 0)
return map[i].config;
}
return AUTHCFG_AUTH_TYPE_NONE;
}
static uint32_t entry_to_config(Slapi_Entry *e)
{
char **auth_types = NULL;
if (e == NULL)
return AUTHCFG_AUTH_TYPE_NONE;
/* Fetch the auth type values from the config entry. */
auth_types = slapi_entry_attr_get_charray(e, "ipaUserAuthType");
if (auth_types == NULL)
return AUTHCFG_AUTH_TYPE_NONE;
uint32_t types = AUTHCFG_AUTH_TYPE_NONE;
for (uint32_t i = 0; auth_types[i] != NULL; i++)
types |= string_to_config(auth_types[i]);
slapi_ch_array_free(auth_types);
return types;
}
static Slapi_DN *suffix_to_config_dn(Slapi_DN *suffix)
{
Slapi_DN *sdn = NULL;
char *dn = NULL;
if (suffix == NULL)
return NULL;
dn = PR_smprintf("cn=ipaConfig,cn=etc,%s", slapi_sdn_get_dn(suffix));
if (dn == NULL)
return NULL;
sdn = slapi_sdn_new_dn_byval(dn);
PR_smprintf_free(dn);
return sdn;
}
static uint32_t suffix_to_config(Slapi_DN *suffix)
{
static char *attrs[] = { "ipaUserAuthType", NULL };
Slapi_Entry *entry = NULL;
Slapi_DN *sdn = NULL;
uint32_t types;
int ret;
sdn = suffix_to_config_dn(suffix);
if (sdn == NULL)
return AUTHCFG_AUTH_TYPE_NONE;
ret = slapi_search_internal_get_entry(sdn, attrs, &entry,
ipapwd_get_plugin_id());
slapi_sdn_free(&sdn);
if (ret != LDAP_SUCCESS)
return AUTHCFG_AUTH_TYPE_NONE;
types = entry_to_config(entry);
slapi_entry_free(entry);
return types;
}
static Slapi_DN *sdn_to_suffix(Slapi_DN *sdn)
{
Slapi_DN *suffix = NULL;
void *node = NULL;
if (sdn == NULL)
return NULL;
for (suffix = slapi_get_first_suffix(&node, 0); suffix != NULL;
suffix = slapi_get_next_suffix(&node, 0)) {
if (slapi_sdn_issuffix(sdn, suffix))
return suffix;
}
return NULL;
}
static bool sdn_is_config(Slapi_DN *sdn)
{
Slapi_DN *sfx = NULL;
Slapi_DN *cfg = NULL;
int cmp;
if (sdn == NULL)
return false;
sfx = sdn_to_suffix(sdn);
if (sfx == NULL)
return false;
cfg = suffix_to_config_dn(sfx);
if (cfg == NULL)
return false;
cmp = slapi_sdn_compare(cfg, sdn);
slapi_sdn_free(&cfg);
return cmp == 0;
}
void cache_free(struct config **cfg)
{
if (cfg == NULL || *cfg == NULL)
return;
cache_free(&(*cfg)->next);
free(*cfg);
*cfg = NULL;
}
bool authcfg_init(void)
{
struct config *cfg = NULL;
Slapi_DN *sfx = NULL;
void *node = NULL;
/* If we are already initialized, return true. */
if (config != NULL)
return true;
/* Look up the config for each suffix. */
for (sfx = slapi_get_first_suffix(&node, 0); sfx != NULL;
sfx = slapi_get_next_suffix(&node, 0)) {
cfg = calloc(1, sizeof(*cfg));
if (cfg == NULL) {
authcfg_fini();
return false;
}
cfg->suffix = sfx;
cfg->config = suffix_to_config(sfx);
cfg->next = config;
config = cfg;
}
return true;
}
void authcfg_fini(void)
{
cache_free(&config);
}
uint32_t authcfg_get_auth_types(Slapi_Entry *user_entry)
{
uint32_t glbl = AUTHCFG_AUTH_TYPE_NONE;
uint32_t user = AUTHCFG_AUTH_TYPE_NONE;
Slapi_DN *sfx = NULL;
Slapi_DN *sdn = NULL;
/* Find the root suffix. */
sdn = slapi_entry_get_sdn(user_entry);
sfx = sdn_to_suffix(sdn);
/* Find the global config. */
if (sfx != NULL) {
for (struct config *cfg = config; cfg && sfx; cfg = cfg->next) {
if (slapi_sdn_compare(sfx, cfg->suffix) == 0) {
glbl = PR_ATOMIC_ADD(&cfg->config, 0);
break;
}
}
}
/* Global disabled overrides user settings. */
if (glbl & AUTHCFG_AUTH_TYPE_DISABLED)
return AUTHCFG_AUTH_TYPE_DISABLED;
/* Get the user's config. */
user = entry_to_config(user_entry);
if (user == AUTHCFG_AUTH_TYPE_NONE) {
if (glbl == AUTHCFG_AUTH_TYPE_NONE)
return AUTHCFG_AUTH_TYPE_PASSWORD;
return glbl;
}
return user & ~AUTHCFG_AUTH_TYPE_DISABLED;
}
void authcfg_reload_global_config(Slapi_DN *sdn, Slapi_Entry *config_entry)
{
uint32_t glbl = AUTHCFG_AUTH_TYPE_NONE;
Slapi_DN *sfx = NULL;
Slapi_DN *dest;
/* Get the destination DN. */
dest = config_entry == NULL ? NULL : slapi_entry_get_sdn(config_entry);
/* Added, modified, moved into place. */
if (sdn_is_config(dest)) {
sfx = sdn_to_suffix(dest);
glbl = entry_to_config(config_entry);
/* Deleted, moved out of place. */
} else if (sdn_is_config(sdn)) {
sfx = sdn_to_suffix(sdn);
}
/* Reload config. */
for (struct config *cfg = config; cfg && sfx; cfg = cfg->next) {
if (slapi_sdn_compare(sfx, cfg->suffix) == 0) {
PR_ATOMIC_SET(&cfg->config, glbl);
break;
}
}
}

View File

@@ -0,0 +1,82 @@
/** BEGIN COPYRIGHT BLOCK
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Additional permission under GPLv3 section 7:
*
* In the following paragraph, "GPL" means the GNU General Public
* License, version 3 or any later version, and "Non-GPL Code" means
* code that is governed neither by the GPL nor a license
* compatible with the GPL.
*
* You may link the code of this Program with Non-GPL Code and convey
* linked combinations including the two, provided that such Non-GPL
* Code only links to the code of this Program through those well
* defined interfaces identified in the file named EXCEPTION found in
* the source code files (the "Approved Interfaces"). The files of
* Non-GPL Code may instantiate templates or use macros or inline
* functions from the Approved Interfaces without causing the resulting
* work to be covered by the GPL. Only the copyright holders of this
* Program may make changes or additions to the list of Approved
* Interfaces.
*
* Authors:
* Nathaniel McCallum <npmccallum@redhat.com>
*
* Copyright (C) 2014 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
#ifndef AUTHCFG_H_
#define AUTHCFG_H_
#include <dirsrv/slapi-plugin.h>
#include <stdbool.h>
#define AUTHCFG_AUTH_TYPE_NONE 0
#define AUTHCFG_AUTH_TYPE_DISABLED 1
#define AUTHCFG_AUTH_TYPE_PASSWORD 2
#define AUTHCFG_AUTH_TYPE_OTP 4
#define AUTHCFG_AUTH_TYPE_PKINIT 8
#define AUTHCFG_AUTH_TYPE_RADIUS 16
/* Initialize authentication configuration.
*
* Thread Safety: NO
*/
bool authcfg_init(void);
/* Free global authentication configuration resources.
*
* Thread Safety: NO
*/
void authcfg_fini(void);
/* Gets the permitted authentication types for the given user entry.
*
* The entry should be queried for the "ipaUserAuthType" attribute.
*
* Thread Safety: YES
*/
uint32_t authcfg_get_auth_types(Slapi_Entry *user_entry);
/* Reloads configuration from the specified global config entry.
*
* If the provided entry isn't a global config entry, this is a no-op.
*
* Thread Safety: YES
*/
void authcfg_reload_global_config(Slapi_DN *sdn, Slapi_Entry *config_entry);
#endif /* AUTHCFG_H_ */

View File

@@ -55,10 +55,18 @@ extern const char *ipa_realm_dn;
extern const char *ipa_etc_config_dn;
extern const char *ipa_pwd_config_dn;
/* These are the default enc:salt types if nothing is defined in LDAP */
/* These are the default enc:salt types if nothing is defined.
* TODO: retrieve the configure set of ecntypes either from the
* kfc.conf file or by synchronizing the file content into
* the directory */
static const char *ipapwd_def_encsalts[] = {
"aes256-cts:special",
"aes128-cts:special",
"des3-hmac-sha1:normal",
/* "arcfour-hmac:normal",
"des-hmac-sha1:normal",
"des-cbc-md5:normal", */
"des-cbc-crc:normal",
/* "des-cbc-crc:v4",
"des-cbc-crc:afs3", */
NULL
};

View File

@@ -104,7 +104,6 @@ void ipapwd_keyset_free(struct ipapwd_keyset **pkset)
Slapi_Value **ipapwd_encrypt_encode_key(struct ipapwd_krbcfg *krbcfg,
struct ipapwd_data *data,
char *preferred_principal,
int num_encsalts,
krb5_key_salt_tuple *encsalts,
char **errMesg)
@@ -129,20 +128,12 @@ Slapi_Value **ipapwd_encrypt_encode_key(struct ipapwd_krbcfg *krbcfg,
kvno = ipapwd_get_cur_kvno(data->target);
if (preferred_principal) {
krbPrincipalName = slapi_ch_strdup(preferred_principal);
} else {
krbPrincipalName = slapi_entry_attr_get_charptr(data->target,
"krbCanonicalName");
if (!krbPrincipalName) {
krbPrincipalName = slapi_entry_attr_get_charptr(data->target,
"krbPrincipalName");
}
if (!krbPrincipalName) {
*errMesg = "no krbPrincipalName present in this entry\n";
LOG_FATAL("%s", *errMesg);
goto enc_error;
}
krbPrincipalName = slapi_entry_attr_get_charptr(data->target,
"krbPrincipalName");
if (!krbPrincipalName) {
*errMesg = "no krbPrincipalName present in this entry\n";
LOG_FATAL("%s", *errMesg);
goto enc_error;
}
krberr = krb5_parse_name(krbctx, krbPrincipalName, &princ);
@@ -224,7 +215,7 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
if (is_krb) {
*svals = ipapwd_encrypt_encode_key(krbcfg, data, NULL,
*svals = ipapwd_encrypt_encode_key(krbcfg, data,
krbcfg->num_pref_encsalts,
krbcfg->pref_encsalts,
errMesg);

View File

@@ -39,8 +39,7 @@
#include "ipapwd.h"
#include "util.h"
#include "../libotp/otp_config.h"
#include "ipa_asn1.h"
#include "authcfg.h"
/*
* Password Modify - LDAP Extended Operation.
@@ -89,8 +88,6 @@ Slapi_PluginDesc ipapwd_plugin_desc = {
void *ipapwd_plugin_id;
static int usetxn = 0;
extern struct otp_config *otp_config;
void *ipapwd_get_plugin_id(void)
{
return ipapwd_plugin_id;
@@ -128,48 +125,6 @@ static void filter_keys(struct ipapwd_krbcfg *krbcfg,
}
}
static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
krb5_key_salt_tuple *kenctypes,
int *num_kenctypes)
{
/* first filter for duplicates */
for (int i = 0; i + 1 < *num_kenctypes; i++) {
for (int 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++) {
kenctypes[k].ks_enctype = kenctypes[k + 1].ks_enctype;
kenctypes[k].ks_salttype = kenctypes[k + 1].ks_salttype;
}
(*num_kenctypes)--;
j--;
}
}
}
/* then filter for supported */
for (int i = 0; i < *num_kenctypes; i++) {
int j;
/* Check if supported */
for (j = 0; j < krbcfg->num_supp_encsalts; j++) {
if (kenctypes[i].ks_enctype ==
krbcfg->supp_encsalts[j].ks_enctype) {
break;
}
}
if (j == krbcfg->num_supp_encsalts) {
/* Unsupported, filter out */
for (int 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;
}
(*num_kenctypes)--;
i--;
}
}
}
static int ipapwd_to_ldap_pwpolicy_error(int ipapwderr)
{
switch (ipapwderr) {
@@ -661,7 +616,6 @@ static Slapi_Entry *get_entry_by_principal(const char *principal)
Slapi_PBlock *pb = NULL;
char *attrlist[] = { "krbPrincipalKey", "krbLastPwdChange",
"userPassword", "krbPrincipalName",
"krbCanonicalName",
"enrolledBy", NULL };
Slapi_Entry **es = NULL;
int res, ret, i;
@@ -1314,7 +1268,31 @@ free_and_return:
return SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
}
/* decode a getkeytab control request using libipaasn1 helpers */
/* Format of getkeytab request
*
* KeytabGetRequest ::= CHOICE {
* newkeys [0] Newkeys,
* curkeys [1] CurrentKeys,
* reply [2] Reply
* }
*
* NewKeys ::= SEQUENCE {
* serviceIdentity [0] OCTET STRING,
* enctypes [1] SEQUENCE OF Int16
* password [2] OCTET STRING OPTIONAL,
* }
*
* CurrentKeys ::= SEQUENCE {
* serviceIdentity [0] OCTET STRING,
* }
*/
#define GK_REQUEST_NEWKEYS (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 0)
#define GK_REQUEST_CURKEYS (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
#define GKREQ_SVCNAME_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
#define GKREQ_ENCTYPES_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
#define GKREQ_PASSWORD_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 2)
static int decode_getkeytab_request(struct berval *extop, bool *wantold,
char **_svcname, char **_password,
krb5_key_salt_tuple **kenctypes,
@@ -1322,80 +1300,175 @@ static int decode_getkeytab_request(struct berval *extop, bool *wantold,
{
int rc = LDAP_OPERATIONS_ERROR;
char *err_msg = NULL;
BerElement *ber = NULL;
ber_len_t tlen;
ber_tag_t rtag;
ber_tag_t ttag;
ber_tag_t ctag;
char *svcname = NULL;
char *password = NULL;
long *etypes = NULL;
int numtypes = 0;
ber_int_t enctype;
krb5_key_salt_tuple *enctypes = NULL;
bool newkt;
bool ret;
int i;
int num = 0;
ret = ipaasn1_dec_getkt(extop->bv_val, extop->bv_len, &newkt,
&svcname, &password, &etypes, &numtypes);
if (!ret) {
err_msg = "Failed to decode GetKeytab Control.\n";
ber = ber_init(extop);
if (ber == NULL) {
err_msg = "KeytabGet Request decode failed.\n";
rc = LDAP_PROTOCOL_ERROR;
goto done;
}
if (newkt) {
if (numtypes) {
enctypes = malloc(numtypes * sizeof(krb5_key_salt_tuple));
/* check this is a request */
rtag = ber_peek_tag(ber, &tlen);
if (rtag != GK_REQUEST_NEWKEYS && rtag != GK_REQUEST_CURKEYS) {
LOG_FATAL("ber_peek_tag failed, wrong request type\n");
err_msg = "Invalid payload.\n";
rc = LDAP_PROTOCOL_ERROR;
goto done;
}
/* ber parse code */
ttag = ber_scanf(ber, "{ta", &ctag, &svcname);
if (ttag == LBER_ERROR || ctag != GKREQ_SVCNAME_TAG) {
LOG_FATAL("ber_scanf failed to decode service name\n");
err_msg = "Invalid payload.\n";
rc = LDAP_PROTOCOL_ERROR;
goto done;
}
if (rtag == GK_REQUEST_CURKEYS) {
rc = LDAP_SUCCESS;
goto done;
}
ttag = ber_peek_tag(ber, &tlen);
if (ttag != GKREQ_ENCTYPES_TAG) {
LOG_FATAL("ber_peek_tag failed to find enctypes\n");
err_msg = "Invalid payload.\n";
rc = LDAP_PROTOCOL_ERROR;
goto done;
}
ttag = ber_peek_tag(ber, &tlen);
for (num = 0; ttag == LBER_INTEGER; num++) {
if ((num % 10) == 0) {
/* allocate space for at least 10 more enctypes */
enctypes = realloc(enctypes,
(num + 10) * sizeof(krb5_key_salt_tuple));
if (!enctypes) {
LOG_FATAL("allocation failed\n");
err_msg = "Internal error\n";
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
}
for (i = 0; i < numtypes; i++) {
enctypes[i].ks_enctype = etypes[i];
enctypes[i].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL;
}
ttag = ber_scanf(ber, "i", &enctype);
if (ttag == LBER_ERROR) {
LOG_FATAL("ber_scanf failed to decode enctype\n");
err_msg = "Invalid payload.\n";
rc = LDAP_PROTOCOL_ERROR;
goto done;
}
enctypes[num].ks_enctype = enctype;
enctypes[num].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL;
ttag = ber_peek_tag(ber, &tlen);
}
/* ttag peek done as last step of the previous for loop */
if (ttag == GKREQ_PASSWORD_TAG) {
/* optional password present */
ttag = ber_scanf(ber, "a", &password);
if (ttag == LBER_ERROR) {
LOG_FATAL("ber_scanf failed to decode password\n");
err_msg = "Invalid payload.\n";
rc = LDAP_PROTOCOL_ERROR;
goto done;
}
}
rc = LDAP_SUCCESS;
done:
free(etypes);
if (rc != LDAP_SUCCESS) {
free(password);
free(svcname);
free(enctypes);
*_err_msg = err_msg;
} else {
*_password = password;
*_svcname = svcname;
*wantold = (newkt == false);
*wantold = (rtag == GK_REQUEST_CURKEYS);
*kenctypes = enctypes;
*num_kenctypes = numtypes;
*num_kenctypes = num;
}
if (ber) ber_free(ber, 1);
return rc;
}
/* Format of getkeytab reply
*
* Reply ::= SEQUENCE {
* new_kvno Int32
* keys SEQUENCE OF KrbKey,
* }
*
* KrbKey ::= SEQUENCE {
* key [0] EncryptionKey,
* salt [1] KrbSalt OPTIONAL,
* s2kparams [2] OCTET STRING OPTIONAL,
* }
*
* EncryptionKey ::= SEQUENCE {
* keytype [0] Int32,
* keyvalue [1] OCTET STRING
* }
*
* KrbSalt ::= SEQUENCE {
* type [0] Int32,
* salt [1] OCTET STRING
* }
*/
#define GK_REPLY_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 2)
#define GKREP_KEY_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 0)
#define GKREP_SALT_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
#define GKREP_S2KPARAMS_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 2)
#define GKREP_KEYTYPE_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 0)
#define GKREP_KEYVALUE_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
#define GKREP_SALTTYPE_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 0)
#define GKREP_SALTVALUE_TAG (LBER_CLASS_CONTEXT | LBER_CONSTRUCTED | 1)
static int encode_getkeytab_reply(krb5_context krbctx,
krb5_keyblock *kmkey, int mkvno,
krb5_key_data *keys, int num_keys,
struct berval **_bvp)
{
int rc = LDAP_OPERATIONS_ERROR;
struct krb_key_salt ksdata[num_keys];
struct keys_container ksc = { num_keys, ksdata };
struct berval *bvp = NULL;
int kvno;
bool ret;
BerElement *ber = NULL;
ber_int_t kvno;
krb5_data plain = { 0 };
memset(ksdata, '\0', num_keys * sizeof(struct krb_key_salt));
ber = ber_alloc();
if (!ber) {
LOG_OOM();
goto done;
}
/* uses last key kvno */
kvno = keys[num_keys-1].key_data_kvno;
rc = ber_printf(ber, "t{i{", GK_REPLY_TAG, kvno);
if (rc == -1) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to initiate key buffer\n");
goto done;
}
for (int i = 0; i < num_keys; i++) {
krb5_enc_data cipher = { 0 };
krb5_data plain = { 0 };
krb5_int16 plen;
void *p;
/* retrieve plain key */
memcpy(&plen, keys[i].key_data_contents[0], 2);
@@ -1405,12 +1478,13 @@ static int encode_getkeytab_reply(krb5_context krbctx,
cipher.kvno = mkvno;
plain.length = le16toh(plen);
plain.data = malloc(plain.length);
if (!plain.data) {
p = realloc(plain.data, plain.length);
if (!p) {
LOG_FATAL("Failed to allocate plain buffer\n");
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
plain.data = p;
rc = krb5_c_decrypt(krbctx, kmkey, 0, 0, &cipher, &plain);
if (rc) {
@@ -1419,37 +1493,68 @@ static int encode_getkeytab_reply(krb5_context krbctx,
goto done;
}
ksc.ksdata[i].enctype = keys[i].key_data_type[0];
ksc.ksdata[i].key.enctype = keys[i].key_data_type[0];
ksc.ksdata[i].key.contents = (void *)plain.data;
ksc.ksdata[i].key.length = plain.length;
rc = ber_printf(ber,
"{t{tito}",
GKREP_KEY_TAG,
GKREP_KEYTYPE_TAG,
(ber_int_t)keys[i].key_data_type[0],
GKREP_KEYVALUE_TAG,
plain.data, (ber_len_t)plain.length);
if (rc == -1) {
LOG_FATAL("Failed to encode key data\n");
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
/* if salt available, add it */
if (keys[i].key_data_length[1] != 0) {
ksc.ksdata[i].salttype = keys[i].key_data_type[1];
ksc.ksdata[i].salt.data = (void *)keys[i].key_data_contents[1];
ksc.ksdata[i].salt.length = keys[i].key_data_length[1];
rc = ber_printf(ber,
"t{tito}",
GKREP_SALT_TAG,
GKREP_SALTTYPE_TAG,
(ber_int_t)keys[i].key_data_type[1],
GKREP_SALTVALUE_TAG,
keys[i].key_data_contents[1],
(ber_len_t)keys[i].key_data_length[1]);
if (rc == -1) {
LOG_FATAL("Failed to encode salt data\n");
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
}
rc = ber_printf(ber, "}");
if (rc == -1) {
LOG_FATAL("Failed to encode data\n");
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
}
bvp = calloc(1, sizeof(struct berval));
if (!bvp) goto done;
rc = ber_printf(ber, "}}");
if (rc == -1) {
LOG_FATAL("Failed to terminate key buffer\n");
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
ret = ipaasn1_enc_getktreply(kvno, &ksc,
(void **)&bvp->bv_val, &bvp->bv_len);
if (!ret) goto done;
rc = ber_flatten(ber, &bvp);
if (rc == -1) {
LOG_FATAL("Failed to encode key buffer\n");
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
rc = LDAP_SUCCESS;
done:
for (int i = 0; i < ksc.nkeys; i ++) {
free(ksc.ksdata[i].key.contents);
}
if (rc != LDAP_SUCCESS) {
if (bvp) ber_bvfree(bvp);
} else {
*_bvp = bvp;
}
if (ber) ber_free(ber, 1);
free(plain.data);
return rc;
}
@@ -1534,6 +1639,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
krb5_context krbctx = NULL;
krb5_error_code krberr;
struct berval *extop_value = NULL;
BerElement *ber = NULL;
char *service_name = NULL;
char *svcname;
Slapi_Entry *target_entry = NULL;
@@ -1613,8 +1719,8 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
READKEYS_OP_CHECK, NULL,
SLAPI_ACL_READ);
if (!acl_ok) {
LOG_FATAL("Not allowed to retrieve keytab on [%s] as user [%s]!\n",
service_name, bind_dn);
LOG_FATAL("Not allowed to retrieve keytab on [%s]!\n",
service_name);
err_msg = "Insufficient access rights\n";
rc = LDAP_INSUFFICIENT_ACCESS;
goto free_and_return;
@@ -1634,7 +1740,23 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
goto free_and_return;
}
filter_enctypes(krbcfg, kenctypes, &num_kenctypes);
for (int i = 0; i < num_kenctypes; i++) {
/* Check if supported */
for (int j = 0; j < krbcfg->num_supp_encsalts; j++) {
if (kenctypes[i].ks_enctype ==
krbcfg->supp_encsalts[j].ks_enctype) {
continue;
}
}
/* Unsupported, filter out */
for (int j = i; j + 1 < num_kenctypes; j++) {
kenctypes[j].ks_enctype = kenctypes[j + 1].ks_enctype;
kenctypes[j].ks_salttype = kenctypes[j + 1].ks_salttype;
}
num_kenctypes--;
i--;
}
/* check if we have any left */
if (num_kenctypes == 0 && kenctypes != NULL) {
@@ -1649,7 +1771,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
data.target = target_entry;
data.password = password;
svals = ipapwd_encrypt_encode_key(krbcfg, &data, service_name,
svals = ipapwd_encrypt_encode_key(krbcfg, &data,
kenctypes ? num_kenctypes :
krbcfg->num_pref_encsalts,
kenctypes ? kenctypes :
@@ -1705,6 +1827,7 @@ free_and_return:
}
free(svals);
}
if (ber) ber_free(ber, 1);
if (bvp) ber_bvfree(bvp);
return SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
@@ -1795,6 +1918,16 @@ static int ipapwd_start( Slapi_PBlock *pb )
Slapi_Entry *config_entry = NULL;
int ret;
/* NOTE: We never call authcfg_fini() from a destructor. This is because
* it may race with threaded requests at shutdown. This leak should
* only occur when the DS is exiting, so it isn't a big deal.
*/
if (!authcfg_init()) {
LOG_FATAL("AuthConf initialization failed!\n");
ret = LDAP_OPERATIONS_ERROR;
goto done;
}
krberr = krb5_init_context(&krbctx);
if (krberr) {
LOG_FATAL("krb5_init_context failed\n");
@@ -1864,16 +1997,11 @@ static int ipapwd_start( Slapi_PBlock *pb )
ret = LDAP_SUCCESS;
/* NOTE: We never call otp_config_fini() from a destructor. This is because
* it may race with threaded requests at shutdown. This leak should
* only occur when the DS is exiting, so it isn't a big deal.
*/
otp_config = otp_config_init(ipapwd_plugin_id);
done:
free(realm);
krb5_free_context(krbctx);
if (config_entry) slapi_entry_free(config_entry);
if (ret != LDAP_SUCCESS) authcfg_fini();
return ret;
}

View File

@@ -41,7 +41,7 @@
# include <config.h>
#endif
#include "../libotp/otp_token.h"
#include <libotp.h>
#include <stdio.h>
#include <string.h>
@@ -143,7 +143,6 @@ void ipapwd_keyset_free(struct ipapwd_keyset **pkset);
Slapi_Value **ipapwd_encrypt_encode_key(struct ipapwd_krbcfg *krbcfg,
struct ipapwd_data *data,
char *preferred_principal,
int num_encsalts,
krb5_key_salt_tuple *encsalts,
char **errMesg);

View File

@@ -63,17 +63,18 @@
#include "ipapwd.h"
#include "util.h"
#include "syncreq.h"
#include "authcfg.h"
#define IPAPWD_OP_NULL 0
#define IPAPWD_OP_ADD 1
#define IPAPWD_OP_MOD 2
#define OTP_VALIDATE_STEPS 3
extern Slapi_PluginDesc ipapwd_plugin_desc;
extern void *ipapwd_plugin_id;
extern const char *ipa_realm_tree;
struct otp_config *otp_config = NULL;
/* structure with information for each extension */
struct ipapwd_op_ext {
char *object_name; /* name of the object extended */
@@ -151,43 +152,6 @@ done:
return value;
}
static bool has_krbprincipalkey(Slapi_Entry *entry) {
int rc;
krb5_key_data *keys = NULL;
int num_keys = 0;
int mkvno = 0;
int hint;
Slapi_Attr *attr;
Slapi_Value *keys_value;
const struct berval *bval;
if (slapi_entry_attr_find(entry, "krbPrincipalKey", &attr)) {
return false;
}
/* It exists a krbPrincipalKey attribute checks it exists a valid value */
for (hint = slapi_attr_first_value(attr, &keys_value);
hint != -1; hint = slapi_attr_next_value(attr, hint, &keys_value)) {
bval = slapi_value_get_berval(keys_value);
if (NULL != bval && NULL != bval->bv_val) {
rc = ber_decode_krb5_key_data(discard_const(bval),
&mkvno, &num_keys, &keys);
if (rc || (num_keys <= 0)) {
/* this one is not valid, ignore it */
if (keys) ipa_krb5_free_key_data(keys, num_keys);
} else {
/* It exists at least this one that is valid, no need to continue */
if (keys) ipa_krb5_free_key_data(keys, num_keys);
return true;
}
}
}
return false;
}
/* PRE ADD Operation:
* Gets the clean text password (fail the operation if the password came
@@ -282,17 +246,6 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
return 0;
}
/* With User Life Cycle, it could be a stage user that is activated.
* The userPassword and krb keys were set while the user was a stage user.
* Accept hashed userPassword and krb keys at the condition, it already contains
* 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");
return 0;
}
LOG("pre-hashed passwords are not valid\n");
errMesg = "pre-hashed passwords are not valid\n";
goto done;
@@ -683,8 +636,6 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
is_smb = 0;
is_ipant = 0;
/* After examining the output of covscan, we think that this
* fallthrough is intentional.*/
case LDAP_MOD_ADD:
if (!lmod->mod_bvalues ||
!lmod->mod_bvalues[0]) {
@@ -1016,9 +967,23 @@ static int ipapwd_regen_nthash(Slapi_PBlock *pb, Slapi_Mods *smods,
return ret;
}
static int ipapwd_post_updatecfg(Slapi_PBlock *pb)
static int ipapwd_post_authcfg(Slapi_PBlock *pb)
{
otp_config_update(otp_config, pb);
Slapi_Entry *config_entry = NULL;
Slapi_DN *sdn = NULL;
int oprc = 0;
/* Just bail if the operation failed. */
if (slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0 || oprc != 0)
return 0;
if (slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn) != 0)
return 0;
/* Ignore the error here (delete operations). */
slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &config_entry);
authcfg_reload_global_config(sdn, config_entry);
return 0;
}
@@ -1038,7 +1003,8 @@ static int ipapwd_post_modadd(Slapi_PBlock *pb)
LOG_TRACE("=>\n");
otp_config_update(otp_config, pb);
/* Ignore error when parsing configuration. */
ipapwd_post_authcfg(pb);
/* time to get the operation handler */
ret = slapi_pblock_get(pb, SLAPI_OPERATION, &op);
@@ -1161,8 +1127,8 @@ done:
}
/*
* This function handles the bind functionality for OTP. The return value
* indicates if the OTP portion of authentication was successful.
* Authenticates creds against OTP tokens. Returns true when authentication
* completed successfully against a token OR when a user has no active tokens.
*
* WARNING: This function DOES NOT authenticate the first factor. Only the OTP
* code is validated! You still need to validate the first factor.
@@ -1171,13 +1137,64 @@ done:
* value at the end. This leaves only the password in creds for later
* validation.
*/
static bool ipapwd_do_otp_auth(const char *dn, Slapi_Entry *bind_entry,
struct berval *creds)
{
struct otptoken **tokens = NULL;
bool success = false;
/* Find all of the user's active tokens. */
tokens = otptoken_find(ipapwd_plugin_id, dn, NULL, true, NULL);
if (tokens == NULL) {
slapi_log_error(SLAPI_LOG_FATAL, IPAPWD_PLUGIN_NAME,
"%s: can't find tokens for '%s'.\n", __func__, dn);
return false;
}
/* If the user has no active tokens, succeed. */
success = tokens[0] == NULL;
/* Loop through each token. */
for (int i = 0; tokens[i] && !success; i++) {
/* Attempt authentication. */
success = otptoken_validate_berval(tokens[i], OTP_VALIDATE_STEPS,
creds, true);
/* Truncate the password to remove the OTP code at the end. */
if (success) {
creds->bv_len -= otptoken_get_digits(tokens[i]);
creds->bv_val[creds->bv_len] = '\0';
}
slapi_log_error(SLAPI_LOG_PLUGIN, IPAPWD_PLUGIN_NAME,
"%s: token authentication %s "
"(user: '%s', token: '%s\').\n", __func__,
success ? "succeeded" : "failed", dn,
slapi_sdn_get_ndn(otptoken_get_sdn(tokens[i])));
}
otptoken_free_array(tokens);
return success;
}
/*
* This function handles the bind functionality for OTP. The return value
* indicates if the OTP portion of authentication was successful.
*
* NOTE: This function may modify creds. See explanation in the comment for
* ipapwd_do_otp_auth() above.
*/
static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
struct berval *creds)
{
uint32_t auth_types;
/* Get the configured authentication types. */
auth_types = otp_config_auth_types(otp_config, entry);
auth_types = authcfg_get_auth_types(entry);
/* If global disabled flag is set, just punt. */
if (auth_types & AUTHCFG_AUTH_TYPE_DISABLED)
return true;
/*
* IMPORTANT SECTION!
@@ -1189,36 +1206,14 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
* 2. If PWD is enabled or OTP succeeded, fall through to PWD validation.
*/
if (auth_types & OTP_CONFIG_AUTH_TYPE_OTP) {
struct otp_token **tokens = NULL;
if (auth_types & AUTHCFG_AUTH_TYPE_OTP) {
LOG_PLUGIN_NAME(IPAPWD_PLUGIN_NAME,
"Attempting OTP authentication for '%s'.\n", bind_dn);
/* Find all of the user's active tokens. */
tokens = otp_token_find(otp_config, bind_dn, NULL, true, NULL);
if (tokens == NULL) {
slapi_log_error(SLAPI_LOG_FATAL, IPAPWD_PLUGIN_NAME,
"%s: can't find tokens for '%s'.\n",
__func__, bind_dn);
return false;
}
/* If the user has no active tokens, succeed. */
if (tokens[0] == NULL) {
otp_token_free_array(tokens);
if (ipapwd_do_otp_auth(bind_dn, entry, creds))
return true;
}
if (otp_token_validate_berval(tokens, creds, NULL)) {
otp_token_free_array(tokens);
return true;
}
otp_token_free_array(tokens);
}
return auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD;
return auth_types & AUTHCFG_AUTH_TYPE_PASSWORD;
}
static int ipapwd_authenticate(const char *dn, Slapi_Entry *entry,
@@ -1386,7 +1381,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
static const char *attrs_list[] = {
SLAPI_USERPWD_ATTR, "ipaUserAuthType", "krbprincipalkey", "uid",
"krbprincipalname", "objectclass", "passwordexpirationtime",
"passwordhistory", "krbprincipalexpiration", "krbcanonicalname",
"passwordhistory", "krbprincipalexpiration",
NULL
};
struct berval *credentials = NULL;
@@ -1466,7 +1461,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
}
/* Attempt to handle a token synchronization request. */
if (syncreq && !sync_request_handle(otp_config, pb, dn))
if (syncreq && !sync_request_handle(ipapwd_get_plugin_id(), pb, dn))
goto invalid_creds;
/* Attempt to write out kerberos keys for the user. */
@@ -1518,9 +1513,9 @@ int ipapwd_post_init(Slapi_PBlock *pb)
ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&ipapwd_plugin_desc);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN, (void *)ipapwd_post_modadd);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN, (void *)ipapwd_post_updatecfg);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN, (void *)ipapwd_post_authcfg);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN, (void *)ipapwd_post_modadd);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, (void *)ipapwd_post_updatecfg);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, (void *)ipapwd_post_authcfg);
return ret;
}
@@ -1531,10 +1526,10 @@ int ipapwd_intpost_init(Slapi_PBlock *pb)
ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&ipapwd_plugin_desc);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN, (void *)ipapwd_post_updatecfg);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN, (void *)ipapwd_post_updatecfg);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN, (void *)ipapwd_post_updatecfg);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN, (void *)ipapwd_post_updatecfg);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN, (void *)ipapwd_post_authcfg);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN, (void *)ipapwd_post_authcfg);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN, (void *)ipapwd_post_authcfg);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN, (void *)ipapwd_post_authcfg);
return ret;
}

View File

@@ -37,9 +37,12 @@
* All rights reserved.
* END COPYRIGHT BLOCK **/
#include "../libotp/otp_token.h"
#include <libotp.h>
#include "syncreq.h"
#define OTP_SYNC_MAX_STEPS 25
bool sync_request_present(Slapi_PBlock *pb)
{
LDAPControl **controls = NULL;
@@ -50,10 +53,10 @@ bool sync_request_present(Slapi_PBlock *pb)
return ldap_control_find(OTP_SYNC_REQUEST_OID, controls, NULL) != NULL;
}
bool sync_request_handle(const struct otp_config *cfg, Slapi_PBlock *pb,
bool sync_request_handle(Slapi_ComponentId *plugin_id, Slapi_PBlock *pb,
const char *user_dn)
{
struct otp_token **tokens = NULL;
struct otptoken **tokens = NULL;
LDAPControl **controls = NULL;
struct berval *second = NULL;
struct berval *first = NULL;
@@ -83,15 +86,15 @@ bool sync_request_handle(const struct otp_config *cfg, Slapi_PBlock *pb,
}
/* Decode the optional token DN. */
(void)ber_scanf(ber, "a", &token_dn);
ber_scanf(ber, "a", &token_dn);
/* Process the synchronization. */
success = false;
if (ber_scanf(ber, "}") != LBER_ERROR) {
tokens = otp_token_find(cfg, user_dn, token_dn, true, NULL);
tokens = otptoken_find(plugin_id, user_dn, token_dn, true, NULL);
if (tokens != NULL) {
success = otp_token_validate_berval(tokens, first, second);
otp_token_free_array(tokens);
success = otptoken_sync_berval(tokens, OTP_SYNC_MAX_STEPS, first, second);
otptoken_free_array(tokens);
}
}

View File

@@ -41,7 +41,7 @@
#ifndef SYNCREQ_H_
#define SYNCREQ_H_
#include "../libotp/otp_config.h"
#include <dirsrv/slapi-plugin.h>
#include <stdbool.h>
/*
@@ -57,7 +57,7 @@
bool sync_request_present(Slapi_PBlock *pb);
bool sync_request_handle(const struct otp_config *cfg, Slapi_PBlock *pb,
bool sync_request_handle(Slapi_ComponentId *plugin_id, Slapi_PBlock *pb,
const char *user_dn);
#endif /* SYNCREQ_H_ */