LCOV - code coverage report
Current view: top level - providers/ldap - sdap_async_autofs.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 405 0.0 %
Date: 2015-10-19 Functions: 0 21 0.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Async LDAP Helper routines for autofs
       5             : 
       6             :     Authors:
       7             :         Jakub Hrozek <jhrozek@redhat.com>
       8             : 
       9             :     Copyright (C) 2012 Red Hat
      10             : 
      11             :     This program is free software; you can redistribute it and/or modify
      12             :     it under the terms of the GNU General Public License as published by
      13             :     the Free Software Foundation; either version 3 of the License, or
      14             :     (at your option) any later version.
      15             : 
      16             :     This program is distributed in the hope that it will be useful,
      17             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :     GNU General Public License for more details.
      20             : 
      21             :     You should have received a copy of the GNU General Public License
      22             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "util/util.h"
      26             : #include "db/sysdb.h"
      27             : #include "providers/ldap/sdap_async_private.h"
      28             : #include "db/sysdb_autofs.h"
      29             : #include "providers/ldap/ldap_common.h"
      30             : #include "providers/ldap/sdap_autofs.h"
      31             : 
      32             : enum autofs_map_op {
      33             :     AUTOFS_MAP_OP_ADD,
      34             :     AUTOFS_MAP_OP_DEL
      35             : };
      36             : 
      37             : /* ====== Utility functions ====== */
      38             : static const char *
      39           0 : get_autofs_map_name(struct sysdb_attrs *map, struct sdap_options *opts)
      40             : {
      41             :     errno_t ret;
      42             :     struct ldb_message_element *el;
      43             : 
      44           0 :     ret = sysdb_attrs_get_el(map,
      45           0 :             opts->autofs_mobject_map[SDAP_AT_AUTOFS_MAP_NAME].sys_name,
      46             :             &el);
      47           0 :     if (ret) return NULL;
      48           0 :     if (el->num_values == 0) return NULL;
      49             : 
      50           0 :     return (const char *)el->values[0].data;
      51             : }
      52             : 
      53             : static const char *
      54           0 : get_autofs_entry_attr(struct sysdb_attrs *entry, struct sdap_options *opts,
      55             :                       enum sdap_autofs_entry_attrs attr)
      56             : {
      57             :     errno_t ret;
      58             :     struct ldb_message_element *el;
      59             : 
      60           0 :     ret = sysdb_attrs_get_el(entry,
      61           0 :             opts->autofs_entry_map[attr].sys_name,
      62             :             &el);
      63           0 :     if (ret) return NULL;
      64           0 :     if (el->num_values != 1) {
      65           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
      66             :               "Expected one entry got %d\n", el->num_values);
      67           0 :         return NULL;
      68             :     }
      69             : 
      70           0 :     return (const char *)el->values[0].data;
      71             : }
      72             : 
      73             : static const char *
      74           0 : get_autofs_entry_key(struct sysdb_attrs *entry, struct sdap_options *opts)
      75             : {
      76           0 :     return get_autofs_entry_attr(entry, opts, SDAP_AT_AUTOFS_ENTRY_KEY);
      77             : }
      78             : 
      79             : static const char *
      80           0 : get_autofs_entry_value(struct sysdb_attrs *entry, struct sdap_options *opts)
      81             : {
      82           0 :     return get_autofs_entry_attr(entry, opts, SDAP_AT_AUTOFS_ENTRY_VALUE);
      83             : }
      84             : 
      85             : static errno_t
      86           0 : add_autofs_entry(struct sss_domain_info *domain,
      87             :                  const char *map,
      88             :                  struct sdap_options *opts,
      89             :                  struct sysdb_attrs *entry)
      90             : {
      91             :     const char *key;
      92             :     const char *value;
      93             : 
      94           0 :     key = get_autofs_entry_key(entry, opts);
      95           0 :     if (!key) {
      96           0 :         DEBUG(SSSDBG_OP_FAILURE, "Could not get autofs entry key\n");
      97           0 :         return EINVAL;
      98             :     }
      99             : 
     100           0 :     value = get_autofs_entry_value(entry, opts);
     101           0 :     if (!value) {
     102           0 :         DEBUG(SSSDBG_OP_FAILURE, "Could not get autofs entry value\n");
     103           0 :         return EINVAL;
     104             :     }
     105             : 
     106           0 :     return sysdb_save_autofsentry(domain, map, key, value, NULL);
     107             : }
     108             : 
     109             : static errno_t
     110           0 : save_autofs_entries(struct sss_domain_info *domain,
     111             :                     struct sdap_options *opts,
     112             :                     const char *map,
     113             :                     char **add_dn_list,
     114             :                     hash_table_t *entry_hash)
     115             : {
     116             :     hash_key_t key;
     117             :     hash_value_t value;
     118             :     size_t i;
     119             :     int hret;
     120             :     errno_t ret;
     121             :     struct sysdb_attrs *entry;
     122             : 
     123           0 :     if (!add_dn_list) {
     124           0 :         return EOK;
     125             :     }
     126             : 
     127           0 :     for (i=0; add_dn_list[i]; i++) {
     128           0 :         key.type = HASH_KEY_STRING;
     129           0 :         key.str = (char *) add_dn_list[i];
     130             : 
     131           0 :         hret = hash_lookup(entry_hash, &key, &value);
     132           0 :         if (hret != HASH_SUCCESS) {
     133           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     134             :                   "Cannot retrieve entry [%s] from hash\n", add_dn_list[i]);
     135           0 :             continue;
     136             :         }
     137             : 
     138           0 :         entry = talloc_get_type(value.ptr, struct sysdb_attrs);
     139           0 :         if (!entry) {
     140           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     141             :                   "Cannot retrieve entry [%s] from ptr\n", add_dn_list[i]);
     142           0 :             continue;
     143             :         }
     144             : 
     145           0 :         DEBUG(SSSDBG_TRACE_FUNC,
     146             :               "Saving autofs entry [%s]\n", add_dn_list[i]);
     147           0 :         ret = add_autofs_entry(domain, map, opts, entry);
     148           0 :         if (ret) {
     149           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     150             :                   "Cannot save entry [%s] to cache\n", add_dn_list[i]);
     151           0 :             continue;
     152             :         }
     153             : 
     154           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Saved entry [%s]\n", add_dn_list[i]);
     155             :     }
     156             : 
     157           0 :     DEBUG(SSSDBG_TRACE_INTERNAL, "All entries saved\n");
     158           0 :     return EOK;
     159             : }
     160             : 
     161             : static errno_t
     162           0 : del_autofs_entries(struct sss_domain_info *dom,
     163             :                    char **del_dn_list)
     164             : {
     165             :     size_t i;
     166             :     errno_t ret;
     167             : 
     168           0 :     for (i=0; del_dn_list[i]; i++) {
     169           0 :         DEBUG(SSSDBG_TRACE_FUNC,
     170             :               "Removing autofs entry [%s]\n", del_dn_list[i]);
     171             : 
     172           0 :         ret = sysdb_del_autofsentry(dom, del_dn_list[i]);
     173           0 :         if (ret) {
     174           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     175             :                   "Cannot delete entry %s\n", del_dn_list[i]);
     176           0 :             continue;
     177             :         }
     178             :     }
     179             : 
     180           0 :     DEBUG(SSSDBG_TRACE_INTERNAL, "All entries removed\n");
     181           0 :     return EOK;
     182             : }
     183             : 
     184             : static errno_t
     185           0 : save_autofs_map(struct sss_domain_info *dom,
     186             :                 struct sdap_options *opts,
     187             :                 struct sysdb_attrs *map)
     188             : {
     189             :     const char *mapname;
     190             :     errno_t ret;
     191             :     time_t now;
     192             : 
     193           0 :     mapname = get_autofs_map_name(map, opts);
     194           0 :     if (!mapname) return EINVAL;
     195             : 
     196           0 :     now = time(NULL);
     197             : 
     198           0 :     ret = sysdb_save_autofsmap(dom, mapname, mapname,
     199           0 :                                NULL, dom->autofsmap_timeout, now);
     200           0 :     if (ret != EOK) {
     201           0 :         return ret;
     202             :     }
     203             : 
     204           0 :     return EOK;
     205             : }
     206             : 
     207             : struct automntmaps_process_members_state {
     208             :     struct tevent_context *ev;
     209             :     struct sdap_options *opts;
     210             :     struct sdap_handle *sh;
     211             :     struct sss_domain_info *dom;
     212             :     int    timeout;
     213             : 
     214             :     const char *orig_dn;
     215             :     char *base_filter;
     216             :     char *filter;
     217             :     const char **attrs;
     218             :     size_t base_iter;
     219             :     struct sdap_search_base **search_bases;
     220             : 
     221             :     struct sysdb_attrs *map;
     222             : 
     223             :     struct sysdb_attrs **entries;
     224             :     size_t entries_count;
     225             : };
     226             : 
     227             : static void
     228             : automntmaps_process_members_done(struct tevent_req *subreq);
     229             : static errno_t
     230             : automntmaps_process_members_next_base(struct tevent_req *req);
     231             : 
     232             : static struct tevent_req *
     233           0 : automntmaps_process_members_send(TALLOC_CTX *mem_ctx,
     234             :                                  struct tevent_context *ev,
     235             :                                  struct sdap_options *opts,
     236             :                                  struct sdap_handle *sh,
     237             :                                  struct sss_domain_info *dom,
     238             :                                  struct sdap_search_base **search_bases,
     239             :                                  int    timeout,
     240             :                                  struct sysdb_attrs *map)
     241             : {
     242             :     errno_t ret;
     243             :     struct tevent_req *req;
     244             :     struct automntmaps_process_members_state *state;
     245             : 
     246           0 :     req = tevent_req_create(mem_ctx, &state,
     247             :                             struct automntmaps_process_members_state);
     248           0 :     if (!req) return NULL;
     249             : 
     250           0 :     state->ev = ev;
     251           0 :     state->opts = opts;
     252           0 :     state->dom = dom;
     253           0 :     state->sh = sh;
     254           0 :     state->timeout = timeout;
     255           0 :     state->base_iter = 0;
     256           0 :     state->map = map;
     257           0 :     state->search_bases = search_bases;
     258             : 
     259           0 :     state->base_filter = talloc_asprintf(state, "(&(%s=*)(objectclass=%s))",
     260           0 :                     opts->autofs_entry_map[SDAP_AT_AUTOFS_ENTRY_KEY].name,
     261           0 :                     opts->autofs_entry_map[SDAP_OC_AUTOFS_ENTRY].name);
     262           0 :     if (!state->base_filter) {
     263           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build filter\n");
     264           0 :         ret = ENOMEM;
     265           0 :         goto immediate;
     266             :     }
     267             : 
     268           0 :     ret = build_attrs_from_map(state, opts->autofs_entry_map,
     269             :                                SDAP_OPTS_AUTOFS_ENTRY, NULL,
     270           0 :                                &state->attrs, NULL);
     271           0 :     if (ret != EOK) {
     272           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build attributes from map\n");
     273           0 :         ret = ENOMEM;
     274           0 :         goto immediate;
     275             :     }
     276             : 
     277             : 
     278           0 :     ret = sysdb_attrs_get_string(state->map, SYSDB_ORIG_DN, &state->orig_dn);
     279           0 :     if (ret != EOK) {
     280           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot get originalDN\n");
     281           0 :         goto immediate;
     282             :     }
     283             : 
     284           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     285             :           "Examining autofs map [%s]\n", state->orig_dn);
     286             : 
     287           0 :     ret = automntmaps_process_members_next_base(req);
     288           0 :     if (ret != EOK) {
     289           0 :         DEBUG(SSSDBG_OP_FAILURE,
     290             :               "search failed [%d]: %s\n", ret, strerror(ret));
     291           0 :         goto immediate;
     292             :     }
     293             : 
     294           0 :     return req;
     295             : 
     296             : immediate:
     297           0 :     if (ret != EOK) {
     298           0 :         tevent_req_error(req, ret);
     299             :     } else {
     300           0 :         tevent_req_done(req);
     301             :     }
     302           0 :     tevent_req_post(req, ev);
     303           0 :     return req;
     304             : }
     305             : 
     306             : static errno_t
     307           0 : automntmaps_process_members_next_base(struct tevent_req *req)
     308             : {
     309             :     struct tevent_req *subreq;
     310           0 :     struct automntmaps_process_members_state *state =
     311           0 :         tevent_req_data(req, struct automntmaps_process_members_state);
     312             : 
     313           0 :     talloc_zfree(state->filter);
     314           0 :     state->filter = sdap_get_id_specific_filter(state,
     315           0 :                         state->base_filter,
     316           0 :                         state->search_bases[state->base_iter]->filter);
     317           0 :     if (!state->filter) {
     318           0 :         return ENOMEM;
     319             :     }
     320             : 
     321           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     322             :           "Searching for automount map entries with base [%s]\n",
     323             :            state->search_bases[state->base_iter]->basedn);
     324             : 
     325           0 :     subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
     326             :                                    state->orig_dn,
     327           0 :                                    state->search_bases[state->base_iter]->scope,
     328           0 :                                    state->filter, state->attrs,
     329           0 :                                    state->opts->autofs_entry_map,
     330             :                                    SDAP_OPTS_AUTOFS_ENTRY,
     331             :                                    state->timeout, true);
     332           0 :     if (!subreq) {
     333           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot start search for entries\n");
     334           0 :         return EIO;
     335             :     }
     336           0 :     tevent_req_set_callback(subreq, automntmaps_process_members_done, req);
     337             : 
     338           0 :     return EOK;
     339             : }
     340             : 
     341             : static void
     342           0 : automntmaps_process_members_done(struct tevent_req *subreq)
     343             : {
     344           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     345             :                                                       struct tevent_req);
     346           0 :     struct automntmaps_process_members_state *state =
     347           0 :         tevent_req_data(req, struct automntmaps_process_members_state);
     348             :     errno_t ret;
     349             :     struct sysdb_attrs **entries;
     350             :     size_t entries_count, i;
     351             : 
     352           0 :     ret = sdap_get_generic_recv(subreq, state,
     353             :                                 &entries_count, &entries);
     354           0 :     talloc_zfree(subreq);
     355           0 :     if (ret) {
     356           0 :         tevent_req_error(req, ret);
     357           0 :         return;
     358             :     }
     359             : 
     360           0 :     if (entries_count > 0) {
     361           0 :         state->entries = talloc_realloc(state, state->entries,
     362             :                                         struct sysdb_attrs *,
     363             :                                         state->entries_count + entries_count + 1);
     364           0 :         if (state->entries == NULL) {
     365           0 :             tevent_req_error(req, ENOMEM);
     366           0 :             return;
     367             :         }
     368             : 
     369           0 :         for (i=0; i < entries_count; i++) {
     370           0 :             state->entries[state->entries_count + i] =
     371           0 :                 talloc_steal(state->entries, entries[i]);
     372             :         }
     373             : 
     374           0 :         state->entries_count += entries_count;
     375           0 :         state->entries[state->entries_count] = NULL;
     376             :     }
     377             : 
     378           0 :     state->base_iter++;
     379           0 :     if (state->search_bases[state->base_iter]) {
     380           0 :         ret = automntmaps_process_members_next_base(req);
     381           0 :         if (ret != EOK) {
     382           0 :             tevent_req_error(req, ret);
     383           0 :             return;
     384             :         }
     385             :     }
     386             : 
     387           0 :     DEBUG(SSSDBG_TRACE_INTERNAL, "No more search bases to try\n");
     388             : 
     389           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     390             :           "Search for autofs entries, returned %zu results.\n",
     391             :           state->entries_count);
     392             : 
     393           0 :     tevent_req_done(req);
     394           0 :     return;
     395             : }
     396             : 
     397             : static errno_t
     398           0 : automntmaps_process_members_recv(struct tevent_req *req,
     399             :                                  TALLOC_CTX *mem_ctx,
     400             :                                  size_t *entries_count,
     401             :                                  struct sysdb_attrs ***entries)
     402             : {
     403             :     struct automntmaps_process_members_state *state;
     404           0 :     state = tevent_req_data(req, struct automntmaps_process_members_state);
     405             : 
     406           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     407             : 
     408           0 :     if (entries_count) {
     409           0 :         *entries_count = state->entries_count;
     410             :     }
     411             : 
     412           0 :     if (entries) {
     413           0 :         *entries = talloc_steal(mem_ctx, state->entries);
     414             :     }
     415             : 
     416           0 :     return EOK;
     417             : }
     418             : 
     419             : struct sdap_get_automntmap_state {
     420             :     struct tevent_context *ev;
     421             :     struct sdap_options *opts;
     422             :     struct sdap_handle *sh;
     423             :     struct sss_domain_info *dom;
     424             :     const char **attrs;
     425             :     const char *base_filter;
     426             :     char *filter;
     427             :     int timeout;
     428             : 
     429             :     char *higher_timestamp;
     430             : 
     431             :     struct sysdb_attrs **map;
     432             :     size_t count;
     433             : 
     434             :     struct sysdb_attrs **entries;
     435             :     size_t entries_count;
     436             : 
     437             :     size_t base_iter;
     438             :     struct sdap_search_base **search_bases;
     439             : };
     440             : 
     441             : static errno_t
     442             : sdap_get_automntmap_next_base(struct tevent_req *req);
     443             : static void
     444             : sdap_get_automntmap_process(struct tevent_req *subreq);
     445             : 
     446             : static struct tevent_req *
     447           0 : sdap_get_automntmap_send(TALLOC_CTX *memctx,
     448             :                          struct tevent_context *ev,
     449             :                          struct sss_domain_info *dom,
     450             :                          struct sdap_options *opts,
     451             :                          struct sdap_search_base **search_bases,
     452             :                          struct sdap_handle *sh,
     453             :                          const char **attrs,
     454             :                          const char *filter,
     455             :                          int timeout)
     456             : {
     457             :     errno_t ret;
     458             :     struct tevent_req *req;
     459             :     struct sdap_get_automntmap_state *state;
     460             : 
     461           0 :     req = tevent_req_create(memctx, &state, struct sdap_get_automntmap_state);
     462           0 :     if (!req) return NULL;
     463             : 
     464           0 :     state->ev = ev;
     465           0 :     state->opts = opts;
     466           0 :     state->dom = dom;
     467           0 :     state->sh = sh;
     468           0 :     state->attrs = attrs;
     469           0 :     state->higher_timestamp = NULL;
     470           0 :     state->map =  NULL;
     471           0 :     state->count = 0;
     472           0 :     state->timeout = timeout;
     473           0 :     state->base_filter = filter;
     474           0 :     state->base_iter = 0;
     475           0 :     state->search_bases = search_bases;
     476             : 
     477           0 :     ret = sdap_get_automntmap_next_base(req);
     478           0 :     if (ret != EOK) {
     479           0 :         tevent_req_error(req, ret);
     480           0 :         tevent_req_post(req, state->ev);
     481             :     }
     482           0 :     return req;
     483             : }
     484             : 
     485             : static errno_t
     486           0 : sdap_get_automntmap_next_base(struct tevent_req *req)
     487             : {
     488             :     struct tevent_req *subreq;
     489             :     struct sdap_get_automntmap_state *state;
     490             : 
     491           0 :     state = tevent_req_data(req, struct sdap_get_automntmap_state);
     492             : 
     493           0 :     talloc_zfree(state->filter);
     494           0 :     state->filter = sdap_get_id_specific_filter(state,
     495             :                         state->base_filter,
     496           0 :                         state->search_bases[state->base_iter]->filter);
     497           0 :     if (!state->filter) {
     498           0 :         return ENOMEM;
     499             :     }
     500             : 
     501           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     502             :           "Searching for automount maps with base [%s]\n",
     503             :            state->search_bases[state->base_iter]->basedn);
     504             : 
     505           0 :     subreq = sdap_get_generic_send(
     506             :             state, state->ev, state->opts, state->sh,
     507           0 :             state->search_bases[state->base_iter]->basedn,
     508           0 :             state->search_bases[state->base_iter]->scope,
     509           0 :             state->filter, state->attrs,
     510           0 :             state->opts->autofs_mobject_map, SDAP_OPTS_AUTOFS_MAP,
     511             :             state->timeout,
     512             :             false);
     513           0 :     if (!subreq) {
     514           0 :         return EIO;
     515             :     }
     516           0 :     tevent_req_set_callback(subreq, sdap_get_automntmap_process, req);
     517             : 
     518           0 :     return EOK;
     519             : }
     520             : 
     521             : static void
     522             : sdap_get_automntmap_done(struct tevent_req *subreq);
     523             : 
     524             : static void
     525           0 : sdap_get_automntmap_process(struct tevent_req *subreq)
     526             : {
     527           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     528             :                                                       struct tevent_req);
     529           0 :     struct sdap_get_automntmap_state *state = tevent_req_data(req,
     530             :                                                struct sdap_get_automntmap_state);
     531             :     errno_t ret;
     532             : 
     533           0 :     ret = sdap_get_generic_recv(subreq, state,
     534             :                                 &state->count, &state->map);
     535           0 :     talloc_zfree(subreq);
     536           0 :     if (ret) {
     537           0 :         tevent_req_error(req, ret);
     538           0 :         return;
     539             :     }
     540             : 
     541           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     542             :           "Search for autofs maps, returned %zu results.\n", state->count);
     543             : 
     544           0 :     if (state->count == 0) {
     545             :         /* No maps found in this search */
     546           0 :         state->base_iter++;
     547           0 :         if (state->search_bases[state->base_iter]) {
     548             :             /* There are more search bases to try */
     549           0 :             ret = sdap_get_automntmap_next_base(req);
     550           0 :             if (ret != EOK) {
     551           0 :                 tevent_req_error(req, ENOENT);
     552             :             }
     553           0 :             return;
     554             :         }
     555             : 
     556           0 :         tevent_req_error(req, ENOENT);
     557           0 :         return;
     558           0 :     } else if (state->count > 1) {
     559           0 :         DEBUG(SSSDBG_OP_FAILURE,
     560             :               "The search yielded more than one autofs map\n");
     561           0 :         tevent_req_error(req, EIO);
     562           0 :         return;
     563             :     }
     564             : 
     565           0 :     DEBUG(SSSDBG_TRACE_INTERNAL, "Processing autofs maps\n");
     566           0 :     subreq = automntmaps_process_members_send(state, state->ev, state->opts,
     567             :                                               state->sh, state->dom,
     568             :                                               state->search_bases,
     569             :                                               state->timeout,
     570           0 :                                               state->map[0]);
     571           0 :     if (!subreq) {
     572           0 :         tevent_req_error(req, ENOMEM);
     573           0 :         return;
     574             :     }
     575           0 :     tevent_req_set_callback(subreq, sdap_get_automntmap_done, req);
     576             : 
     577           0 :     return;
     578             : }
     579             : 
     580             : static void
     581           0 : sdap_get_automntmap_done(struct tevent_req *subreq)
     582             : {
     583           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     584             :                                                       struct tevent_req);
     585           0 :     struct sdap_get_automntmap_state *state = tevent_req_data(req,
     586             :                                                struct sdap_get_automntmap_state);
     587             :     errno_t ret;
     588             : 
     589           0 :     ret = automntmaps_process_members_recv(subreq, state, &state->entries_count,
     590             :                                            &state->entries);
     591           0 :     talloc_zfree(subreq);
     592           0 :     if (ret != EOK) {
     593           0 :         tevent_req_error(req, ret);
     594           0 :         return;
     595             :     }
     596             : 
     597           0 :     DEBUG(SSSDBG_TRACE_FUNC, "automount map members received\n");
     598           0 :     tevent_req_done(req);
     599           0 :     return;
     600             : }
     601             : 
     602             : static errno_t
     603           0 : sdap_get_automntmap_recv(struct tevent_req *req,
     604             :                          TALLOC_CTX *mem_ctx,
     605             :                          struct sysdb_attrs **map,
     606             :                          size_t *entries_count,
     607             :                          struct sysdb_attrs ***entries)
     608             : {
     609           0 :     struct sdap_get_automntmap_state *state = tevent_req_data(req,
     610             :                                                struct sdap_get_automntmap_state);
     611             : 
     612           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     613             : 
     614           0 :     if (map) {
     615           0 :         *map = talloc_steal(mem_ctx, state->map[0]);
     616             :     }
     617             : 
     618           0 :     if (entries_count) {
     619           0 :         *entries_count = state->entries_count;
     620             :     }
     621             : 
     622           0 :     if (entries) {
     623           0 :         *entries = talloc_steal(mem_ctx, state->entries);
     624             :     }
     625             : 
     626           0 :     return EOK;
     627             : }
     628             : 
     629             : struct sdap_autofs_setautomntent_state {
     630             :     char *filter;
     631             :     const char **attrs;
     632             :     struct sdap_options *opts;
     633             :     struct sdap_handle *sh;
     634             :     struct sysdb_ctx *sysdb;
     635             :     struct sdap_id_op *sdap_op;
     636             :     struct sss_domain_info *dom;
     637             : 
     638             :     const char *mapname;
     639             :     struct sysdb_attrs *map;
     640             :     struct sysdb_attrs **entries;
     641             :     size_t entries_count;
     642             : 
     643             :     int dp_error;
     644             : };
     645             : 
     646             : static void
     647             : sdap_autofs_setautomntent_done(struct tevent_req *subreq);
     648             : 
     649             : struct tevent_req *
     650           0 : sdap_autofs_setautomntent_send(TALLOC_CTX *memctx,
     651             :                                struct tevent_context *ev,
     652             :                                struct sss_domain_info *dom,
     653             :                                struct sysdb_ctx *sysdb,
     654             :                                struct sdap_handle *sh,
     655             :                                struct sdap_id_op *op,
     656             :                                struct sdap_options *opts,
     657             :                                const char *mapname)
     658             : {
     659             :     struct tevent_req *req;
     660             :     struct tevent_req *subreq;
     661             :     struct sdap_autofs_setautomntent_state *state;
     662             :     char *clean_mapname;
     663             :     errno_t ret;
     664             : 
     665           0 :     req = tevent_req_create(memctx, &state,
     666             :                             struct sdap_autofs_setautomntent_state);
     667           0 :     if (!req) return NULL;
     668             : 
     669           0 :     if (!mapname) {
     670           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No map name given\n");
     671           0 :         ret = EINVAL;
     672           0 :         goto fail;
     673             :     }
     674             : 
     675           0 :     state->sh = sh;
     676           0 :     state->sysdb = sysdb;
     677           0 :     state->opts = opts;
     678           0 :     state->sdap_op = op;
     679           0 :     state->dom = dom;
     680           0 :     state->mapname = mapname;
     681             : 
     682           0 :     ret = sss_filter_sanitize(state, mapname, &clean_mapname);
     683           0 :     if (ret != EOK) {
     684           0 :         goto fail;
     685             :     }
     686             : 
     687           0 :     state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
     688           0 :                     state->opts->autofs_mobject_map[SDAP_AT_AUTOFS_MAP_NAME].name,
     689             :                     clean_mapname,
     690           0 :                     state->opts->autofs_mobject_map[SDAP_OC_AUTOFS_MAP].name);
     691           0 :     if (!state->filter) {
     692           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build filter\n");
     693           0 :         ret = ENOMEM;
     694           0 :         goto fail;
     695             :     }
     696           0 :     talloc_free(clean_mapname);
     697             : 
     698           0 :     ret = build_attrs_from_map(state, state->opts->autofs_mobject_map,
     699             :                                SDAP_OPTS_AUTOFS_MAP, NULL,
     700           0 :                                &state->attrs, NULL);
     701           0 :     if (ret != EOK) {
     702           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build attributes from map\n");
     703           0 :         ret = ENOMEM;
     704           0 :         goto fail;
     705             :     }
     706             : 
     707           0 :     subreq = sdap_get_automntmap_send(state, ev, dom,
     708           0 :                                       state->opts,
     709           0 :                                       state->opts->sdom->autofs_search_bases,
     710           0 :                                       state->sh,
     711           0 :                                       state->attrs, state->filter,
     712           0 :                                       dp_opt_get_int(state->opts->basic,
     713             :                                                      SDAP_SEARCH_TIMEOUT));
     714           0 :     if (!subreq) {
     715           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
     716           0 :         ret = ENOMEM;
     717           0 :         goto fail;
     718             :     }
     719           0 :     tevent_req_set_callback(subreq, sdap_autofs_setautomntent_done, req);
     720           0 :     return req;
     721             : 
     722             : fail:
     723           0 :     tevent_req_error(req, ret);
     724           0 :     tevent_req_post(req, ev);
     725           0 :     return req;
     726             : }
     727             : 
     728             : static errno_t
     729             : sdap_autofs_setautomntent_save(struct tevent_req *req);
     730             : 
     731             : static void
     732           0 : sdap_autofs_setautomntent_done(struct tevent_req *subreq)
     733             : {
     734             :     errno_t ret;
     735           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     736             :                                                       struct tevent_req);
     737           0 :     struct sdap_autofs_setautomntent_state *state = tevent_req_data(req,
     738             :                                     struct sdap_autofs_setautomntent_state);
     739             : 
     740           0 :     ret = sdap_get_automntmap_recv(subreq, state, &state->map,
     741             :                                    &state->entries_count, &state->entries);
     742           0 :     talloc_zfree(subreq);
     743           0 :     if (ret != EOK) {
     744           0 :         if (ret == ENOENT) {
     745           0 :             DEBUG(SSSDBG_MINOR_FAILURE, "Could not find automount map\n");
     746             :         } else {
     747           0 :             DEBUG(SSSDBG_OP_FAILURE,
     748             :                 "sdap_get_automntmap_recv failed [%d]: %s\n",
     749             :                 ret, strerror(ret));
     750             :         }
     751           0 :         tevent_req_error(req, ret);
     752           0 :         return;
     753             :     }
     754             : 
     755           0 :     ret = sdap_autofs_setautomntent_save(req);
     756           0 :     if (ret != EOK) {
     757           0 :         DEBUG(SSSDBG_OP_FAILURE, "Could not save automount map\n");
     758           0 :         tevent_req_error(req, ret);
     759           0 :         return;
     760             :     }
     761             : 
     762           0 :     state->dp_error = DP_ERR_OK;
     763           0 :     tevent_req_done(req);
     764           0 :     return;
     765             : }
     766             : 
     767             : static errno_t
     768           0 : sdap_autofs_setautomntent_save(struct tevent_req *req)
     769             : {
     770           0 :     struct sdap_autofs_setautomntent_state *state = tevent_req_data(req,
     771             :                                     struct sdap_autofs_setautomntent_state);
     772             :     errno_t ret, tret;
     773           0 :     bool in_transaction = false;
     774             :     TALLOC_CTX *tmp_ctx;
     775           0 :     struct ldb_message **entries = NULL;
     776             :     size_t count;
     777             :     const char *key;
     778             :     const char *val;
     779             :     char **sysdb_entrylist;
     780             :     char **ldap_entrylist;
     781             :     char **add_entries;
     782             :     char **del_entries;
     783             :     size_t i, j;
     784             : 
     785             :     hash_table_t *entry_hash;
     786             :     hash_key_t hkey;
     787             :     hash_value_t value;
     788             :     int hret;
     789             : 
     790           0 :     tmp_ctx = talloc_new(NULL);
     791           0 :     if (!tmp_ctx) return ENOMEM;
     792             : 
     793           0 :     DEBUG(SSSDBG_TRACE_LIBS,
     794             :           "Got %zu map entries from LDAP\n", state->entries_count);
     795           0 :     if (state->entries_count == 0) {
     796             :         /* No entries for this map in LDAP.
     797             :          * We need to ensure that there are no entries
     798             :          * in the sysdb either.
     799             :          */
     800           0 :         ldap_entrylist = NULL;
     801             :     } else {
     802           0 :         ldap_entrylist = talloc_array(tmp_ctx, char *,
     803             :                                       state->entries_count+1);
     804           0 :         if (!ldap_entrylist) {
     805           0 :             ret = ENOMEM;
     806           0 :             goto done;
     807             :         }
     808             : 
     809           0 :         ret = sss_hash_create(state, 32, &entry_hash);
     810           0 :         if (ret) {
     811           0 :             goto done;
     812             :         }
     813             : 
     814             :         /* Get a list of the map members by DN */
     815           0 :         for (i=0, j=0; i < state->entries_count; i++) {
     816           0 :             key = get_autofs_entry_key(state->entries[i], state->opts);
     817           0 :             val = get_autofs_entry_value(state->entries[i], state->opts);
     818           0 :             if (!key || !val) {
     819           0 :                 DEBUG(SSSDBG_MINOR_FAILURE, "Malformed entry, skipping\n");
     820           0 :                 continue;
     821             :             }
     822             : 
     823           0 :             ldap_entrylist[j] = sysdb_autofsentry_strdn(ldap_entrylist,
     824             :                                                         state->dom,
     825             :                                                         state->mapname,
     826             :                                                         key, val);
     827           0 :             if (!ldap_entrylist[j]) {
     828           0 :                 ret = ENOMEM;
     829           0 :                 goto done;
     830             :             }
     831             : 
     832           0 :             hkey.type = HASH_KEY_STRING;
     833           0 :             hkey.str = ldap_entrylist[j];
     834           0 :             value.type = HASH_VALUE_PTR;
     835           0 :             value.ptr = state->entries[i];
     836             : 
     837           0 :             hret = hash_enter(entry_hash, &hkey, &value);
     838           0 :             if (hret != HASH_SUCCESS) {
     839           0 :                 ret = EIO;
     840           0 :                 goto done;
     841             :             }
     842             : 
     843           0 :             j++;
     844             :         }
     845             :         /* terminate array with NULL after the last retrieved entry */
     846           0 :         ldap_entrylist[j] = NULL;
     847             :     }
     848             : 
     849           0 :     ret = sysdb_autofs_entries_by_map(tmp_ctx, state->dom, state->mapname,
     850             :                                       &count, &entries);
     851           0 :     if (ret != EOK && ret != ENOENT) {
     852           0 :         DEBUG(SSSDBG_OP_FAILURE,
     853             :               "cache lookup for the map failed [%d]: %s\n",
     854             :                ret, strerror(ret));
     855           0 :         goto done;
     856             :     }
     857             : 
     858           0 :     DEBUG(SSSDBG_TRACE_LIBS, "Got %zu map entries from sysdb\n", count);
     859           0 :     if (count == 0) {
     860             :         /* No map members for this map in sysdb currently */
     861           0 :         sysdb_entrylist = NULL;
     862             :     } else {
     863           0 :         sysdb_entrylist = talloc_array(state, char *, count+1);
     864           0 :         if (!sysdb_entrylist) {
     865           0 :             ret = ENOMEM;
     866           0 :             goto done;
     867             :         }
     868             : 
     869             :         /* Get a list of the map members by DN */
     870           0 :         for (i=0; i < count; i++) {
     871           0 :             sysdb_entrylist[i] = talloc_strdup(sysdb_entrylist,
     872           0 :                                         ldb_dn_get_linearized(entries[i]->dn));
     873           0 :             if (!sysdb_entrylist[i]) {
     874           0 :                 ret = ENOMEM;
     875           0 :                 goto done;
     876             :             }
     877             :         }
     878           0 :         sysdb_entrylist[count] = NULL;
     879             :     }
     880             : 
     881             :     /* Find the differences between the sysdb and LDAP lists
     882             :      * Entries in the sysdb only must be removed.
     883             :      */
     884           0 :     ret = diff_string_lists(tmp_ctx, ldap_entrylist, sysdb_entrylist,
     885             :                             &add_entries, &del_entries, NULL);
     886           0 :     if (ret != EOK) goto done;
     887             : 
     888           0 :     ret = sysdb_transaction_start(state->sysdb);
     889           0 :     if (ret != EOK) {
     890           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     891             :              "Cannot start sysdb transaction [%d]: %s\n",
     892             :               ret, strerror(ret));
     893           0 :         goto done;
     894             :     }
     895           0 :     in_transaction = true;
     896             : 
     897             :     /* Save the map itself */
     898           0 :     ret = save_autofs_map(state->dom, state->opts, state->map);
     899           0 :     if (ret != EOK) {
     900           0 :         DEBUG(SSSDBG_OP_FAILURE,
     901             :              "Cannot save autofs map entry [%d]: %s\n",
     902             :               ret, strerror(ret));
     903           0 :         goto done;
     904             :     }
     905             : 
     906             :     /* Create entries that don't exist yet */
     907           0 :     if (add_entries && add_entries[0]) {
     908           0 :         ret = save_autofs_entries(state->dom, state->opts,
     909             :                                   state->mapname, add_entries,
     910             :                                   entry_hash);
     911           0 :         if (ret != EOK) {
     912           0 :             DEBUG(SSSDBG_OP_FAILURE,
     913             :                   "Cannot save autofs entries [%d]: %s\n",
     914             :                   ret, strerror(ret));
     915           0 :             goto done;
     916             :         }
     917             :     }
     918             : 
     919             :     /* Delete entries that don't exist anymore */
     920           0 :     if (del_entries && del_entries[0]) {
     921           0 :         ret = del_autofs_entries(state->dom, del_entries);
     922           0 :         if (ret != EOK) {
     923           0 :             DEBUG(SSSDBG_OP_FAILURE,
     924             :                   "Cannot delete autofs entries [%d]: %s\n",
     925             :                   ret, strerror(ret));
     926           0 :             goto done;
     927             :         }
     928             :     }
     929             : 
     930             : 
     931           0 :     ret = sysdb_transaction_commit(state->sysdb);
     932           0 :     if (ret != EOK) {
     933           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     934             :              "Cannot commit sysdb transaction [%d]: %s\n",
     935             :               ret, strerror(ret));
     936           0 :         goto done;
     937             :     }
     938           0 :     in_transaction = false;
     939             : 
     940           0 :     ret = EOK;
     941             : done:
     942           0 :     if (in_transaction) {
     943           0 :         tret = sysdb_transaction_cancel(state->sysdb);
     944           0 :         if (tret != EOK) {
     945           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     946             :                 "Cannot cancel sysdb transaction [%d]: %s\n",
     947             :                 ret, strerror(ret));
     948             :         }
     949             :     }
     950           0 :     talloc_zfree(tmp_ctx);
     951           0 :     return ret;
     952             : }
     953             : 
     954             : errno_t
     955           0 : sdap_autofs_setautomntent_recv(struct tevent_req *req)
     956             : {
     957           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     958           0 :     return EOK;
     959             : }
     960             : 

Generated by: LCOV version 1.10