summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--src/config/etc/sssd.api.d/sssd-ad.conf1
-rw-r--r--src/config/etc/sssd.api.d/sssd-ipa.conf1
-rw-r--r--src/config/etc/sssd.api.d/sssd-ldap.conf1
-rw-r--r--src/man/sssd-ldap.5.xml31
-rw-r--r--src/providers/ad/ad_opts.h1
-rw-r--r--src/providers/ipa/ipa_opts.h1
-rw-r--r--src/providers/ldap/ldap_id.c39
-rw-r--r--src/providers/ldap/ldap_opts.h1
-rw-r--r--src/providers/ldap/sdap.h1
-rw-r--r--src/providers/ldap/sdap_async_initgroups.c17
-rw-r--r--src/providers/ldap/sdap_async_private.h10
-rw-r--r--src/providers/ldap/sdap_async_users.c91
-rw-r--r--src/providers/ldap/sdap_users.h43
14 files changed, 228 insertions, 11 deletions
diff --git a/Makefile.am b/Makefile.am
index 211472195..9dbde0391 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -440,6 +440,7 @@ dist_noinst_HEADERS = \
src/providers/ldap/sdap_id_op.h \
src/providers/ldap/ldap_opts.h \
src/providers/ldap/sdap_range.h \
+ src/providers/ldap/sdap_users.h \
src/providers/ipa/ipa_common.h \
src/providers/ipa/ipa_config.h \
src/providers/ipa/ipa_access.h \
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index 0154e6aa9..85e34cb18 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -104,6 +104,7 @@ ldap_idmap_default_domain = str, None, false
ldap_idmap_default_domain_sid = str, None, false
ldap_groups_use_matching_rule_in_chain = bool, None, false
ldap_initgroups_use_matching_rule_in_chain = bool, None, false
+ldap_rfc2307_fallback_to_local_users = bool, None, false
[provider/ad/auth]
krb5_ccachedir = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 87f69a23f..e9c7b2326 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -125,6 +125,7 @@ ldap_idmap_default_domain = str, None, false
ldap_idmap_default_domain_sid = str, None, false
ldap_groups_use_matching_rule_in_chain = bool, None, false
ldap_initgroups_use_matching_rule_in_chain = bool, None, false
+ldap_rfc2307_fallback_to_local_users = bool, None, false
[provider/ipa/auth]
krb5_ccachedir = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index 3b6b4e8fb..40e2aa09d 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -114,6 +114,7 @@ ldap_idmap_default_domain = str, None, false
ldap_idmap_default_domain_sid = str, None, false
ldap_groups_use_matching_rule_in_chain = bool, None, false
ldap_initgroups_use_matching_rule_in_chain = bool, None, false
+ldap_rfc2307_fallback_to_local_users = bool, None, false
[provider/ldap/auth]
ldap_pwd_policy = str, None, false
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index c1553c736..799213300 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -1810,6 +1810,37 @@ ldap_access_filter = memberOf=cn=allowedusers,ou=Groups,dc=example,dc=com
</para>
</listitem>
</varlistentry>
+
+ <varlistentry>
+ <term>ldap_rfc2307_fallback_to_local_users (boolean)</term>
+ <listitem>
+ <para>
+ Allows to retain local users as members of an LDAP
+ group for servers that use the RFC2307 schema.
+ </para>
+ <para>
+ In some environments where the RFC2307 schema is
+ used, local users are made members of LDAP groups
+ by adding their names to the memberUid attribute.
+ The self-consistency of the domain is compromised
+ when this is done, so SSSD would normally remove
+ the "missing" users from the cached group
+ memberships as soon as nsswitch tries to fetch
+ information about the user via getpw*() or
+ initgroups() calls.
+ </para>
+ <para>
+ This option falls back to checking if local users
+ are referenced, and caches them so that later
+ initgroups() calls will augment the local users
+ with the additional LDAP groups.
+ </para>
+ <para>
+ Default: false
+ </para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</para>
</refsect1>
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h
index efd966e93..285672226 100644
--- a/src/providers/ad/ad_opts.h
+++ b/src/providers/ad/ad_opts.h
@@ -120,6 +120,7 @@ struct dp_option ad_def_ldap_opts[] = {
{ "ldap_idmap_default_domain_sid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
+ { "ldap_rfc2307_fallback_to_local_users", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
DP_OPTION_TERMINATOR
};
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 7923b1ec8..cb6f40e8b 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -136,6 +136,7 @@ struct dp_option ipa_def_ldap_opts[] = {
{ "ldap_idmap_default_domain_sid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
+ { "ldap_rfc2307_fallback_to_local_users", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
DP_OPTION_TERMINATOR
};
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index d24b8aa69..073f6869e 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -32,6 +32,7 @@
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_async.h"
#include "providers/ldap/sdap_idmap.h"
+#include "providers/ldap/sdap_users.h"
/* =Users-Related-Functions-(by-name,by-uid)============================== */
@@ -244,6 +245,44 @@ static void users_get_done(struct tevent_req *subreq)
return;
}
+ if ((ret == ENOENT) &&
+ (state->ctx->opts->schema_type == SDAP_SCHEMA_RFC2307) &&
+ (dp_opt_get_bool(state->ctx->opts->basic,
+ SDAP_RFC2307_FALLBACK_TO_LOCAL_USERS) == true)) {
+ struct sysdb_attrs **usr_attrs;
+ const char *name = NULL;
+ bool fallback;
+
+ switch (state->filter_type) {
+ case BE_FILTER_NAME:
+ name = state->name;
+ uid = -1;
+ fallback = true;
+ break;
+ case BE_FILTER_IDNUM:
+ uid = (uid_t) strtouint32(state->name, &endptr, 10);
+ if (errno || *endptr || (state->name == endptr)) {
+ tevent_req_error(req, errno ? errno : EINVAL);
+ return;
+ }
+ fallback = true;
+ break;
+ default:
+ fallback = false;
+ break;
+ }
+
+ if (fallback) {
+ ret = sdap_fallback_local_user(state, state->ctx->opts,
+ name, uid, &usr_attrs);
+ if (ret == EOK) {
+ ret = sdap_save_user(state, state->sysdb,
+ state->ctx->opts, state->domain,
+ usr_attrs[0], false, NULL, 0);
+ }
+ }
+ }
+
if (ret && ret != ENOENT) {
state->dp_error = dp_error;
tevent_req_error(req, ret);
diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h
index 5a941a4c6..2ed89f977 100644
--- a/src/providers/ldap/ldap_opts.h
+++ b/src/providers/ldap/ldap_opts.h
@@ -112,6 +112,7 @@ struct dp_option default_basic_opts[] = {
{ "ldap_idmap_default_domain_sid", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
+ { "ldap_rfc2307_fallback_to_local_users", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
DP_OPTION_TERMINATOR
};
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 27f18ae17..1235d1df3 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -215,6 +215,7 @@ enum sdap_basic_opt {
SDAP_IDMAP_DEFAULT_DOMAIN_SID,
SDAP_AD_MATCHING_RULE_GROUPS,
SDAP_AD_MATCHING_RULE_INITGROUPS,
+ SDAP_RFC2307_FALLBACK_TO_LOCAL_USERS,
SDAP_OPTS_BASIC /* opts counter */
};
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index a4310b463..23be22fd1 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -26,6 +26,7 @@
#include "providers/ldap/sdap_async_private.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_idmap.h"
+#include "providers/ldap/sdap_users.h"
/* ==Save-fake-group-list=====================================*/
static errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
@@ -2658,8 +2659,20 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
return;
}
- tevent_req_error(req, ENOENT);
- return;
+ /* fallback to fetch a local user if required */
+ if ((state->opts->schema_type == SDAP_SCHEMA_RFC2307) &&
+ (dp_opt_get_bool(state->opts->basic,
+ SDAP_RFC2307_FALLBACK_TO_LOCAL_USERS) == true)) {
+ ret = sdap_fallback_local_user(state, state->opts,
+ state->name, -1, &usr_attrs);
+ } else {
+ ret = ENOENT;
+ }
+
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
} else if (count != 1) {
DEBUG(2, ("Expected one user entry and got %d\n", count));
tevent_req_error(req, EINVAL);
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index 156255b97..71cb2e53f 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -89,15 +89,6 @@ int sdap_get_tgt_recv(struct tevent_req *req,
char **ccname,
time_t *expire_time_out);
-int sdap_save_user(TALLOC_CTX *memctx,
- struct sysdb_ctx *ctx,
- struct sdap_options *opts,
- struct sss_domain_info *dom,
- struct sysdb_attrs *attrs,
- bool is_initgr,
- char **_usn_value,
- time_t now);
-
int sdap_save_users(TALLOC_CTX *memctx,
struct sysdb_ctx *sysdb,
struct sss_domain_info *dom,
@@ -120,4 +111,5 @@ errno_t get_sysdb_grouplist(TALLOC_CTX *mem_ctx,
struct sss_domain_info *domain,
const char *name,
char ***grouplist);
+
#endif /* _SDAP_ASYNC_PRIVATE_H_ */
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index cd577a7f7..ccd2f24e0 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -26,6 +26,8 @@
#include "providers/ldap/sdap_async_private.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_idmap.h"
+#include "providers/ldap/sdap_users.h"
+
/* ==Save-User-Entry====================================================== */
@@ -701,3 +703,92 @@ int sdap_get_users_recv(struct tevent_req *req,
return EOK;
}
+
+/* ==Fetch-Fallback-local-user============================================ */
+
+errno_t sdap_fallback_local_user(TALLOC_CTX *memctx,
+ struct sdap_options *opts,
+ const char *name, uid_t uid,
+ struct sysdb_attrs ***reply)
+{
+ struct sysdb_attrs **ua;
+ struct sysdb_attrs *user;
+ struct passwd *pwd;
+ int ret;
+
+ if (name) {
+ pwd = getpwnam(name);
+ } else {
+ pwd = getpwuid(uid);
+ }
+
+ if (!pwd) {
+ return errno ? errno : ENOENT;
+ }
+
+ ua = talloc_array(memctx, struct sysdb_attrs *, 2);
+ if (!ua) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ua[1] = NULL;
+
+ user = sysdb_new_attrs(ua);
+ if (!user) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ua[0] = user;
+
+ ret = sysdb_attrs_add_string(user, SYSDB_NAME, pwd->pw_name);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (pwd->pw_passwd) {
+ ret = sysdb_attrs_add_string(user, SYSDB_PWD, pwd->pw_passwd);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+ ret = sysdb_attrs_add_long(user, SYSDB_UIDNUM, (long)pwd->pw_uid);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sysdb_attrs_add_long(user, SYSDB_GIDNUM, (long)pwd->pw_gid);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (pwd->pw_gecos) {
+ ret = sysdb_attrs_add_string(user, SYSDB_GECOS, pwd->pw_gecos);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+ if (pwd->pw_dir) {
+ ret = sysdb_attrs_add_string(user, SYSDB_HOMEDIR, pwd->pw_dir);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+ if (pwd->pw_shell) {
+ ret = sysdb_attrs_add_string(user, SYSDB_SHELL, pwd->pw_shell);
+ if (ret != EOK) {
+ goto done;
+ }
+ }
+
+done:
+ if (ret != EOK) {
+ talloc_free(ua);
+ } else {
+ *reply = ua;
+ }
+
+ return ret;
+}
diff --git a/src/providers/ldap/sdap_users.h b/src/providers/ldap/sdap_users.h
new file mode 100644
index 000000000..16620a9ed
--- /dev/null
+++ b/src/providers/ldap/sdap_users.h
@@ -0,0 +1,43 @@
+/*
+ SSSD
+
+ Async LDAP Helper routines
+
+ Copyright (C) Simo Sorce <ssorce@redhat.com>
+
+ 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/>.
+*/
+
+#ifndef _SDAP_USERS_H_
+#define _SDAP_USERS_H_
+
+#include "config.h"
+
+/* shared non-async user functions */
+
+errno_t sdap_fallback_local_user(TALLOC_CTX *memctx,
+ struct sdap_options *opts,
+ const char *name, uid_t uid,
+ struct sysdb_attrs ***reply);
+
+int sdap_save_user(TALLOC_CTX *memctx,
+ struct sysdb_ctx *ctx,
+ struct sdap_options *opts,
+ struct sss_domain_info *dom,
+ struct sysdb_attrs *attrs,
+ bool is_initgr,
+ char **_usn_value,
+ time_t now);
+
+#endif /* _SDAP_USERS_H_ */