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

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Authors:
       5             :         Stephen Gallagher <sgallagh@redhat.com>
       6             : 
       7             :     Copyright (C) 2012 Red Hat
       8             : 
       9             :     This program is free software; you can redistribute it and/or modify
      10             :     it under the terms of the GNU General Public License as published by
      11             :     the Free Software Foundation; either version 3 of the License, or
      12             :     (at your option) any later version.
      13             : 
      14             :     This program is distributed in the hope that it will be useful,
      15             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :     GNU General Public License for more details.
      18             : 
      19             :     You should have received a copy of the GNU General Public License
      20             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "util/util.h"
      24             : #include "db/sysdb.h"
      25             : #include "db/sysdb_services.h"
      26             : #include "providers/ldap/sdap_async_private.h"
      27             : #include "providers/ldap/ldap_common.h"
      28             : 
      29             : struct sdap_get_services_state {
      30             :     struct tevent_context *ev;
      31             :     struct sdap_options *opts;
      32             :     struct sdap_handle *sh;
      33             :     struct sss_domain_info *dom;
      34             :     struct sysdb_ctx *sysdb;
      35             :     const char **attrs;
      36             :     const char *base_filter;
      37             :     char *filter;
      38             :     int timeout;
      39             :     bool enumeration;
      40             : 
      41             :     char *higher_usn;
      42             :     struct sysdb_attrs **services;
      43             :     size_t count;
      44             : 
      45             :     size_t base_iter;
      46             :     struct sdap_search_base **search_bases;
      47             : };
      48             : 
      49             : static errno_t
      50             : sdap_get_services_next_base(struct tevent_req *req);
      51             : static void
      52             : sdap_get_services_process(struct tevent_req *subreq);
      53             : static errno_t
      54             : sdap_save_services(TALLOC_CTX *memctx,
      55             :                    struct sysdb_ctx *sysdb,
      56             :                    struct sss_domain_info *dom,
      57             :                    struct sdap_options *opts,
      58             :                    struct sysdb_attrs **services,
      59             :                    size_t num_services,
      60             :                    char **_usn_value);
      61             : static errno_t
      62             : sdap_save_service(TALLOC_CTX *mem_ctx,
      63             :                   struct sysdb_ctx *sysdb,
      64             :                   struct sdap_options *opts,
      65             :                   struct sss_domain_info *dom,
      66             :                   struct sysdb_attrs *attrs,
      67             :                   char **_usn_value,
      68             :                   time_t now);
      69             : 
      70             : struct tevent_req *
      71           0 : sdap_get_services_send(TALLOC_CTX *memctx,
      72             :                        struct tevent_context *ev,
      73             :                        struct sss_domain_info *dom,
      74             :                        struct sysdb_ctx *sysdb,
      75             :                        struct sdap_options *opts,
      76             :                        struct sdap_search_base **search_bases,
      77             :                        struct sdap_handle *sh,
      78             :                        const char **attrs,
      79             :                        const char *filter,
      80             :                        int timeout,
      81             :                        bool enumeration)
      82             : {
      83             :     errno_t ret;
      84             :     struct tevent_req *req;
      85             :     struct sdap_get_services_state *state;
      86             : 
      87           0 :     req = tevent_req_create(memctx, &state, struct sdap_get_services_state);
      88           0 :     if (!req) return NULL;
      89             : 
      90           0 :     state->ev = ev;
      91           0 :     state->opts = opts;
      92           0 :     state->dom = dom;
      93           0 :     state->sh = sh;
      94           0 :     state->sysdb = sysdb;
      95           0 :     state->attrs = attrs;
      96           0 :     state->higher_usn = NULL;
      97           0 :     state->services =  NULL;
      98           0 :     state->count = 0;
      99           0 :     state->timeout = timeout;
     100           0 :     state->base_filter = filter;
     101           0 :     state->base_iter = 0;
     102           0 :     state->search_bases = search_bases;
     103           0 :     state->enumeration = enumeration;
     104             : 
     105           0 :     if (!state->search_bases) {
     106           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     107             :               "Services lookup request without a search base\n");
     108           0 :         ret = EINVAL;
     109           0 :         goto done;
     110             :     }
     111             : 
     112           0 :     ret = sdap_get_services_next_base(req);
     113             : 
     114             : done:
     115           0 :     if (ret != EOK) {
     116           0 :         tevent_req_error(req, ret);
     117           0 :         tevent_req_post(req, state->ev);
     118             :     }
     119             : 
     120           0 :     return req;
     121             : }
     122             : 
     123             : static errno_t
     124           0 : sdap_get_services_next_base(struct tevent_req *req)
     125             : {
     126             :     struct tevent_req *subreq;
     127             :     struct sdap_get_services_state *state;
     128             : 
     129           0 :     state = tevent_req_data(req, struct sdap_get_services_state);
     130             : 
     131           0 :     talloc_zfree(state->filter);
     132           0 :     state->filter = sdap_combine_filters(state, state->base_filter,
     133           0 :                         state->search_bases[state->base_iter]->filter);
     134           0 :     if (!state->filter) {
     135           0 :         return ENOMEM;
     136             :     }
     137             : 
     138           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     139             :           "Searching for services with base [%s]\n",
     140             :            state->search_bases[state->base_iter]->basedn);
     141             : 
     142           0 :     subreq = sdap_get_generic_send(
     143             :             state, state->ev, state->opts, state->sh,
     144           0 :             state->search_bases[state->base_iter]->basedn,
     145           0 :             state->search_bases[state->base_iter]->scope,
     146           0 :             state->filter, state->attrs,
     147           0 :             state->opts->service_map, SDAP_OPTS_SERVICES,
     148             :             state->timeout,
     149           0 :             state->enumeration); /* If we're enumerating, we need paging */
     150           0 :     if (!subreq) {
     151           0 :         return ENOMEM;
     152             :     }
     153           0 :     tevent_req_set_callback(subreq, sdap_get_services_process, req);
     154             : 
     155           0 :     return EOK;
     156             : }
     157             : 
     158             : static void
     159           0 : sdap_get_services_process(struct tevent_req *subreq)
     160             : {
     161           0 :     struct tevent_req *req =
     162           0 :             tevent_req_callback_data(subreq, struct tevent_req);
     163           0 :     struct sdap_get_services_state *state =
     164           0 :             tevent_req_data(req, struct sdap_get_services_state);
     165             :     int ret;
     166             :     size_t count, i;
     167             :     struct sysdb_attrs **services;
     168           0 :     bool next_base = false;
     169             : 
     170           0 :     ret = sdap_get_generic_recv(subreq, state,
     171             :                                 &count, &services);
     172           0 :     talloc_zfree(subreq);
     173           0 :     if (ret) {
     174           0 :         tevent_req_error(req, ret);
     175           0 :         return;
     176             :     }
     177             : 
     178           0 :     DEBUG(SSSDBG_TRACE_FUNC,
     179             :           "Search for services, returned %zu results.\n",
     180             :            count);
     181             : 
     182           0 :     if (state->enumeration || count == 0) {
     183             :         /* No services found in this search or enumerating */
     184           0 :         next_base = true;
     185             :     }
     186             : 
     187             :     /* Add this batch of sevices to the list */
     188           0 :     if (count > 0) {
     189           0 :         state->services =
     190           0 :                 talloc_realloc(state,
     191             :                                state->services,
     192             :                                struct sysdb_attrs *,
     193             :                                state->count + count + 1);
     194           0 :         if (!state->services) {
     195           0 :             tevent_req_error(req, ENOMEM);
     196           0 :             return;
     197             :         }
     198             : 
     199             :         /* Copy the new services into the list
     200             :          */
     201           0 :         for (i = 0; i < count; i++) {
     202           0 :             state->services[state->count + i] =
     203           0 :                 talloc_steal(state->services, services[i]);
     204             :         }
     205             : 
     206           0 :         state->count += count;
     207           0 :         state->services[state->count] = NULL;
     208             :     }
     209             : 
     210           0 :     if (next_base) {
     211           0 :         state->base_iter++;
     212           0 :         if (state->search_bases[state->base_iter]) {
     213             :             /* There are more search bases to try */
     214           0 :             ret = sdap_get_services_next_base(req);
     215           0 :             if (ret != EOK) {
     216           0 :                 tevent_req_error(req, ret);
     217             :             }
     218           0 :             return;
     219             :         }
     220             :     }
     221             : 
     222             :     /* No more search bases
     223             :      * Return ENOENT if no services were found
     224             :      */
     225           0 :     if (state->count == 0) {
     226           0 :         tevent_req_error(req, ENOENT);
     227           0 :         return;
     228             :     }
     229             : 
     230           0 :     ret = sdap_save_services(state, state->sysdb,
     231             :                              state->dom, state->opts,
     232             :                              state->services, state->count,
     233             :                              &state->higher_usn);
     234           0 :     if (ret) {
     235           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     236             :               "Failed to store services.\n");
     237           0 :         tevent_req_error(req, ret);
     238           0 :         return;
     239             :     }
     240             : 
     241           0 :     DEBUG(SSSDBG_TRACE_INTERNAL,
     242             :           "Saving %zu services - Done\n", state->count);
     243             : 
     244           0 :     tevent_req_done(req);
     245             : }
     246             : 
     247             : static errno_t
     248           0 : sdap_save_services(TALLOC_CTX *mem_ctx,
     249             :                    struct sysdb_ctx *sysdb,
     250             :                    struct sss_domain_info *dom,
     251             :                    struct sdap_options *opts,
     252             :                    struct sysdb_attrs **services,
     253             :                    size_t num_services,
     254             :                    char **_usn_value)
     255             : {
     256             :     errno_t ret, sret;
     257             :     time_t now;
     258             :     size_t i;
     259           0 :     bool in_transaction = false;
     260           0 :     char *higher_usn = NULL;
     261             :     char *usn_value;
     262             :     TALLOC_CTX *tmp_ctx;
     263             : 
     264           0 :     if (num_services == 0) {
     265             :         /* Nothing to do */
     266           0 :         return ENOENT;
     267             :     }
     268             : 
     269           0 :     tmp_ctx = talloc_new(NULL);
     270           0 :     if (!tmp_ctx) {
     271           0 :         return ENOMEM;
     272             :     }
     273             : 
     274           0 :     ret = sysdb_transaction_start(sysdb);
     275           0 :     if (ret != EOK) {
     276           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
     277           0 :         goto done;
     278             :     }
     279             : 
     280           0 :     in_transaction = true;
     281             : 
     282           0 :     now = time(NULL);
     283           0 :     for (i = 0; i < num_services; i++) {
     284           0 :         usn_value = NULL;
     285             : 
     286           0 :         ret = sdap_save_service(tmp_ctx, sysdb, opts, dom,
     287           0 :                                 services[i],
     288             :                                 &usn_value, now);
     289             : 
     290             :         /* Do not fail completely on errors.
     291             :          * Just report the failure to save and go on */
     292           0 :         if (ret) {
     293           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     294             :                   "Failed to store service %zu. Ignoring.\n", i);
     295             :         } else {
     296           0 :             DEBUG(SSSDBG_TRACE_INTERNAL,
     297             :                   "Service [%zu/%zu] processed!\n", i, num_services);
     298             :         }
     299             : 
     300           0 :         if (usn_value) {
     301           0 :             if (higher_usn) {
     302           0 :                 if ((strlen(usn_value) > strlen(higher_usn)) ||
     303           0 :                     (strcmp(usn_value, higher_usn) > 0)) {
     304           0 :                     talloc_zfree(higher_usn);
     305           0 :                     higher_usn = usn_value;
     306             :                 } else {
     307           0 :                     talloc_zfree(usn_value);
     308             :                 }
     309             :             } else {
     310           0 :                 higher_usn = usn_value;
     311             :             }
     312             :         }
     313             :     }
     314             : 
     315           0 :     ret = sysdb_transaction_commit(sysdb);
     316           0 :     if (ret != EOK) {
     317           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     318             :               "Failed to commit transaction!\n");
     319           0 :         goto done;
     320             :     }
     321           0 :     in_transaction = false;
     322             : 
     323           0 :     if (_usn_value) {
     324           0 :         *_usn_value = talloc_steal(mem_ctx, higher_usn);
     325             :     }
     326             : 
     327             : done:
     328           0 :     if (in_transaction) {
     329           0 :         sret = sysdb_transaction_cancel(sysdb);
     330           0 :         if (sret != EOK) {
     331           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     332             :                   "Failed to cancel transaction!\n");
     333             :         }
     334             :     }
     335           0 :     talloc_free(tmp_ctx);
     336           0 :     return ret;
     337             : }
     338             : 
     339             : static errno_t
     340           0 : sdap_save_service(TALLOC_CTX *mem_ctx,
     341             :                   struct sysdb_ctx *sysdb,
     342             :                   struct sdap_options *opts,
     343             :                   struct sss_domain_info *dom,
     344             :                   struct sysdb_attrs *attrs,
     345             :                   char **_usn_value,
     346             :                   time_t now)
     347             : {
     348             :     errno_t ret;
     349           0 :     TALLOC_CTX *tmp_ctx = NULL;
     350             :     struct sysdb_attrs *svc_attrs;
     351             :     struct ldb_message_element *el;
     352           0 :     char *usn_value = NULL;
     353           0 :     const char *name = NULL;
     354             :     const char **aliases;
     355             :     const char **protocols;
     356             :     const char **cased_protocols;
     357             :     const char **store_protocols;
     358             :     char **missing;
     359             :     uint16_t port;
     360             :     uint64_t cache_timeout;
     361             : 
     362           0 :     DEBUG(SSSDBG_TRACE_ALL, "Saving service\n");
     363             : 
     364           0 :     tmp_ctx = talloc_new(NULL);
     365           0 :     if (!tmp_ctx) {
     366           0 :         ret = ENOMEM;
     367           0 :         goto done;
     368             :     }
     369             : 
     370           0 :     svc_attrs = sysdb_new_attrs(tmp_ctx);
     371           0 :     if (!svc_attrs) {
     372           0 :         ret = ENOMEM;
     373           0 :         goto done;
     374             :     }
     375             : 
     376             :     /* Identify the primary name of this services */
     377           0 :     ret = sysdb_attrs_primary_name(
     378             :             sysdb, attrs,
     379           0 :             opts->service_map[SDAP_AT_SERVICE_NAME].name,
     380             :             &name);
     381           0 :     if (ret != EOK) {
     382           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     383             :               "Could not determine the primary name of the service\n");
     384           0 :         goto done;
     385             :     }
     386             : 
     387           0 :     DEBUG(SSSDBG_TRACE_INTERNAL, "Primary name: [%s]\n", name);
     388             : 
     389             : 
     390             :     /* Handle any available aliases */
     391           0 :     ret = sysdb_attrs_get_aliases(tmp_ctx, attrs, name,
     392           0 :                                   !dom->case_sensitive,
     393           0 :                                   &aliases);
     394           0 :     if (ret != EOK) {
     395           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     396             :               "Failed to identify service aliases\n");
     397           0 :         goto done;
     398             :     }
     399             : 
     400             :     /* Get the port number */
     401           0 :     ret = sysdb_attrs_get_uint16_t(attrs, SYSDB_SVC_PORT, &port);
     402           0 :     if (ret != EOK) {
     403           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     404             :               "Failed to identify service port: [%s]\n",
     405             :                strerror(ret));
     406           0 :         goto done;
     407             :     }
     408             : 
     409             :     /* Get the protocols this service offers on that port */
     410           0 :     ret = sysdb_attrs_get_string_array(attrs, SYSDB_SVC_PROTO,
     411             :                                        tmp_ctx, &protocols);
     412           0 :     if (ret != EOK) {
     413           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     414             :               "Failed to identify service protocols: [%s]\n",
     415             :                strerror(ret));
     416           0 :         goto done;
     417             :     }
     418             : 
     419           0 :     if (dom->case_sensitive == false) {
     420             :         /* Don't perform the extra mallocs if not necessary */
     421           0 :         ret = sss_get_cased_name_list(tmp_ctx, protocols,
     422           0 :                                       dom->case_sensitive, &cased_protocols);
     423           0 :         if (ret != EOK) {
     424           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     425             :                 "Failed to get case_sensitive protocols names: [%s]\n",
     426             :                 strerror(ret));
     427           0 :             goto done;
     428             :         }
     429             :     }
     430             : 
     431           0 :     store_protocols = dom->case_sensitive ? protocols : cased_protocols;
     432             : 
     433             :     /* Get the USN value, if available */
     434           0 :     ret = sysdb_attrs_get_el(attrs,
     435           0 :                       opts->service_map[SDAP_AT_SERVICE_USN].sys_name, &el);
     436           0 :     if (ret && ret != ENOENT) {
     437           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     438             :               "Failed to retrieve USN value: [%s]\n",
     439             :                strerror(ret));
     440           0 :         goto done;
     441             :     }
     442           0 :     if (ret == ENOENT || el->num_values == 0) {
     443           0 :         DEBUG(SSSDBG_TRACE_LIBS,
     444             :               "Original USN value is not available for [%s].\n",
     445             :                name);
     446             :     } else {
     447           0 :         ret = sysdb_attrs_add_string(svc_attrs,
     448           0 :                           opts->service_map[SDAP_AT_SERVICE_USN].sys_name,
     449           0 :                           (const char*)el->values[0].data);
     450           0 :         if (ret) {
     451           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
     452             :                   "Failed to add USN value: [%s]\n",
     453             :                    strerror(ret));
     454           0 :             goto done;
     455             :         }
     456           0 :         usn_value = talloc_strdup(tmp_ctx, (const char*)el->values[0].data);
     457           0 :         if (!usn_value) {
     458           0 :             ret = ENOMEM;
     459           0 :             goto done;
     460             :         }
     461             :     }
     462             : 
     463             :     /* Make sure to remove any extra attributes from the sysdb
     464             :      * that have been removed from LDAP
     465             :      */
     466           0 :     ret = list_missing_attrs(svc_attrs, opts->service_map, SDAP_OPTS_SERVICES,
     467             :                              attrs, &missing);
     468           0 :     if (ret != EOK) {
     469           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     470             :               "Failed to identify removed attributes: [%s]\n",
     471             :                strerror(ret));
     472           0 :         goto done;
     473             :     }
     474             : 
     475           0 :     cache_timeout = dom->service_timeout;
     476             : 
     477           0 :     ret = sysdb_store_service(dom, name, port, aliases, store_protocols,
     478             :                               svc_attrs, missing, cache_timeout, now);
     479           0 :     if (ret != EOK) {
     480           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     481             :               "Failed to store service in the sysdb: [%s]\n",
     482             :                strerror(ret));
     483           0 :         goto done;
     484             :     }
     485             : 
     486           0 :     *_usn_value = talloc_steal(mem_ctx, usn_value);
     487             : 
     488             : done:
     489           0 :     talloc_free(tmp_ctx);
     490           0 :     return ret;
     491             : }
     492             : 
     493             : errno_t
     494           0 : sdap_get_services_recv(TALLOC_CTX *mem_ctx,
     495             :                        struct tevent_req *req,
     496             :                        char **usn_value)
     497             : {
     498           0 :     struct sdap_get_services_state *state =
     499           0 :             tevent_req_data(req, struct sdap_get_services_state);
     500             : 
     501           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     502             : 
     503           0 :     if (usn_value) {
     504           0 :         *usn_value = talloc_steal(mem_ctx, state->higher_usn);
     505             :     }
     506             : 
     507           0 :     return EOK;
     508             : }
     509             : 
     510             : 
     511             : /* Enumeration routines */
     512             : 
     513             : struct enum_services_state {
     514             :     struct tevent_context *ev;
     515             :     struct sdap_id_ctx *id_ctx;
     516             :     struct sdap_id_op *op;
     517             :     struct sss_domain_info *domain;
     518             :     struct sysdb_ctx *sysdb;
     519             : 
     520             :     char *filter;
     521             :     const char **attrs;
     522             : };
     523             : 
     524             : static void
     525             : enum_services_op_done(struct tevent_req *subreq);
     526             : 
     527             : struct tevent_req *
     528           0 : enum_services_send(TALLOC_CTX *memctx,
     529             :                    struct tevent_context *ev,
     530             :                    struct sdap_id_ctx *id_ctx,
     531             :                    struct sdap_id_op *op,
     532             :                    bool purge)
     533             : {
     534             :     errno_t ret;
     535             :     struct tevent_req *req;
     536             :     struct tevent_req *subreq;
     537             :     struct enum_services_state *state;
     538             : 
     539           0 :     req = tevent_req_create(memctx, &state, struct enum_services_state);
     540           0 :     if (!req) return NULL;
     541             : 
     542           0 :     state->ev = ev;
     543           0 :     state->id_ctx = id_ctx;
     544           0 :     state->domain = id_ctx->be->domain;
     545           0 :     state->sysdb = id_ctx->be->domain->sysdb;
     546           0 :     state->op = op;
     547             : 
     548           0 :     if (id_ctx->srv_opts && id_ctx->srv_opts->max_service_value && !purge) {
     549           0 :         state->filter = talloc_asprintf(
     550             :                 state,
     551             :                 "(&(objectclass=%s)(%s=*)(%s=*)(%s=*)(%s>=%s)(!(%s=%s)))",
     552           0 :                 id_ctx->opts->service_map[SDAP_OC_SERVICE].name,
     553           0 :                 id_ctx->opts->service_map[SDAP_AT_SERVICE_NAME].name,
     554           0 :                 id_ctx->opts->service_map[SDAP_AT_SERVICE_PORT].name,
     555           0 :                 id_ctx->opts->service_map[SDAP_AT_SERVICE_PROTOCOL].name,
     556           0 :                 id_ctx->opts->service_map[SDAP_AT_SERVICE_USN].name,
     557           0 :                 id_ctx->srv_opts->max_service_value,
     558           0 :                 id_ctx->opts->service_map[SDAP_AT_SERVICE_USN].name,
     559           0 :                 id_ctx->srv_opts->max_service_value);
     560             :     } else {
     561           0 :         state->filter = talloc_asprintf(
     562             :                 state,
     563             :                 "(&(objectclass=%s)(%s=*)(%s=*)(%s=*))",
     564           0 :                 id_ctx->opts->service_map[SDAP_OC_SERVICE].name,
     565           0 :                 id_ctx->opts->service_map[SDAP_AT_SERVICE_NAME].name,
     566           0 :                 id_ctx->opts->service_map[SDAP_AT_SERVICE_PORT].name,
     567           0 :                 id_ctx->opts->service_map[SDAP_AT_SERVICE_PROTOCOL].name);
     568             :     }
     569           0 :     if (!state->filter) {
     570           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Failed to build base filter\n");
     571           0 :         ret = ENOMEM;
     572           0 :         goto fail;
     573             :     }
     574             : 
     575             :     /* TODO: handle attrs_type */
     576           0 :     ret = build_attrs_from_map(state, id_ctx->opts->service_map,
     577             :                                SDAP_OPTS_SERVICES, NULL,
     578           0 :                                &state->attrs, NULL);
     579           0 :     if (ret != EOK) goto fail;
     580             : 
     581           0 :     subreq = sdap_get_services_send(state, state->ev,
     582           0 :                                     state->domain, state->sysdb,
     583           0 :                                     state->id_ctx->opts,
     584           0 :                                     state->id_ctx->opts->sdom->service_search_bases,
     585           0 :                                     sdap_id_op_handle(state->op),
     586           0 :                                     state->attrs, state->filter,
     587           0 :                                     dp_opt_get_int(state->id_ctx->opts->basic,
     588             :                                                    SDAP_SEARCH_TIMEOUT),
     589             :                                     true);
     590           0 :     if (!subreq) {
     591           0 :         ret = ENOMEM;
     592           0 :         goto fail;
     593             :     }
     594           0 :     tevent_req_set_callback(subreq, enum_services_op_done, req);
     595             : 
     596           0 :     return req;
     597             : 
     598             : fail:
     599           0 :     tevent_req_error(req, ret);
     600           0 :     tevent_req_post(req, ev);
     601           0 :     return req;
     602             : }
     603             : 
     604             : static void
     605           0 : enum_services_op_done(struct tevent_req *subreq)
     606             : {
     607           0 :     struct tevent_req *req =
     608           0 :             tevent_req_callback_data(subreq, struct tevent_req);
     609           0 :     struct enum_services_state *state =
     610           0 :             tevent_req_data(req, struct enum_services_state);
     611             :     char *usn_value;
     612           0 :     char *endptr = NULL;
     613             :     unsigned usn_number;
     614             :     int ret;
     615             : 
     616           0 :     ret = sdap_get_services_recv(state, subreq, &usn_value);
     617           0 :     talloc_zfree(subreq);
     618           0 :     if (ret != EOK) {
     619           0 :         tevent_req_error(req, ret);
     620           0 :         return;
     621             :     }
     622             : 
     623           0 :     if (usn_value) {
     624           0 :         talloc_zfree(state->id_ctx->srv_opts->max_service_value);
     625           0 :         state->id_ctx->srv_opts->max_service_value =
     626           0 :                 talloc_steal(state->id_ctx, usn_value);
     627             : 
     628           0 :         usn_number = strtoul(usn_value, &endptr, 10);
     629           0 :         if ((endptr == NULL || (*endptr == '\0' && endptr != usn_value))
     630           0 :             && (usn_number > state->id_ctx->srv_opts->last_usn)) {
     631           0 :             state->id_ctx->srv_opts->last_usn = usn_number;
     632             :         }
     633             :     }
     634             : 
     635           0 :     DEBUG(SSSDBG_FUNC_DATA, "Services higher USN value: [%s]\n",
     636             :               state->id_ctx->srv_opts->max_service_value);
     637             : 
     638           0 :     tevent_req_done(req);
     639             : }
     640             : 
     641             : errno_t
     642           0 : enum_services_recv(struct tevent_req *req)
     643             : {
     644           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     645             : 
     646           0 :     return EOK;
     647             : }

Generated by: LCOV version 1.10