LCOV - code coverage report
Current view: top level - providers/ldap - sdap_async_autofs.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 404 0.0 %
Date: 2016-06-29 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_combine_filters(state, state->base_filter,
     315           0 :                         state->search_bases[state->base_iter]->filter);
     316           0 :     if (!state->filter) {
     317           0 :         return ENOMEM;
     318             :     }
     319             : 
     320           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     321             :           "Searching for automount map entries with base [%s]\n",
     322             :            state->search_bases[state->base_iter]->basedn);
     323             : 
     324           0 :     subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
     325             :                                    state->orig_dn,
     326           0 :                                    state->search_bases[state->base_iter]->scope,
     327           0 :                                    state->filter, state->attrs,
     328           0 :                                    state->opts->autofs_entry_map,
     329             :                                    SDAP_OPTS_AUTOFS_ENTRY,
     330             :                                    state->timeout, true);
     331           0 :     if (!subreq) {
     332           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Cannot start search for entries\n");
     333           0 :         return EIO;
     334             :     }
     335           0 :     tevent_req_set_callback(subreq, automntmaps_process_members_done, req);
     336             : 
     337           0 :     return EOK;
     338             : }
     339             : 
     340             : static void
     341           0 : automntmaps_process_members_done(struct tevent_req *subreq)
     342             : {
     343           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     344             :                                                       struct tevent_req);
     345           0 :     struct automntmaps_process_members_state *state =
     346           0 :         tevent_req_data(req, struct automntmaps_process_members_state);
     347             :     errno_t ret;
     348             :     struct sysdb_attrs **entries;
     349             :     size_t entries_count, i;
     350             : 
     351           0 :     ret = sdap_get_generic_recv(subreq, state,
     352             :                                 &entries_count, &entries);
     353           0 :     talloc_zfree(subreq);
     354           0 :     if (ret) {
     355           0 :         tevent_req_error(req, ret);
     356           0 :         return;
     357             :     }
     358             : 
     359           0 :     if (entries_count > 0) {
     360           0 :         state->entries = talloc_realloc(state, state->entries,
     361             :                                         struct sysdb_attrs *,
     362             :                                         state->entries_count + entries_count + 1);
     363           0 :         if (state->entries == NULL) {
     364           0 :             tevent_req_error(req, ENOMEM);
     365           0 :             return;
     366             :         }
     367             : 
     368           0 :         for (i=0; i < entries_count; i++) {
     369           0 :             state->entries[state->entries_count + i] =
     370           0 :                 talloc_steal(state->entries, entries[i]);
     371             :         }
     372             : 
     373           0 :         state->entries_count += entries_count;
     374           0 :         state->entries[state->entries_count] = NULL;
     375             :     }
     376             : 
     377           0 :     state->base_iter++;
     378           0 :     if (state->search_bases[state->base_iter]) {
     379           0 :         ret = automntmaps_process_members_next_base(req);
     380           0 :         if (ret != EOK) {
     381           0 :             tevent_req_error(req, ret);
     382           0 :             return;
     383             :         }
     384             :     }
     385             : 
     386           0 :     DEBUG(SSSDBG_TRACE_INTERNAL, "No more search bases to try\n");
     387             : 
     388           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     389             :           "Search for autofs entries, returned %zu results.\n",
     390             :           state->entries_count);
     391             : 
     392           0 :     tevent_req_done(req);
     393           0 :     return;
     394             : }
     395             : 
     396             : static errno_t
     397           0 : automntmaps_process_members_recv(struct tevent_req *req,
     398             :                                  TALLOC_CTX *mem_ctx,
     399             :                                  size_t *entries_count,
     400             :                                  struct sysdb_attrs ***entries)
     401             : {
     402             :     struct automntmaps_process_members_state *state;
     403           0 :     state = tevent_req_data(req, struct automntmaps_process_members_state);
     404             : 
     405           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     406             : 
     407           0 :     if (entries_count) {
     408           0 :         *entries_count = state->entries_count;
     409             :     }
     410             : 
     411           0 :     if (entries) {
     412           0 :         *entries = talloc_steal(mem_ctx, state->entries);
     413             :     }
     414             : 
     415           0 :     return EOK;
     416             : }
     417             : 
     418             : struct sdap_get_automntmap_state {
     419             :     struct tevent_context *ev;
     420             :     struct sdap_options *opts;
     421             :     struct sdap_handle *sh;
     422             :     struct sss_domain_info *dom;
     423             :     const char **attrs;
     424             :     const char *base_filter;
     425             :     char *filter;
     426             :     int timeout;
     427             : 
     428             :     char *higher_timestamp;
     429             : 
     430             :     struct sysdb_attrs **map;
     431             :     size_t count;
     432             : 
     433             :     struct sysdb_attrs **entries;
     434             :     size_t entries_count;
     435             : 
     436             :     size_t base_iter;
     437             :     struct sdap_search_base **search_bases;
     438             : };
     439             : 
     440             : static errno_t
     441             : sdap_get_automntmap_next_base(struct tevent_req *req);
     442             : static void
     443             : sdap_get_automntmap_process(struct tevent_req *subreq);
     444             : 
     445             : static struct tevent_req *
     446           0 : sdap_get_automntmap_send(TALLOC_CTX *memctx,
     447             :                          struct tevent_context *ev,
     448             :                          struct sss_domain_info *dom,
     449             :                          struct sdap_options *opts,
     450             :                          struct sdap_search_base **search_bases,
     451             :                          struct sdap_handle *sh,
     452             :                          const char **attrs,
     453             :                          const char *filter,
     454             :                          int timeout)
     455             : {
     456             :     errno_t ret;
     457             :     struct tevent_req *req;
     458             :     struct sdap_get_automntmap_state *state;
     459             : 
     460           0 :     req = tevent_req_create(memctx, &state, struct sdap_get_automntmap_state);
     461           0 :     if (!req) return NULL;
     462             : 
     463           0 :     state->ev = ev;
     464           0 :     state->opts = opts;
     465           0 :     state->dom = dom;
     466           0 :     state->sh = sh;
     467           0 :     state->attrs = attrs;
     468           0 :     state->higher_timestamp = NULL;
     469           0 :     state->map =  NULL;
     470           0 :     state->count = 0;
     471           0 :     state->timeout = timeout;
     472           0 :     state->base_filter = filter;
     473           0 :     state->base_iter = 0;
     474           0 :     state->search_bases = search_bases;
     475             : 
     476           0 :     ret = sdap_get_automntmap_next_base(req);
     477           0 :     if (ret != EOK) {
     478           0 :         tevent_req_error(req, ret);
     479           0 :         tevent_req_post(req, state->ev);
     480             :     }
     481           0 :     return req;
     482             : }
     483             : 
     484             : static errno_t
     485           0 : sdap_get_automntmap_next_base(struct tevent_req *req)
     486             : {
     487             :     struct tevent_req *subreq;
     488             :     struct sdap_get_automntmap_state *state;
     489             : 
     490           0 :     state = tevent_req_data(req, struct sdap_get_automntmap_state);
     491             : 
     492           0 :     talloc_zfree(state->filter);
     493           0 :     state->filter = sdap_combine_filters(state, state->base_filter,
     494           0 :                         state->search_bases[state->base_iter]->filter);
     495           0 :     if (!state->filter) {
     496           0 :         return ENOMEM;
     497             :     }
     498             : 
     499           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     500             :           "Searching for automount maps with base [%s]\n",
     501             :            state->search_bases[state->base_iter]->basedn);
     502             : 
     503           0 :     subreq = sdap_get_generic_send(
     504             :             state, state->ev, state->opts, state->sh,
     505           0 :             state->search_bases[state->base_iter]->basedn,
     506           0 :             state->search_bases[state->base_iter]->scope,
     507           0 :             state->filter, state->attrs,
     508           0 :             state->opts->autofs_mobject_map, SDAP_OPTS_AUTOFS_MAP,
     509             :             state->timeout,
     510             :             false);
     511           0 :     if (!subreq) {
     512           0 :         return EIO;
     513             :     }
     514           0 :     tevent_req_set_callback(subreq, sdap_get_automntmap_process, req);
     515             : 
     516           0 :     return EOK;
     517             : }
     518             : 
     519             : static void
     520             : sdap_get_automntmap_done(struct tevent_req *subreq);
     521             : 
     522             : static void
     523           0 : sdap_get_automntmap_process(struct tevent_req *subreq)
     524             : {
     525           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     526             :                                                       struct tevent_req);
     527           0 :     struct sdap_get_automntmap_state *state = tevent_req_data(req,
     528             :                                                struct sdap_get_automntmap_state);
     529             :     errno_t ret;
     530             : 
     531           0 :     ret = sdap_get_generic_recv(subreq, state,
     532             :                                 &state->count, &state->map);
     533           0 :     talloc_zfree(subreq);
     534           0 :     if (ret) {
     535           0 :         tevent_req_error(req, ret);
     536           0 :         return;
     537             :     }
     538             : 
     539           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     540             :           "Search for autofs maps, returned %zu results.\n", state->count);
     541             : 
     542           0 :     if (state->count == 0) {
     543             :         /* No maps found in this search */
     544           0 :         state->base_iter++;
     545           0 :         if (state->search_bases[state->base_iter]) {
     546             :             /* There are more search bases to try */
     547           0 :             ret = sdap_get_automntmap_next_base(req);
     548           0 :             if (ret != EOK) {
     549           0 :                 tevent_req_error(req, ENOENT);
     550             :             }
     551           0 :             return;
     552             :         }
     553             : 
     554           0 :         tevent_req_error(req, ENOENT);
     555           0 :         return;
     556           0 :     } else if (state->count > 1) {
     557           0 :         DEBUG(SSSDBG_OP_FAILURE,
     558             :               "The search yielded more than one autofs map\n");
     559           0 :         tevent_req_error(req, EIO);
     560           0 :         return;
     561             :     }
     562             : 
     563           0 :     DEBUG(SSSDBG_TRACE_INTERNAL, "Processing autofs maps\n");
     564           0 :     subreq = automntmaps_process_members_send(state, state->ev, state->opts,
     565             :                                               state->sh, state->dom,
     566             :                                               state->search_bases,
     567             :                                               state->timeout,
     568           0 :                                               state->map[0]);
     569           0 :     if (!subreq) {
     570           0 :         tevent_req_error(req, ENOMEM);
     571           0 :         return;
     572             :     }
     573           0 :     tevent_req_set_callback(subreq, sdap_get_automntmap_done, req);
     574             : 
     575           0 :     return;
     576             : }
     577             : 
     578             : static void
     579           0 : sdap_get_automntmap_done(struct tevent_req *subreq)
     580             : {
     581           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     582             :                                                       struct tevent_req);
     583           0 :     struct sdap_get_automntmap_state *state = tevent_req_data(req,
     584             :                                                struct sdap_get_automntmap_state);
     585             :     errno_t ret;
     586             : 
     587           0 :     ret = automntmaps_process_members_recv(subreq, state, &state->entries_count,
     588             :                                            &state->entries);
     589           0 :     talloc_zfree(subreq);
     590           0 :     if (ret != EOK) {
     591           0 :         tevent_req_error(req, ret);
     592           0 :         return;
     593             :     }
     594             : 
     595           0 :     DEBUG(SSSDBG_TRACE_FUNC, "automount map members received\n");
     596           0 :     tevent_req_done(req);
     597           0 :     return;
     598             : }
     599             : 
     600             : static errno_t
     601           0 : sdap_get_automntmap_recv(struct tevent_req *req,
     602             :                          TALLOC_CTX *mem_ctx,
     603             :                          struct sysdb_attrs **map,
     604             :                          size_t *entries_count,
     605             :                          struct sysdb_attrs ***entries)
     606             : {
     607           0 :     struct sdap_get_automntmap_state *state = tevent_req_data(req,
     608             :                                                struct sdap_get_automntmap_state);
     609             : 
     610           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     611             : 
     612           0 :     if (map) {
     613           0 :         *map = talloc_steal(mem_ctx, state->map[0]);
     614             :     }
     615             : 
     616           0 :     if (entries_count) {
     617           0 :         *entries_count = state->entries_count;
     618             :     }
     619             : 
     620           0 :     if (entries) {
     621           0 :         *entries = talloc_steal(mem_ctx, state->entries);
     622             :     }
     623             : 
     624           0 :     return EOK;
     625             : }
     626             : 
     627             : struct sdap_autofs_setautomntent_state {
     628             :     char *filter;
     629             :     const char **attrs;
     630             :     struct sdap_options *opts;
     631             :     struct sdap_handle *sh;
     632             :     struct sysdb_ctx *sysdb;
     633             :     struct sdap_id_op *sdap_op;
     634             :     struct sss_domain_info *dom;
     635             : 
     636             :     const char *mapname;
     637             :     struct sysdb_attrs *map;
     638             :     struct sysdb_attrs **entries;
     639             :     size_t entries_count;
     640             : 
     641             :     int dp_error;
     642             : };
     643             : 
     644             : static void
     645             : sdap_autofs_setautomntent_done(struct tevent_req *subreq);
     646             : 
     647             : struct tevent_req *
     648           0 : sdap_autofs_setautomntent_send(TALLOC_CTX *memctx,
     649             :                                struct tevent_context *ev,
     650             :                                struct sss_domain_info *dom,
     651             :                                struct sysdb_ctx *sysdb,
     652             :                                struct sdap_handle *sh,
     653             :                                struct sdap_id_op *op,
     654             :                                struct sdap_options *opts,
     655             :                                const char *mapname)
     656             : {
     657             :     struct tevent_req *req;
     658             :     struct tevent_req *subreq;
     659             :     struct sdap_autofs_setautomntent_state *state;
     660             :     char *clean_mapname;
     661             :     errno_t ret;
     662             : 
     663           0 :     req = tevent_req_create(memctx, &state,
     664             :                             struct sdap_autofs_setautomntent_state);
     665           0 :     if (!req) return NULL;
     666             : 
     667           0 :     if (!mapname) {
     668           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No map name given\n");
     669           0 :         ret = EINVAL;
     670           0 :         goto fail;
     671             :     }
     672             : 
     673           0 :     state->sh = sh;
     674           0 :     state->sysdb = sysdb;
     675           0 :     state->opts = opts;
     676           0 :     state->sdap_op = op;
     677           0 :     state->dom = dom;
     678           0 :     state->mapname = mapname;
     679             : 
     680           0 :     ret = sss_filter_sanitize(state, mapname, &clean_mapname);
     681           0 :     if (ret != EOK) {
     682           0 :         goto fail;
     683             :     }
     684             : 
     685           0 :     state->filter = talloc_asprintf(state, "(&(%s=%s)(objectclass=%s))",
     686           0 :                     state->opts->autofs_mobject_map[SDAP_AT_AUTOFS_MAP_NAME].name,
     687             :                     clean_mapname,
     688           0 :                     state->opts->autofs_mobject_map[SDAP_OC_AUTOFS_MAP].name);
     689           0 :     if (!state->filter) {
     690           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build filter\n");
     691           0 :         ret = ENOMEM;
     692           0 :         goto fail;
     693             :     }
     694           0 :     talloc_free(clean_mapname);
     695             : 
     696           0 :     ret = build_attrs_from_map(state, state->opts->autofs_mobject_map,
     697             :                                SDAP_OPTS_AUTOFS_MAP, NULL,
     698           0 :                                &state->attrs, NULL);
     699           0 :     if (ret != EOK) {
     700           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build attributes from map\n");
     701           0 :         ret = ENOMEM;
     702           0 :         goto fail;
     703             :     }
     704             : 
     705           0 :     subreq = sdap_get_automntmap_send(state, ev, dom,
     706           0 :                                       state->opts,
     707           0 :                                       state->opts->sdom->autofs_search_bases,
     708           0 :                                       state->sh,
     709           0 :                                       state->attrs, state->filter,
     710           0 :                                       dp_opt_get_int(state->opts->basic,
     711             :                                                      SDAP_SEARCH_TIMEOUT));
     712           0 :     if (!subreq) {
     713           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
     714           0 :         ret = ENOMEM;
     715           0 :         goto fail;
     716             :     }
     717           0 :     tevent_req_set_callback(subreq, sdap_autofs_setautomntent_done, req);
     718           0 :     return req;
     719             : 
     720             : fail:
     721           0 :     tevent_req_error(req, ret);
     722           0 :     tevent_req_post(req, ev);
     723           0 :     return req;
     724             : }
     725             : 
     726             : static errno_t
     727             : sdap_autofs_setautomntent_save(struct tevent_req *req);
     728             : 
     729             : static void
     730           0 : sdap_autofs_setautomntent_done(struct tevent_req *subreq)
     731             : {
     732             :     errno_t ret;
     733           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     734             :                                                       struct tevent_req);
     735           0 :     struct sdap_autofs_setautomntent_state *state = tevent_req_data(req,
     736             :                                     struct sdap_autofs_setautomntent_state);
     737             : 
     738           0 :     ret = sdap_get_automntmap_recv(subreq, state, &state->map,
     739             :                                    &state->entries_count, &state->entries);
     740           0 :     talloc_zfree(subreq);
     741           0 :     if (ret != EOK) {
     742           0 :         if (ret == ENOENT) {
     743           0 :             DEBUG(SSSDBG_MINOR_FAILURE, "Could not find automount map\n");
     744             :         } else {
     745           0 :             DEBUG(SSSDBG_OP_FAILURE,
     746             :                 "sdap_get_automntmap_recv failed [%d]: %s\n",
     747             :                 ret, strerror(ret));
     748             :         }
     749           0 :         tevent_req_error(req, ret);
     750           0 :         return;
     751             :     }
     752             : 
     753           0 :     ret = sdap_autofs_setautomntent_save(req);
     754           0 :     if (ret != EOK) {
     755           0 :         DEBUG(SSSDBG_OP_FAILURE, "Could not save automount map\n");
     756           0 :         tevent_req_error(req, ret);
     757           0 :         return;
     758             :     }
     759             : 
     760           0 :     state->dp_error = DP_ERR_OK;
     761           0 :     tevent_req_done(req);
     762           0 :     return;
     763             : }
     764             : 
     765             : static errno_t
     766           0 : sdap_autofs_setautomntent_save(struct tevent_req *req)
     767             : {
     768           0 :     struct sdap_autofs_setautomntent_state *state = tevent_req_data(req,
     769             :                                     struct sdap_autofs_setautomntent_state);
     770             :     errno_t ret, tret;
     771           0 :     bool in_transaction = false;
     772             :     TALLOC_CTX *tmp_ctx;
     773           0 :     struct ldb_message **entries = NULL;
     774             :     size_t count;
     775             :     const char *key;
     776             :     const char *val;
     777             :     char **sysdb_entrylist;
     778             :     char **ldap_entrylist;
     779             :     char **add_entries;
     780             :     char **del_entries;
     781             :     size_t i, j;
     782             : 
     783             :     hash_table_t *entry_hash;
     784             :     hash_key_t hkey;
     785             :     hash_value_t value;
     786             :     int hret;
     787             : 
     788           0 :     tmp_ctx = talloc_new(NULL);
     789           0 :     if (!tmp_ctx) return ENOMEM;
     790             : 
     791           0 :     DEBUG(SSSDBG_TRACE_LIBS,
     792             :           "Got %zu map entries from LDAP\n", state->entries_count);
     793           0 :     if (state->entries_count == 0) {
     794             :         /* No entries for this map in LDAP.
     795             :          * We need to ensure that there are no entries
     796             :          * in the sysdb either.
     797             :          */
     798           0 :         ldap_entrylist = NULL;
     799             :     } else {
     800           0 :         ldap_entrylist = talloc_array(tmp_ctx, char *,
     801             :                                       state->entries_count+1);
     802           0 :         if (!ldap_entrylist) {
     803           0 :             ret = ENOMEM;
     804           0 :             goto done;
     805             :         }
     806             : 
     807           0 :         ret = sss_hash_create(state, 32, &entry_hash);
     808           0 :         if (ret) {
     809           0 :             goto done;
     810             :         }
     811             : 
     812             :         /* Get a list of the map members by DN */
     813           0 :         for (i=0, j=0; i < state->entries_count; i++) {
     814           0 :             key = get_autofs_entry_key(state->entries[i], state->opts);
     815           0 :             val = get_autofs_entry_value(state->entries[i], state->opts);
     816           0 :             if (!key || !val) {
     817           0 :                 DEBUG(SSSDBG_MINOR_FAILURE, "Malformed entry, skipping\n");
     818           0 :                 continue;
     819             :             }
     820             : 
     821           0 :             ldap_entrylist[j] = sysdb_autofsentry_strdn(ldap_entrylist,
     822             :                                                         state->dom,
     823             :                                                         state->mapname,
     824             :                                                         key, val);
     825           0 :             if (!ldap_entrylist[j]) {
     826           0 :                 ret = ENOMEM;
     827           0 :                 goto done;
     828             :             }
     829             : 
     830           0 :             hkey.type = HASH_KEY_STRING;
     831           0 :             hkey.str = ldap_entrylist[j];
     832           0 :             value.type = HASH_VALUE_PTR;
     833           0 :             value.ptr = state->entries[i];
     834             : 
     835           0 :             hret = hash_enter(entry_hash, &hkey, &value);
     836           0 :             if (hret != HASH_SUCCESS) {
     837           0 :                 ret = EIO;
     838           0 :                 goto done;
     839             :             }
     840             : 
     841           0 :             j++;
     842             :         }
     843             :         /* terminate array with NULL after the last retrieved entry */
     844           0 :         ldap_entrylist[j] = NULL;
     845             :     }
     846             : 
     847           0 :     ret = sysdb_autofs_entries_by_map(tmp_ctx, state->dom, state->mapname,
     848             :                                       &count, &entries);
     849           0 :     if (ret != EOK && ret != ENOENT) {
     850           0 :         DEBUG(SSSDBG_OP_FAILURE,
     851             :               "cache lookup for the map failed [%d]: %s\n",
     852             :                ret, strerror(ret));
     853           0 :         goto done;
     854             :     }
     855             : 
     856           0 :     DEBUG(SSSDBG_TRACE_LIBS, "Got %zu map entries from sysdb\n", count);
     857           0 :     if (count == 0) {
     858             :         /* No map members for this map in sysdb currently */
     859           0 :         sysdb_entrylist = NULL;
     860             :     } else {
     861           0 :         sysdb_entrylist = talloc_array(state, char *, count+1);
     862           0 :         if (!sysdb_entrylist) {
     863           0 :             ret = ENOMEM;
     864           0 :             goto done;
     865             :         }
     866             : 
     867             :         /* Get a list of the map members by DN */
     868           0 :         for (i=0; i < count; i++) {
     869           0 :             sysdb_entrylist[i] = talloc_strdup(sysdb_entrylist,
     870           0 :                                         ldb_dn_get_linearized(entries[i]->dn));
     871           0 :             if (!sysdb_entrylist[i]) {
     872           0 :                 ret = ENOMEM;
     873           0 :                 goto done;
     874             :             }
     875             :         }
     876           0 :         sysdb_entrylist[count] = NULL;
     877             :     }
     878             : 
     879             :     /* Find the differences between the sysdb and LDAP lists
     880             :      * Entries in the sysdb only must be removed.
     881             :      */
     882           0 :     ret = diff_string_lists(tmp_ctx, ldap_entrylist, sysdb_entrylist,
     883             :                             &add_entries, &del_entries, NULL);
     884           0 :     if (ret != EOK) goto done;
     885             : 
     886           0 :     ret = sysdb_transaction_start(state->sysdb);
     887           0 :     if (ret != EOK) {
     888           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     889             :              "Cannot start sysdb transaction [%d]: %s\n",
     890             :               ret, strerror(ret));
     891           0 :         goto done;
     892             :     }
     893           0 :     in_transaction = true;
     894             : 
     895             :     /* Save the map itself */
     896           0 :     ret = save_autofs_map(state->dom, state->opts, state->map);
     897           0 :     if (ret != EOK) {
     898           0 :         DEBUG(SSSDBG_OP_FAILURE,
     899             :              "Cannot save autofs map entry [%d]: %s\n",
     900             :               ret, strerror(ret));
     901           0 :         goto done;
     902             :     }
     903             : 
     904             :     /* Create entries that don't exist yet */
     905           0 :     if (add_entries && add_entries[0]) {
     906           0 :         ret = save_autofs_entries(state->dom, state->opts,
     907             :                                   state->mapname, add_entries,
     908             :                                   entry_hash);
     909           0 :         if (ret != EOK) {
     910           0 :             DEBUG(SSSDBG_OP_FAILURE,
     911             :                   "Cannot save autofs entries [%d]: %s\n",
     912             :                   ret, strerror(ret));
     913           0 :             goto done;
     914             :         }
     915             :     }
     916             : 
     917             :     /* Delete entries that don't exist anymore */
     918           0 :     if (del_entries && del_entries[0]) {
     919           0 :         ret = del_autofs_entries(state->dom, del_entries);
     920           0 :         if (ret != EOK) {
     921           0 :             DEBUG(SSSDBG_OP_FAILURE,
     922             :                   "Cannot delete autofs entries [%d]: %s\n",
     923             :                   ret, strerror(ret));
     924           0 :             goto done;
     925             :         }
     926             :     }
     927             : 
     928             : 
     929           0 :     ret = sysdb_transaction_commit(state->sysdb);
     930           0 :     if (ret != EOK) {
     931           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     932             :              "Cannot commit sysdb transaction [%d]: %s\n",
     933             :               ret, strerror(ret));
     934           0 :         goto done;
     935             :     }
     936           0 :     in_transaction = false;
     937             : 
     938           0 :     ret = EOK;
     939             : done:
     940           0 :     if (in_transaction) {
     941           0 :         tret = sysdb_transaction_cancel(state->sysdb);
     942           0 :         if (tret != EOK) {
     943           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     944             :                 "Cannot cancel sysdb transaction [%d]: %s\n",
     945             :                 ret, strerror(ret));
     946             :         }
     947             :     }
     948           0 :     talloc_zfree(tmp_ctx);
     949           0 :     return ret;
     950             : }
     951             : 
     952             : errno_t
     953           0 : sdap_autofs_setautomntent_recv(struct tevent_req *req)
     954             : {
     955           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     956           0 :     return EOK;
     957             : }
     958             : 

Generated by: LCOV version 1.10