diff options
author | Simo Sorce <simo@redhat.com> | 2013-03-15 15:27:31 -0400 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-04-15 15:15:54 +0200 |
commit | 2d654a45796b1c50a3c2368ba2aa78412073171d (patch) | |
tree | e00d60eca667adca30c4b6b7efdb430d3eeda968 /src/providers | |
parent | 5925e134b87e79e60177b5861ec2a67b659aaa27 (diff) | |
download | sssd-2d654a45796b1c50a3c2368ba2aa78412073171d.tar.gz sssd-2d654a45796b1c50a3c2368ba2aa78412073171d.tar.xz sssd-2d654a45796b1c50a3c2368ba2aa78412073171d.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/providers')
-rw-r--r-- | src/providers/ad/ad_opts.h | 1 | ||||
-rw-r--r-- | src/providers/ipa/ipa_opts.h | 1 | ||||
-rw-r--r-- | src/providers/ldap/ldap_id.c | 39 | ||||
-rw-r--r-- | src/providers/ldap/ldap_opts.h | 1 | ||||
-rw-r--r-- | src/providers/ldap/sdap.h | 1 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async_initgroups.c | 17 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async_private.h | 10 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async_users.c | 91 | ||||
-rw-r--r-- | src/providers/ldap/sdap_users.h | 43 |
9 files changed, 193 insertions, 11 deletions
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h index bcf848c07..c283f714a 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 fe9f48930..ff461db19 100644 --- a/src/providers/ipa/ipa_opts.h +++ b/src/providers/ipa/ipa_opts.h @@ -134,6 +134,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 b8520df83..d8dc3b299 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 d14365799..5bbf27594 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -228,6 +228,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 e9d1f3cc9..57ad0e578 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, @@ -2656,8 +2657,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 c0faab50e..1fea5bd7b 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, @@ -118,4 +109,5 @@ errno_t get_sysdb_grouplist(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, 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 ade1d37b5..5a2e375cb 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====================================================== */ @@ -700,3 +702,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_ */ |