diff options
author | Simo Sorce <simo@redhat.com> | 2013-03-15 15:27:31 -0400 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-03-20 11:49:50 +0100 |
commit | fae99bfe4bfc8b4a12e9c2a0ad01b3684c22f934 (patch) | |
tree | 333f20454afe5782e569a41d929631d938905151 /src/providers/ldap | |
parent | dfd71fc92db940b2892cc996911cec03d7b6c52b (diff) | |
download | sssd-fae99bfe4bfc8b4a12e9c2a0ad01b3684c22f934.tar.gz sssd-fae99bfe4bfc8b4a12e9c2a0ad01b3684c22f934.tar.bz2 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/providers/ldap')
-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 |
7 files changed, 191 insertions, 11 deletions
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index d24b8aa6..073f6869 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 5a941a4c..2ed89f97 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 27f18ae1..1235d1df 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 a4310b46..23be22fd 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 156255b9..71cb2e53 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 cd577a7f..ccd2f24e 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 00000000..16620a9e --- /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_ */ |