LCOV - code coverage report
Current view: top level - providers/ldap - sdap_async_netgroups.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 352 0.0 %
Date: 2016-06-29 Functions: 0 12 0.0 %

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Async LDAP Helper routines for netgroups
       5             : 
       6             :     Authors:
       7             :         Sumit Bose <sbose@redhat.com>
       8             : 
       9             :     Copyright (C) 2010 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 "providers/ldap/ldap_common.h"
      29             : 
      30           0 : bool is_dn(const char *str)
      31             : {
      32             :     int ret;
      33             :     LDAPDN dn;
      34             : 
      35           0 :     ret = ldap_str2dn(str, &dn, LDAP_DN_FORMAT_LDAPV3);
      36           0 :     ldap_dnfree(dn);
      37             : 
      38           0 :     return (ret == LDAP_SUCCESS ? true : false);
      39             : }
      40             : 
      41           0 : static errno_t sdap_save_netgroup(TALLOC_CTX *memctx,
      42             :                                   struct sss_domain_info *dom,
      43             :                                   struct sdap_options *opts,
      44             :                                   struct sysdb_attrs *attrs,
      45             :                                   char **_timestamp,
      46             :                                   time_t now)
      47             : {
      48             :     struct ldb_message_element *el;
      49             :     struct sysdb_attrs *netgroup_attrs;
      50           0 :     const char *name = NULL;
      51             :     int ret;
      52           0 :     char *timestamp = NULL;
      53           0 :     char **missing = NULL;
      54             : 
      55           0 :     ret = sdap_get_netgroup_primary_name(memctx, opts, attrs, dom, &name);
      56           0 :     if (ret != EOK) {
      57           0 :         DEBUG(SSSDBG_OP_FAILURE, "Failed to get netgroup name\n");
      58           0 :         goto fail;
      59             :     }
      60             : 
      61           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Processing netgroup %s\n", name);
      62             : 
      63           0 :     netgroup_attrs = sysdb_new_attrs(memctx);
      64           0 :     if (!netgroup_attrs) {
      65           0 :         ret = ENOMEM;
      66           0 :         goto fail;
      67             :     }
      68             : 
      69           0 :     ret = sdap_attrs_add_string(attrs, SYSDB_ORIG_DN,
      70             :                                 "original DN",
      71             :                                 name, netgroup_attrs);
      72           0 :     if (ret != EOK) {
      73           0 :         goto fail;
      74             :     }
      75             : 
      76           0 :     ret = sysdb_attrs_get_el(attrs,
      77           0 :                          opts->netgroup_map[SDAP_AT_NETGROUP_MODSTAMP].sys_name,
      78             :                          &el);
      79           0 :     if (ret) {
      80           0 :         goto fail;
      81             :     }
      82           0 :     if (el->num_values == 0) {
      83           0 :         DEBUG(SSSDBG_TRACE_LIBS,
      84             :               "Original mod-Timestamp is not available for [%s].\n",
      85             :                   name);
      86             :     } else {
      87           0 :         ret = sysdb_attrs_add_string(netgroup_attrs,
      88           0 :                          opts->netgroup_map[SDAP_AT_NETGROUP_MODSTAMP].sys_name,
      89           0 :                          (const char*)el->values[0].data);
      90           0 :         if (ret) {
      91           0 :             goto fail;
      92             :         }
      93           0 :         timestamp = talloc_strdup(memctx, (const char*)el->values[0].data);
      94           0 :         if (!timestamp) {
      95           0 :             ret = ENOMEM;
      96           0 :             goto fail;
      97             :         }
      98             :     }
      99             : 
     100           0 :     ret = sdap_attrs_add_list(attrs,
     101             :                         opts->netgroup_map[SDAP_AT_NETGROUP_TRIPLE].sys_name,
     102             :                         "netgroup triple",
     103             :                         name, netgroup_attrs);
     104           0 :     if (ret != EOK) {
     105           0 :         goto fail;
     106             :     }
     107             : 
     108           0 :     ret = sdap_attrs_add_list(attrs,
     109             :                         opts->netgroup_map[SDAP_AT_NETGROUP_MEMBER].sys_name,
     110             :                         "original members",
     111             :                         name, netgroup_attrs);
     112           0 :     if (ret != EOK) {
     113           0 :         goto fail;
     114             :     }
     115             : 
     116           0 :     ret = sdap_attrs_add_list(attrs, SYSDB_NETGROUP_MEMBER,
     117             :                         "members", name, netgroup_attrs);
     118           0 :     if (ret != EOK) {
     119           0 :         goto fail;
     120             :     }
     121             : 
     122           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Storing info for netgroup %s\n", name);
     123             : 
     124           0 :     ret = sdap_save_all_names(name, attrs, dom,
     125             :                               netgroup_attrs);
     126           0 :     if (ret != EOK) {
     127           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save netgroup names\n");
     128           0 :         goto fail;
     129             :     }
     130             : 
     131             :     /* Make sure that any attributes we requested from LDAP that we
     132             :      * did not receive are also removed from the sysdb
     133             :      */
     134           0 :     ret = list_missing_attrs(attrs, opts->netgroup_map, SDAP_OPTS_NETGROUP,
     135             :                              attrs, &missing);
     136           0 :     if (ret != EOK) {
     137           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to list missing attributes\n");
     138           0 :         goto fail;
     139             :     }
     140             : 
     141           0 :     ret = sysdb_add_netgroup(dom, name, NULL, netgroup_attrs, missing,
     142           0 :                              dom->netgroup_timeout, now);
     143           0 :     if (ret) goto fail;
     144             : 
     145           0 :     if (_timestamp) {
     146           0 :         *_timestamp = timestamp;
     147             :     }
     148             : 
     149           0 :     return EOK;
     150             : 
     151             : fail:
     152           0 :     DEBUG(SSSDBG_OP_FAILURE, "Failed to save netgroup %s\n", name);
     153           0 :     return ret;
     154             : }
     155             : 
     156           0 : errno_t update_dn_list(struct dn_item *dn_list, const size_t count,
     157             :                        struct ldb_message **res, bool *all_resolved)
     158             : {
     159             :     struct dn_item *dn_item;
     160             :     size_t c;
     161             :     const char *dn;
     162             :     const char *cn;
     163           0 :     bool not_resolved = false;
     164             : 
     165           0 :     *all_resolved = false;
     166             : 
     167           0 :     DLIST_FOR_EACH(dn_item, dn_list) {
     168           0 :         if (dn_item->cn != NULL) {
     169           0 :             continue;
     170             :         }
     171             : 
     172           0 :         for(c = 0; c < count; c++) {
     173           0 :             dn = ldb_msg_find_attr_as_string(res[c], SYSDB_ORIG_DN, NULL);
     174           0 :             if (dn == NULL) {
     175           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "Missing original DN.\n");
     176           0 :                 return EINVAL;
     177             :             }
     178           0 :             if (strcmp(dn, dn_item->dn) == 0) {
     179           0 :                 DEBUG(SSSDBG_TRACE_ALL,
     180             :                       "Found matching entry for [%s].\n", dn_item->dn);
     181           0 :                 cn = ldb_msg_find_attr_as_string(res[c], SYSDB_NAME, NULL);
     182           0 :                 if (cn == NULL) {
     183           0 :                     DEBUG(SSSDBG_CRIT_FAILURE, "Missing name.\n");
     184           0 :                     return EINVAL;
     185             :                 }
     186           0 :                 dn_item->cn = talloc_strdup(dn_item, cn);
     187           0 :                 break;
     188             :             }
     189             :         }
     190             : 
     191           0 :         if (dn_item->cn == NULL) {
     192           0 :             not_resolved = true;
     193             :         }
     194             :     }
     195             : 
     196           0 :     *all_resolved = !not_resolved;
     197             : 
     198           0 :     return EOK;
     199             : }
     200             : 
     201             : struct netgr_translate_members_state {
     202             :     struct tevent_context *ev;
     203             :     struct sdap_options *opts;
     204             :     struct sdap_handle *sh;
     205             : 
     206             :     struct sysdb_attrs **netgroups;
     207             :     size_t count;
     208             :     struct dn_item *dn_list;
     209             :     struct dn_item *dn_item;
     210             :     struct dn_item *dn_idx;
     211             : };
     212             : 
     213             : static errno_t netgr_translate_members_ldap_step(struct tevent_req *req);
     214             : static void netgr_translate_members_ldap_done(struct tevent_req *subreq);
     215             : 
     216           0 : struct tevent_req *netgr_translate_members_send(TALLOC_CTX *memctx,
     217             :                                                 struct tevent_context *ev,
     218             :                                                 struct sdap_options *opts,
     219             :                                                 struct sdap_handle *sh,
     220             :                                                 struct sss_domain_info *dom,
     221             :                                                 struct sysdb_ctx *sysdb,
     222             :                                                 const size_t count,
     223             :                                                 struct sysdb_attrs **netgroups)
     224             : {
     225             :     struct tevent_req *req;
     226             :     struct netgr_translate_members_state *state;
     227             :     size_t c;
     228             :     size_t mc;
     229             :     const char **member_list;
     230             :     size_t sysdb_count;
     231             :     int ret;
     232             :     struct ldb_message **sysdb_res;
     233             :     struct dn_item *dn_item;
     234             :     char *dn_filter;
     235             :     char *sysdb_filter;
     236             :     struct ldb_dn *netgr_basedn;
     237             :     bool all_resolved;
     238           0 :     const char *cn_attr[] = { SYSDB_NAME, SYSDB_ORIG_DN, NULL };
     239             : 
     240           0 :     req = tevent_req_create(memctx, &state,
     241             :                             struct netgr_translate_members_state);
     242           0 :     if (req == NULL) {
     243           0 :         return NULL;
     244             :     }
     245             : 
     246           0 :     state->ev = ev;
     247           0 :     state->opts = opts;
     248           0 :     state->sh = sh;
     249           0 :     state->netgroups = netgroups;
     250           0 :     state->count = count;
     251           0 :     state->dn_list = NULL;
     252           0 :     state->dn_item = NULL;
     253           0 :     state->dn_idx = NULL;
     254             : 
     255           0 :     for (c = 0; c < count; c++) {
     256           0 :         ret = sysdb_attrs_get_string_array(netgroups[c],
     257             :                                            SYSDB_ORIG_NETGROUP_MEMBER, state,
     258             :                                            &member_list);
     259           0 :         if (ret != EOK) {
     260           0 :             DEBUG(SSSDBG_TRACE_LIBS, "Missing netgroup members.\n");
     261           0 :             continue;
     262             :         }
     263             : 
     264           0 :         for (mc = 0; member_list[mc] != NULL; mc++) {
     265           0 :             if (is_dn(member_list[mc])) {
     266           0 :                 dn_item = talloc_zero(state, struct dn_item);
     267           0 :                 if (dn_item == NULL) {
     268           0 :                     DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
     269           0 :                     ret = ENOMEM;
     270           0 :                     goto fail;
     271             :                 }
     272             : 
     273           0 :                 DEBUG(SSSDBG_TRACE_ALL,
     274             :                       "Adding [%s] to DN list.\n", member_list[mc]);
     275           0 :                 dn_item->netgroup = netgroups[c];
     276           0 :                 dn_item->dn = member_list[mc];
     277           0 :                 DLIST_ADD(state->dn_list, dn_item);
     278             :             } else {
     279           0 :                 ret = sysdb_attrs_add_string(netgroups[c], SYSDB_NETGROUP_MEMBER,
     280           0 :                                              member_list[mc]);
     281           0 :                 if (ret != EOK) {
     282           0 :                     DEBUG(SSSDBG_CRIT_FAILURE,
     283             :                           "sysdb_attrs_add_string failed.\n");
     284           0 :                     goto fail;
     285             :                 }
     286             :             }
     287             :         }
     288             :     }
     289             : 
     290           0 :     if (state->dn_list == NULL) {
     291           0 :         DEBUG(SSSDBG_TRACE_ALL, "No DNs found among netgroup members.\n");
     292           0 :         tevent_req_done(req);
     293           0 :         tevent_req_post(req, ev);
     294           0 :         return req;
     295             :     }
     296             : 
     297           0 :     dn_filter = talloc_strdup(state, "(|");
     298           0 :     if (dn_filter == NULL) {
     299           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
     300           0 :         ret = ENOMEM;;
     301           0 :         goto fail;
     302             :     }
     303             : 
     304           0 :     DLIST_FOR_EACH(dn_item, state->dn_list) {
     305           0 :             dn_filter = talloc_asprintf_append(dn_filter, "(%s=%s)",
     306             :                                                SYSDB_ORIG_DN, dn_item->dn);
     307           0 :             if (dn_filter == NULL) {
     308           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n");
     309           0 :                 ret = ENOMEM;
     310           0 :                 goto fail;
     311             :             }
     312             :     }
     313             : 
     314           0 :     dn_filter = talloc_asprintf_append(dn_filter, ")");
     315           0 :     if (dn_filter == NULL) {
     316           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n");
     317           0 :         ret = ENOMEM;
     318           0 :         goto fail;
     319             :     }
     320             : 
     321           0 :     sysdb_filter = talloc_asprintf(state, "(&(%s)%s)", SYSDB_NC, dn_filter);
     322           0 :     if (sysdb_filter == NULL) {
     323           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
     324           0 :         ret = ENOMEM;
     325           0 :         goto fail;
     326             :     }
     327             : 
     328           0 :     netgr_basedn = sysdb_netgroup_base_dn(state, dom);
     329           0 :     if (netgr_basedn == NULL) {
     330           0 :         ret = ENOMEM;
     331           0 :         goto fail;
     332             :     }
     333             : 
     334           0 :     ret = sysdb_search_entry(state, sysdb, netgr_basedn, LDB_SCOPE_BASE,
     335             :                              sysdb_filter, cn_attr, &sysdb_count, &sysdb_res);
     336           0 :     talloc_zfree(netgr_basedn);
     337           0 :     talloc_zfree(sysdb_filter);
     338           0 :     if (ret != EOK && ret != ENOENT) {
     339           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_search_entry failed.\n");
     340           0 :         goto fail;
     341             :     }
     342             : 
     343           0 :     if (ret == EOK) {
     344           0 :         ret = update_dn_list(state->dn_list, sysdb_count, sysdb_res,
     345             :                              &all_resolved);
     346           0 :         if (ret != EOK) {
     347           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "update_dn_list failed.\n");
     348           0 :             goto fail;
     349             :         }
     350             : 
     351           0 :         if (all_resolved) {
     352           0 :             DLIST_FOR_EACH(dn_item, state->dn_list) {
     353           0 :                     ret = sysdb_attrs_add_string(dn_item->netgroup,
     354             :                                                  SYSDB_NETGROUP_MEMBER,
     355           0 :                                                  dn_item->cn);
     356           0 :                     if (ret != EOK) {
     357           0 :                         DEBUG(SSSDBG_CRIT_FAILURE,
     358             :                               "sysdb_attrs_add_string failed.\n");
     359           0 :                         goto fail;
     360             :                     }
     361             :             }
     362             : 
     363           0 :             tevent_req_done(req);
     364           0 :             tevent_req_post(req, ev);
     365           0 :             return req;
     366             :         }
     367             :     }
     368             : 
     369           0 :     state->dn_idx = state->dn_list;
     370           0 :     ret = netgr_translate_members_ldap_step(req);
     371           0 :     if (ret != EOK && ret != EAGAIN) {
     372           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     373             :               "netgr_translate_members_ldap_step failed.\n");
     374           0 :         goto fail;
     375             :     }
     376             : 
     377           0 :     if (ret == EOK) {
     378           0 :         tevent_req_done(req);
     379           0 :         tevent_req_post(req, ev);
     380             :     }
     381           0 :     return req;
     382             : 
     383             : fail:
     384           0 :     tevent_req_error(req, ret);
     385           0 :     tevent_req_post(req, ev);
     386           0 :     return req;
     387             : }
     388             : 
     389             : /* netgr_translate_members_ldap_step() returns
     390             :  *   EOK: if everthing is translated, the caller can call tevent_req_done
     391             :  *   EAGAIN: if there are still members waiting to be translated, the caller
     392             :  *   should return to the mainloop
     393             :  *   Exyz: every other return code indicates an error and tevent_req_error
     394             :  *   should be called
     395             :  */
     396           0 : static errno_t netgr_translate_members_ldap_step(struct tevent_req *req)
     397             : {
     398           0 :     struct netgr_translate_members_state *state = tevent_req_data(req,
     399             :                                           struct netgr_translate_members_state);
     400             :     const char **cn_attr;
     401           0 :     char *filter = NULL;
     402             :     struct tevent_req *subreq;
     403             :     int ret;
     404             : 
     405           0 :     DLIST_FOR_EACH(state->dn_item, state->dn_idx) {
     406           0 :         if (state->dn_item->cn == NULL) {
     407           0 :             break;
     408             :         }
     409             :     }
     410           0 :     if (state->dn_item == NULL) {
     411           0 :         DLIST_FOR_EACH(state->dn_item, state->dn_list) {
     412           0 :                 ret = sysdb_attrs_add_string(state->dn_item->netgroup,
     413             :                                              SYSDB_NETGROUP_MEMBER,
     414           0 :                                              state->dn_item->cn);
     415           0 :                 if (ret != EOK) {
     416           0 :                     DEBUG(SSSDBG_CRIT_FAILURE,
     417             :                           "sysdb_attrs_add_string failed.\n");
     418           0 :                     tevent_req_error(req, ret);
     419           0 :                     return ret;
     420             :                 }
     421             :         }
     422             : 
     423           0 :         return EOK;
     424             :     }
     425             : 
     426           0 :     if (!sss_ldap_dn_in_search_bases(state, state->dn_item->dn,
     427           0 :                                      state->opts->sdom->netgroup_search_bases,
     428             :                                      &filter)) {
     429             :         /* not in search base, skip it */
     430           0 :         state->dn_idx = state->dn_item->next;
     431           0 :         DLIST_REMOVE(state->dn_list, state->dn_item);
     432           0 :         return netgr_translate_members_ldap_step(req);
     433             :     }
     434             : 
     435           0 :     cn_attr = talloc_array(state, const char *, 3);
     436           0 :     if (cn_attr == NULL) {
     437           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n");
     438           0 :         return ENOMEM;
     439             :     }
     440           0 :     cn_attr[0] = state->opts->netgroup_map[SDAP_AT_NETGROUP_NAME].name;
     441           0 :     cn_attr[1] = "objectclass";
     442           0 :     cn_attr[2] = NULL;
     443             : 
     444           0 :     DEBUG(SSSDBG_TRACE_ALL, "LDAP base search for [%s].\n", state->dn_item->dn);
     445           0 :     subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
     446           0 :                                    state->dn_item->dn, LDAP_SCOPE_BASE, filter,
     447           0 :                                    cn_attr, state->opts->netgroup_map,
     448             :                                    SDAP_OPTS_NETGROUP,
     449           0 :                                    dp_opt_get_int(state->opts->basic,
     450             :                                                   SDAP_SEARCH_TIMEOUT),
     451             :                                    false);
     452           0 :     if (!subreq) {
     453           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic_send failed.\n");
     454           0 :         return ENOMEM;
     455             :     }
     456           0 :     talloc_steal(subreq, cn_attr);
     457             : 
     458           0 :     tevent_req_set_callback(subreq, netgr_translate_members_ldap_done, req);
     459           0 :     return EAGAIN;
     460             : }
     461             : 
     462           0 : static void netgr_translate_members_ldap_done(struct tevent_req *subreq)
     463             : {
     464           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     465             :                                                       struct tevent_req);
     466           0 :     struct netgr_translate_members_state *state = tevent_req_data(req,
     467             :                                           struct netgr_translate_members_state);
     468             :     int ret;
     469             :     size_t count;
     470             :     struct sysdb_attrs **netgroups;
     471             :     const char *str;
     472             : 
     473           0 :     ret = sdap_get_generic_recv(subreq, state, &count, &netgroups);
     474           0 :     talloc_zfree(subreq);
     475           0 :     if (ret != EOK) {
     476           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic request failed.\n");
     477           0 :         goto fail;
     478             :     }
     479             : 
     480           0 :     switch (count) {
     481             :         case 0:
     482           0 :             DEBUG(SSSDBG_FATAL_FAILURE,
     483             :                   "sdap_get_generic_recv found no entry for [%s].\n",
     484             :                       state->dn_item->dn);
     485           0 :             break;
     486             :         case 1:
     487           0 :             ret = sysdb_attrs_get_string(netgroups[0], SYSDB_NAME, &str);
     488           0 :             if (ret != EOK) {
     489           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n");
     490           0 :                 break;
     491             :             }
     492           0 :             state->dn_item->cn = talloc_strdup(state->dn_item, str);
     493           0 :             if (state->dn_item->cn == NULL) {
     494           0 :                 DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
     495             :             }
     496           0 :             break;
     497             :         default:
     498           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     499             :                   "Unexpected number of results [%zu] for base search.\n",
     500             :                    count);
     501             :     }
     502             : 
     503           0 :     if (state->dn_item->cn == NULL) {
     504           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     505             :               "Failed to resolve netgroup name for DN [%s], using DN.\n",
     506             :                   state->dn_item->dn);
     507           0 :         state->dn_item->cn = talloc_strdup(state->dn_item, state->dn_item->dn);
     508             :     }
     509             : 
     510           0 :     state->dn_idx = state->dn_item->next;
     511           0 :     ret = netgr_translate_members_ldap_step(req);
     512           0 :     if (ret != EOK && ret != EAGAIN) {
     513           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     514             :               "netgr_translate_members_ldap_step failed.\n");
     515           0 :         goto fail;
     516             :     }
     517             : 
     518           0 :     if (ret == EOK) {
     519           0 :         tevent_req_done(req);
     520             :     }
     521           0 :     return;
     522             : 
     523             : fail:
     524           0 :     tevent_req_error(req, ret);
     525           0 :     return;
     526             : }
     527             : 
     528           0 : static errno_t netgroup_translate_ldap_members_recv(struct tevent_req *req,
     529             :                                                 TALLOC_CTX *mem_ctx,
     530             :                                                 size_t *count,
     531             :                                                 struct sysdb_attrs ***netgroups)
     532             : {
     533           0 :     struct netgr_translate_members_state *state = tevent_req_data(req,
     534             :                                           struct netgr_translate_members_state);
     535             : 
     536           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     537             : 
     538           0 :     *count = state->count;
     539           0 :     *netgroups = talloc_steal(mem_ctx, state->netgroups);
     540             : 
     541           0 :     return EOK;
     542             : }
     543             : 
     544             : /* ==Search-Netgroups-with-filter============================================ */
     545             : 
     546             : struct sdap_get_netgroups_state {
     547             :     struct tevent_context *ev;
     548             :     struct sdap_options *opts;
     549             :     struct sdap_handle *sh;
     550             :     struct sss_domain_info *dom;
     551             :     struct sysdb_ctx *sysdb;
     552             :     const char **attrs;
     553             :     const char *base_filter;
     554             :     char *filter;
     555             :     int timeout;
     556             : 
     557             :     char *higher_timestamp;
     558             :     struct sysdb_attrs **netgroups;
     559             :     size_t count;
     560             : 
     561             :     size_t base_iter;
     562             :     struct sdap_search_base **search_bases;
     563             : };
     564             : 
     565             : static errno_t sdap_get_netgroups_next_base(struct tevent_req *req);
     566             : static void sdap_get_netgroups_process(struct tevent_req *subreq);
     567             : static void netgr_translate_members_done(struct tevent_req *subreq);
     568             : 
     569           0 : struct tevent_req *sdap_get_netgroups_send(TALLOC_CTX *memctx,
     570             :                                            struct tevent_context *ev,
     571             :                                            struct sss_domain_info *dom,
     572             :                                            struct sysdb_ctx *sysdb,
     573             :                                            struct sdap_options *opts,
     574             :                                            struct sdap_search_base **search_bases,
     575             :                                            struct sdap_handle *sh,
     576             :                                            const char **attrs,
     577             :                                            const char *filter,
     578             :                                            int timeout)
     579             : {
     580             :     errno_t ret;
     581             :     struct tevent_req *req;
     582             :     struct sdap_get_netgroups_state *state;
     583             : 
     584           0 :     req = tevent_req_create(memctx, &state, struct sdap_get_netgroups_state);
     585           0 :     if (!req) return NULL;
     586             : 
     587           0 :     state->ev = ev;
     588           0 :     state->opts = opts;
     589           0 :     state->dom = dom;
     590           0 :     state->sh = sh;
     591           0 :     state->sysdb = sysdb;
     592           0 :     state->attrs = attrs;
     593           0 :     state->higher_timestamp = NULL;
     594           0 :     state->netgroups =  NULL;
     595           0 :     state->count = 0;
     596           0 :     state->timeout = timeout;
     597           0 :     state->base_filter = filter;
     598           0 :     state->base_iter = 0;
     599           0 :     state->search_bases = search_bases;
     600             : 
     601           0 :     if (!state->search_bases) {
     602           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     603             :               "Netgroup lookup request without a netgroup search base\n");
     604           0 :         ret = EINVAL;
     605           0 :         goto done;
     606             :     }
     607             : 
     608             : 
     609           0 :     ret = sdap_get_netgroups_next_base(req);
     610             : 
     611             : done:
     612           0 :     if (ret != EOK) {
     613           0 :         tevent_req_error(req, ret);
     614           0 :         tevent_req_post(req, state->ev);
     615             :     }
     616           0 :     return req;
     617             : }
     618             : 
     619           0 : static errno_t sdap_get_netgroups_next_base(struct tevent_req *req)
     620             : {
     621             :     struct tevent_req *subreq;
     622             :     struct sdap_get_netgroups_state *state;
     623             : 
     624           0 :     state = tevent_req_data(req, struct sdap_get_netgroups_state);
     625             : 
     626           0 :     talloc_zfree(state->filter);
     627           0 :     state->filter = sdap_combine_filters(state, state->base_filter,
     628           0 :                         state->search_bases[state->base_iter]->filter);
     629           0 :     if (!state->filter) {
     630           0 :         return ENOMEM;
     631             :     }
     632             : 
     633           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     634             :           "Searching for netgroups with base [%s]\n",
     635             :            state->search_bases[state->base_iter]->basedn);
     636             : 
     637           0 :     subreq = sdap_get_generic_send(
     638             :             state, state->ev, state->opts, state->sh,
     639           0 :             state->search_bases[state->base_iter]->basedn,
     640           0 :             state->search_bases[state->base_iter]->scope,
     641           0 :             state->filter, state->attrs,
     642           0 :             state->opts->netgroup_map, SDAP_OPTS_NETGROUP,
     643             :             state->timeout,
     644             :             false);
     645           0 :     if (!subreq) {
     646           0 :         return ENOMEM;
     647             :     }
     648           0 :     tevent_req_set_callback(subreq, sdap_get_netgroups_process, req);
     649             : 
     650           0 :     return EOK;
     651             : }
     652             : 
     653           0 : static void sdap_get_netgroups_process(struct tevent_req *subreq)
     654             : {
     655           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     656             :                                                       struct tevent_req);
     657           0 :     struct sdap_get_netgroups_state *state = tevent_req_data(req,
     658             :                                                struct sdap_get_netgroups_state);
     659             :     int ret;
     660             : 
     661           0 :     ret = sdap_get_generic_recv(subreq, state,
     662             :                                 &state->count, &state->netgroups);
     663           0 :     talloc_zfree(subreq);
     664           0 :     if (ret) {
     665           0 :         tevent_req_error(req, ret);
     666           0 :         return;
     667             :     }
     668             : 
     669           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     670             :           "Search for netgroups, returned %zu results.\n", state->count);
     671             : 
     672           0 :     if (state->count == 0) {
     673             :         /* No netgroups found in this search */
     674           0 :         state->base_iter++;
     675           0 :         if (state->search_bases[state->base_iter]) {
     676             :             /* There are more search bases to try */
     677           0 :             ret = sdap_get_netgroups_next_base(req);
     678           0 :             if (ret != EOK) {
     679           0 :                 tevent_req_error(req, ENOENT);
     680             :             }
     681           0 :             return;
     682             :         }
     683             : 
     684           0 :         tevent_req_error(req, ENOENT);
     685           0 :         return;
     686             :     }
     687             : 
     688           0 :     subreq = netgr_translate_members_send(state, state->ev, state->opts,
     689             :                                           state->sh, state->dom, state->sysdb,
     690             :                                           state->count, state->netgroups);
     691           0 :     if (!subreq) {
     692           0 :         tevent_req_error(req, ENOMEM);
     693           0 :         return;
     694             :     }
     695           0 :     tevent_req_set_callback(subreq, netgr_translate_members_done, req);
     696             : 
     697           0 :     return;
     698             : 
     699             : }
     700             : 
     701           0 : static void netgr_translate_members_done(struct tevent_req *subreq)
     702             : {
     703           0 :     struct tevent_req *req = tevent_req_callback_data(subreq,
     704             :                                                       struct tevent_req);
     705           0 :     struct sdap_get_netgroups_state *state = tevent_req_data(req,
     706             :                                                struct sdap_get_netgroups_state);
     707             :     int ret;
     708             :     size_t c;
     709             :     time_t now;
     710             : 
     711           0 :     ret = netgroup_translate_ldap_members_recv(subreq, state, &state->count,
     712             :                                                &state->netgroups);
     713           0 :     talloc_zfree(subreq);
     714           0 :     if (ret) {
     715           0 :         tevent_req_error(req, ret);
     716           0 :         return;
     717             :     }
     718             : 
     719           0 :     now = time(NULL);
     720           0 :     for (c = 0; c < state->count; c++) {
     721           0 :         ret = sdap_save_netgroup(state,
     722             :                                  state->dom,
     723             :                                  state->opts,
     724           0 :                                  state->netgroups[c],
     725             :                                  &state->higher_timestamp,
     726             :                                  now);
     727           0 :         if (ret) {
     728           0 :             DEBUG(SSSDBG_OP_FAILURE, "Failed to store netgroups.\n");
     729           0 :             tevent_req_error(req, ret);
     730           0 :             return;
     731             :         }
     732             :     }
     733             : 
     734           0 :     DEBUG(SSSDBG_TRACE_ALL, "Saving %zu Netgroups - Done\n", state->count);
     735             : 
     736           0 :     tevent_req_done(req);
     737             : }
     738             : 
     739           0 : int sdap_get_netgroups_recv(struct tevent_req *req,
     740             :                             TALLOC_CTX *mem_ctx, char **timestamp,
     741             :                             size_t *reply_count,
     742             :                             struct sysdb_attrs ***reply)
     743             : {
     744           0 :     struct sdap_get_netgroups_state *state = tevent_req_data(req,
     745             :                                                struct sdap_get_netgroups_state);
     746             : 
     747           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     748             : 
     749           0 :     if (timestamp) {
     750           0 :         *timestamp = talloc_steal(mem_ctx, state->higher_timestamp);
     751             :     }
     752             : 
     753           0 :     if (reply_count) {
     754           0 :         *reply_count = state->count;
     755             :     }
     756             : 
     757           0 :     if (reply) {
     758           0 :         *reply = talloc_steal(mem_ctx, state->netgroups);
     759             :     }
     760             : 
     761           0 :     return EOK;
     762             : }

Generated by: LCOV version 1.10