sdap_async_autofs.c revision e7d1cd14ce1a427007b1a7e9789dcb7e9619f84f
/*
SSSD
Async LDAP Helper routines for autofs
Authors:
Jakub Hrozek <jhrozek@redhat.com>
Copyright (C) 2012 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 <http://www.gnu.org/licenses/>.
*/
#include "util/util.h"
#include "db/sysdb.h"
#include "providers/ldap/sdap_async_private.h"
#include "db/sysdb_autofs.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_autofs.h"
enum autofs_map_op {
AUTOFS_MAP_OP_ADD,
AUTOFS_MAP_OP_DEL
};
/* ====== Utility functions ====== */
static const char *
get_autofs_map_name(struct sysdb_attrs *map, struct sdap_options *opts)
{
errno_t ret;
struct ldb_message_element *el;
ret = sysdb_attrs_get_el(map,
opts->autofs_mobject_map[SDAP_AT_AUTOFS_MAP_NAME].sys_name,
&el);
if (ret) return NULL;
if (el->num_values == 0) return NULL;
return (const char *)el->values[0].data;
}
static const char *
get_autofs_entry_attr(struct sysdb_attrs *entry, struct sdap_options *opts,
enum sdap_autofs_entry_attrs attr)
{
errno_t ret;
struct ldb_message_element *el;
ret = sysdb_attrs_get_el(entry,
opts->autofs_entry_map[attr].sys_name,
&el);
if (ret) return NULL;
if (el->num_values != 1) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Expected one entry got %d\n", el->num_values));
return NULL;
}
return (const char *)el->values[0].data;
}
static const char *
get_autofs_entry_key(struct sysdb_attrs *entry, struct sdap_options *opts)
{
return get_autofs_entry_attr(entry, opts, SDAP_AT_AUTOFS_ENTRY_KEY);
}
static const char *
get_autofs_entry_value(struct sysdb_attrs *entry, struct sdap_options *opts)
{
return get_autofs_entry_attr(entry, opts, SDAP_AT_AUTOFS_ENTRY_VALUE);
}
static errno_t
add_autofs_entry(struct sss_domain_info *domain,
const char *map,
struct sdap_options *opts,
struct sysdb_attrs *entry)
{
const char *key;
const char *value;
key = get_autofs_entry_key(entry, opts);
if (!key) {
DEBUG(SSSDBG_OP_FAILURE, ("Could not get autofs entry key\n"));
return EINVAL;
}
value = get_autofs_entry_value(entry, opts);
if (!value) {
DEBUG(SSSDBG_OP_FAILURE, ("Could not get autofs entry value\n"));
return EINVAL;
}
return sysdb_save_autofsentry(domain, map, key, value, NULL);
}
static errno_t
save_autofs_entries(struct sss_domain_info *domain,
struct sdap_options *opts,
const char *map,
char **add_dn_list,
hash_table_t *entry_hash)
{
hash_key_t key;
hash_value_t value;
size_t i;
int hret;
errno_t ret;
struct sysdb_attrs *entry;
if (!add_dn_list) {
return EOK;
}
for (i=0; add_dn_list[i]; i++) {
key.type = HASH_KEY_STRING;
key.str = (char *) add_dn_list[i];
hret = hash_lookup(entry_hash, &key, &value);
if (hret != HASH_SUCCESS) {
DEBUG(SSSDBG_MINOR_FAILURE,
("Cannot retrieve entry [%s] from hash\n", add_dn_list[i]));
continue;
}
entry = talloc_get_type(value.ptr, struct sysdb_attrs);
if (!entry) {
DEBUG(SSSDBG_MINOR_FAILURE,
("Cannot retrieve entry [%s] from ptr\n", add_dn_list[i]));
continue;
}
DEBUG(SSSDBG_TRACE_FUNC,
("Saving autofs entry [%s]\n", add_dn_list[i]));
ret = add_autofs_entry(domain, map, opts, entry);
if (ret) {
DEBUG(SSSDBG_MINOR_FAILURE,
("Cannot save entry [%s] to cache\n", add_dn_list[i]));
continue;
}
DEBUG(SSSDBG_TRACE_FUNC, ("Saved entry [%s]\n", add_dn_list[i]));
}
DEBUG(SSSDBG_TRACE_INTERNAL, ("All entries saved\n"));
return EOK;
}
static errno_t
del_autofs_entries(struct sss_domain_info *dom,
struct sdap_options *opts,
const char *map,
char **del_dn_list)
{
size_t i;
errno_t ret;
for (i=0; del_dn_list[i]; i++) {
DEBUG(SSSDBG_TRACE_FUNC,
("Removing autofs entry [%s]\n", del_dn_list[i]));
ret = sysdb_del_autofsentry(dom, del_dn_list[i]);
if (ret) {
DEBUG(SSSDBG_MINOR_FAILURE,
("Cannot delete entry %s\n", del_dn_list[i]));
continue;
}
}
DEBUG(SSSDBG_TRACE_INTERNAL, ("All entries removed\n"));
return EOK;
}
static errno_t
save_autofs_map(struct sss_domain_info *dom,
struct sdap_options *opts,
struct sysdb_attrs *map)
{
const char *mapname;
errno_t ret;
time_t now;
mapname = get_autofs_map_name(map, opts);
if (!mapname) return EINVAL;
now = time(NULL);
ret = sysdb_save_autofsmap(dom, mapname, mapname,
NULL, dom->autofsmap_timeout, now);
if (ret != EOK) {
return ret;
}
return EOK;
}
struct automntmaps_process_members_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sdap_handle *sh;
struct sss_domain_info *dom;
int timeout;
const char *orig_dn;
char *base_filter;
char *filter;
const char **attrs;
size_t base_iter;
struct sdap_search_base **search_bases;
struct sysdb_attrs *map;
struct sysdb_attrs **entries;
size_t entries_count;
};
static void
automntmaps_process_members_done(struct tevent_req *subreq);
static errno_t
automntmaps_process_members_next_base(struct tevent_req *req);
static struct tevent_req *
automntmaps_process_members_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sdap_options *opts,
struct sdap_handle *sh,
struct sss_domain_info *dom,
struct sdap_search_base **search_bases,
int timeout,
struct sysdb_attrs *map)
{
errno_t ret;
struct tevent_req *req;
struct automntmaps_process_members_state *state;
req = tevent_req_create(mem_ctx, &state,
struct automntmaps_process_members_state);
if (!req) return NULL;
state->ev = ev;
state->opts = opts;
state->dom = dom;
state->sh = sh;
state->timeout = timeout;
state->base_iter = 0;
state->map = map;
state->search_bases = search_bases;
state->base_filter = talloc_asprintf(state, "(&(%s=*)(objectclass=%s))",
opts->autofs_entry_map[SDAP_AT_AUTOFS_ENTRY_KEY].name,
opts->autofs_entry_map[SDAP_OC_AUTOFS_ENTRY].name);
if (!state->base_filter) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to build filter\n"));
ret = ENOMEM;
goto immediate;
}
ret = build_attrs_from_map(state, opts->autofs_entry_map,
SDAP_OPTS_AUTOFS_ENTRY, NULL,
&state->attrs, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to build attributes from map\n"));
ret = ENOMEM;
goto immediate;
}
ret = sysdb_attrs_get_string(state->map, SYSDB_ORIG_DN, &state->orig_dn);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot get originalDN\n"));
goto immediate;
}
DEBUG(SSSDBG_TRACE_FUNC,
("Examining autofs map [%s]\n", state->orig_dn));
ret = automntmaps_process_members_next_base(req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
("search failed [%d]: %s\n", ret, strerror(ret)));
goto immediate;
}
return req;
immediate:
if (ret != EOK) {
tevent_req_error(req, ret);
} else {
tevent_req_done(req);
}
tevent_req_post(req, ev);
return req;
}
static errno_t
automntmaps_process_members_next_base(struct tevent_req *req)
{
struct tevent_req *subreq;
struct automntmaps_process_members_state *state =
tevent_req_data(req, struct automntmaps_process_members_state);
talloc_zfree(state->filter);
state->filter = sdap_get_id_specific_filter(state,
state->base_filter,
state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
}
DEBUG(SSSDBG_TRACE_FUNC,
("Searching for automount map entries with base [%s]\n",
state->search_bases[state->base_iter]->basedn));
subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
state->orig_dn,
state->search_bases[state->base_iter]->scope,
state->filter, state->attrs,
state->opts->autofs_entry_map,
SDAP_OPTS_AUTOFS_ENTRY,
state->timeout, true);
if (!subreq) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot start search for entries\n"));
return EIO;
}
tevent_req_set_callback(subreq, automntmaps_process_members_done, req);
return EOK;
}
static void
automntmaps_process_members_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct automntmaps_process_members_state *state =
tevent_req_data(req, struct automntmaps_process_members_state);
errno_t ret;
struct sysdb_attrs **entries;
size_t entries_count, i;
ret = sdap_get_generic_recv(subreq, state,
&entries_count, &entries);
talloc_zfree(subreq);
if (ret) {
tevent_req_error(req, ret);
return;
}
if (entries_count > 0) {
state->entries = talloc_realloc(state, state->entries,
struct sysdb_attrs *,
state->entries_count + entries_count + 1);
if (state->entries == NULL) {
tevent_req_error(req, ENOMEM);
return;
}
for (i=0; i < entries_count; i++) {
state->entries[state->entries_count + i] =
talloc_steal(state->entries, entries[i]);
}
state->entries_count += entries_count;
state->entries[state->entries_count] = NULL;
}
state->base_iter++;
if (state->search_bases[state->base_iter]) {
ret = automntmaps_process_members_next_base(req);
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
}
DEBUG(SSSDBG_TRACE_INTERNAL, ("No more search bases to try\n"));
DEBUG(SSSDBG_TRACE_FUNC,
("Search for autofs entries, returned %zu results.\n",
state->entries_count));
tevent_req_done(req);
return;
}
static errno_t
automntmaps_process_members_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
size_t *entries_count,
struct sysdb_attrs ***entries)
{
struct automntmaps_process_members_state *state;
state = tevent_req_data(req, struct automntmaps_process_members_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
if (entries_count) {
*entries_count = state->entries_count;
}
if (entries) {
*entries = talloc_steal(mem_ctx, state->entries);
}
return EOK;
}
struct sdap_get_automntmap_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sdap_handle *sh;
struct sss_domain_info *dom;
const char **attrs;
const char *base_filter;
char *filter;
int timeout;
char *higher_timestamp;
struct sysdb_attrs **map;
size_t count;
struct sysdb_attrs **entries;
size_t entries_count;
size_t base_iter;
struct sdap_search_base **search_bases;
};
static errno_t
sdap_get_automntmap_next_base(struct tevent_req *req);
static void
sdap_get_automntmap_process(struct tevent_req *subreq);
static struct tevent_req *
sdap_get_automntmap_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct sss_domain_info *dom,
struct sdap_options *opts,
struct sdap_search_base **search_bases,
struct sdap_handle *sh,
const char **attrs,
const char *filter,
int timeout)
{
errno_t ret;
struct tevent_req *req;
struct sdap_get_automntmap_state *state;
req = tevent_req_create(memctx, &state, struct sdap_get_automntmap_state);
if (!req) return NULL;
state->ev = ev;
state->opts = opts;
state->dom = dom;
state->sh = sh;
state->attrs = attrs;
state->higher_timestamp = NULL;
state->map = NULL;
state->count = 0;
state->timeout = timeout;
state->base_filter = filter;
state->base_iter = 0;
state->search_bases = search_bases;
ret = sdap_get_automntmap_next_base(req);
if (ret != EOK) {
tevent_req_error(req, ret);
tevent_req_post(req, state->ev);
}
return req;
}
static errno_t
sdap_get_automntmap_next_base(struct tevent_req *req)
{
struct tevent_req *subreq;
struct sdap_get_automntmap_state *state;
state = tevent_req_data(req, struct sdap_get_automntmap_state);
talloc_zfree(state->filter);
state->filter = sdap_get_id_specific_filter(state,
state->base_filter,
state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
}
DEBUG(SSSDBG_TRACE_FUNC,
("Searching for automount maps with base [%s]\n",
state->search_bases[state->base_iter]->basedn));
subreq = sdap_get_generic_send(
state, state->ev, state->opts, state->sh,
state->search_bases[state->base_iter]->basedn,
state->search_bases[state->base_iter]->scope,
state->filter, state->attrs,
state->opts->autofs_mobject_map, SDAP_OPTS_AUTOFS_MAP,
state->timeout,
false);
if (!subreq) {
return EIO;
}
tevent_req_set_callback(subreq, sdap_get_automntmap_process, req);
return EOK;
}
static void
sdap_get_automntmap_done(struct tevent_req *subreq);
static void
sdap_get_automntmap_process(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct sdap_get_automntmap_state *state = tevent_req_data(req,
struct sdap_get_automntmap_state);
errno_t ret;
ret = sdap_get_generic_recv(subreq, state,
&state->count, &state->map);
talloc_zfree(subreq);
if (ret) {
tevent_req_error(req, ret);
return;
}
DEBUG(SSSDBG_TRACE_FUNC,
("Search for autofs maps, returned %zu results.\n", state->count));
if (state->count == 0) {
/* No maps found in this search */
state->base_iter++;
if (state->search_bases[state->base_iter]) {
/* There are more search bases to try */
ret = sdap_get_automntmap_next_base(req);
if (ret != EOK) {
tevent_req_error(req, ENOENT);
}
return;
}
tevent_req_error(req, ENOENT);
return;
} else if (state->count > 1) {
DEBUG(SSSDBG_OP_FAILURE,
("The search yielded more than one autofs map\n"));
tevent_req_error(req, EIO);
return;
}
DEBUG(SSSDBG_TRACE_INTERNAL, ("Processing autofs maps\n"));
subreq = automntmaps_process_members_send(state, state->ev, state->opts,
state->sh, state->dom,
state->search_bases,
state->timeout,
state->map[0]);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
}
tevent_req_set_callback(subreq, sdap_get_automntmap_done, req);
return;
}
static void
sdap_get_automntmap_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct sdap_get_automntmap_state *state = tevent_req_data(req,
struct sdap_get_automntmap_state);
errno_t ret;
ret = automntmaps_process_members_recv(subreq, state, &state->entries_count,
&state->entries);
talloc_zfree(subreq);
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
DEBUG(SSSDBG_TRACE_FUNC, ("automount map members received\n"));
tevent_req_done(req);
return;
}
static errno_t
sdap_get_automntmap_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
struct sysdb_attrs **map,
size_t *entries_count,
struct sysdb_attrs ***entries)
{
struct sdap_get_automntmap_state *state = tevent_req_data(req,
struct sdap_get_automntmap_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
if (map) {
*map = talloc_steal(mem_ctx, state->map[0]);
}
if (entries_count) {
*entries_count = state->entries_count;
}
if (entries) {
*entries = talloc_steal(mem_ctx, state->entries);
}
return EOK;
}
struct sdap_autofs_setautomntent_state {
char *filter;
const char **attrs;
struct sdap_options *opts;
struct sdap_handle *sh;
struct sysdb_ctx *sysdb;
struct sdap_id_op *sdap_op;
struct sss_domain_info *dom;
const char *mapname;
struct sysdb_attrs *map;
struct sysdb_attrs **entries;
size_t entries_count;
int dp_error;
};
static void
sdap_autofs_setautomntent_done(struct tevent_req *subreq);
struct tevent_req *
sdap_autofs_setautomntent_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct sss_domain_info *dom,
struct sysdb_ctx *sysdb,
struct sdap_handle *sh,
struct sdap_id_op *op,
struct sdap_options *opts,
const char *mapname)
{
struct tevent_req *req;
struct tevent_req *subreq;
struct sdap_autofs_setautomntent_state *state;
char *clean_mapname;
errno_t ret;
req = tevent_req_create(memctx, &state,
struct sdap_autofs_setautomntent_state);
if (!req) return NULL;
if (!mapname) {
DEBUG(SSSDBG_CRIT_FAILURE, ("No map name given\n"));
ret = EINVAL;
goto fail;
}
state->sh = sh;
state->sysdb = sysdb;
state->opts = opts;
state->sdap_op = op;
state->dom = dom;
state->mapname = mapname;
ret = sss_filter_sanitize(state, mapname, &clean_mapname);
if (ret != EOK) {
goto fail;
}
state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
state->opts->autofs_mobject_map[SDAP_AT_AUTOFS_MAP_NAME].name,
clean_mapname,
state->opts->autofs_mobject_map[SDAP_OC_AUTOFS_MAP].name);
if (!state->filter) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to build filter\n"));
ret = ENOMEM;
goto fail;
}
talloc_free(clean_mapname);
ret = build_attrs_from_map(state, state->opts->autofs_mobject_map,
SDAP_OPTS_AUTOFS_MAP, NULL,
&state->attrs, NULL);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to build attributes from map\n"));
ret = ENOMEM;
goto fail;
}
subreq = sdap_get_automntmap_send(state, ev, dom,
state->opts,
state->opts->sdom->autofs_search_bases,
state->sh,
state->attrs, state->filter,
dp_opt_get_int(state->opts->basic,
SDAP_SEARCH_TIMEOUT));
if (!subreq) {
DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory\n"));
ret = ENOMEM;
goto fail;
}
tevent_req_set_callback(subreq, sdap_autofs_setautomntent_done, req);
return req;
fail:
tevent_req_error(req, ret);
tevent_req_post(req, ev);
return req;
}
static errno_t
sdap_autofs_setautomntent_save(struct tevent_req *req);
static void
sdap_autofs_setautomntent_done(struct tevent_req *subreq)
{
errno_t ret;
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct sdap_autofs_setautomntent_state *state = tevent_req_data(req,
struct sdap_autofs_setautomntent_state);
ret = sdap_get_automntmap_recv(subreq, state, &state->map,
&state->entries_count, &state->entries);
talloc_zfree(subreq);
if (ret != EOK) {
if (ret == ENOENT) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Could not find automount map\n"));
} else {
DEBUG(SSSDBG_OP_FAILURE,
("sdap_get_automntmap_recv failed [%d]: %s\n",
ret, strerror(ret)));
}
tevent_req_error(req, ret);
return;
}
ret = sdap_autofs_setautomntent_save(req);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("Could not save automount map\n"));
tevent_req_error(req, ret);
return;
}
state->dp_error = DP_ERR_OK;
tevent_req_done(req);
return;
}
static errno_t
sdap_autofs_setautomntent_save(struct tevent_req *req)
{
struct sdap_autofs_setautomntent_state *state = tevent_req_data(req,
struct sdap_autofs_setautomntent_state);
errno_t ret, tret;
bool in_transaction = false;
TALLOC_CTX *tmp_ctx;
struct ldb_message **entries = NULL;
size_t count;
const char *key;
const char *val;
char **sysdb_entrylist;
char **ldap_entrylist;
char **add_entries;
char **del_entries;
size_t i, j;
hash_table_t *entry_hash;
hash_key_t hkey;
hash_value_t value;
int hret;
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return ENOMEM;
DEBUG(SSSDBG_TRACE_LIBS,
("Got %zu map entries from LDAP\n", state->entries_count));
if (state->entries_count == 0) {
/* No entries for this map in LDAP.
* We need to ensure that there are no entries
* in the sysdb either.
*/
ldap_entrylist = NULL;
} else {
ldap_entrylist = talloc_array(tmp_ctx, char *,
state->entries_count+1);
if (!ldap_entrylist) {
ret = ENOMEM;
goto done;
}
ret = sss_hash_create(state, 32, &entry_hash);
if (ret) {
goto done;
}
/* Get a list of the map members by DN */
for (i=0, j=0; i < state->entries_count; i++) {
key = get_autofs_entry_key(state->entries[i], state->opts);
val = get_autofs_entry_value(state->entries[i], state->opts);
if (!key || !val) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Malformed entry, skipping\n"));
continue;
}
ldap_entrylist[j] = sysdb_autofsentry_strdn(ldap_entrylist,
state->dom,
state->mapname,
key, val);
if (!ldap_entrylist[j]) {
ret = ENOMEM;
goto done;
}
hkey.type = HASH_KEY_STRING;
hkey.str = ldap_entrylist[j];
value.type = HASH_VALUE_PTR;
value.ptr = state->entries[i];
hret = hash_enter(entry_hash, &hkey, &value);
if (hret != HASH_SUCCESS) {
ret = EIO;
goto done;
}
j++;
}
ldap_entrylist[state->entries_count] = NULL;
}
ret = sysdb_autofs_entries_by_map(tmp_ctx, state->dom, state->mapname,
&count, &entries);
if (ret != EOK && ret != ENOENT) {
DEBUG(SSSDBG_OP_FAILURE,
("cache lookup for the map failed [%d]: %s\n",
ret, strerror(ret)));
goto done;
}
DEBUG(SSSDBG_TRACE_LIBS, ("Got %zu map entries from sysdb\n", count));
if (count == 0) {
/* No map members for this map in sysdb currently */
sysdb_entrylist = NULL;
} else {
sysdb_entrylist = talloc_array(state, char *, count+1);
if (!sysdb_entrylist) {
ret = ENOMEM;
goto done;
}
/* Get a list of the map members by DN */
for (i=0; i < count; i++) {
sysdb_entrylist[i] = talloc_strdup(sysdb_entrylist,
ldb_dn_get_linearized(entries[i]->dn));
if (!sysdb_entrylist[i]) {
ret = ENOMEM;
goto done;
}
}
sysdb_entrylist[count] = NULL;
}
/* Find the differences between the sysdb and LDAP lists
* Entries in the sysdb only must be removed.
*/
ret = diff_string_lists(tmp_ctx, ldap_entrylist, sysdb_entrylist,
&add_entries, &del_entries, NULL);
if (ret != EOK) goto done;
ret = sysdb_transaction_start(state->sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Cannot start sysdb transaction [%d]: %s\n",
ret, strerror(ret)));
goto done;
}
in_transaction = true;
/* Save the map itself */
ret = save_autofs_map(state->dom, state->opts, state->map);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
("Cannot save autofs map entry [%d]: %s\n",
ret, strerror(ret)));
goto done;
}
/* Create entries that don't exist yet */
if (add_entries && add_entries[0]) {
ret = save_autofs_entries(state->dom, state->opts,
state->mapname, add_entries,
entry_hash);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
("Cannot save autofs entries [%d]: %s\n",
ret, strerror(ret)));
goto done;
}
}
/* Delete entries that don't exist anymore */
if (del_entries && del_entries[0]) {
ret = del_autofs_entries(state->dom, state->opts,
state->mapname, del_entries);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
("Cannot delete autofs entries [%d]: %s\n",
ret, strerror(ret)));
goto done;
}
}
ret = sysdb_transaction_commit(state->sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Cannot commit sysdb transaction [%d]: %s\n",
ret, strerror(ret)));
goto done;
}
in_transaction = false;
ret = EOK;
done:
if (in_transaction) {
tret = sysdb_transaction_cancel(state->sysdb);
if (tret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
("Cannot cancel sysdb transaction [%d]: %s\n",
ret, strerror(ret)));
}
}
talloc_zfree(tmp_ctx);
return ret;
}
errno_t
sdap_autofs_setautomntent_recv(struct tevent_req *req)
{
TEVENT_REQ_RETURN_ON_ERROR(req);
return EOK;
}