summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2013-03-15 15:27:31 -0400
committerJakub Hrozek <jhrozek@redhat.com>2013-03-20 11:49:50 +0100
commitfae99bfe4bfc8b4a12e9c2a0ad01b3684c22f934 (patch)
tree333f20454afe5782e569a41d929631d938905151 /src
parentdfd71fc92db940b2892cc996911cec03d7b6c52b (diff)
downloadsssd-fae99bfe4bfc8b4a12e9c2a0ad01b3684c22f934.tar.gz
sssd-fae99bfe4bfc8b4a12e9c2a0ad01b3684c22f934.tar.xz
sssd-fae99bfe4bfc8b4a12e9c2a0ad01b3684c22f934.zip
ldap: Fallback option for rfc2307 schema
Add option to fallback to fetch local users if rfc2307is being used. This is useful for cases where people added local users as LDAP members and rely on these group memberships to be maintained on the local host. Disabled by default as it violates identity domain separation. Ticket: https://fedorahosted.org/sssd/ticket/1020
Diffstat (limited to 'src')
-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
13 files changed, 227 insertions, 11 deletions
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_ */