From 92510080b965f57115f26775a5c52953c5ff68ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ezina?= Date: Wed, 7 Dec 2011 17:20:47 +0100 Subject: [PATCH 05/11] SUDO Integration - LDAP configuration options --- src/providers/ipa/ipa_common.c | 39 ++++++++++++++++++++ src/providers/ipa/ipa_common.h | 2 +- src/providers/ldap/ldap_common.c | 73 +++++++++++++++++++++++++++++++++++++- src/providers/ldap/ldap_common.h | 5 +++ src/providers/ldap/sdap.c | 14 +++++++- src/providers/ldap/sdap.h | 20 ++++++++++ 6 files changed, 150 insertions(+), 3 deletions(-) diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c index f437580..4f90b18 100644 --- a/src/providers/ipa/ipa_common.c +++ b/src/providers/ipa/ipa_common.c @@ -60,6 +60,7 @@ struct dp_option ipa_def_ldap_opts[] = { { "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, { "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_sudo_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_schema", DP_OPT_STRING, { "ipa_v1" }, NULL_STRING }, { "ldap_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, { "ldap_force_upper_case_realm", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, @@ -465,6 +466,44 @@ int ipa_get_id_options(struct ipa_options *ipa_opts, if (ret != EOK) goto done; if (NULL == dp_opt_get_string(ipa_opts->id->basic, + SDAP_SUDO_SEARCH_BASE)) { +#if 0 + ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_NETGROUP_SEARCH_BASE, + dp_opt_get_string(ipa_opts->id->basic, + SDAP_SEARCH_BASE)); + if (ret != EOK) { + goto done; + } +#else + /* We don't yet have support for the native representation + * of sudo in IPA. For now, we need to point at the + * compat tree + */ + value = talloc_asprintf(tmpctx, "ou=SUDOers,%s", basedn); + if (!value) { + ret = ENOMEM; + goto done; + } + + ret = dp_opt_set_string(ipa_opts->id->basic, + SDAP_SUDO_SEARCH_BASE, + value); + if (ret != EOK) { + goto done; + } +#endif + + DEBUG(6, ("Option %s set to %s\n", + ipa_opts->id->basic[SDAP_SUDO_SEARCH_BASE].opt_name, + dp_opt_get_string(ipa_opts->id->basic, + SDAP_SUDO_SEARCH_BASE))); + } + ret = sdap_parse_search_base(ipa_opts->id, ipa_opts->id->basic, + SDAP_SUDO_SEARCH_BASE, + &ipa_opts->id->sudo_search_bases); + if (ret != EOK) goto done; + + if (NULL == dp_opt_get_string(ipa_opts->id->basic, SDAP_NETGROUP_SEARCH_BASE)) { value = talloc_asprintf(tmpctx, "cn=ng,cn=alt,%s", basedn); if (!value) { diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h index f7ab5ef..577e3e1 100644 --- a/src/providers/ipa/ipa_common.h +++ b/src/providers/ipa/ipa_common.h @@ -35,7 +35,7 @@ struct ipa_service { /* the following defines are used to keep track of the options in the ldap * module, so that if they change and ipa is not updated correspondingly * this will trigger a runtime abort error */ -#define IPA_OPTS_BASIC_TEST 55 +#define IPA_OPTS_BASIC_TEST 56 /* the following define is used to keep track of the options in the krb5 * module, so that if they change and ipa is not updated correspondingly diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c index dc55f6e..7192196 100644 --- a/src/providers/ldap/ldap_common.c +++ b/src/providers/ldap/ldap_common.c @@ -26,6 +26,7 @@ #include "providers/fail_over.h" #include "providers/ldap/sdap_async_private.h" #include "providers/krb5/krb5_common.h" +#include "db/sysdb_sudo.h" #include "util/sss_krb5.h" #include "util/crypto/sss_crypto.h" @@ -49,6 +50,7 @@ struct dp_option default_basic_opts[] = { { "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, { "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_sudo_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "ldap_schema", DP_OPT_STRING, { "rfc2307" }, NULL_STRING }, { "ldap_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, { "ldap_force_upper_case_realm", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, @@ -214,6 +216,20 @@ struct sdap_attr_map netgroup_map[] = { { "ldap_netgroup_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL } }; +struct sdap_attr_map native_sudorule_map[] = { + { "ldap_sudorule_object_class", "sudoRole", SYSDB_SUDO_CACHE_AT_OC, NULL }, + { "ldap_sudorule_name", "cn", SYSDB_SUDO_CACHE_AT_CN, NULL }, + { "ldap_sudorule_command", "sudoCommand", SYSDB_SUDO_CACHE_AT_COMMAND, NULL }, + { "ldap_sudorule_host", "sudoHost", SYSDB_SUDO_CACHE_AT_HOST, NULL }, + { "ldap_sudorule_user", "sudoUser", SYSDB_SUDO_CACHE_AT_USER, NULL }, + { "ldap_sudorule_option", "sudoOption", SYSDB_SUDO_CACHE_AT_OPTION, NULL }, + { "ldap_sudorule_runasuser", "sudoRunAsUser", SYSDB_SUDO_CACHE_AT_RUNASUSER, NULL }, + { "ldap_sudorule_runasgroup", "sudoRunAsGroup", SYSDB_SUDO_CACHE_AT_RUNASGROUP, NULL }, + { "ldap_sudorule_notbefore", "sudoNotBefore", SYSDB_SUDO_CACHE_AT_NOTBEFORE, NULL }, + { "ldap_sudorule_notafter", "sudoNotAfter", SYSDB_SUDO_CACHE_AT_NOTAFTER, NULL }, + { "ldap_sudorule_order", "sudoOrder", SYSDB_SUDO_CACHE_AT_ORDER, NULL } +}; + int ldap_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, @@ -255,7 +271,7 @@ int ldap_get_options(TALLOC_CTX *memctx, /* Handle search bases */ search_base = dp_opt_get_string(opts->basic, SDAP_SEARCH_BASE); if (search_base != NULL) { - /* set user/group/netgroup search bases if they are not */ + /* set user/group/netgroup/sudo search bases if they are not */ for (o = 0; search_base_options[o] != -1; o++) { if (NULL == dp_opt_get_string(opts->basic, search_base_options[o])) { ret = dp_opt_set_string(opts->basic, search_base_options[o], @@ -496,6 +512,58 @@ done: return ret; } +int ldap_get_sudo_options(TALLOC_CTX *memctx, + struct confdb_ctx *cdb, + const char *conf_path, + struct sdap_options *opts) +{ + const char *search_base; + int ret; + + /* search base */ + search_base = dp_opt_get_string(opts->basic, SDAP_SEARCH_BASE); + if (search_base != NULL) { + /* set sudo search bases if they are not */ + if (dp_opt_get_string(opts->basic, SDAP_SUDO_SEARCH_BASE) == NULL) { + ret = dp_opt_set_string(opts->basic, SDAP_SUDO_SEARCH_BASE, + search_base); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not set SUDO search base" + "to default value\n")); + return ret; + } + + DEBUG(SSSDBG_FUNC_DATA, ("Option %s set to %s\n", + opts->basic[SDAP_SUDO_SEARCH_BASE].opt_name, + dp_opt_get_string(opts->basic, SDAP_SUDO_SEARCH_BASE))); + } + } else { + /* FIXME: try to discover it later */ + DEBUG(SSSDBG_OP_FAILURE, ("Error: no SUDO search base set\n")); + return ENOENT; + } + + ret = sdap_parse_search_base(opts, opts->basic, + SDAP_SUDO_SEARCH_BASE, + &opts->sudo_search_bases); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not parse SUDO search base\n")); + return ret; + } + + /* attrs map */ + ret = sdap_get_map(opts, cdb, conf_path, + native_sudorule_map, + SDAP_OPTS_SUDO, + &opts->sudorule_map); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Could not get SUDO attribute map\n")); + return ret; + } + + return EOK; +} + errno_t sdap_parse_search_base(TALLOC_CTX *mem_ctx, struct dp_option *opts, int class, struct sdap_search_base ***_search_bases) @@ -531,6 +599,9 @@ errno_t sdap_parse_search_base(TALLOC_CTX *mem_ctx, case SDAP_NETGROUP_SEARCH_BASE: class_name = "NETGROUP"; break; + case SDAP_SUDO_SEARCH_BASE: + class_name = "SUDO"; + break; default: DEBUG(SSSDBG_CONF_SETTINGS, ("Unknown search base type: [%d]\n", class)); diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h index e937cf2..844f605 100644 --- a/src/providers/ldap/ldap_common.h +++ b/src/providers/ldap/ldap_common.h @@ -115,6 +115,11 @@ int ldap_get_options(TALLOC_CTX *memctx, const char *conf_path, struct sdap_options **_opts); +int ldap_get_sudo_options(TALLOC_CTX *memctx, + struct confdb_ctx *cdb, + const char *conf_path, + struct sdap_options *opts); + int ldap_id_enumerate_set_timer(struct sdap_id_ctx *ctx, struct timeval tv); int ldap_id_cleanup_set_timer(struct sdap_id_ctx *ctx, struct timeval tv); diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index afaa87f..3ca2e28 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -709,6 +709,9 @@ static errno_t sdap_set_search_base(struct sdap_options *opts, case SDAP_NETGROUP_SEARCH_BASE: bases = &opts->netgroup_search_bases; break; + case SDAP_SUDO_SEARCH_BASE: + bases = &opts->sudo_search_bases; + break; default: return EINVAL; } @@ -740,7 +743,8 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, if (!opts->search_bases ||!opts->user_search_bases || !opts->group_search_bases - || !opts->netgroup_search_bases) { + || !opts->netgroup_search_bases + || !opts->sudo_search_bases) { naming_context = get_naming_context(opts->basic, rootdse); if (naming_context == NULL) { DEBUG(1, ("get_naming_context failed.\n")); @@ -781,6 +785,14 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, if (ret != EOK) goto done; } + /* Sudo */ + if (!opts->sudo_search_bases) { + ret = sdap_set_search_base(opts, + SDAP_SUDO_SEARCH_BASE, + naming_context); + if (ret != EOK) goto done; + } + ret = EOK; done: diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index f08200c..da328d2 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -164,6 +164,7 @@ enum sdap_basic_opt { SDAP_GROUP_SEARCH_BASE, SDAP_GROUP_SEARCH_SCOPE, SDAP_GROUP_SEARCH_FILTER, + SDAP_SUDO_SEARCH_BASE, SDAP_SCHEMA, SDAP_OFFLINE_TIMEOUT, SDAP_FORCE_UPPER_CASE_REALM, @@ -282,6 +283,22 @@ enum sdap_netgroup_attrs { SDAP_OPTS_NETGROUP /* attrs counter */ }; +enum sdap_sudorule_attrs { + SDAP_OC_SUDORULE = 0, + SDAP_AT_SUDO_NAME, + SDAP_AT_SUDO_COMMAND, + SDAP_AT_SUDO_HOST, + SDAP_AT_SUDO_USER, + SDAP_AT_SUDO_OPTION, + SDAP_AT_SUDO_RUNASUSER, + SDAP_AT_SUDO_RUNASGROUP, + SDAP_AT_SUDO_NOTBEFORE, + SDAP_AT_SUDO_NOTAFTER, + SDAP_AT_SUDO_ORDER, + + SDAP_OPTS_SUDO /* attrs counter */ +}; + struct sdap_attr_map { const char *opt_name; const char *def_name; @@ -302,6 +319,8 @@ struct sdap_options { struct sdap_attr_map *group_map; struct sdap_attr_map *netgroup_map; struct sdap_attr_map *host_map; + /* FIXME - should this go to a special struct to avoid mixing with name-service-switch maps? */ + struct sdap_attr_map *sudorule_map; /* supported schema types */ enum schema_type { @@ -315,6 +334,7 @@ struct sdap_options { struct sdap_search_base **user_search_bases; struct sdap_search_base **group_search_bases; struct sdap_search_base **netgroup_search_bases; + struct sdap_search_base **sudo_search_bases; }; struct sdap_server_opts { -- 1.7.6.4