From 1199bb0194d735e212f80735b33307a3467b7a3c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 16 Oct 2009 18:38:40 -0400 Subject: Start implementing ipa specific options. First step generate ldap options from ipa options. Add sssd-ipa man page too. --- server/providers/ipa/ipa_common.c | 319 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 319 insertions(+) create mode 100644 server/providers/ipa/ipa_common.c (limited to 'server/providers/ipa/ipa_common.c') diff --git a/server/providers/ipa/ipa_common.c b/server/providers/ipa/ipa_common.c new file mode 100644 index 000000000..799ac2f94 --- /dev/null +++ b/server/providers/ipa/ipa_common.c @@ -0,0 +1,319 @@ +/* + SSSD + + IPA Provider Common Functions + + Authors: + Simo Sorce + + Copyright (C) 2009 Red Hat + + 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 . +*/ + +#include +#include "providers/ipa/ipa_common.h" + +struct dp_option ipa_basic_opts[] = { + { "ipa_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ipa_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ipa_hostname", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ipa_search_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, + { "ipa_network_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, + { "ipa_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, + { "ipa_offline_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, + { "ipa_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER }, + { "ipa_stale_time", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER }, +}; + +struct dp_option ipa_def_ldap_opts[] = { + { "ldap_uri", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_default_bind_dn", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_default_authtok_type", DP_OPT_STRING, NULL_STRING, NULL_STRING}, + { "ldap_default_authtok", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB }, + { "ldap_search_timeout", DP_OPT_NUMBER, { .number = 60 }, NULL_NUMBER }, + { "ldap_network_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, + { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, + { "ldap_tls_reqcert", DP_OPT_STRING, { "hard" }, NULL_STRING }, + { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, + { "ldap_user_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "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_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 }, + { "ldap_enumeration_refresh_timeout", DP_OPT_NUMBER, { .number = 300 }, NULL_NUMBER }, + { "ldap_stale_time", DP_OPT_NUMBER, { .number = 1800 }, NULL_NUMBER }, + { "ldap_tls_cacert", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_tls_cacertdir", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_id_use_start_tls", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, + { "ldap_sasl_mech", DP_OPT_STRING, { "GSSAPI" } , NULL_STRING }, + { "ldap_sasl_authid", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_krb5_keytab", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_krb5_init_creds", DP_OPT_BOOL, BOOL_TRUE, BOOL_TRUE }, + /* use the same parm name as the krb5 module so we set it only once */ + { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING } +}; + +struct sdap_id_map ipa_user_map[] = { + { "ldap_user_object_class", "posixAccount", SYSDB_USER_CLASS, NULL }, + { "ldap_user_name", "uid", SYSDB_NAME, NULL }, + { "ldap_user_pwd", "userPassword", SYSDB_PWD, NULL }, + { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL }, + { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, + { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL }, + { "ldap_user_home_directory", "homeDirectory", SYSDB_HOMEDIR, NULL }, + { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL }, + { "ldap_user_principal", "krbPrincipalName", SYSDB_UPN, NULL }, + { "ldap_user_fullname", "cn", SYSDB_FULLNAME, NULL }, + { "ldap_user_member_of", "memberOf", SYSDB_MEMBEROF, NULL }, + { "ldap_user_uuid", "nsUniqueId", SYSDB_UUID, NULL }, + { "ldap_user_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }, + { "ldap_user_shadow_last_change", "shadowLastChange", SYSDB_SHADOWPW_LASTCHANGE, NULL }, + { "ldap_user_shadow_min", "shadowMin", SYSDB_SHADOWPW_MIN, NULL }, + { "ldap_user_shadow_max", "shadowMax", SYSDB_SHADOWPW_MAX, NULL }, + { "ldap_user_shadow_warning", "shadowWarning", SYSDB_SHADOWPW_WARNING, NULL }, + { "ldap_user_shadow_inactive", "shadowInactive", SYSDB_SHADOWPW_INACTIVE, NULL }, + { "ldap_user_shadow_expire", "shadowExpire", SYSDB_SHADOWPW_EXPIRE, NULL }, + { "ldap_user_shadow_flag", "shadowFlag", SYSDB_SHADOWPW_FLAG, NULL }, + { "ldap_user_krb_last_pwd_change", "krbLastPwdChange", SYSDB_KRBPW_LASTCHANGE, NULL }, + { "ldap_user_krb_password_expiration", "krbPasswordExpiration", SYSDB_KRBPW_EXPIRATION, NULL }, + { "ldap_pwd_attribute", "pwdAttribute", SYSDB_PWD_ATTRIBUTE, NULL } +}; + +struct sdap_id_map ipa_group_map[] = { + { "ldap_group_object_class", "posixGroup", SYSDB_GROUP_CLASS, NULL }, + { "ldap_group_name", "cn", SYSDB_NAME, NULL }, + { "ldap_group_pwd", "userPassword", SYSDB_PWD, NULL }, + { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL }, + { "ldap_group_member", "member", SYSDB_MEMBER, NULL }, + { "ldap_group_uuid", "nsUniqueId", SYSDB_UUID, NULL }, + { "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL } +}; + +int domain_to_basedn(TALLOC_CTX *memctx, const char *domain, char **basedn) +{ + const char *s; + char *dn; + char *p; + int l; + + s = domain; + dn = talloc_strdup(memctx, "dc="); + + while ((p = strchr(s, '.'))) { + l = p - s; + dn = talloc_asprintf_append_buffer(dn, "%.*s,dc=", l, s); + if (!dn) { + return ENOMEM; + } + s = p + 1; + } + dn = talloc_strdup_append_buffer(dn, s); + if (!dn) { + return ENOMEM; + } + + *basedn = dn; + return EOK; +} + +int ipa_get_options(TALLOC_CTX *memctx, + struct confdb_ctx *cdb, + const char *conf_path, + struct sss_domain_info *dom, + struct ipa_options **_opts) +{ + struct ipa_options *opts; + char *domain; + char *server; + int ret; + + opts = talloc_zero(memctx, struct ipa_options); + if (!opts) return ENOMEM; + + ret = dp_get_options(opts, cdb, conf_path, + ipa_basic_opts, + IPA_OPTS_BASIC, + &opts->basic); + if (ret != EOK) { + goto done; + } + + domain = dp_opt_get_string(opts->basic, IPA_DOMAIN); + if (!domain) { + ret = dp_opt_set_string(opts->basic, IPA_DOMAIN, dom->name); + if (ret != EOK) { + goto done; + } + } + + /* FIXME: Make non-fatal once we have discovery */ + server = dp_opt_get_string(opts->basic, IPA_SERVER); + if (!server) { + DEBUG(0, ("Can't find ipa server, missing option!\n")); + ret = EINVAL; + goto done; + } + + ret = EOK; + *_opts = opts; + +done: + if (ret != EOK) { + talloc_zfree(opts); + } + return ret; +} + +/* the following preprocessor code is 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 build error */ +#if SDAP_OPTS_BASIC > 27 +#error There are ldap options not accounted for +#endif + +int ipa_get_id_options(TALLOC_CTX *memctx, + struct confdb_ctx *cdb, + const char *conf_path, + struct ipa_options *ipa_opts, + struct sdap_options **_opts) +{ + TALLOC_CTX *tmpctx; + char *hostname; + char *basedn; + char *realm; + char *value; + int ret; + int i; + + tmpctx = talloc_new(memctx); + if (!tmpctx) { + return ENOMEM; + } + + ipa_opts->id = talloc_zero(memctx, struct sdap_options); + if (!ipa_opts->id) { + ret = ENOMEM; + goto done; + } + + /* generate sdap options */ + ret = dp_copy_options(ipa_opts, ipa_def_ldap_opts, + SDAP_OPTS_BASIC, &ipa_opts->id->basic); + if (ret != EOK) { + goto done; + } + + /* set ldap_uri */ + value = talloc_asprintf(tmpctx, "ldap://%s", + dp_opt_get_string(ipa_opts->basic, IPA_SERVER)); + if (!value) { + ret = ENOMEM; + goto done; + } + ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_URI, value); + if (ret != EOK) { + goto done; + } + + ret = domain_to_basedn(tmpctx, + dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN), + &basedn); + if (ret != EOK) { + goto done; + } + + /* FIXME: get values by querying IPA */ + /* set ldap_user_search_base */ + value = talloc_asprintf(tmpctx, "cn=users,cn=accounts,%s", basedn); + if (!value) { + ret = ENOMEM; + goto done; + } + ret = dp_opt_set_string(ipa_opts->id->basic, + SDAP_USER_SEARCH_BASE, value); + if (ret != EOK) { + goto done; + } + + /* set ldap_group_search_base */ + value = talloc_asprintf(tmpctx, "cn=groups,cn=accounts,%s", basedn); + if (!value) { + ret = ENOMEM; + goto done; + } + ret = dp_opt_set_string(ipa_opts->id->basic, + SDAP_GROUP_SEARCH_BASE, value); + if (ret != EOK) { + goto done; + } + + /* set the ldap_sasl_authid if the ipa_hostname override was specified */ + hostname = dp_opt_get_string(ipa_opts->basic, IPA_HOSTNAME); + if (hostname) { + value = talloc_asprintf(tmpctx, "host/%s", hostname); + if (!value) { + ret = ENOMEM; + goto done; + } + ret = dp_opt_set_string(ipa_opts->id->basic, + SDAP_SASL_AUTHID, value); + if (ret != EOK) { + goto done; + } + } + + /* set krb realm */ + realm = dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN); + for (i = 0; realm[i]; i++) { + realm[i] = toupper(realm[i]); + } + ret = dp_opt_set_string(ipa_opts->id->basic, + SDAP_KRB5_REALM, realm); + if (ret != EOK) { + goto done; + } + + ret = sdap_get_map(ipa_opts->id, + cdb, conf_path, + ipa_user_map, + SDAP_OPTS_USER, + &ipa_opts->id->user_map); + if (ret != EOK) { + goto done; + } + + ret = sdap_get_map(ipa_opts->id, + cdb, conf_path, + ipa_group_map, + SDAP_OPTS_GROUP, + &ipa_opts->id->group_map); + if (ret != EOK) { + goto done; + } + + ret = EOK; + *_opts = ipa_opts->id; + +done: + talloc_zfree(tmpctx); + if (ret != EOK) { + talloc_zfree(ipa_opts->id); + } + return ret; +} + -- cgit