mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Teach ipa-pwd-extop to respect global ipaUserAuthType settings
https://fedorahosted.org/freeipa/ticket/4105 Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
This commit is contained in:
parent
a51b07c275
commit
9f62d0c157
@ -40,6 +40,7 @@ plugindir = $(libdir)/dirsrv/plugins
|
|||||||
plugin_LTLIBRARIES = libipa_pwd_extop.la
|
plugin_LTLIBRARIES = libipa_pwd_extop.la
|
||||||
libipa_pwd_extop_la_LIBADD = $(builddir)/../libotp/libotp.la
|
libipa_pwd_extop_la_LIBADD = $(builddir)/../libotp/libotp.la
|
||||||
libipa_pwd_extop_la_SOURCES = \
|
libipa_pwd_extop_la_SOURCES = \
|
||||||
|
authcfg.c \
|
||||||
common.c \
|
common.c \
|
||||||
encoding.c \
|
encoding.c \
|
||||||
prepost.c \
|
prepost.c \
|
||||||
|
280
daemons/ipa-slapi-plugins/ipa-pwd-extop/authcfg.c
Normal file
280
daemons/ipa-slapi-plugins/ipa-pwd-extop/authcfg.c
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
82
daemons/ipa-slapi-plugins/ipa-pwd-extop/authcfg.h
Normal file
82
daemons/ipa-slapi-plugins/ipa-pwd-extop/authcfg.h
Normal 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_ */
|
@ -70,133 +70,6 @@ static const char *ipapwd_def_encsalts[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static PRInt32 g_allowed_auth_types = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Checks if an authentication type is allowed. A NULL terminated
|
|
||||||
* list of allowed auth type values is passed in along with the flag
|
|
||||||
* for the auth type you are inquiring about. If auth_type_list is
|
|
||||||
* NULL, the global config will be consulted.
|
|
||||||
*/
|
|
||||||
bool ipapwd_is_auth_type_allowed(char **auth_type_list, int auth_type)
|
|
||||||
{
|
|
||||||
char *auth_type_value = NULL;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
/* Get the string value for the authentication type we are checking for. */
|
|
||||||
switch (auth_type) {
|
|
||||||
case IPA_OTP_AUTH_TYPE_OTP:
|
|
||||||
auth_type_value = IPA_OTP_AUTH_TYPE_VALUE_OTP;
|
|
||||||
break;
|
|
||||||
case IPA_OTP_AUTH_TYPE_PASSWORD:
|
|
||||||
auth_type_value = IPA_OTP_AUTH_TYPE_VALUE_PASSWORD;
|
|
||||||
break;
|
|
||||||
case IPA_OTP_AUTH_TYPE_PKINIT:
|
|
||||||
auth_type_value = IPA_OTP_AUTH_TYPE_VALUE_PKINIT;
|
|
||||||
break;
|
|
||||||
default: /* Unknown type.*/
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auth_type_list == NULL) {
|
|
||||||
/* Check if the requested authentication type is in the global list. */
|
|
||||||
PRInt32 auth_type_flags;
|
|
||||||
|
|
||||||
/* Do an atomic read of the allowed auth types bit field. */
|
|
||||||
auth_type_flags = PR_ATOMIC_ADD(&g_allowed_auth_types, 0);
|
|
||||||
|
|
||||||
/* Check if the flag for the desired auth type is set. */
|
|
||||||
return auth_type_flags & auth_type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the requested authentication type is in the user list. */
|
|
||||||
for (i = 0; auth_type_list[i]; i++) {
|
|
||||||
if (strcasecmp(auth_type_list[i], auth_type_value) == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Parses and validates an OTP config entry. If apply is non-zero, then
|
|
||||||
* we will load and start using the new config. You can simply
|
|
||||||
* validate config without making any changes by setting apply to false.
|
|
||||||
*/
|
|
||||||
bool ipapwd_parse_otp_config_entry(Slapi_Entry * e, bool apply)
|
|
||||||
{
|
|
||||||
PRInt32 allowed_auth_types = 0;
|
|
||||||
PRInt32 default_auth_types = 0;
|
|
||||||
char **auth_types = NULL;
|
|
||||||
|
|
||||||
/* If no auth types are set, we default to only allowing password
|
|
||||||
* authentication. Other authentication types can be allowed at the
|
|
||||||
* user level. */
|
|
||||||
default_auth_types |= IPA_OTP_AUTH_TYPE_PASSWORD;
|
|
||||||
|
|
||||||
if (e == NULL) {
|
|
||||||
/* There is no config entry, so just set the defaults. */
|
|
||||||
allowed_auth_types = default_auth_types;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse and validate the config entry. We currently tolerate invalid
|
|
||||||
* config settings, so there is no real validation performed. We will
|
|
||||||
* likely want to reject invalid config as we expand the plug-in
|
|
||||||
* functionality, so the validation logic is here for us to use later. */
|
|
||||||
|
|
||||||
/* Fetch the auth type values from the config entry. */
|
|
||||||
auth_types = slapi_entry_attr_get_charray(e, IPA_OTP_USER_AUTH_TYPE);
|
|
||||||
if (auth_types == NULL) {
|
|
||||||
/* No allowed auth types are specified, so set the defaults. */
|
|
||||||
allowed_auth_types = default_auth_types;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check each type to see if it is set. */
|
|
||||||
if (ipapwd_is_auth_type_allowed(auth_types, IPA_OTP_AUTH_TYPE_DISABLED)) {
|
|
||||||
allowed_auth_types |= IPA_OTP_AUTH_TYPE_DISABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipapwd_is_auth_type_allowed(auth_types, IPA_OTP_AUTH_TYPE_PASSWORD)) {
|
|
||||||
allowed_auth_types |= IPA_OTP_AUTH_TYPE_PASSWORD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipapwd_is_auth_type_allowed(auth_types, IPA_OTP_AUTH_TYPE_OTP)) {
|
|
||||||
allowed_auth_types |= IPA_OTP_AUTH_TYPE_OTP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipapwd_is_auth_type_allowed(auth_types, IPA_OTP_AUTH_TYPE_PKINIT)) {
|
|
||||||
allowed_auth_types |= IPA_OTP_AUTH_TYPE_PKINIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipapwd_is_auth_type_allowed(auth_types, IPA_OTP_AUTH_TYPE_RADIUS)) {
|
|
||||||
allowed_auth_types |= IPA_OTP_AUTH_TYPE_RADIUS;
|
|
||||||
}
|
|
||||||
|
|
||||||
slapi_ch_array_free(auth_types);
|
|
||||||
|
|
||||||
done:
|
|
||||||
if (apply) {
|
|
||||||
/* Atomically set the global allowed types. */
|
|
||||||
PR_ATOMIC_SET(&g_allowed_auth_types, allowed_auth_types);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ipapwd_otp_is_disabled(void)
|
|
||||||
{
|
|
||||||
PRInt32 auth_type_flags;
|
|
||||||
|
|
||||||
/* Do an atomic read of the allowed auth types bit field. */
|
|
||||||
auth_type_flags = PR_ATOMIC_ADD(&g_allowed_auth_types, 0);
|
|
||||||
|
|
||||||
/* Check if the disabled bit is set. */
|
|
||||||
return auth_type_flags & IPA_OTP_AUTH_TYPE_DISABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
static struct ipapwd_krbcfg *ipapwd_getConfig(void)
|
||||||
{
|
{
|
||||||
krb5_error_code krberr;
|
krb5_error_code krberr;
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include "ipapwd.h"
|
#include "ipapwd.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "authcfg.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Password Modify - LDAP Extended Operation.
|
* Password Modify - LDAP Extended Operation.
|
||||||
@ -87,30 +88,11 @@ Slapi_PluginDesc ipapwd_plugin_desc = {
|
|||||||
void *ipapwd_plugin_id;
|
void *ipapwd_plugin_id;
|
||||||
static int usetxn = 0;
|
static int usetxn = 0;
|
||||||
|
|
||||||
static Slapi_DN *_ConfigAreaDN = NULL;
|
|
||||||
static Slapi_DN *_PluginDN = NULL;
|
|
||||||
static bool g_plugin_started = false;
|
|
||||||
|
|
||||||
void *ipapwd_get_plugin_id(void)
|
void *ipapwd_get_plugin_id(void)
|
||||||
{
|
{
|
||||||
return ipapwd_plugin_id;
|
return ipapwd_plugin_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
Slapi_DN *ipapwd_get_otp_config_area(void)
|
|
||||||
{
|
|
||||||
return _ConfigAreaDN;
|
|
||||||
}
|
|
||||||
|
|
||||||
Slapi_DN *ipapwd_get_plugin_sdn(void)
|
|
||||||
{
|
|
||||||
return _PluginDN;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ipapwd_get_plugin_started(void)
|
|
||||||
{
|
|
||||||
return g_plugin_started;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int filter_keys(struct ipapwd_krbcfg *krbcfg,
|
static int filter_keys(struct ipapwd_krbcfg *krbcfg,
|
||||||
struct ipapwd_keyset *kset)
|
struct ipapwd_keyset *kset)
|
||||||
{
|
{
|
||||||
@ -1222,40 +1204,6 @@ Slapi_Filter *ipapwd_string2filter(char *strfilter)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Loads the OTP config entry, parses it, and applies it. */
|
|
||||||
static bool ipapwd_load_otp_config(void)
|
|
||||||
{
|
|
||||||
char *config_attrs[] = { IPA_USER_AUTH_TYPE, NULL };
|
|
||||||
Slapi_Entry *config_entry = NULL;
|
|
||||||
Slapi_DN *config_sdn = NULL;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* If we are using an alternate config area, check it for our
|
|
||||||
* configuration, otherwise we just use our main plug-in config
|
|
||||||
* entry. */
|
|
||||||
if ((config_sdn = ipapwd_get_otp_config_area()) == NULL) {
|
|
||||||
config_sdn = ipapwd_get_plugin_sdn();
|
|
||||||
}
|
|
||||||
|
|
||||||
slapi_log_error(SLAPI_LOG_PLUGIN, IPAPWD_PLUGIN_NAME,
|
|
||||||
"Looking for config settings in \"%s\".\n",
|
|
||||||
config_sdn ? slapi_sdn_get_ndn(config_sdn) : "null");
|
|
||||||
|
|
||||||
/* Fetch the config entry. */
|
|
||||||
ret = slapi_search_internal_get_entry(config_sdn, config_attrs,
|
|
||||||
&config_entry, ipapwd_plugin_id);
|
|
||||||
if (ret != LDAP_SUCCESS) {
|
|
||||||
LOG_TRACE("Search for OTP config failed, err (%d)\n", ret);
|
|
||||||
/* fall through, defaults will be set */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Parse and apply the config. */
|
|
||||||
ipapwd_parse_otp_config_entry(config_entry, true);
|
|
||||||
|
|
||||||
slapi_entry_free(config_entry);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Init data structs */
|
/* Init data structs */
|
||||||
static int ipapwd_start( Slapi_PBlock *pb )
|
static int ipapwd_start( Slapi_PBlock *pb )
|
||||||
{
|
{
|
||||||
@ -1264,35 +1212,16 @@ static int ipapwd_start( Slapi_PBlock *pb )
|
|||||||
char *realm = NULL;
|
char *realm = NULL;
|
||||||
char *config_dn;
|
char *config_dn;
|
||||||
Slapi_Entry *config_entry = NULL;
|
Slapi_Entry *config_entry = NULL;
|
||||||
Slapi_DN *plugindn = NULL;
|
|
||||||
char *config_area = NULL;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Check if we're already started */
|
/* NOTE: We never call authcfg_fini() from a destructor. This is because
|
||||||
if (g_plugin_started) {
|
* it may race with threaded requests at shutdown. This leak should
|
||||||
return LDAP_SUCCESS;
|
* only occur when the DS is exiting, so it isn't a big deal.
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the plug-in target dn from the system and store for future use. */
|
|
||||||
slapi_pblock_get(pb, SLAPI_TARGET_SDN, &plugindn);
|
|
||||||
if (plugindn == NULL || slapi_sdn_get_ndn_len(plugindn) == 0) {
|
|
||||||
LOG_FATAL("No plugin dn?\n");
|
|
||||||
return LDAP_OPERATIONS_ERROR;
|
|
||||||
}
|
|
||||||
_PluginDN = slapi_sdn_dup(plugindn);
|
|
||||||
|
|
||||||
/* Set the alternate config area if one is defined. */
|
|
||||||
slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_AREA, &config_area);
|
|
||||||
if (config_area != NULL) {
|
|
||||||
_ConfigAreaDN = slapi_sdn_new_normdn_byval(config_area);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Load the config.
|
|
||||||
*/
|
*/
|
||||||
if (!ipapwd_load_otp_config()) {
|
if (!authcfg_init()) {
|
||||||
LOG_FATAL("Unable to load plug-in config\n");
|
LOG_FATAL("AuthConf initialization failed!\n");
|
||||||
return LDAP_OPERATIONS_ERROR;
|
ret = LDAP_OPERATIONS_ERROR;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
krberr = krb5_init_context(&krbctx);
|
krberr = krb5_init_context(&krbctx);
|
||||||
@ -1363,35 +1292,15 @@ static int ipapwd_start( Slapi_PBlock *pb )
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = LDAP_SUCCESS;
|
ret = LDAP_SUCCESS;
|
||||||
g_plugin_started = true;
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
free(realm);
|
free(realm);
|
||||||
krb5_free_context(krbctx);
|
krb5_free_context(krbctx);
|
||||||
if (config_entry) slapi_entry_free(config_entry);
|
if (config_entry) slapi_entry_free(config_entry);
|
||||||
|
if (ret != LDAP_SUCCESS) authcfg_fini();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clean up any resources allocated at startup. */
|
|
||||||
static int ipapwd_close(Slapi_PBlock * pb)
|
|
||||||
{
|
|
||||||
if (!g_plugin_started) {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_plugin_started = false;
|
|
||||||
|
|
||||||
/* We are not guaranteed that other threads are finished accessing
|
|
||||||
* PluginDN or ConfigAreaDN, so we don't want to free them. This is
|
|
||||||
* only a one-time leak at shutdown, so it should be fine.
|
|
||||||
* slapi_sdn_free(&_PluginDN);
|
|
||||||
* slapi_sdn_free(&_ConfigAreaDN);
|
|
||||||
*/
|
|
||||||
|
|
||||||
done:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *ipapwd_oid_list[] = {
|
static char *ipapwd_oid_list[] = {
|
||||||
EXOP_PASSWD_OID,
|
EXOP_PASSWD_OID,
|
||||||
KEYTAB_SET_OID,
|
KEYTAB_SET_OID,
|
||||||
@ -1443,7 +1352,6 @@ int ipapwd_init( Slapi_PBlock *pb )
|
|||||||
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_EXT_OP_OIDLIST, ipapwd_oid_list);
|
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_EXT_OP_OIDLIST, ipapwd_oid_list);
|
||||||
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_EXT_OP_NAMELIST, ipapwd_name_list);
|
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_EXT_OP_NAMELIST, ipapwd_name_list);
|
||||||
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_EXT_OP_FN, (void *)ipapwd_extop);
|
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_EXT_OP_FN, (void *)ipapwd_extop);
|
||||||
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *)ipapwd_close);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG("Failed to set plug-in version, function, and OID.\n" );
|
LOG("Failed to set plug-in version, function, and OID.\n" );
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -76,30 +76,6 @@
|
|||||||
#define IPA_CHANGETYPE_ADMIN 1
|
#define IPA_CHANGETYPE_ADMIN 1
|
||||||
#define IPA_CHANGETYPE_DSMGR 2
|
#define IPA_CHANGETYPE_DSMGR 2
|
||||||
|
|
||||||
/*
|
|
||||||
* Attribute type defines
|
|
||||||
*/
|
|
||||||
#define IPA_USER_AUTH_TYPE "ipaUserAuthType"
|
|
||||||
#define IPA_OTP_TOKEN_OWNER_TYPE "ipaTokenOwner"
|
|
||||||
#define IPA_OTP_TOKEN_LENGTH_TYPE "ipaTokenOTPDigits"
|
|
||||||
#define IPA_OTP_TOKEN_KEY_TYPE "ipaTokenOTPKey"
|
|
||||||
#define IPA_OTP_TOKEN_ALGORITHM_TYPE "ipaTokenOTPAlgorithm"
|
|
||||||
#define IPA_OTP_TOKEN_OFFSET_TYPE "ipaTokenTOTPClockOffset"
|
|
||||||
#define IPA_OTP_TOKEN_STEP_TYPE "ipaTokenTOTPTimeStep"
|
|
||||||
|
|
||||||
/* Authentication type defines */
|
|
||||||
#define IPA_OTP_AUTH_TYPE_NONE 0
|
|
||||||
#define IPA_OTP_AUTH_TYPE_DISABLED 1
|
|
||||||
#define IPA_OTP_AUTH_TYPE_PASSWORD 2
|
|
||||||
#define IPA_OTP_AUTH_TYPE_OTP 4
|
|
||||||
#define IPA_OTP_AUTH_TYPE_PKINIT 8
|
|
||||||
#define IPA_OTP_AUTH_TYPE_RADIUS 16
|
|
||||||
#define IPA_OTP_AUTH_TYPE_VALUE_DISABLED "DISABLED"
|
|
||||||
#define IPA_OTP_AUTH_TYPE_VALUE_PASSWORD "PASSWORD"
|
|
||||||
#define IPA_OTP_AUTH_TYPE_VALUE_OTP "OTP"
|
|
||||||
#define IPA_OTP_AUTH_TYPE_VALUE_PKINIT "PKINIT"
|
|
||||||
#define IPA_OTP_AUTH_TYPE_VALUE_RADIUS "RADIUS"
|
|
||||||
|
|
||||||
struct ipapwd_data {
|
struct ipapwd_data {
|
||||||
Slapi_Entry *target;
|
Slapi_Entry *target;
|
||||||
char *dn;
|
char *dn;
|
||||||
@ -135,9 +111,6 @@ struct ipapwd_krbcfg {
|
|||||||
bool allow_nt_hash;
|
bool allow_nt_hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool ipapwd_is_auth_type_allowed(char **auth_type_list, int auth_type);
|
|
||||||
bool ipapwd_parse_otp_config_entry(Slapi_Entry * e, bool apply);
|
|
||||||
bool ipapwd_otp_is_disabled(void);
|
|
||||||
int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
|
int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
|
||||||
int *is_root, int *is_krb, int *is_smb, int *is_ipant,
|
int *is_root, int *is_krb, int *is_smb, int *is_ipant,
|
||||||
char *attr, int access);
|
char *attr, int access);
|
||||||
@ -184,6 +157,3 @@ int ipapwd_post_init_betxn(Slapi_PBlock *pb);
|
|||||||
|
|
||||||
/* from ipa_pwd_extop.c */
|
/* from ipa_pwd_extop.c */
|
||||||
void *ipapwd_get_plugin_id(void);
|
void *ipapwd_get_plugin_id(void);
|
||||||
Slapi_DN *ipapwd_get_otp_config_area(void);
|
|
||||||
Slapi_DN *ipapwd_get_plugin_sdn(void);
|
|
||||||
bool ipapwd_get_plugin_started(void);
|
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
#include "ipapwd.h"
|
#include "ipapwd.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "syncreq.h"
|
#include "syncreq.h"
|
||||||
|
#include "authcfg.h"
|
||||||
|
|
||||||
#define IPAPWD_OP_NULL 0
|
#define IPAPWD_OP_NULL 0
|
||||||
#define IPAPWD_OP_ADD 1
|
#define IPAPWD_OP_ADD 1
|
||||||
@ -966,73 +967,23 @@ static int ipapwd_regen_nthash(Slapi_PBlock *pb, Slapi_Mods *smods,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static int ipapwd_post_authcfg(Slapi_PBlock *pb)
|
||||||
* Check if we want to process this operation. We need to be
|
|
||||||
* sure that the operation succeeded.
|
|
||||||
*/
|
|
||||||
static bool ipapwd_otp_oktodo(Slapi_PBlock *pb)
|
|
||||||
{
|
|
||||||
bool ok = false;
|
|
||||||
int oprc = 0;
|
|
||||||
int ret = 1;
|
|
||||||
|
|
||||||
ret = slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc);
|
|
||||||
if (ret != 0) {
|
|
||||||
LOG_FATAL("Could not get parameters\n");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This plugin should only execute if the operation succeeded. */
|
|
||||||
ok = oprc == 0;
|
|
||||||
|
|
||||||
done:
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ipapwd_dn_is_otp_config(Slapi_DN *sdn)
|
|
||||||
{
|
|
||||||
bool ret = false;
|
|
||||||
Slapi_DN *dn;
|
|
||||||
|
|
||||||
/* If an alternate config area is configured, it is considered to be
|
|
||||||
* the config entry, otherwise the main plug-in config entry is used. */
|
|
||||||
if (sdn != NULL) {
|
|
||||||
dn = ipapwd_get_otp_config_area();
|
|
||||||
if (dn == NULL)
|
|
||||||
dn = ipapwd_get_plugin_sdn();
|
|
||||||
|
|
||||||
ret = slapi_sdn_compare(sdn, dn) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ipapwd_post_modadd_otp(Slapi_PBlock *pb)
|
|
||||||
{
|
{
|
||||||
Slapi_Entry *config_entry = NULL;
|
Slapi_Entry *config_entry = NULL;
|
||||||
Slapi_DN *sdn = NULL;
|
Slapi_DN *sdn = NULL;
|
||||||
|
int oprc = 0;
|
||||||
|
|
||||||
/* Just bail if we are not started yet, or if the operation failed. */
|
/* Just bail if the operation failed. */
|
||||||
if (!ipapwd_get_plugin_started() || !ipapwd_otp_oktodo(pb)) {
|
if (slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0 || oprc != 0)
|
||||||
goto done;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if a change affected our config entry and reload the
|
if (slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn) != 0)
|
||||||
* in-memory config settings if needed. */
|
return 0;
|
||||||
slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
|
|
||||||
if (ipapwd_dn_is_otp_config(sdn)) {
|
|
||||||
/* The config entry was added or modified, so reload it from
|
|
||||||
* the post-op entry. */
|
|
||||||
slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &config_entry);
|
|
||||||
if (config_entry == NULL) {
|
|
||||||
LOG_FATAL("Unable to retrieve config entry.\n");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
ipapwd_parse_otp_config_entry(config_entry, true);
|
/* Ignore the error here (delete operations). */
|
||||||
}
|
slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &config_entry);
|
||||||
|
|
||||||
done:
|
authcfg_reload_global_config(sdn, config_entry);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1052,10 +1003,8 @@ static int ipapwd_post_modadd(Slapi_PBlock *pb)
|
|||||||
|
|
||||||
LOG_TRACE("=>\n");
|
LOG_TRACE("=>\n");
|
||||||
|
|
||||||
ret = ipapwd_post_modadd_otp(pb);
|
/* Ignore error when parsing configuration. */
|
||||||
if (ret != 0) {
|
ipapwd_post_authcfg(pb);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* time to get the operation handler */
|
/* time to get the operation handler */
|
||||||
ret = slapi_pblock_get(pb, SLAPI_OPERATION, &op);
|
ret = slapi_pblock_get(pb, SLAPI_OPERATION, &op);
|
||||||
@ -1177,70 +1126,6 @@ done:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ipapwd_post_modrdn_otp(Slapi_PBlock *pb)
|
|
||||||
{
|
|
||||||
Slapi_Entry *config_entry = NULL;
|
|
||||||
Slapi_DN *new_sdn = NULL;
|
|
||||||
Slapi_DN *sdn = NULL;
|
|
||||||
|
|
||||||
/* Just bail if we are not started yet, or if the operation failed. */
|
|
||||||
if (!ipapwd_get_plugin_started() || !ipapwd_otp_oktodo(pb)) {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if a change affected our config entry and reload the
|
|
||||||
* in-memory config settings if needed. */
|
|
||||||
slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
|
|
||||||
if (ipapwd_dn_is_otp_config(sdn)) {
|
|
||||||
/* Our config entry was renamed. We treat this like the entry
|
|
||||||
* was deleted, so just set the defaults. */
|
|
||||||
ipapwd_parse_otp_config_entry(NULL, true);
|
|
||||||
} else {
|
|
||||||
/* Check if an entry was renamed such that it has become our
|
|
||||||
* config entry. If so, reload the config from this new entry. */
|
|
||||||
slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &config_entry);
|
|
||||||
if (config_entry == NULL) {
|
|
||||||
LOG_FATAL("Unable to retrieve renamed entry.\n");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
new_sdn = slapi_entry_get_sdn(config_entry);
|
|
||||||
if (new_sdn == NULL) {
|
|
||||||
LOG_FATAL("Unable to retrieve DN of renamed entry.\n");
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipapwd_dn_is_otp_config(new_sdn)) {
|
|
||||||
ipapwd_parse_otp_config_entry(config_entry, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ipapwd_post_del_otp(Slapi_PBlock *pb)
|
|
||||||
{
|
|
||||||
Slapi_DN *sdn = NULL;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
/* Just bail if we are not started yet, or if the operation failed. */
|
|
||||||
if (!ipapwd_get_plugin_started() || !ipapwd_otp_oktodo(pb)) {
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if a change affected our config entry and reload the
|
|
||||||
* in-memory config settings if needed. */
|
|
||||||
slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
|
|
||||||
if (ipapwd_dn_is_otp_config(sdn)) {
|
|
||||||
/* The config entry was deleted, so this just sets the defaults. */
|
|
||||||
ipapwd_parse_otp_config_entry(NULL, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Authenticates creds against OTP tokens. Returns true when authentication
|
* Authenticates creds against OTP tokens. Returns true when authentication
|
||||||
* completed successfully against a token OR when a user has no active tokens.
|
* completed successfully against a token OR when a user has no active tokens.
|
||||||
@ -1302,16 +1187,13 @@ static bool ipapwd_do_otp_auth(const char *dn, Slapi_Entry *bind_entry,
|
|||||||
static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
|
static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
|
||||||
struct berval *creds)
|
struct berval *creds)
|
||||||
{
|
{
|
||||||
char **auth_types = NULL;
|
uint32_t auth_types;
|
||||||
bool otpauth;
|
|
||||||
bool pwdauth;
|
|
||||||
|
|
||||||
/* If we didn't start successfully, bail. */
|
/* Get the configured authentication types. */
|
||||||
if (!ipapwd_get_plugin_started())
|
auth_types = authcfg_get_auth_types(entry);
|
||||||
return true;
|
|
||||||
|
|
||||||
/* If global disabled flag is set, just punt. */
|
/* If global disabled flag is set, just punt. */
|
||||||
if (ipapwd_otp_is_disabled())
|
if (auth_types & AUTHCFG_AUTH_TYPE_DISABLED)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1323,19 +1205,15 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
|
|||||||
* 1. If OTP is enabled, validate OTP.
|
* 1. If OTP is enabled, validate OTP.
|
||||||
* 2. If PWD is enabled or OTP succeeded, fall through to PWD validation.
|
* 2. If PWD is enabled or OTP succeeded, fall through to PWD validation.
|
||||||
*/
|
*/
|
||||||
auth_types = slapi_entry_attr_get_charray(entry, IPA_USER_AUTH_TYPE);
|
|
||||||
otpauth = ipapwd_is_auth_type_allowed(auth_types, IPA_OTP_AUTH_TYPE_OTP);
|
|
||||||
pwdauth = ipapwd_is_auth_type_allowed(auth_types, IPA_OTP_AUTH_TYPE_PASSWORD);
|
|
||||||
slapi_ch_array_free(auth_types);
|
|
||||||
|
|
||||||
if (otpauth) {
|
if (auth_types & AUTHCFG_AUTH_TYPE_OTP) {
|
||||||
LOG_PLUGIN_NAME(IPAPWD_PLUGIN_NAME,
|
LOG_PLUGIN_NAME(IPAPWD_PLUGIN_NAME,
|
||||||
"Attempting OTP authentication for '%s'.\n", bind_dn);
|
"Attempting OTP authentication for '%s'.\n", bind_dn);
|
||||||
if (ipapwd_do_otp_auth(bind_dn, entry, creds))
|
if (ipapwd_do_otp_auth(bind_dn, entry, creds))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pwdauth;
|
return auth_types & AUTHCFG_AUTH_TYPE_PASSWORD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ipapwd_authenticate(const char *dn, Slapi_Entry *entry,
|
static int ipapwd_authenticate(const char *dn, Slapi_Entry *entry,
|
||||||
@ -1501,7 +1379,7 @@ done:
|
|||||||
static int ipapwd_pre_bind(Slapi_PBlock *pb)
|
static int ipapwd_pre_bind(Slapi_PBlock *pb)
|
||||||
{
|
{
|
||||||
static const char *attrs_list[] = {
|
static const char *attrs_list[] = {
|
||||||
SLAPI_USERPWD_ATTR, IPA_USER_AUTH_TYPE, "krbprincipalkey", "uid",
|
SLAPI_USERPWD_ATTR, "ipaUserAuthType", "krbprincipalkey", "uid",
|
||||||
"krbprincipalname", "objectclass", "passwordexpirationtime",
|
"krbprincipalname", "objectclass", "passwordexpirationtime",
|
||||||
"passwordhistory",
|
"passwordhistory",
|
||||||
NULL
|
NULL
|
||||||
@ -1599,9 +1477,9 @@ int ipapwd_post_init(Slapi_PBlock *pb)
|
|||||||
ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01);
|
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_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_ADD_FN, (void *)ipapwd_post_modadd);
|
||||||
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN, (void *)ipapwd_post_del_otp);
|
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_MODIFY_FN, (void *)ipapwd_post_modadd);
|
||||||
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, (void *)ipapwd_post_modrdn_otp);
|
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, (void *)ipapwd_post_authcfg);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1612,10 +1490,10 @@ int ipapwd_intpost_init(Slapi_PBlock *pb)
|
|||||||
|
|
||||||
ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03);
|
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_DESCRIPTION, (void *)&ipapwd_plugin_desc);
|
||||||
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN, (void *)ipapwd_post_modadd_otp);
|
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_del_otp);
|
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_modadd_otp);
|
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_modrdn_otp);
|
if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN, (void *)ipapwd_post_authcfg);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user