confdb.c revision ff22e829fd73fc53027d1e6ca005a9ac334086dd
a945f35eff8b6a88009ce73de6d4c862ce58de3cslive NSS Configuratoin DB
a945f35eff8b6a88009ce73de6d4c862ce58de3cslive Copyright (C) Simo Sorce <ssorce@redhat.com> 2008
fe64b2ba25510d8c9dba5560a2d537763566cf40nd This program is free software; you can redistribute it and/or modify
fe64b2ba25510d8c9dba5560a2d537763566cf40nd it under the terms of the GNU General Public License as published by
fe64b2ba25510d8c9dba5560a2d537763566cf40nd the Free Software Foundation; either version 3 of the License, or
fe64b2ba25510d8c9dba5560a2d537763566cf40nd (at your option) any later version.
fe64b2ba25510d8c9dba5560a2d537763566cf40nd This program is distributed in the hope that it will be useful,
fe64b2ba25510d8c9dba5560a2d537763566cf40nd but WITHOUT ANY WARRANTY; without even the implied warranty of
fe64b2ba25510d8c9dba5560a2d537763566cf40nd MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52fff662005b1866a3ff09bb6c902800c5cc6dedjerenkrantz GNU General Public License for more details.
fe64b2ba25510d8c9dba5560a2d537763566cf40nd You should have received a copy of the GNU General Public License
fe64b2ba25510d8c9dba5560a2d537763566cf40nd along with this program. If not, see <http://www.gnu.org/licenses/>.
fe64b2ba25510d8c9dba5560a2d537763566cf40nd#define CONFDB_ZERO_CHECK_OR_JUMP(var, ret, err, label) do { \
fe64b2ba25510d8c9dba5560a2d537763566cf40nd/* Warning messages */
117c1f888a14e73cdd821dc6c23eb0411144a41cnd#define SAME_DOMAINS_ERROR_MSG "Domain '%s' is the same as or differs only "\
117c1f888a14e73cdd821dc6c23eb0411144a41cnd "in case from domain '%s'.\n"
117c1f888a14e73cdd821dc6c23eb0411144a41cndstatic char *prepend_cn(char *str, int *slen, const char *comp, int clen)
117c1f888a14e73cdd821dc6c23eb0411144a41cnd ret = talloc_realloc(NULL, str, char, *slen + 4 + clen + 1);
117c1f888a14e73cdd821dc6c23eb0411144a41cnd /* move current string to the end */
8559a67073808d84d85bb5dd552d4247caafe709sf memmove(&ret[clen +4], ret, *slen+1); /* includes termination */
117c1f888a14e73cdd821dc6c23eb0411144a41cndint parse_section(TALLOC_CTX *mem_ctx, const char *section,
117c1f888a14e73cdd821dc6c23eb0411144a41cnd const char *s;
117c1f888a14e73cdd821dc6c23eb0411144a41cnd /* section must be a non null string and must not start with '/' */
117c1f888a14e73cdd821dc6c23eb0411144a41cnd if (!section || !*section || *section == '/') return EINVAL;
117c1f888a14e73cdd821dc6c23eb0411144a41cnd if (l == 0) {
117c1f888a14e73cdd821dc6c23eb0411144a41cnd l = 3 + (p-s);
9f19223e8fb7b99f5f1cc02c8c3c2c6567793262rbowen if (*p == '\0') {
117c1f888a14e73cdd821dc6c23eb0411144a41cnd break; /* reached end */
117c1f888a14e73cdd821dc6c23eb0411144a41cnd const char *section,
fe64b2ba25510d8c9dba5560a2d537763566cf40nd const char *attribute,
fe64b2ba25510d8c9dba5560a2d537763566cf40nd const char **values)
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna const char *rdn_name;
d972e4a0688f66b1402473dd9dacfecefa2132a8rbowen ret = parse_section(tmp_ctx, section, &secdn, &rdn_name);
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna CONFDB_ZERO_CHECK_OR_JUMP(msg->dn, ret, ENOMEM, done);
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor /* cn first */
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna /* now the requested attribute */
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna for (i = 0; values[i]; i++) {
7e8f5c6496b3825b6b128e2aacc4b1b09d28553dpquerna ret = ldb_msg_add_string(msg, attribute, values[i]);
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe /* mark this as a replacement */
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe ret = ldb_msg_add_empty(msg, attribute, optype, NULL);
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe /* now the requested attribute */
5ae609a8a09239d20f48a4a95c4f21b713995babwrowe for (i = 0; values[i]; i++) {
06ba4a61654b3763ad65f52283832ebf058fdf1cslive "Failed to add [%s] to [%s], error [%d] (%s)\n",
06ba4a61654b3763ad65f52283832ebf058fdf1cslive const char *section,
06ba4a61654b3763ad65f52283832ebf058fdf1cslive const char *attribute,
130d299c4b2b15be45532a176604c71fdc7bea5bnd vals = talloc_realloc(mem_ctx, vals, char *, el->num_values +1);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /* should always be strings so this should be safe */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd vals[i] = talloc_strndup(vals, (char *)v.data, v.length);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd if (!vals[i]) {
06ba4a61654b3763ad65f52283832ebf058fdf1cslive "Failed to get [%s] from [%s], error [%d] (%s)\n",
130d299c4b2b15be45532a176604c71fdc7bea5bnd const char *section,
130d299c4b2b15be45532a176604c71fdc7bea5bnd const char *attribute,
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd lret = ldb_msg_add_empty(msg, attribute, LDB_FLAG_MOD_REPLACE, NULL);
5224ff8eae5156a05f676f1dad8add2e2f2efe1dnd "ldb_msg_add_string failed: [%s]\n", ldb_strerror(lret));
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd "Failed to set [%s] from [%s], error [%d] (%s)\n",
4335f1cbf345c91bb996eec540c11ba8ce5d4268nd const char *section,
2509f1cd3be884abbe4852e15b8da00bebaad5b1poirier const char *attribute,
fe64b2ba25510d8c9dba5560a2d537763566cf40nd lret = ldb_msg_add_empty(msg, attribute, LDB_FLAG_MOD_REPLACE, NULL);
fb77c505254b6e9c925e23e734463e87574f8f40kess "ldb_msg_add_string failed: [%s]\n", ldb_strerror(lret));
06ba4a61654b3763ad65f52283832ebf058fdf1cslive "Failed to set [%s] from [%s], error [%d] (%s)\n",
9335f6d807d76d60e54af4ededdebebddb3e3d13noodlint confdb_get_string(struct confdb_ctx *cdb, TALLOC_CTX *ctx,
604c89126c27104f659d7a51b0113e3bd435faf8fielding ret = confdb_get_param(cdb, ctx, section, attribute, &values);
909ce17e2bd0faef7b1c294f2307f009793fd493nd /* too many values */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive /* Did not return a value, so use the default */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive /* Copy the default string */
2b6565aedca9e9c10691b12fd2f3689bf4c85bc7jim "Failed to get [%s] from [%s], error [%d] (%s)\n",
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor ret = confdb_get_param(cdb, tmp_ctx, section, attribute, &values);
7802d43d20007fa575e43b6ae77d5177ceffdb71sf /* too many values */
bed3c2e56e8f3328e780200466b9d009093db468sf "Failed to read [%s] from [%s], error [%d] (%s)\n",
bed3c2e56e8f3328e780200466b9d009093db468sf ret = confdb_get_param(cdb, tmp_ctx, section, attribute, &values);
bed3c2e56e8f3328e780200466b9d009093db468sf /* too many values */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd "Failed to read [%s] from [%s], error [%d] (%s)\n",
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ret = confdb_get_param(cdb, tmp_ctx, section, attribute, &values);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive /* too many values */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive DEBUG(SSSDBG_OP_FAILURE, "Value is not a boolean!\n");
604c89126c27104f659d7a51b0113e3bd435faf8fielding "Failed to read [%s] from [%s], error [%d] (%s)\n",
88d86cfadffe2275a3dfb67a4d7bdc018630b661rbowen/* WARNING: Unlike other similar functions, this one does NOT take a default,
fe64b2ba25510d8c9dba5560a2d537763566cf40nd * and returns ENOENT if the attribute was not found ! */
604c89126c27104f659d7a51b0113e3bd435faf8fieldingint confdb_get_string_as_list(struct confdb_ctx *cdb, TALLOC_CTX *ctx,
22265f1724519886e2a2b5e0ebd61477506b7379noodl ret = confdb_get_param(cdb, ctx, section, attribute, &values);
604c89126c27104f659d7a51b0113e3bd435faf8fielding /* too many values */
9597f440430d8c876dd64f5f78066804650a18ecnoodl /* Did not return a value */
141fd59714368d3bbe3a3d8f5b8dc8a516c48f9fsf ret = split_on_separator(ctx, values[0], ',', true, true, result, NULL);
141fd59714368d3bbe3a3d8f5b8dc8a516c48f9fsf "Failed to get [%s] from [%s], error [%d] (%s)\n",
141fd59714368d3bbe3a3d8f5b8dc8a516c48f9fsf /* Because confdb calls use sync ldb calls, we create a separate event
141fd59714368d3bbe3a3d8f5b8dc8a516c48f9fsf * context here. This will prevent the ldb sync calls to start nested
cba8c0896ba04d42cf9a9e50df5040fd6bae14a4sf * NOTE: this means that we *cannot* do async calls and return in confdb
cba8c0896ba04d42cf9a9e50df5040fd6bae14a4sf * unless we convert all calls and hook back to the main event context.
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ret = ldb_set_debug(cdb->ldb, ldb_debug_messages, NULL);
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor DEBUG(SSSDBG_FATAL_FAILURE,"Could not set up debug fn.\n");
ff797e743eb73c1d45b08158aa6b288c2d0c46eeslive DEBUG(SSSDBG_FATAL_FAILURE, "Unable to open config database [%s]\n",
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cndstatic errno_t get_entry_as_uint32(struct ldb_message *msg,
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd const char *entry,
130d299c4b2b15be45532a176604c71fdc7bea5bnd /* Not all of the string was a valid number */
06ba4a61654b3763ad65f52283832ebf058fdf1cslivestatic errno_t get_entry_as_bool(struct ldb_message *msg,
06ba4a61654b3763ad65f52283832ebf058fdf1cslive const char *entry,
6b64034fa2a644ba291c484c0c01c7df5b8d982ckess/* The default UID/GID for domains is 1. This wouldn't work well with
06ba4a61654b3763ad65f52283832ebf058fdf1cslive * the local provider */
88d86cfadffe2275a3dfb67a4d7bdc018630b661rbowenstatic uint32_t confdb_get_min_id(struct sss_domain_info *domain)
06ba4a61654b3763ad65f52283832ebf058fdf1cslive if (domain && strcasecmp(domain->provider, "local") == 0) {
130d299c4b2b15be45532a176604c71fdc7bea5bndstatic int confdb_get_domain_internal(struct confdb_ctx *cdb,
06ba4a61654b3763ad65f52283832ebf058fdf1cslive const char *name,
97a9a944b5887e91042b019776c41d5dd74557aferikabele const char *tmp;
06ba4a61654b3763ad65f52283832ebf058fdf1cslive DEBUG(SSSDBG_FATAL_FAILURE, "Unknown domain [%s]\n", name);
06ba4a61654b3763ad65f52283832ebf058fdf1cslive tmp = ldb_msg_find_attr_as_string(res->msgs[0], "cn", NULL);
fa1c7ce09927decc1eecd1e9a35cc5331078a052covener "Invalid configuration entry, fatal error!\n");
fe64b2ba25510d8c9dba5560a2d537763566cf40nd "Domain [%s] does not specify an ID provider, disabling!\n",
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /* The files provider is not valid anymore */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd DEBUG(SSSDBG_FATAL_FAILURE, "The \"files\" provider is invalid\n");
fb77c505254b6e9c925e23e734463e87574f8f40kess /* If this is the local provider, we need to ensure that
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd * no other provider was specified for other types, since
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd * the local provider cannot load them.
c68acc9d712af079afa2bd1a5a4aeef9a3ea573ckess "Local ID provider does not support [%s] as an AUTH provider.\n", tmp);
fe64b2ba25510d8c9dba5560a2d537763566cf40nd "Local ID provider does not support [%s] as an ACCESS provider.\n", tmp);
8559a67073808d84d85bb5dd552d4247caafe709sf "Local ID provider does not support [%s] as a CHPASS provider.\n", tmp);
8559a67073808d84d85bb5dd552d4247caafe709sf /* The LOCAL provider use always Magic Private Groups */
8559a67073808d84d85bb5dd552d4247caafe709sf /* Determine if this domain can be enumerated */
8559a67073808d84d85bb5dd552d4247caafe709sf /* TEMP: test if the old bitfield conf value is used and warn it has been
8559a67073808d84d85bb5dd552d4247caafe709sf * superceeded. */
8559a67073808d84d85bb5dd552d4247caafe709sf val = ldb_msg_find_attr_as_int(res->msgs[0], CONFDB_DOMAIN_ENUMERATE, 0);
8559a67073808d84d85bb5dd552d4247caafe709sf "Warning: enumeration parameter in %s still uses integers! "
8559a67073808d84d85bb5dd552d4247caafe709sf "Enumeration is now a boolean and takes true/false values. "
8559a67073808d84d85bb5dd552d4247caafe709sf } else { /* assume the new format */
8559a67073808d84d85bb5dd552d4247caafe709sf ret = get_entry_as_bool(res->msgs[0], &domain->enumerate,
8559a67073808d84d85bb5dd552d4247caafe709sf DEBUG(SSSDBG_TRACE_FUNC, "No enumeration for [%s]!\n", domain->name);
8559a67073808d84d85bb5dd552d4247caafe709sf /* Determine if user/group names will be Fully Qualified
8559a67073808d84d85bb5dd552d4247caafe709sf * in NSS interfaces */
8559a67073808d84d85bb5dd552d4247caafe709sf ret = get_entry_as_bool(res->msgs[0], &domain->fqnames, CONFDB_DOMAIN_FQ, 0);
8559a67073808d84d85bb5dd552d4247caafe709sf DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for %s\n", CONFDB_DOMAIN_FQ);
8559a67073808d84d85bb5dd552d4247caafe709sf ret = get_entry_as_bool(res->msgs[0], &domain->ignore_group_members,
8559a67073808d84d85bb5dd552d4247caafe709sf "Invalid value for %s\n",
8559a67073808d84d85bb5dd552d4247caafe709sf DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for minId\n");
8559a67073808d84d85bb5dd552d4247caafe709sf DEBUG(SSSDBG_FATAL_FAILURE, "Invalid value for maxId\n");
8559a67073808d84d85bb5dd552d4247caafe709sf if (domain->id_max && (domain->id_max < domain->id_min)) {
8559a67073808d84d85bb5dd552d4247caafe709sf /* Do we allow to cache credentials */
8559a67073808d84d85bb5dd552d4247caafe709sf ret = get_entry_as_bool(res->msgs[0], &domain->cache_credentials,
8559a67073808d84d85bb5dd552d4247caafe709sf ret = get_entry_as_bool(res->msgs[0], &domain->legacy_passwords,
fb77c505254b6e9c925e23e734463e87574f8f40kess /* Get the global entry cache timeout setting */
fb77c505254b6e9c925e23e734463e87574f8f40kess ret = get_entry_as_uint32(res->msgs[0], &entry_cache_timeout,
fe64b2ba25510d8c9dba5560a2d537763566cf40nd "Invalid value for [%s]\n",
fb77c505254b6e9c925e23e734463e87574f8f40kess /* Override the user cache timeout, if specified */
88d86cfadffe2275a3dfb67a4d7bdc018630b661rbowen ret = get_entry_as_uint32(res->msgs[0], &domain->user_timeout,
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd "Invalid value for [%s]\n",
e4286c93598ad346ac365e59ac9c6f9e6e9fd324poirier /* Override the group cache timeout, if specified */
e4286c93598ad346ac365e59ac9c6f9e6e9fd324poirier ret = get_entry_as_uint32(res->msgs[0], &domain->group_timeout,
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd "Invalid value for [%s]\n",
a7f40ca49262952d6dd69d021cf5b0c2b452ae4cnd /* Override the netgroup cache timeout, if specified */
5f86589186bcc15ee13e288a9d73acbeab2409fbdpejesh ret = get_entry_as_uint32(res->msgs[0], &domain->netgroup_timeout,
5f86589186bcc15ee13e288a9d73acbeab2409fbdpejesh "Invalid value for [%s]\n",
5f86589186bcc15ee13e288a9d73acbeab2409fbdpejesh /* Override the service cache timeout, if specified */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd ret = get_entry_as_uint32(res->msgs[0], &domain->service_timeout,
fe64b2ba25510d8c9dba5560a2d537763566cf40nd "Invalid value for [%s]\n",
fe64b2ba25510d8c9dba5560a2d537763566cf40nd /* Override the autofs cache timeout, if specified */
fe64b2ba25510d8c9dba5560a2d537763566cf40nd ret = get_entry_as_uint32(res->msgs[0], &domain->autofsmap_timeout,
9bcfc3697a91b5215893a7d0206865b13fc72148nd "Invalid value for [%s]\n",
5f86589186bcc15ee13e288a9d73acbeab2409fbdpejesh /* Override the sudo cache timeout, if specified */
9b5e2c5e769dc678a1aca06df75c32022b2f1492trawick ret = get_entry_as_uint32(res->msgs[0], &domain->sudo_timeout,
5f86589186bcc15ee13e288a9d73acbeab2409fbdpejesh "Invalid value for [%s]\n",
78f4d313fd5edf76dc5cfb8725e082a08cd29740jwoolley /* Set refresh_expired_interval, if specified */
78f4d313fd5edf76dc5cfb8725e082a08cd29740jwoolley ret = get_entry_as_uint32(res->msgs[0], &domain->refresh_expired_interval,
9fb925624300c864fe3969a264e52aa83f3c2dd0slive "Invalid value for [%s]\n",
5f86589186bcc15ee13e288a9d73acbeab2409fbdpejesh /* Set the PAM warning time, if specified. If not specified, pass on
5f86589186bcc15ee13e288a9d73acbeab2409fbdpejesh * the "not set" value of "-1" which means "use provider default". The
29b517f9fe7f32a2c3fbdc53e359b6db6f8e8c2csf * value 0 means "always display the warning if server sends one" */
5f86589186bcc15ee13e288a9d73acbeab2409fbdpejesh "Failed to read PAM expiration warning, not fatal.\n");
832853bb93c1831daf24e4727c5ca0e1b1786e83lars DEBUG(SSSDBG_TRACE_LIBS, "pwd_expiration_warning is %d\n", val);
832853bb93c1831daf24e4727c5ca0e1b1786e83lars if (val >= 0) {
dce2bc31f4940687c7ffabb80570bc37ea7296d8trawick "Setting domain password expiration warning to %d days\n", val);
dce2bc31f4940687c7ffabb80570bc37ea7296d8trawick /* The value is in days, transform it to seconds */
dce2bc31f4940687c7ffabb80570bc37ea7296d8trawick ret = get_entry_as_uint32(res->msgs[0], &domain->override_gid,
dce2bc31f4940687c7ffabb80570bc37ea7296d8trawick "Invalid value for [%s]\n", CONFDB_DOMAIN_OVERRIDE_GID);
dce2bc31f4940687c7ffabb80570bc37ea7296d8trawick domain->override_homedir = talloc_strdup(domain, tmp);
dce2bc31f4940687c7ffabb80570bc37ea7296d8trawick domain->fallback_homedir = talloc_strdup(domain, tmp);
7a497a1b89d0b52f5284854eb12662b4bd80ba5cnd /* default */
06ba4a61654b3763ad65f52283832ebf058fdf1cslive "Local ID provider does not support the case insensitive flag\n");
06ba4a61654b3763ad65f52283832ebf058fdf1cslive ret = split_on_separator(domain, tmp, ',', true, true,
06ba4a61654b3763ad65f52283832ebf058fdf1cslive if (ret != 0) {
4f854c24127e28f7ad72ce9a39d4448aaf910fc1slive ret = get_entry_as_uint32(res->msgs[0], &domain->subdomain_refresh_interval,
4f854c24127e28f7ad72ce9a39d4448aaf910fc1slive if (ret != EOK || domain->subdomain_refresh_interval == 0) {
59cd19c3d75e35ae820e23f6b0161910784fce4eslive "Invalid value for [%s]\n", CONFDB_DOMAIN_SUBDOMAIN_REFRESH);
fb109b84906e3ee61680aa289953c2f9e859354erbowen DEBUG(SSSDBG_FATAL_FAILURE, "No domains configured, fatal error!\n");
313bb560bc5c323cfd40c9cad7335b4b8e060aedkess DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error retrieving domains list!\n");
06ba4a61654b3763ad65f52283832ebf058fdf1cslive for (i = 0; domlist[i]; i++) {
fb109b84906e3ee61680aa289953c2f9e859354erbowen /* check if domain name is really unique */
5155e92c6100b47513159eee1b2b9914ab204a5acovener ret = confdb_get_domain_internal(cdb, cdb, domlist[i], &domain);
fb109b84906e3ee61680aa289953c2f9e859354erbowen "Error (%d [%s]) retrieving domain [%s], skipping!\n",
9b5e2c5e769dc678a1aca06df75c32022b2f1492trawick DLIST_ADD_END(cdb->doms, domain, struct sss_domain_info *);
031bbbc0d1189b07330e38d0c126820a9ab7795egryzor "No properly configured domains, fatal error!\n");
2851546ce44280e54301016a7e92b00a87745509sf const char *name,
29b517f9fe7f32a2c3fbdc53e359b6db6f8e8c2csf for (dom = doms; dom; dom = get_next_domain(dom, false)) {
29b517f9fe7f32a2c3fbdc53e359b6db6f8e8c2csf dn = ldb_dn_new(tmp_ctx, cdb->ldb, CONFDB_DOMAIN_BASEDN);
a547340d7d0f0e79c9ba921c7dec7b18d0c800ffrbowen ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_ONELEVEL,
221a06bb836af6024708190895834af79c90d1c8rbowen names = talloc_zero_array(tmp_ctx, char*, res->count + 1);
2bb4320391b88748dc6e851deca941b058231664rbowen name = ldb_msg_find_attr_as_string(res->msgs[i], CONFDB_DOMAIN_ATTR,
2bb4320391b88748dc6e851deca941b058231664rbowen "The object [%s] doesn't have a name\n",