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

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Pavel Březina <pbrezina@redhat.com>
       4             : 
       5             :     Copyright (C) 2015 Red Hat
       6             : 
       7             :     This program is free software; you can redistribute it and/or modify
       8             :     it under the terms of the GNU General Public License as published by
       9             :     the Free Software Foundation; either version 3 of the License, or
      10             :     (at your option) any later version.
      11             : 
      12             :     This program is distributed in the hope that it will be useful,
      13             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :     GNU General Public License for more details.
      16             : 
      17             :     You should have received a copy of the GNU General Public License
      18             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      19             : */
      20             : 
      21             : #include <talloc.h>
      22             : #include <tevent.h>
      23             : 
      24             : #include "util/util.h"
      25             : #include "providers/ldap/sdap.h"
      26             : #include "providers/ldap/sdap_async.h"
      27             : #include "providers/ldap/ldap_common.h"
      28             : 
      29             : struct sdap_search_bases_ex_state {
      30             :     struct tevent_context *ev;
      31             :     struct sdap_options *opts;
      32             :     struct sdap_handle *sh;
      33             :     const char *filter;
      34             :     const char **attrs;
      35             :     struct sdap_attr_map *map;
      36             :     int map_num_attrs;
      37             :     int timeout;
      38             :     bool allow_paging;
      39             :     bool return_first_reply;
      40             : 
      41             :     size_t base_iter;
      42             :     struct sdap_search_base *cur_base;
      43             :     struct sdap_search_base **bases;
      44             : 
      45             :     size_t reply_count;
      46             :     struct sysdb_attrs **reply;
      47             : };
      48             : 
      49             : static errno_t sdap_search_bases_ex_next_base(struct tevent_req *req);
      50             : static void sdap_search_bases_ex_done(struct tevent_req *subreq);
      51             : 
      52             : static struct tevent_req *
      53           0 : sdap_search_bases_ex_send(TALLOC_CTX *mem_ctx,
      54             :                           struct tevent_context *ev,
      55             :                           struct sdap_options *opts,
      56             :                           struct sdap_handle *sh,
      57             :                           struct sdap_search_base **bases,
      58             :                           struct sdap_attr_map *map,
      59             :                           bool allow_paging,
      60             :                           bool return_first_reply,
      61             :                           int timeout,
      62             :                           const char *filter,
      63             :                           const char **attrs)
      64             : {
      65             :     struct tevent_req *req;
      66             :     struct sdap_search_bases_ex_state *state;
      67             :     errno_t ret;
      68             : 
      69           0 :     req = tevent_req_create(mem_ctx, &state, struct sdap_search_bases_ex_state);
      70           0 :     if (req == NULL) {
      71           0 :         return NULL;
      72             :     }
      73             : 
      74           0 :     if (bases == NULL) {
      75           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No search base specified!\n");
      76           0 :         ret = ERR_INTERNAL;
      77           0 :         goto immediately;
      78             :     }
      79             : 
      80           0 :     state->ev = ev;
      81           0 :     state->opts = opts;
      82           0 :     state->sh = sh;
      83           0 :     state->bases = bases;
      84           0 :     state->map = map;
      85           0 :     state->filter = filter;
      86           0 :     state->attrs = attrs;
      87           0 :     state->allow_paging = allow_paging;
      88           0 :     state->return_first_reply = return_first_reply;
      89             : 
      90           0 :     state->timeout = timeout == 0
      91           0 :                      ? dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT)
      92           0 :                      : timeout;
      93             : 
      94           0 :     if (state->map != NULL) {
      95           0 :         for (state->map_num_attrs = 0;
      96           0 :                 state->map[state->map_num_attrs].opt_name != NULL;
      97           0 :                 state->map_num_attrs++) {
      98             :             /* no op */;
      99             :         }
     100             :     } else {
     101           0 :         state->map_num_attrs = 0;
     102             :     }
     103             : 
     104           0 :     if (state->attrs == NULL) {
     105           0 :         ret = build_attrs_from_map(state, state->map, state->map_num_attrs,
     106           0 :                                    NULL, &state->attrs, NULL);
     107           0 :         if (ret != EOK) {
     108           0 :             DEBUG(SSSDBG_OP_FAILURE, "Unable to build attrs from map "
     109             :                   "[%d]: %s\n", ret, sss_strerror(ret));
     110           0 :             goto immediately;
     111             :         }
     112             :     }
     113             : 
     114           0 :     state->base_iter = 0;
     115           0 :     ret = sdap_search_bases_ex_next_base(req);
     116           0 :     if (ret == EAGAIN) {
     117             :         /* asynchronous processing */
     118           0 :         return req;
     119             :     }
     120             : 
     121             : immediately:
     122           0 :     if (ret == EOK) {
     123           0 :         tevent_req_done(req);
     124             :     } else {
     125           0 :         tevent_req_error(req, ret);
     126             :     }
     127           0 :     tevent_req_post(req, ev);
     128             : 
     129           0 :     return req;
     130             : }
     131             : 
     132           0 : static errno_t sdap_search_bases_ex_next_base(struct tevent_req *req)
     133             : {
     134             :     struct sdap_search_bases_ex_state *state;
     135             :     struct tevent_req *subreq;
     136             :     char *filter;
     137             : 
     138           0 :     state = tevent_req_data(req, struct sdap_search_bases_ex_state);
     139           0 :     state->cur_base = state->bases[state->base_iter];
     140           0 :     if (state->cur_base == NULL) {
     141           0 :         return EOK;
     142             :     }
     143             : 
     144             :     /* Combine lookup and search base filters. */
     145           0 :     filter = sdap_combine_filters(state, state->filter,
     146           0 :                                   state->cur_base->filter);
     147           0 :     if (filter == NULL) {
     148           0 :         return ENOMEM;
     149             :     }
     150             : 
     151           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Issuing LDAP lookup with base [%s]\n",
     152             :                              state->cur_base->basedn);
     153             : 
     154           0 :     subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
     155           0 :                                    state->cur_base->basedn,
     156           0 :                                    state->cur_base->scope, filter,
     157             :                                    state->attrs, state->map,
     158             :                                    state->map_num_attrs, state->timeout,
     159           0 :                                    state->allow_paging);
     160           0 :     if (subreq == NULL) {
     161           0 :         return ENOMEM;
     162             :     }
     163             : 
     164           0 :     tevent_req_set_callback(subreq, sdap_search_bases_ex_done, req);
     165             : 
     166           0 :     state->base_iter++;
     167           0 :     return EAGAIN;
     168             : }
     169             : 
     170           0 : static void sdap_search_bases_ex_done(struct tevent_req *subreq)
     171             : {
     172             :     struct tevent_req *req;
     173             :     struct sdap_search_bases_ex_state *state;
     174             :     struct sysdb_attrs **attrs;
     175             :     size_t count;
     176             :     size_t i;
     177             :     int ret;
     178             : 
     179           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     180           0 :     state = tevent_req_data(req, struct sdap_search_bases_ex_state);
     181             : 
     182           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Receiving data from base [%s]\n",
     183             :                              state->cur_base->basedn);
     184             : 
     185           0 :     ret = sdap_get_generic_recv(subreq, state, &count, &attrs);
     186           0 :     talloc_zfree(subreq);
     187           0 :     if (ret != EOK) {
     188           0 :         tevent_req_error(req, ret);
     189           0 :         return;
     190             :     }
     191             : 
     192             :     /* Add rules to result. */
     193           0 :     if (count > 0) {
     194           0 :         if (state->return_first_reply == false) {
     195             :             /* Merge with previous reply. */
     196           0 :             state->reply = talloc_realloc(state, state->reply,
     197             :                                           struct sysdb_attrs *,
     198             :                                           state->reply_count + count);
     199           0 :             if (state->reply == NULL) {
     200           0 :                 tevent_req_error(req, ENOMEM);
     201           0 :                 return;
     202             :             }
     203             : 
     204           0 :             for (i = 0; i < count; i++) {
     205           0 :                 state->reply[state->reply_count + i] = talloc_steal(state->reply,
     206             :                                                                     attrs[i]);
     207             :             }
     208             : 
     209           0 :             state->reply_count += count;
     210             :         } else {
     211             :             /* Return the first successful search result. */
     212           0 :             state->reply_count = count;
     213           0 :             state->reply = attrs;
     214           0 :             tevent_req_done(req);
     215           0 :             return;
     216             :         }
     217             :     }
     218             : 
     219             :     /* Try next search base. */
     220           0 :     ret = sdap_search_bases_ex_next_base(req);
     221           0 :     if (ret == EOK) {
     222           0 :         tevent_req_done(req);
     223           0 :     } else if (ret != EAGAIN) {
     224           0 :         tevent_req_error(req, ret);
     225             :     }
     226             : 
     227           0 :     return;
     228             : }
     229             : 
     230           0 : static int sdap_search_bases_ex_recv(struct tevent_req *req,
     231             :                                      TALLOC_CTX *mem_ctx,
     232             :                                      size_t *reply_count,
     233             :                                      struct sysdb_attrs ***reply)
     234             : {
     235           0 :     struct sdap_search_bases_ex_state *state =
     236           0 :                 tevent_req_data(req, struct sdap_search_bases_ex_state);
     237             : 
     238           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     239             : 
     240           0 :     *reply_count = state->reply_count;
     241           0 :     *reply = talloc_steal(mem_ctx, state->reply);
     242             : 
     243           0 :     return EOK;
     244             : }
     245             : 
     246             : struct tevent_req *
     247           0 : sdap_search_bases_send(TALLOC_CTX *mem_ctx,
     248             :                        struct tevent_context *ev,
     249             :                        struct sdap_options *opts,
     250             :                        struct sdap_handle *sh,
     251             :                        struct sdap_search_base **bases,
     252             :                        struct sdap_attr_map *map,
     253             :                        bool allow_paging,
     254             :                        int timeout,
     255             :                        const char *filter,
     256             :                        const char **attrs)
     257             : {
     258           0 :     return sdap_search_bases_ex_send(mem_ctx, ev, opts, sh, bases, map,
     259             :                                      allow_paging, false, timeout,
     260             :                                      filter, attrs);
     261             : }
     262             : 
     263           0 : int sdap_search_bases_recv(struct tevent_req *req,
     264             :                            TALLOC_CTX *mem_ctx,
     265             :                            size_t *_reply_count,
     266             :                            struct sysdb_attrs ***_reply)
     267             : {
     268           0 :     return sdap_search_bases_ex_recv(req, mem_ctx, _reply_count, _reply);
     269             : }
     270             : 
     271             : struct tevent_req *
     272           0 : sdap_search_bases_return_first_send(TALLOC_CTX *mem_ctx,
     273             :                                     struct tevent_context *ev,
     274             :                                     struct sdap_options *opts,
     275             :                                     struct sdap_handle *sh,
     276             :                                     struct sdap_search_base **bases,
     277             :                                     struct sdap_attr_map *map,
     278             :                                     bool allow_paging,
     279             :                                     int timeout,
     280             :                                     const char *filter,
     281             :                                     const char **attrs)
     282             : {
     283           0 :     return sdap_search_bases_ex_send(mem_ctx, ev, opts, sh, bases, map,
     284             :                                      allow_paging, true, timeout,
     285             :                                      filter, attrs);
     286             : }
     287             : 
     288           0 : int sdap_search_bases_return_first_recv(struct tevent_req *req,
     289             :                                         TALLOC_CTX *mem_ctx,
     290             :                                         size_t *_reply_count,
     291             :                                         struct sysdb_attrs ***_reply)
     292             : {
     293           0 :     return sdap_search_bases_ex_recv(req, mem_ctx, _reply_count, _reply);
     294             : }
     295             : 
     296             : struct sdap_deref_bases_ex_state {
     297             :     struct tevent_context *ev;
     298             :     struct sdap_options *opts;
     299             :     struct sdap_handle *sh;
     300             :     const char *filter;
     301             :     const char **attrs;
     302             :     const char *deref_attr;
     303             :     struct sdap_attr_map_info *maps;
     304             :     size_t num_maps;
     305             :     unsigned int flags;
     306             :     bool return_first_reply;
     307             :     int timeout;
     308             : 
     309             :     size_t base_iter;
     310             :     struct sdap_search_base *cur_base;
     311             :     struct sdap_search_base **bases;
     312             : 
     313             :     size_t reply_count;
     314             :     struct sdap_deref_attrs **reply;
     315             : };
     316             : 
     317             : static errno_t sdap_deref_bases_ex_next_base(struct tevent_req *req);
     318             : static void sdap_deref_bases_ex_done(struct tevent_req *subreq);
     319             : 
     320             : static struct tevent_req *
     321           0 : sdap_deref_bases_ex_send(TALLOC_CTX *mem_ctx,
     322             :                          struct tevent_context *ev,
     323             :                          struct sdap_options *opts,
     324             :                          struct sdap_handle *sh,
     325             :                          struct sdap_search_base **bases,
     326             :                          struct sdap_attr_map_info *maps,
     327             :                          const char *filter,
     328             :                          const char **attrs,
     329             :                          const char *deref_attr,
     330             :                          unsigned int flags,
     331             :                          bool return_first_reply,
     332             :                          int timeout)
     333             : {
     334             :     struct tevent_req *req;
     335             :     struct sdap_deref_bases_ex_state *state;
     336             :     errno_t ret;
     337             : 
     338           0 :     req = tevent_req_create(mem_ctx, &state, struct sdap_deref_bases_ex_state);
     339           0 :     if (req == NULL) {
     340           0 :         return NULL;
     341             :     }
     342             : 
     343           0 :     if (bases == NULL) {
     344           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No search base specified!\n");
     345           0 :         ret = ERR_INTERNAL;
     346           0 :         goto immediately;
     347             :     }
     348             : 
     349           0 :     if (maps == NULL || attrs == NULL || deref_attr == NULL) {
     350           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "No attributes or map specified!\n");
     351           0 :         ret = ERR_INTERNAL;
     352           0 :         goto immediately;
     353             :     }
     354             : 
     355           0 :     state->ev = ev;
     356           0 :     state->opts = opts;
     357           0 :     state->sh = sh;
     358           0 :     state->bases = bases;
     359           0 :     state->maps = maps;
     360           0 :     state->filter = filter;
     361           0 :     state->attrs = attrs;
     362           0 :     state->deref_attr = deref_attr;
     363           0 :     state->return_first_reply = return_first_reply;
     364           0 :     state->flags = flags;
     365             : 
     366           0 :     state->timeout = timeout == 0
     367           0 :                      ? dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT)
     368           0 :                      : timeout;
     369             : 
     370           0 :     for (state->num_maps = 0; maps[state->num_maps].map != NULL;
     371           0 :             state->num_maps++) {
     372             :             /* no op */;
     373             :     }
     374             : 
     375           0 :     state->base_iter = 0;
     376           0 :     ret = sdap_deref_bases_ex_next_base(req);
     377           0 :     if (ret == EAGAIN) {
     378             :         /* asynchronous processing */
     379           0 :         return req;
     380             :     }
     381             : 
     382             : immediately:
     383           0 :     if (ret == EOK) {
     384           0 :         tevent_req_done(req);
     385             :     } else {
     386           0 :         tevent_req_error(req, ret);
     387             :     }
     388           0 :     tevent_req_post(req, ev);
     389             : 
     390           0 :     return req;
     391             : }
     392             : 
     393           0 : static errno_t sdap_deref_bases_ex_next_base(struct tevent_req *req)
     394             : {
     395             :     struct sdap_deref_bases_ex_state *state;
     396             :     struct tevent_req *subreq;
     397             : 
     398           0 :     state = tevent_req_data(req, struct sdap_deref_bases_ex_state);
     399           0 :     state->cur_base = state->bases[state->base_iter];
     400           0 :     if (state->cur_base == NULL) {
     401           0 :         return EOK;
     402             :     }
     403             : 
     404           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Issuing LDAP deref lookup with base [%s]\n",
     405             :                              state->cur_base->basedn);
     406             : 
     407           0 :     subreq = sdap_deref_search_with_filter_send(state, state->ev, state->opts,
     408           0 :                  state->sh, state->cur_base->basedn, state->filter,
     409           0 :                  state->deref_attr, state->attrs, state->num_maps, state->maps,
     410             :                  state->timeout, state->flags);
     411           0 :     if (subreq == NULL) {
     412           0 :         return ENOMEM;
     413             :     }
     414             : 
     415           0 :     tevent_req_set_callback(subreq, sdap_deref_bases_ex_done, req);
     416             : 
     417           0 :     state->base_iter++;
     418           0 :     return EAGAIN;
     419             : }
     420             : 
     421           0 : static void sdap_deref_bases_ex_done(struct tevent_req *subreq)
     422             : {
     423             :     struct tevent_req *req;
     424             :     struct sdap_deref_bases_ex_state *state;
     425             :     struct sdap_deref_attrs **attrs;
     426             :     size_t count;
     427             :     size_t i;
     428             :     int ret;
     429             : 
     430           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     431           0 :     state = tevent_req_data(req, struct sdap_deref_bases_ex_state);
     432             : 
     433           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Receiving data from base [%s]\n",
     434             :                              state->cur_base->basedn);
     435             : 
     436           0 :     ret = sdap_deref_search_with_filter_recv(subreq, state, &count, &attrs);
     437           0 :     talloc_zfree(subreq);
     438           0 :     if (ret != EOK) {
     439           0 :         tevent_req_error(req, ret);
     440           0 :         return;
     441             :     }
     442             : 
     443             :     /* Add rules to result. */
     444           0 :     if (count > 0) {
     445           0 :         if (state->return_first_reply == false) {
     446             :             /* Merge with previous reply. */
     447           0 :             state->reply = talloc_realloc(state, state->reply,
     448             :                                           struct sdap_deref_attrs *,
     449             :                                           state->reply_count + count);
     450           0 :             if (state->reply == NULL) {
     451           0 :                 tevent_req_error(req, ENOMEM);
     452           0 :                 return;
     453             :             }
     454             : 
     455           0 :             for (i = 0; i < count; i++) {
     456           0 :                 state->reply[state->reply_count + i] = talloc_steal(state->reply,
     457             :                                                                     attrs[i]);
     458             :             }
     459             : 
     460           0 :             state->reply_count += count;
     461             :         } else {
     462             :             /* Return the first successful search result. */
     463           0 :             state->reply_count = count;
     464           0 :             state->reply = attrs;
     465           0 :             tevent_req_done(req);
     466           0 :             return;
     467             :         }
     468             :     }
     469             : 
     470             :     /* Try next search base. */
     471           0 :     ret = sdap_deref_bases_ex_next_base(req);
     472           0 :     if (ret == EOK) {
     473           0 :         tevent_req_done(req);
     474           0 :     } else if (ret != EAGAIN) {
     475           0 :         tevent_req_error(req, ret);
     476             :     }
     477             : 
     478           0 :     return;
     479             : }
     480             : 
     481           0 : static int sdap_deref_bases_ex_recv(struct tevent_req *req,
     482             :                                     TALLOC_CTX *mem_ctx,
     483             :                                     size_t *reply_count,
     484             :                                     struct sdap_deref_attrs ***reply)
     485             : {
     486           0 :     struct sdap_deref_bases_ex_state *state =
     487           0 :                 tevent_req_data(req, struct sdap_deref_bases_ex_state);
     488             : 
     489           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     490             : 
     491           0 :     *reply_count = state->reply_count;
     492           0 :     *reply = talloc_steal(mem_ctx, state->reply);
     493             : 
     494           0 :     return EOK;
     495             : }
     496             : 
     497             : struct tevent_req *
     498           0 : sdap_deref_bases_send(TALLOC_CTX *mem_ctx,
     499             :                       struct tevent_context *ev,
     500             :                       struct sdap_options *opts,
     501             :                       struct sdap_handle *sh,
     502             :                       struct sdap_search_base **bases,
     503             :                       struct sdap_attr_map_info *maps,
     504             :                       const char *filter,
     505             :                       const char **attrs,
     506             :                       const char *deref_attr,
     507             :                       unsigned int flags,
     508             :                       int timeout)
     509             : {
     510           0 :     return sdap_deref_bases_ex_send(mem_ctx, ev, opts, sh, bases, maps,
     511             :                                     filter, attrs, deref_attr, flags,
     512             :                                     false, timeout);
     513             : }
     514             : 
     515           0 : int sdap_deref_bases_recv(struct tevent_req *req,
     516             :                           TALLOC_CTX *mem_ctx,
     517             :                           size_t *_reply_count,
     518             :                           struct sdap_deref_attrs ***_reply)
     519             : {
     520           0 :     return sdap_deref_bases_ex_recv(req, mem_ctx, _reply_count, _reply);
     521             : }
     522             : 
     523             : struct tevent_req *
     524           0 : sdap_deref_bases_return_first_send(TALLOC_CTX *mem_ctx,
     525             :                                    struct tevent_context *ev,
     526             :                                    struct sdap_options *opts,
     527             :                                    struct sdap_handle *sh,
     528             :                                    struct sdap_search_base **bases,
     529             :                                    struct sdap_attr_map_info *maps,
     530             :                                    const char *filter,
     531             :                                    const char **attrs,
     532             :                                    const char *deref_attr,
     533             :                                    unsigned int flags,
     534             :                                    int timeout)
     535             : {
     536           0 :     return sdap_deref_bases_ex_send(mem_ctx, ev, opts, sh, bases, maps,
     537             :                                     filter, attrs, deref_attr, flags,
     538             :                                     true, timeout);
     539             : }
     540             : 
     541           0 : int sdap_deref_bases_return_first_recv(struct tevent_req *req,
     542             :                                        TALLOC_CTX *mem_ctx,
     543             :                                        size_t *_reply_count,
     544             :                                        struct sdap_deref_attrs ***_reply)
     545             : {
     546           0 :     return sdap_deref_bases_ex_recv(req, mem_ctx, _reply_count, _reply);
     547             : }

Generated by: LCOV version 1.10