LCOV - code coverage report
Current view: top level - providers/ipa - ipa_sudo_async.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 503 0.0 %
Date: 2016-06-29 Functions: 0 23 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             : #include <dhash.h>
      24             : 
      25             : #include "providers/ldap/sdap_ops.h"
      26             : #include "providers/ldap/sdap_sudo_shared.h"
      27             : #include "providers/ipa/ipa_common.h"
      28             : #include "providers/ipa/ipa_hosts.h"
      29             : #include "providers/ipa/ipa_sudo.h"
      30             : #include "providers/ipa/ipa_dn.h"
      31             : #include "db/sysdb.h"
      32             : #include "db/sysdb_sudo.h"
      33             : 
      34             : struct ipa_hostinfo {
      35             :     size_t num_hosts;
      36             :     size_t num_hostgroups;
      37             :     struct sysdb_attrs **hosts;
      38             :     struct sysdb_attrs **hostgroups;
      39             : };
      40             : 
      41             : static char *
      42           0 : ipa_sudo_filter_append_origdn(char *filter,
      43             :                               struct sysdb_attrs *attrs,
      44             :                               const char *attr_name)
      45             : {
      46             :     const char *origdn;
      47             :     char *sanitizeddn;
      48             :     errno_t ret;
      49             : 
      50           0 :     ret = sysdb_attrs_get_string(attrs, SYSDB_ORIG_DN, &origdn);
      51           0 :     if (ret != EOK) {
      52           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get original DN "
      53             :               "[%d]: %s\n", ret, sss_strerror(ret));
      54           0 :         return NULL;
      55             :     }
      56             : 
      57           0 :     ret = sss_filter_sanitize(NULL, origdn, &sanitizeddn);
      58           0 :     if (ret != EOK) {
      59           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to sanitize DN "
      60             :               "[%d]: %s\n", ret, sss_strerror(ret));
      61           0 :         return NULL;
      62             :     }
      63             : 
      64           0 :     filter = talloc_asprintf_append(filter, "(%s=%s)", attr_name, sanitizeddn);
      65           0 :     talloc_free(sanitizeddn);
      66           0 :     if (filter == NULL) {
      67           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append() failed\n");
      68             :     }
      69             : 
      70           0 :     return filter;
      71             : }
      72             : 
      73             : /**
      74             :  * (|(hostCategory=ALL)(memberHost=$DN(fqdn))(memberHost=$DN(hostgroup))...)
      75             :  */
      76             : static char *
      77           0 : ipa_sudo_host_filter(TALLOC_CTX *mem_ctx,
      78             :                      struct ipa_hostinfo *host,
      79             :                      struct sdap_attr_map *map)
      80             : {
      81             :     TALLOC_CTX *tmp_ctx;
      82             :     char *filter;
      83             :     size_t i;
      84             : 
      85             :     /* If realloc fails we will free all data through tmp_ctx. */
      86           0 :     tmp_ctx = talloc_new(NULL);
      87           0 :     if (tmp_ctx == NULL) {
      88           0 :         return NULL;
      89             :     }
      90             : 
      91           0 :     filter = talloc_asprintf(tmp_ctx, "(!(%s=*))",
      92           0 :                              map[IPA_AT_SUDORULE_HOST].name);
      93           0 :     if (filter == NULL) {
      94           0 :         goto fail;
      95             :     }
      96             : 
      97             :     /* Append hostCategory=ALL */
      98           0 :     filter = talloc_asprintf_append(filter, "(%s=ALL)",
      99           0 :                                     map[IPA_AT_SUDORULE_HOSTCATEGORY].name);
     100           0 :     if (filter == NULL) {
     101           0 :         goto fail;
     102             :     }
     103             : 
     104             :     /* Append client machine */
     105           0 :     for (i = 0; i < host->num_hosts; i++) {
     106           0 :         filter = ipa_sudo_filter_append_origdn(filter, host->hosts[i],
     107           0 :                                                map[IPA_AT_SUDORULE_HOST].name);
     108           0 :         if (filter == NULL) {
     109           0 :             goto fail;
     110             :         }
     111             :     }
     112             : 
     113             :     /* Append hostgroups */
     114           0 :     for (i = 0; i < host->num_hostgroups; i++) {
     115           0 :         filter = ipa_sudo_filter_append_origdn(filter, host->hostgroups[i],
     116           0 :                                                map[IPA_AT_SUDORULE_HOST].name);
     117           0 :         if (filter == NULL) {
     118           0 :             goto fail;
     119             :         }
     120             :     }
     121             : 
     122             :     /* OR filters */
     123           0 :     filter = talloc_asprintf(tmp_ctx, "(|%s)", filter);
     124           0 :     if (filter == NULL) {
     125           0 :         goto fail;
     126             :     }
     127             : 
     128           0 :     talloc_steal(mem_ctx, filter);
     129           0 :     talloc_free(tmp_ctx);
     130           0 :     return filter;
     131             : 
     132             : fail:
     133           0 :     talloc_free(tmp_ctx);
     134           0 :     return NULL;
     135             : }
     136             : 
     137             : static errno_t
     138           0 : ipa_sudo_highest_usn(TALLOC_CTX *mem_ctx,
     139             :                      struct sysdb_attrs **attrs,
     140             :                      size_t num_attrs,
     141             :                      char **current_usn)
     142             : {
     143             :     errno_t ret;
     144             :     char *usn;
     145             : 
     146           0 :     ret = sysdb_get_highest_usn(mem_ctx, attrs, num_attrs, &usn);
     147           0 :     if (ret != EOK) {
     148           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get highest USN [%d]: %s\n",
     149             :               ret, sss_strerror(ret));
     150           0 :         return ret;
     151             :     }
     152             : 
     153           0 :     if (sysdb_compare_usn(usn, *current_usn) > 0) {
     154           0 :         talloc_free(*current_usn);
     155           0 :         *current_usn = usn;
     156           0 :         return EOK;
     157             :     }
     158             : 
     159           0 :     talloc_free(usn);
     160           0 :     return EOK;
     161             : }
     162             : 
     163             : static errno_t
     164           0 : ipa_sudo_assoc_rules_filter(TALLOC_CTX *mem_ctx,
     165             :                             struct sysdb_attrs **cmdgroups,
     166             :                             size_t num_cmdgroups,
     167             :                             char **_filter)
     168             : {
     169             :     TALLOC_CTX *tmp_ctx;
     170             :     const char *origdn;
     171             :     char *sanitized;
     172             :     char *filter;
     173             :     errno_t ret;
     174             :     size_t i;
     175             : 
     176           0 :     if (num_cmdgroups == 0) {
     177           0 :         return ENOENT;
     178             :     }
     179             : 
     180           0 :     tmp_ctx = talloc_new(NULL);
     181           0 :     if (tmp_ctx == NULL) {
     182           0 :         return ENOMEM;
     183             :     }
     184             : 
     185           0 :     filter = talloc_strdup(tmp_ctx, "");
     186           0 :     if (filter == NULL) {
     187           0 :         ret = ENOMEM;
     188           0 :         goto done;
     189             :     }
     190             : 
     191           0 :     for (i = 0; i < num_cmdgroups; i++) {
     192           0 :         ret = sysdb_attrs_get_string(cmdgroups[i], SYSDB_ORIG_DN, &origdn);
     193           0 :         if (ret != EOK) {
     194           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get original dn [%d]: %s\n",
     195             :                   ret, sss_strerror(ret));
     196           0 :             ret = ERR_INTERNAL;
     197           0 :             goto done;
     198             :         }
     199             : 
     200           0 :         ret = sss_filter_sanitize(tmp_ctx, origdn, &sanitized);
     201           0 :         if (ret != EOK) {
     202           0 :             goto done;
     203             :         }
     204             : 
     205           0 :         filter = talloc_asprintf_append(filter, "(%s=%s)",
     206             :                                         SYSDB_IPA_SUDORULE_ORIGCMD, sanitized);
     207           0 :         if (filter == NULL) {
     208           0 :             ret = ENOMEM;
     209           0 :             goto done;
     210             :         }
     211             :     }
     212             : 
     213           0 :     filter = talloc_asprintf(tmp_ctx, "(&(objectClass=%s)(|%s)))",
     214             :                              SYSDB_SUDO_CACHE_OC, filter);
     215           0 :     if (filter == NULL) {
     216           0 :         ret = ENOMEM;
     217           0 :         goto done;
     218             :     }
     219             : 
     220           0 :     *_filter = talloc_steal(mem_ctx, filter);
     221           0 :     ret = EOK;
     222             : 
     223             : done:
     224           0 :     talloc_free(tmp_ctx);
     225           0 :     return ret;
     226             : }
     227             : 
     228             : static errno_t
     229           0 : ipa_sudo_assoc_rules(TALLOC_CTX *mem_ctx,
     230             :                      struct sss_domain_info *domain,
     231             :                      struct sysdb_attrs **cmdgroups,
     232             :                      size_t num_cmdgroups,
     233             :                      struct sysdb_attrs ***_rules,
     234             :                      size_t *_num_rules)
     235             : {
     236             :     TALLOC_CTX *tmp_ctx;
     237           0 :     const char *attrs[] = {SYSDB_NAME, NULL};
     238             :     struct sysdb_attrs **rules;
     239             :     struct ldb_message **msgs;
     240             :     size_t num_rules;
     241             :     char *filter;
     242             :     errno_t ret;
     243             : 
     244           0 :     tmp_ctx = talloc_new(NULL);
     245           0 :     if (tmp_ctx == NULL) {
     246           0 :         return ENOMEM;
     247             :     }
     248             : 
     249           0 :     ret = ipa_sudo_assoc_rules_filter(tmp_ctx, cmdgroups,
     250             :                                       num_cmdgroups, &filter);
     251           0 :     if (ret != EOK) {
     252           0 :         goto done;
     253             :     }
     254             : 
     255           0 :     ret = sysdb_search_custom(tmp_ctx, domain, filter,
     256             :                               SUDORULE_SUBDIR, attrs,
     257             :                               &num_rules, &msgs);
     258           0 :     if (ret == ENOENT) {
     259           0 :         *_rules = NULL;
     260           0 :         *_num_rules = 0;
     261           0 :         ret = EOK;
     262           0 :         goto done;
     263           0 :     } else if (ret != EOK) {
     264           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up sudo rules [%d]: %s\n",
     265             :               ret, sss_strerror(ret));
     266           0 :         goto done;
     267             :     }
     268             : 
     269           0 :     ret = sysdb_msg2attrs(tmp_ctx, num_rules, msgs, &rules);
     270           0 :     if (ret != EOK) {
     271           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Could not convert ldb message to "
     272             :               "sysdb_attrs [%d]: %s\n", ret, sss_strerror(ret));
     273           0 :         goto done;
     274             :     }
     275             : 
     276           0 :     *_rules = talloc_steal(mem_ctx, rules);
     277           0 :     *_num_rules = num_rules;
     278             : 
     279             : done:
     280           0 :     talloc_free(tmp_ctx);
     281           0 :     return ret;
     282             : }
     283             : 
     284             : static errno_t
     285           0 : ipa_sudo_filter_rules_bycmdgroups(TALLOC_CTX *mem_ctx,
     286             :                                   struct sss_domain_info *domain,
     287             :                                   struct sysdb_attrs **cmdgroups,
     288             :                                   size_t num_cmdgroups,
     289             :                                   struct sdap_attr_map *map_rule,
     290             :                                   char **_filter)
     291             : {
     292             :     TALLOC_CTX *tmp_ctx;
     293             :     struct sysdb_attrs **rules;
     294             :     size_t num_rules;
     295             :     const char *name;
     296             :     char *sanitized;
     297             :     char *filter;
     298             :     errno_t ret;
     299             :     size_t i;
     300             : 
     301           0 :     if (num_cmdgroups == 0) {
     302           0 :         *_filter = NULL;
     303           0 :         return EOK;
     304             :     }
     305             : 
     306           0 :     tmp_ctx = talloc_new(NULL);
     307           0 :     if (tmp_ctx == NULL) {
     308           0 :         return ENOMEM;
     309             :     }
     310             : 
     311           0 :     ret = ipa_sudo_assoc_rules(tmp_ctx, domain, cmdgroups, num_cmdgroups,
     312             :                                &rules, &num_rules);
     313           0 :     if (ret != EOK) {
     314           0 :         goto done;
     315             :     }
     316             : 
     317           0 :     if (num_rules == 0) {
     318           0 :         *_filter = NULL;
     319           0 :         ret = EOK;
     320           0 :         goto done;
     321             :     }
     322             : 
     323           0 :     filter = talloc_strdup(tmp_ctx, "");
     324           0 :     if (filter == NULL) {
     325           0 :         ret = ENOMEM;
     326           0 :         goto done;
     327             :     }
     328             : 
     329           0 :     for (i = 0; i < num_rules; i++) {
     330           0 :         ret = sysdb_attrs_get_string(rules[i], SYSDB_NAME, &name);
     331           0 :         if (ret != EOK) {
     332           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get name [%d]: %s\n",
     333             :                   ret, sss_strerror(ret));
     334           0 :             goto done;
     335             :         }
     336             : 
     337           0 :         ret = sss_filter_sanitize(tmp_ctx, name, &sanitized);
     338           0 :         if (ret != EOK) {
     339           0 :             goto done;
     340             :         }
     341             : 
     342           0 :         filter = talloc_asprintf_append(filter, "(%s=%s)",
     343           0 :                     map_rule[IPA_AT_SUDORULE_NAME].name, sanitized);
     344           0 :         if (filter == NULL) {
     345           0 :             ret = ENOMEM;
     346           0 :             goto done;
     347             :         }
     348             :     }
     349             : 
     350           0 :     filter = talloc_asprintf(tmp_ctx, "(|%s)", filter);
     351           0 :     if (filter == NULL) {
     352           0 :         ret = ENOMEM;
     353           0 :         goto done;
     354             :     }
     355             : 
     356           0 :     *_filter = talloc_steal(mem_ctx, filter);
     357           0 :     ret = EOK;
     358             : 
     359             : done:
     360           0 :     talloc_free(tmp_ctx);
     361           0 :     return ret;
     362             : }
     363             : 
     364             : struct ipa_sudo_fetch_state {
     365             :     struct tevent_context *ev;
     366             :     struct sysdb_ctx *sysdb;
     367             :     struct sss_domain_info *domain;
     368             :     struct ipa_sudo_ctx *sudo_ctx;
     369             :     struct sdap_options *sdap_opts;
     370             :     struct ipa_hostinfo *host;
     371             :     struct sdap_handle *sh;
     372             :     const char *search_filter;
     373             :     const char *cmdgroups_filter;
     374             : 
     375             :     struct sdap_attr_map *map_cmdgroup;
     376             :     struct sdap_attr_map *map_rule;
     377             :     struct sdap_attr_map *map_cmd;
     378             :     struct sdap_search_base **sudo_sb;
     379             : 
     380             :     struct ipa_sudo_conv *conv;
     381             :     struct sysdb_attrs **rules;
     382             :     size_t num_rules;
     383             :     char *usn;
     384             : };
     385             : 
     386             : static errno_t ipa_sudo_fetch_addtl_cmdgroups(struct tevent_req *req);
     387             : static void ipa_sudo_fetch_addtl_cmdgroups_done(struct tevent_req *subreq);
     388             : static errno_t ipa_sudo_fetch_rules(struct tevent_req *req);
     389             : static void ipa_sudo_fetch_rules_done(struct tevent_req *subreq);
     390             : static errno_t ipa_sudo_fetch_cmdgroups(struct tevent_req *req);
     391             : static void ipa_sudo_fetch_cmdgroups_done(struct tevent_req *subreq);
     392             : static errno_t ipa_sudo_fetch_cmds(struct tevent_req *req);
     393             : static void ipa_sudo_fetch_cmds_done(struct tevent_req *subreq);
     394             : static void ipa_sudo_fetch_done(struct tevent_req *req);
     395             : 
     396             : static struct tevent_req *
     397           0 : ipa_sudo_fetch_send(TALLOC_CTX *mem_ctx,
     398             :                     struct tevent_context *ev,
     399             :                     struct sss_domain_info *domain,
     400             :                     struct sysdb_ctx *sysdb,
     401             :                     struct ipa_sudo_ctx *sudo_ctx,
     402             :                     struct ipa_hostinfo *host,
     403             :                     struct sdap_attr_map *map_user,
     404             :                     struct sdap_attr_map *map_group,
     405             :                     struct sdap_attr_map *map_host,
     406             :                     struct sdap_attr_map *map_hostgroup,
     407             :                     struct sdap_handle *sh,
     408             :                     const char *cmdgroups_filter,
     409             :                     const char *search_filter)
     410             : {
     411           0 :     struct ipa_sudo_fetch_state *state = NULL;
     412           0 :     struct tevent_req *req = NULL;
     413             :     errno_t ret;
     414             : 
     415           0 :     req = tevent_req_create(mem_ctx, &state,
     416             :                             struct ipa_sudo_fetch_state);
     417           0 :     if (req == NULL) {
     418           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
     419           0 :         return NULL;
     420             :     }
     421             : 
     422           0 :     state->ev = ev;
     423           0 :     state->sysdb = sysdb;
     424           0 :     state->domain = domain;
     425           0 :     state->sudo_ctx = sudo_ctx;
     426           0 :     state->sdap_opts = sudo_ctx->sdap_opts;
     427           0 :     state->host = host;
     428           0 :     state->sh = sh;
     429           0 :     state->search_filter = search_filter == NULL ? "" : search_filter;
     430           0 :     state->cmdgroups_filter = cmdgroups_filter;
     431             : 
     432           0 :     state->map_cmdgroup = sudo_ctx->sudocmdgroup_map;
     433           0 :     state->map_rule = sudo_ctx->sudorule_map;
     434           0 :     state->map_cmd = sudo_ctx->sudocmd_map;
     435           0 :     state->sudo_sb = sudo_ctx->sudo_sb;
     436             : 
     437           0 :     state->conv = ipa_sudo_conv_init(state, sysdb, state->map_rule,
     438           0 :                                      state->map_cmdgroup, state->map_cmd,
     439             :                                      map_user, map_group, map_host,
     440             :                                      map_hostgroup);
     441           0 :     if (state->conv == NULL) {
     442           0 :         ret = ENOMEM;
     443           0 :         goto immediately;
     444             :     }
     445             : 
     446           0 :     if (state->cmdgroups_filter != NULL) {
     447             :         /* We need to fetch additional cmdgroups that may not be revealed
     448             :          * during normal search. Such as when using entryUSN filter in smart
     449             :          * refresh, some command groups may have change but none rule was
     450             :          * modified but we need to fetch associated rules anyway. */
     451           0 :         ret = ipa_sudo_fetch_addtl_cmdgroups(req);
     452             :     } else {
     453           0 :         ret = ipa_sudo_fetch_rules(req);
     454             :     }
     455           0 :     if (ret != EAGAIN) {
     456           0 :         goto immediately;
     457             :     }
     458             : 
     459           0 :     return req;
     460             : 
     461             : immediately:
     462           0 :     if (ret == EOK) {
     463           0 :         tevent_req_done(req);
     464             :     } else {
     465           0 :         tevent_req_error(req, ret);
     466             :     }
     467           0 :     tevent_req_post(req, state->ev);
     468             : 
     469           0 :     return req;
     470             : }
     471             : 
     472             : static errno_t
     473           0 : ipa_sudo_fetch_addtl_cmdgroups(struct tevent_req *req)
     474             : {
     475             :     struct ipa_sudo_fetch_state *state;
     476             :     struct tevent_req *subreq;
     477             :     struct sdap_attr_map *map;
     478             :     char *filter;
     479             : 
     480           0 :     DEBUG(SSSDBG_TRACE_FUNC, "About to fetch additional command groups\n");
     481             : 
     482           0 :     state = tevent_req_data(req, struct ipa_sudo_fetch_state);
     483           0 :     map = state->map_cmdgroup;
     484             : 
     485           0 :     filter = talloc_asprintf(state, "(&(objectClass=%s)%s)",
     486             :                              map[IPA_OC_SUDOCMDGROUP].name,
     487             :                              state->cmdgroups_filter);
     488           0 :     if (filter == NULL) {
     489           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n");
     490           0 :         return ENOMEM;
     491             :     }
     492             : 
     493           0 :     subreq = sdap_search_bases_send(state, state->ev, state->sdap_opts,
     494             :                                     state->sh, state->sudo_sb, map, true, 0,
     495             :                                     filter, NULL);
     496           0 :     if (subreq == NULL) {
     497           0 :         return ENOMEM;
     498             :     }
     499             : 
     500           0 :     tevent_req_set_callback(subreq, ipa_sudo_fetch_addtl_cmdgroups_done, req);
     501           0 :     return EAGAIN;
     502             : }
     503             : 
     504             : static void
     505           0 : ipa_sudo_fetch_addtl_cmdgroups_done(struct tevent_req *subreq)
     506             : {
     507           0 :     struct ipa_sudo_fetch_state *state = NULL;
     508           0 :     struct tevent_req *req = NULL;
     509             :     struct sysdb_attrs **attrs;
     510             :     size_t num_attrs;
     511             :     char *filter;
     512             :     errno_t ret;
     513             : 
     514           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     515           0 :     state = tevent_req_data(req, struct ipa_sudo_fetch_state);
     516             : 
     517           0 :     ret = sdap_search_bases_recv(subreq, state, &num_attrs, &attrs);
     518           0 :     talloc_zfree(subreq);
     519           0 :     if (ret != EOK) {
     520           0 :         goto done;
     521             :     }
     522             : 
     523           0 :     DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu additional command groups\n",
     524             :           num_attrs);
     525             : 
     526           0 :     ret = ipa_sudo_filter_rules_bycmdgroups(state, state->domain, attrs,
     527             :                                             num_attrs, state->map_rule,
     528             :                                             &filter);
     529           0 :     if (ret != EOK) {
     530           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to construct rules filter "
     531             :               "[%d]: %s\n", ret, sss_strerror(ret));
     532           0 :         goto done;
     533             :     }
     534             : 
     535           0 :     state->search_filter = sdap_or_filters(state, state->search_filter, filter);
     536           0 :     if (state->search_filter == NULL) {
     537           0 :         ret = ENOMEM;
     538           0 :         goto done;
     539             :     }
     540             : 
     541           0 :     ret = ipa_sudo_fetch_rules(req);
     542             : 
     543             : done:
     544           0 :     if (ret == EOK) {
     545           0 :         ipa_sudo_fetch_done(req);
     546           0 :     } else if (ret != EAGAIN) {
     547           0 :         tevent_req_error(req, ret);
     548             :     }
     549             : 
     550           0 :     return;
     551             : }
     552             : 
     553             : static errno_t
     554           0 : ipa_sudo_fetch_rules(struct tevent_req *req)
     555             : {
     556             :     struct ipa_sudo_fetch_state *state;
     557             :     struct tevent_req *subreq;
     558             :     struct sdap_attr_map *map;
     559             :     char *host_filter;
     560             :     char *filter;
     561             : 
     562           0 :     DEBUG(SSSDBG_TRACE_FUNC, "About to fetch sudo rules\n");
     563             : 
     564           0 :     state = tevent_req_data(req, struct ipa_sudo_fetch_state);
     565           0 :     map = state->map_rule;
     566             : 
     567           0 :     host_filter = ipa_sudo_host_filter(state, state->host, map);
     568           0 :     if (host_filter == NULL) {
     569           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build host filter\n");
     570           0 :         return ENOMEM;
     571             :     }
     572             : 
     573           0 :     filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=TRUE)%s%s)",
     574             :                              map[IPA_OC_SUDORULE].name,
     575           0 :                              map[IPA_AT_SUDORULE_ENABLED].name,
     576             :                              host_filter, state->search_filter);
     577           0 :     talloc_zfree(host_filter);
     578           0 :     if (filter == NULL) {
     579           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n");
     580           0 :         return ENOMEM;
     581             :     }
     582             : 
     583           0 :     subreq = sdap_search_bases_send(state, state->ev, state->sdap_opts,
     584             :                                     state->sh, state->sudo_sb, map, true, 0,
     585             :                                     filter, NULL);
     586           0 :     if (subreq == NULL) {
     587           0 :         return ENOMEM;
     588             :     }
     589             : 
     590           0 :     tevent_req_set_callback(subreq, ipa_sudo_fetch_rules_done, req);
     591           0 :     return EAGAIN;
     592             : }
     593             : 
     594             : static void
     595           0 : ipa_sudo_fetch_rules_done(struct tevent_req *subreq)
     596             : {
     597           0 :     struct ipa_sudo_fetch_state *state = NULL;
     598           0 :     struct tevent_req *req = NULL;
     599             :     struct sysdb_attrs **attrs;
     600             :     size_t num_attrs;
     601             :     errno_t ret;
     602             : 
     603           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     604           0 :     state = tevent_req_data(req, struct ipa_sudo_fetch_state);
     605             : 
     606           0 :     ret = sdap_search_bases_recv(subreq, state, &num_attrs, &attrs);
     607           0 :     talloc_zfree(subreq);
     608           0 :     if (ret != EOK) {
     609           0 :         goto done;
     610             :     }
     611             : 
     612           0 :     DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu sudo rules\n", num_attrs);
     613             : 
     614           0 :     ret = ipa_sudo_conv_rules(state->conv, attrs, num_attrs);
     615           0 :     if (ret != EOK) {
     616           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed when converting rules "
     617             :               "[%d]: %s\n", ret, sss_strerror(ret));
     618           0 :         goto done;
     619             :     }
     620             : 
     621           0 :     ret = ipa_sudo_highest_usn(state, attrs, num_attrs, &state->usn);
     622           0 :     if (ret != EOK) {
     623           0 :         goto done;
     624             :     }
     625             : 
     626           0 :     ret = ipa_sudo_fetch_cmdgroups(req);
     627             : 
     628             : done:
     629           0 :     if (ret == EOK) {
     630           0 :         ipa_sudo_fetch_done(req);
     631           0 :     } else if (ret != EAGAIN) {
     632           0 :         tevent_req_error(req, ret);
     633             :     }
     634             : 
     635           0 :     return;
     636             : }
     637             : 
     638             : static errno_t
     639           0 : ipa_sudo_fetch_cmdgroups(struct tevent_req *req)
     640             : {
     641             :     struct ipa_sudo_fetch_state *state;
     642             :     struct tevent_req *subreq;
     643             :     char *filter;
     644             : 
     645           0 :     DEBUG(SSSDBG_TRACE_FUNC, "About to fetch sudo command groups\n");
     646             : 
     647           0 :     state = tevent_req_data(req, struct ipa_sudo_fetch_state);
     648             : 
     649           0 :     if (ipa_sudo_conv_has_cmdgroups(state->conv)) {
     650           0 :         DEBUG(SSSDBG_TRACE_FUNC, "No command groups needs to be downloaded\n");
     651           0 :         return ipa_sudo_fetch_cmds(req);
     652             :     }
     653             : 
     654           0 :     filter = ipa_sudo_conv_cmdgroup_filter(state, state->conv);
     655           0 :     if (filter == NULL) {
     656           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n");
     657           0 :         return ENOMEM;
     658             :     }
     659             : 
     660           0 :     subreq = sdap_search_bases_send(state, state->ev, state->sdap_opts,
     661             :                                     state->sh, state->sudo_sb,
     662             :                                     state->map_cmdgroup, true, 0,
     663             :                                     filter, NULL);
     664           0 :     if (subreq == NULL) {
     665           0 :         return ENOMEM;
     666             :     }
     667             : 
     668           0 :     tevent_req_set_callback(subreq, ipa_sudo_fetch_cmdgroups_done, req);
     669           0 :     return EAGAIN;
     670             : }
     671             : 
     672             : static void
     673           0 : ipa_sudo_fetch_cmdgroups_done(struct tevent_req *subreq)
     674             : {
     675           0 :     struct ipa_sudo_fetch_state *state = NULL;
     676           0 :     struct tevent_req *req = NULL;
     677             :     struct sysdb_attrs **attrs;
     678             :     size_t num_attrs;
     679             :     errno_t ret;
     680             : 
     681           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     682           0 :     state = tevent_req_data(req, struct ipa_sudo_fetch_state);
     683             : 
     684           0 :     ret = sdap_search_bases_recv(subreq, state, &num_attrs, &attrs);
     685           0 :     talloc_zfree(subreq);
     686           0 :     if (ret != EOK) {
     687           0 :         goto done;
     688             :     }
     689             : 
     690           0 :     DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu sudo command groups\n",
     691             :           num_attrs);
     692             : 
     693           0 :     ret = ipa_sudo_conv_cmdgroups(state->conv, attrs, num_attrs);
     694           0 :     if (ret != EOK) {
     695           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed when converting command groups "
     696             :               "[%d]: %s\n", ret, sss_strerror(ret));
     697           0 :         goto done;
     698             :     }
     699             : 
     700           0 :     ret = ipa_sudo_highest_usn(state, attrs, num_attrs, &state->usn);
     701           0 :     if (ret != EOK) {
     702           0 :         goto done;
     703             :     }
     704             : 
     705           0 :     ret = ipa_sudo_fetch_cmds(req);
     706             : 
     707             : done:
     708           0 :     if (ret == EOK) {
     709           0 :         ipa_sudo_fetch_done(req);
     710           0 :     } else if (ret != EAGAIN) {
     711           0 :         tevent_req_error(req, ret);
     712             :     }
     713             : 
     714           0 :     return;
     715             : }
     716             : 
     717             : static errno_t
     718           0 : ipa_sudo_fetch_cmds(struct tevent_req *req)
     719             : {
     720             :     struct ipa_sudo_fetch_state *state;
     721             :     struct tevent_req *subreq;
     722             :     char *filter;
     723             : 
     724           0 :     DEBUG(SSSDBG_TRACE_FUNC, "About to fetch sudo commands\n");
     725             : 
     726           0 :     state = tevent_req_data(req, struct ipa_sudo_fetch_state);
     727             : 
     728           0 :     if (ipa_sudo_conv_has_cmds(state->conv)) {
     729           0 :         DEBUG(SSSDBG_TRACE_FUNC, "No commands needs to be downloaded\n");
     730           0 :         return EOK;
     731             :     }
     732             : 
     733           0 :     filter = ipa_sudo_conv_cmd_filter(state, state->conv);
     734           0 :     if (filter == NULL) {
     735           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n");
     736           0 :         return ENOMEM;
     737             :     }
     738             : 
     739           0 :     subreq = sdap_search_bases_send(state, state->ev, state->sdap_opts,
     740             :                                     state->sh, state->sudo_sb,
     741             :                                     state->map_cmd, true, 0,
     742             :                                     filter, NULL);
     743           0 :     if (subreq == NULL) {
     744           0 :         return ENOMEM;
     745             :     }
     746             : 
     747           0 :     tevent_req_set_callback(subreq, ipa_sudo_fetch_cmds_done, req);
     748           0 :     return EAGAIN;
     749             : }
     750             : 
     751             : static void
     752           0 : ipa_sudo_fetch_cmds_done(struct tevent_req *subreq)
     753             : {
     754           0 :     struct ipa_sudo_fetch_state *state = NULL;
     755           0 :     struct tevent_req *req = NULL;
     756             :     struct sysdb_attrs **attrs;
     757             :     size_t num_attrs;
     758             :     errno_t ret;
     759             : 
     760           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     761           0 :     state = tevent_req_data(req, struct ipa_sudo_fetch_state);
     762             : 
     763           0 :     ret = sdap_search_bases_recv(subreq, state, &num_attrs, &attrs);
     764           0 :     talloc_zfree(subreq);
     765           0 :     if (ret != EOK) {
     766           0 :         goto done;
     767             :     }
     768             : 
     769           0 :     DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu sudo commands\n", num_attrs);
     770             : 
     771           0 :     ret = ipa_sudo_conv_cmds(state->conv, attrs, num_attrs);
     772           0 :     if (ret != EOK) {
     773           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed when converting commands "
     774             :               "[%d]: %s\n", ret, sss_strerror(ret));
     775           0 :         goto done;
     776             :     }
     777             : 
     778             : done:
     779           0 :     if (ret == EOK) {
     780           0 :         ipa_sudo_fetch_done(req);
     781           0 :     } else if (ret != EAGAIN) {
     782           0 :         tevent_req_error(req, ret);
     783             :     }
     784             : 
     785           0 :     return;
     786             : }
     787             : 
     788             : static void
     789           0 : ipa_sudo_fetch_done(struct tevent_req *req)
     790             : {
     791           0 :     struct ipa_sudo_fetch_state *state = NULL;
     792             :     errno_t ret;
     793             : 
     794           0 :     state = tevent_req_data(req, struct ipa_sudo_fetch_state);
     795             : 
     796           0 :     DEBUG(SSSDBG_TRACE_FUNC, "About to convert rules\n");
     797             : 
     798           0 :     ret = ipa_sudo_conv_result(state, state->conv,
     799             :                                &state->rules, &state->num_rules);
     800           0 :     if (ret != EOK) {
     801           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to convert rules [%d]: %s\n",
     802             :               ret, sss_strerror(ret));
     803           0 :         goto done;
     804             :     }
     805             : 
     806           0 :     ret = EOK;
     807             : 
     808             : done:
     809           0 :     if (ret != EOK) {
     810           0 :         tevent_req_error(req, ret);
     811           0 :         return;
     812             :     }
     813             : 
     814           0 :     tevent_req_done(req);
     815             : }
     816             : 
     817             : static errno_t
     818           0 : ipa_sudo_fetch_recv(TALLOC_CTX *mem_ctx,
     819             :                     struct tevent_req *req,
     820             :                     struct sysdb_attrs ***_rules,
     821             :                     size_t *_num_rules,
     822             :                     char **_usn)
     823             : {
     824           0 :     struct ipa_sudo_fetch_state *state = NULL;
     825           0 :     state = tevent_req_data(req, struct ipa_sudo_fetch_state);
     826             : 
     827           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     828             : 
     829           0 :     *_rules = talloc_steal(mem_ctx, state->rules);
     830           0 :     *_num_rules = state->num_rules;
     831           0 :     *_usn = talloc_steal(mem_ctx, state->usn);
     832             : 
     833           0 :     return EOK;
     834             : }
     835             : 
     836             : 
     837             : struct ipa_sudo_refresh_state {
     838             :     struct tevent_context *ev;
     839             :     struct sysdb_ctx *sysdb;
     840             :     struct sss_domain_info *domain;
     841             :     struct ipa_sudo_ctx *sudo_ctx;
     842             :     struct ipa_options *ipa_opts;
     843             :     struct sdap_options *sdap_opts;
     844             :     const char *cmdgroups_filter;
     845             :     const char *search_filter;
     846             :     const char *delete_filter;
     847             : 
     848             :     struct sdap_id_op *sdap_op;
     849             :     struct sdap_handle *sh;
     850             :     int dp_error;
     851             : 
     852             :     struct sysdb_attrs **rules;
     853             :     size_t num_rules;
     854             : };
     855             : 
     856             : static errno_t ipa_sudo_refresh_retry(struct tevent_req *req);
     857             : static void ipa_sudo_refresh_connect_done(struct tevent_req *subreq);
     858             : static void ipa_sudo_refresh_host_done(struct tevent_req *subreq);
     859             : static void ipa_sudo_refresh_done(struct tevent_req *subreq);
     860             : 
     861             : struct tevent_req *
     862           0 : ipa_sudo_refresh_send(TALLOC_CTX *mem_ctx,
     863             :                       struct tevent_context *ev,
     864             :                       struct ipa_sudo_ctx *sudo_ctx,
     865             :                       const char *cmdgroups_filter,
     866             :                       const char *search_filter,
     867             :                       const char *delete_filter)
     868             : {
     869             :     struct ipa_sudo_refresh_state *state;
     870             :     struct tevent_req *req;
     871             :     errno_t ret;
     872             : 
     873           0 :     req = tevent_req_create(mem_ctx, &state, struct ipa_sudo_refresh_state);
     874           0 :     if (req == NULL) {
     875           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
     876           0 :         return NULL;
     877             :     }
     878             : 
     879           0 :     state->ev = ev;
     880           0 :     state->sysdb = sudo_ctx->id_ctx->be->domain->sysdb;
     881           0 :     state->domain = sudo_ctx->id_ctx->be->domain;
     882           0 :     state->sudo_ctx = sudo_ctx;
     883           0 :     state->ipa_opts = sudo_ctx->ipa_opts;
     884           0 :     state->sdap_opts = sudo_ctx->sdap_opts;
     885           0 :     state->dp_error = DP_ERR_FATAL;
     886             : 
     887           0 :     state->sdap_op = sdap_id_op_create(state,
     888           0 :                                        sudo_ctx->id_ctx->conn->conn_cache);
     889           0 :     if (!state->sdap_op) {
     890           0 :         DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create() failed\n");
     891           0 :         ret = ENOMEM;
     892           0 :         goto immediately;
     893             :     }
     894             : 
     895           0 :     state->cmdgroups_filter = talloc_strdup(state, cmdgroups_filter);
     896           0 :     if (cmdgroups_filter != NULL && state->cmdgroups_filter == NULL) {
     897           0 :         ret = ENOMEM;
     898           0 :         goto immediately;
     899             :     }
     900             : 
     901           0 :     state->search_filter = talloc_strdup(state, search_filter);
     902           0 :     if (search_filter != NULL && state->search_filter == NULL) {
     903           0 :         ret = ENOMEM;
     904           0 :         goto immediately;
     905             :     }
     906             : 
     907           0 :     state->delete_filter = talloc_strdup(state, delete_filter);
     908           0 :     if (delete_filter != NULL && state->delete_filter == NULL) {
     909           0 :         ret = ENOMEM;
     910           0 :         goto immediately;
     911             :     }
     912             : 
     913           0 :     ret = ipa_sudo_refresh_retry(req);
     914           0 :     if (ret == EAGAIN) {
     915             :         /* asynchronous processing */
     916           0 :         return req;
     917             :     }
     918             : 
     919             : immediately:
     920           0 :     if (ret == EOK) {
     921           0 :         tevent_req_done(req);
     922             :     } else {
     923           0 :         tevent_req_error(req, ret);
     924             :     }
     925           0 :     tevent_req_post(req, state->ev);
     926             : 
     927           0 :     return req;
     928             : }
     929             : 
     930             : static errno_t
     931           0 : ipa_sudo_refresh_retry(struct tevent_req *req)
     932             : {
     933             :     struct ipa_sudo_refresh_state *state;
     934             :     struct tevent_req *subreq;
     935             :     int ret;
     936             : 
     937           0 :     state = tevent_req_data(req, struct ipa_sudo_refresh_state);
     938             : 
     939           0 :     subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret);
     940           0 :     if (subreq == NULL) {
     941           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_connect_send() failed: "
     942             :                                    "%d(%s)\n", ret, strerror(ret));
     943           0 :         return ret;
     944             :     }
     945             : 
     946           0 :     tevent_req_set_callback(subreq, ipa_sudo_refresh_connect_done, req);
     947             : 
     948           0 :     return EAGAIN;
     949             : }
     950             : 
     951             : static void
     952           0 : ipa_sudo_refresh_connect_done(struct tevent_req *subreq)
     953             : {
     954             :     struct ipa_sudo_refresh_state *state;
     955             :     const char *hostname;
     956             :     struct tevent_req *req;
     957             :     int dp_error;
     958             :     int ret;
     959             : 
     960           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     961           0 :     state = tevent_req_data(req, struct ipa_sudo_refresh_state);
     962             : 
     963           0 :     ret = sdap_id_op_connect_recv(subreq, &dp_error);
     964           0 :     talloc_zfree(subreq);
     965             : 
     966           0 :     if (ret != EOK) {
     967           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "SUDO LDAP connection failed "
     968             :                                    "[%d]: %s\n", ret, strerror(ret));
     969           0 :         state->dp_error = dp_error;
     970           0 :         tevent_req_error(req, ret);
     971           0 :         return;
     972             :     }
     973             : 
     974           0 :     state->sh = sdap_id_op_handle(state->sdap_op);
     975             : 
     976           0 :     DEBUG(SSSDBG_TRACE_FUNC, "SUDO LDAP connection successful\n");
     977           0 :     DEBUG(SSSDBG_TRACE_FUNC, "About to fetch host information\n");
     978             : 
     979             :     /* Obtain host information. */
     980           0 :     hostname = dp_opt_get_string(state->ipa_opts->basic, IPA_HOSTNAME);
     981             : 
     982           0 :     subreq = ipa_host_info_send(state, state->ev,
     983             :                                 state->sh, state->sdap_opts, hostname,
     984           0 :                                 state->ipa_opts->host_map,
     985           0 :                                 state->ipa_opts->hostgroup_map,
     986           0 :                                 state->ipa_opts->host_search_bases);
     987           0 :     if (subreq == NULL) {
     988           0 :         state->dp_error = DP_ERR_FATAL;
     989           0 :         tevent_req_error(req, ENOMEM);
     990           0 :         return;
     991             :     }
     992             : 
     993           0 :     tevent_req_set_callback(subreq, ipa_sudo_refresh_host_done, req);
     994             : }
     995             : 
     996             : static void
     997           0 : ipa_sudo_refresh_host_done(struct tevent_req *subreq)
     998             : {
     999             :     struct ipa_sudo_refresh_state *state;
    1000             :     struct ipa_hostinfo *host;
    1001             :     struct tevent_req *req;
    1002             :     int ret;
    1003             : 
    1004           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
    1005           0 :     state = tevent_req_data(req, struct ipa_sudo_refresh_state);
    1006             : 
    1007           0 :     host = talloc_zero(state, struct ipa_hostinfo);
    1008           0 :     if (host == NULL) {
    1009           0 :         state->dp_error = DP_ERR_FATAL;
    1010           0 :         tevent_req_error(req, ENOMEM);
    1011           0 :         return;
    1012             :     }
    1013             : 
    1014           0 :     ret = ipa_host_info_recv(subreq, host, &host->num_hosts, &host->hosts,
    1015             :                              &host->num_hostgroups, &host->hostgroups);
    1016           0 :     talloc_zfree(subreq);
    1017           0 :     if (ret != EOK) {
    1018           0 :         DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve host information "
    1019             :                                  "[%d]: %s\n", ret, sss_strerror(ret));
    1020           0 :         state->dp_error = DP_ERR_FATAL;
    1021           0 :         tevent_req_error(req, ret);
    1022           0 :         return;
    1023             :     }
    1024             : 
    1025           0 :     subreq = ipa_sudo_fetch_send(state, state->ev, state->domain, state->sysdb,
    1026             :                                  state->sudo_ctx, host,
    1027           0 :                                  state->sdap_opts->user_map,
    1028           0 :                                  state->sdap_opts->group_map,
    1029           0 :                                  state->ipa_opts->host_map,
    1030           0 :                                  state->ipa_opts->hostgroup_map, state->sh,
    1031             :                                  state->cmdgroups_filter, state->search_filter);
    1032           0 :     if (subreq == NULL) {
    1033           0 :         state->dp_error = DP_ERR_FATAL;
    1034           0 :         tevent_req_error(req, ENOMEM);
    1035           0 :         return;
    1036             :     }
    1037             : 
    1038           0 :     tevent_req_set_callback(subreq, ipa_sudo_refresh_done, req);
    1039             : }
    1040             : 
    1041             : static void
    1042           0 : ipa_sudo_refresh_done(struct tevent_req *subreq)
    1043             : {
    1044             :     struct ipa_sudo_refresh_state *state;
    1045             :     struct tevent_req *req;
    1046           0 :     char *usn = NULL;
    1047           0 :     bool in_transaction = false;
    1048             :     errno_t sret;
    1049             :     int ret;
    1050             : 
    1051           0 :     req = tevent_req_callback_data(subreq, struct tevent_req);
    1052           0 :     state = tevent_req_data(req, struct ipa_sudo_refresh_state);
    1053             : 
    1054           0 :     ret = ipa_sudo_fetch_recv(state, subreq, &state->rules,
    1055             :                               &state->num_rules, &usn);
    1056           0 :     talloc_zfree(subreq);
    1057             : 
    1058           0 :     ret = sdap_id_op_done(state->sdap_op, ret, &state->dp_error);
    1059           0 :     if (state->dp_error == DP_ERR_OK && ret != EOK) {
    1060             :         /* retry */
    1061           0 :         ret = ipa_sudo_refresh_retry(req);
    1062           0 :         if (ret != EOK) {
    1063           0 :             tevent_req_error(req, ret);
    1064             :         }
    1065           0 :         return;
    1066           0 :     } else if (ret != EOK) {
    1067           0 :         tevent_req_error(req, ret);
    1068           0 :         return;
    1069             :     }
    1070             : 
    1071           0 :     ret = sysdb_transaction_start(state->sysdb);
    1072           0 :     if (ret != EOK) {
    1073           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
    1074           0 :         goto done;
    1075             :     }
    1076           0 :     in_transaction = true;
    1077             : 
    1078           0 :     ret = sysdb_sudo_purge(state->domain, state->delete_filter,
    1079             :                            state->rules, state->num_rules);
    1080           0 :     if (ret != EOK) {
    1081           0 :         goto done;
    1082             :     }
    1083             : 
    1084           0 :     ret = sysdb_sudo_store(state->domain, state->rules, state->num_rules);
    1085           0 :     if (ret != EOK) {
    1086           0 :         goto done;
    1087             :     }
    1088             : 
    1089           0 :     ret = sysdb_transaction_commit(state->sysdb);
    1090           0 :     if (ret != EOK) {
    1091           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
    1092           0 :         goto done;
    1093             :     }
    1094           0 :     in_transaction = false;
    1095             : 
    1096           0 :     if (usn != NULL) {
    1097           0 :         sdap_sudo_set_usn(state->sudo_ctx->id_ctx->srv_opts, usn);
    1098             :     }
    1099             : 
    1100           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Sudo rules are successfully stored in cache\n");
    1101             : 
    1102             : done:
    1103           0 :     if (in_transaction) {
    1104           0 :         sret = sysdb_transaction_cancel(state->sysdb);
    1105           0 :         if (sret != EOK) {
    1106           0 :             DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n");
    1107             :         }
    1108             :     }
    1109             : 
    1110           0 :     if (ret != EOK) {
    1111           0 :         tevent_req_error(req, ret);
    1112           0 :         return;
    1113             :     }
    1114             : 
    1115           0 :     tevent_req_done(req);
    1116             : }
    1117             : 
    1118             : errno_t
    1119           0 : ipa_sudo_refresh_recv(struct tevent_req *req,
    1120             :                       int *dp_error,
    1121             :                       size_t *_num_rules)
    1122             : {
    1123           0 :     struct ipa_sudo_refresh_state *state = NULL;
    1124           0 :     state = tevent_req_data(req, struct ipa_sudo_refresh_state);
    1125             : 
    1126           0 :     TEVENT_REQ_RETURN_ON_ERROR(req);
    1127             : 
    1128           0 :     *dp_error = state->dp_error;
    1129             : 
    1130           0 :     if (_num_rules != NULL) {
    1131           0 :         *_num_rules = state->num_rules;
    1132             :     }
    1133             : 
    1134           0 :     return EOK;
    1135             : }

Generated by: LCOV version 1.10