LCOV - code coverage report
Current view: top level - responder/common - responder_cache_req.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 404 511 79.1 %
Date: 2015-10-19 Functions: 31 32 96.9 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Pavel Březina <pbrezina@redhat.com>
       4             : 
       5             :     Copyright (C) 2014 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 <dbus/dbus.h>
      22             : #include <ldb.h>
      23             : #include <talloc.h>
      24             : #include <tevent.h>
      25             : 
      26             : #include "util/util.h"
      27             : #include "db/sysdb.h"
      28             : #include "responder/common/responder_cache_req.h"
      29             : #include "providers/data_provider.h"
      30             : 
      31           6 : static errno_t updated_users_by_filter(TALLOC_CTX *mem_ctx,
      32             :                                        struct sss_domain_info *domain,
      33             :                                        const char *name_filter,
      34             :                                        time_t since,
      35             :                                        struct ldb_result **_res)
      36             : {
      37             :     int ret;
      38             :     char *recent_filter;
      39             : 
      40           6 :     recent_filter = talloc_asprintf(mem_ctx, "(%s>=%lu)",
      41             :                                     SYSDB_LAST_UPDATE, since);
      42           6 :     ret = sysdb_enumpwent_filter_with_views(mem_ctx, domain,
      43             :                                             name_filter, recent_filter,
      44             :                                             _res);
      45           6 :     talloc_free(recent_filter);
      46             : 
      47           6 :     return ret;
      48             : }
      49             : 
      50           4 : static errno_t updated_groups_by_filter(TALLOC_CTX *mem_ctx,
      51             :                                         struct sss_domain_info *domain,
      52             :                                         const char *name_filter,
      53             :                                         time_t since,
      54             :                                         struct ldb_result **_res)
      55             : {
      56             :     int ret;
      57             :     char *recent_filter;
      58             : 
      59           4 :     recent_filter = talloc_asprintf(mem_ctx, "(%s>=%lu)",
      60             :                                     SYSDB_LAST_UPDATE, since);
      61           4 :     ret = sysdb_enumgrent_filter_with_views(mem_ctx, domain,
      62             :                                             name_filter, recent_filter,
      63             :                                             _res);
      64           4 :     talloc_free(recent_filter);
      65             : 
      66           4 :     return ret;
      67             : }
      68             : 
      69             : struct cache_req_input {
      70             :     enum cache_req_type type;
      71             : 
      72             :     /* Provided input. */
      73             :     const char *orig_name;
      74             :     uint32_t id;
      75             :     const char *cert;
      76             : 
      77             :     /* Parsed name or UPN. */
      78             :     const char *name;
      79             : 
      80             :     /* Data Provider request type resolved from @type.
      81             :      * FIXME: This is currently needed for data provider calls. We should
      82             :      * refactor responder_dp.c to get rid of this member. */
      83             :     enum sss_dp_acct_type dp_type;
      84             : 
      85             :     /* Domain related informations. */
      86             :     struct sss_domain_info *domain;
      87             : 
      88             :     /* Name sanitized according to domain rules such as case sensitivity and
      89             :      * replacement of space character. This needs to be set up for each
      90             :      * domain separately. */
      91             :     const char *dom_objname;
      92             : 
      93             :     /* Fully qualified object name used in debug messages. */
      94             :     const char *debug_fqn;
      95             :     /* Time when the request started. Useful for by-filter lookups */
      96             :     time_t req_start;
      97             : };
      98             : 
      99             : struct cache_req_input *
     100          53 : cache_req_input_create(TALLOC_CTX *mem_ctx,
     101             :                        enum cache_req_type type,
     102             :                        const char *name,
     103             :                        uint32_t id,
     104             :                        const char *cert)
     105             : {
     106             :     struct cache_req_input *input;
     107             : 
     108          53 :     input = talloc_zero(mem_ctx, struct cache_req_input);
     109          53 :     if (input == NULL) {
     110           0 :         return NULL;
     111             :     }
     112             : 
     113          53 :     input->type = type;
     114          53 :     input->req_start = time(NULL);
     115             : 
     116             :     /* Check that input parameters match selected type. */
     117          53 :     switch (input->type) {
     118             :     case CACHE_REQ_USER_BY_NAME:
     119             :     case CACHE_REQ_USER_BY_UPN:
     120             :     case CACHE_REQ_GROUP_BY_NAME:
     121             :     case CACHE_REQ_USER_BY_FILTER:
     122             :     case CACHE_REQ_GROUP_BY_FILTER:
     123             :     case CACHE_REQ_INITGROUPS:
     124             :     case CACHE_REQ_INITGROUPS_BY_UPN:
     125          31 :         if (name == NULL) {
     126           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL!\n");
     127           0 :             goto fail;
     128             :         }
     129             : 
     130          31 :         input->orig_name = talloc_strdup(input, name);
     131          31 :         if (input->orig_name == NULL) {
     132           0 :             goto fail;
     133             :         }
     134          31 :         break;
     135             :     case CACHE_REQ_USER_BY_CERT:
     136           6 :         if (cert == NULL) {
     137           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Bug: certificate cannot be NULL!\n");
     138           0 :             goto fail;
     139             :         }
     140             : 
     141           6 :         input->cert = talloc_strdup(input, cert);
     142           6 :         if (input->cert == NULL) {
     143           0 :             goto fail;
     144             :         }
     145           6 :         break;
     146             :     case CACHE_REQ_USER_BY_ID:
     147             :     case CACHE_REQ_GROUP_BY_ID:
     148          16 :         if (id == 0) {
     149           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0!\n");
     150           0 :             goto fail;
     151             :         }
     152             : 
     153          16 :         input->id = id;
     154          16 :         break;
     155             :     }
     156             : 
     157             :     /* Resolve Data Provider request type. */
     158          53 :     switch (type) {
     159             :     case CACHE_REQ_USER_BY_NAME:
     160             :     case CACHE_REQ_USER_BY_UPN:
     161             :     case CACHE_REQ_USER_BY_ID:
     162          25 :         input->dp_type = SSS_DP_USER;
     163          25 :         break;
     164             : 
     165             :     case CACHE_REQ_GROUP_BY_NAME:
     166             :     case CACHE_REQ_GROUP_BY_ID:
     167          17 :         input->dp_type = SSS_DP_GROUP;
     168          17 :         break;
     169             : 
     170             :     case CACHE_REQ_INITGROUPS:
     171             :     case CACHE_REQ_INITGROUPS_BY_UPN:
     172           0 :         input->dp_type = SSS_DP_INITGROUPS;
     173           0 :         break;
     174             : 
     175             :     case CACHE_REQ_USER_BY_CERT:
     176           6 :         input->dp_type = SSS_DP_CERT;
     177           6 :         break;
     178             : 
     179             :     case CACHE_REQ_USER_BY_FILTER:
     180           3 :         input->dp_type = SSS_DP_WILDCARD_USER;
     181           3 :         break;
     182             : 
     183             :     case CACHE_REQ_GROUP_BY_FILTER:
     184           2 :         input->dp_type = SSS_DP_WILDCARD_GROUP;
     185           2 :         break;
     186             :     }
     187             : 
     188          53 :     return input;
     189             : 
     190             : fail:
     191           0 :     talloc_free(input);
     192           0 :     return NULL;
     193             : }
     194             : 
     195             : static errno_t
     196          31 : cache_req_input_set_name(struct cache_req_input *input,
     197             :                          const char *name)
     198             : {
     199             :     const char *dup;
     200             : 
     201          31 :     dup = talloc_strdup(input, name);
     202          31 :     if (dup == NULL) {
     203           0 :         return ENOMEM;
     204             :     }
     205             : 
     206          31 :     talloc_zfree(input->name);
     207          31 :     input->name = dup;
     208             : 
     209          31 :     return EOK;
     210             : }
     211             : 
     212             : static errno_t
     213          83 : cache_req_input_set_domain(struct cache_req_input *input,
     214             :                            struct sss_domain_info *domain,
     215             :                            struct resp_ctx *rctx)
     216             : {
     217          83 :     TALLOC_CTX *tmp_ctx = NULL;
     218          83 :     const char *name = NULL;
     219          83 :     const char *debug_fqn = NULL;
     220             :     errno_t ret;
     221             : 
     222          83 :     tmp_ctx = talloc_new(NULL);
     223          83 :     if (tmp_ctx == NULL) {
     224           0 :         return ENOMEM;
     225             :     }
     226             : 
     227          83 :     talloc_zfree(input->dom_objname);
     228          83 :     talloc_zfree(input->debug_fqn);
     229             : 
     230          83 :     switch (input->type) {
     231             :     case CACHE_REQ_USER_BY_NAME:
     232             :     case CACHE_REQ_USER_BY_UPN:
     233             :     case CACHE_REQ_GROUP_BY_NAME:
     234             :     case CACHE_REQ_USER_BY_FILTER:
     235             :     case CACHE_REQ_GROUP_BY_FILTER:
     236             :     case CACHE_REQ_INITGROUPS:
     237             :     case CACHE_REQ_INITGROUPS_BY_UPN:
     238          49 :         if (input->name == NULL) {
     239           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Bug: input->name is NULL?\n");
     240           0 :             ret = ERR_INTERNAL;
     241           0 :             goto done;
     242             :         }
     243             : 
     244          49 :         name = sss_get_cased_name(tmp_ctx, input->name, domain->case_sensitive);
     245          49 :         if (name == NULL) {
     246           0 :             ret = ENOMEM;
     247           0 :             goto done;
     248             :         }
     249             : 
     250          49 :         name = sss_reverse_replace_space(tmp_ctx, name, rctx->override_space);
     251          49 :         if (name == NULL) {
     252           0 :             ret = ENOMEM;
     253           0 :             goto done;
     254             :         }
     255             : 
     256          49 :         debug_fqn = talloc_asprintf(tmp_ctx, "%s@%s", name, domain->name);
     257          49 :         if (debug_fqn == NULL) {
     258           0 :             ret = ENOMEM;
     259           0 :             goto done;
     260             :         }
     261             : 
     262          49 :         break;
     263             : 
     264             :     case CACHE_REQ_USER_BY_ID:
     265          14 :         debug_fqn = talloc_asprintf(tmp_ctx, "UID:%d@%s", input->id, domain->name);
     266          14 :         if (debug_fqn == NULL) {
     267           0 :             ret = ENOMEM;
     268           0 :             goto done;
     269             :         }
     270          14 :         break;
     271             : 
     272             :     case CACHE_REQ_GROUP_BY_ID:
     273          14 :         debug_fqn = talloc_asprintf(tmp_ctx, "GID:%d@%s", input->id, domain->name);
     274          14 :         if (debug_fqn == NULL) {
     275           0 :             ret = ENOMEM;
     276           0 :             goto done;
     277             :         }
     278          14 :         break;
     279             :     case CACHE_REQ_USER_BY_CERT:
     280             :         /* certificates might be quite long, only use the last 10 charcters
     281             :          * for logging */
     282           6 :         debug_fqn = talloc_asprintf(tmp_ctx, "CERT:%s@%s",
     283             :                                     get_last_x_chars(input->cert, 10),
     284             :                                     domain->name);
     285           6 :         if (debug_fqn == NULL) {
     286           0 :             ret = ENOMEM;
     287           0 :             goto done;
     288             :         }
     289           6 :         break;
     290             :     }
     291             : 
     292          83 :     input->domain = domain;
     293          83 :     input->dom_objname = talloc_steal(input, name);
     294          83 :     input->debug_fqn = talloc_steal(input, debug_fqn);
     295             : 
     296          83 :     ret = EOK;
     297             : 
     298             : done:
     299          83 :     talloc_free(tmp_ctx);
     300          83 :     return ret;
     301             : }
     302             : 
     303             : static bool
     304         130 : cache_req_input_is_upn(struct cache_req_input *input)
     305             : {
     306         130 :     switch (input->type) {
     307             :     case CACHE_REQ_USER_BY_UPN:
     308             :     case CACHE_REQ_INITGROUPS_BY_UPN:
     309          27 :         return true;
     310             :     default:
     311         103 :         return false;
     312             :     }
     313             : }
     314             : 
     315             : static bool
     316          20 : cache_req_input_assume_upn(struct cache_req_input *input)
     317             : {
     318             :     errno_t ret;
     319             :     bool bret;
     320             : 
     321          20 :     if (input->orig_name == NULL || strchr(input->orig_name, '@') == NULL) {
     322          12 :         return false;
     323             :     }
     324             : 
     325           8 :     switch (input->type) {
     326             :     case CACHE_REQ_USER_BY_NAME:
     327           8 :         input->type = CACHE_REQ_USER_BY_UPN;
     328           8 :         bret = true;
     329           8 :         break;
     330             :     case CACHE_REQ_INITGROUPS:
     331           0 :         input->type = CACHE_REQ_INITGROUPS_BY_UPN;
     332           0 :         bret = true;
     333           0 :         break;
     334             :     default:
     335           0 :         bret = false;
     336           0 :         break;
     337             :     }
     338             : 
     339           8 :     if (bret == true) {
     340           8 :         ret = cache_req_input_set_name(input, input->orig_name);
     341           8 :         if (ret != EOK) {
     342           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     343             :                   "cache_req_input_set_orig_name() failed\n");
     344           0 :             return false;
     345             :         }
     346             : 
     347           8 :         DEBUG(SSSDBG_TRACE_FUNC, "Assuming UPN %s\n", input->orig_name);
     348             :     }
     349             : 
     350           8 :     return bret;
     351             : }
     352             : 
     353          83 : static errno_t cache_req_check_ncache(struct cache_req_input *input,
     354             :                                       struct sss_nc_ctx *ncache,
     355             :                                       int neg_timeout)
     356             : {
     357          83 :     errno_t ret = ERR_INTERNAL;
     358             : 
     359          83 :     switch (input->type) {
     360             :     case CACHE_REQ_USER_BY_NAME:
     361             :     case CACHE_REQ_USER_BY_UPN:
     362             :     case CACHE_REQ_INITGROUPS:
     363             :     case CACHE_REQ_INITGROUPS_BY_UPN:
     364          29 :         ret = sss_ncache_check_user(ncache, neg_timeout,
     365             :                                     input->domain, input->dom_objname);
     366          29 :         break;
     367             :     case CACHE_REQ_GROUP_BY_NAME:
     368          15 :         ret = sss_ncache_check_group(ncache, neg_timeout,
     369             :                                      input->domain, input->dom_objname);
     370          15 :         break;
     371             :     case CACHE_REQ_USER_BY_ID:
     372          14 :         ret = sss_ncache_check_uid(ncache, neg_timeout, NULL, input->id);
     373          14 :         break;
     374             :     case CACHE_REQ_GROUP_BY_ID:
     375          14 :         ret = sss_ncache_check_gid(ncache, neg_timeout, NULL, input->id);
     376          14 :         break;
     377             :     case CACHE_REQ_USER_BY_CERT:
     378           6 :         ret = sss_ncache_check_cert(ncache, neg_timeout, input->cert);
     379           6 :         break;
     380             :     case CACHE_REQ_USER_BY_FILTER:
     381             :     case CACHE_REQ_GROUP_BY_FILTER:
     382           5 :         ret = EOK;
     383           5 :         break;
     384             :     }
     385             : 
     386          83 :     if (ret == EEXIST) {
     387           5 :         DEBUG(SSSDBG_TRACE_FUNC, "[%s] does not exist (negative cache)\n",
     388             :               input->debug_fqn);
     389             :     }
     390             : 
     391          83 :     return ret;
     392             : }
     393             : 
     394          46 : static void cache_req_add_to_ncache(struct cache_req_input *input,
     395             :                                     struct sss_nc_ctx *ncache)
     396             : {
     397          46 :     errno_t ret = ERR_INTERNAL;
     398             : 
     399          46 :     switch (input->type) {
     400             :     case CACHE_REQ_USER_BY_NAME:
     401             :     case CACHE_REQ_USER_BY_UPN:
     402             :     case CACHE_REQ_INITGROUPS:
     403             :     case CACHE_REQ_INITGROUPS_BY_UPN:
     404          16 :         ret = sss_ncache_set_user(ncache, false, input->domain,
     405             :                                   input->dom_objname);
     406          16 :         break;
     407             :     case CACHE_REQ_GROUP_BY_NAME:
     408           8 :         ret = sss_ncache_set_group(ncache, false, input->domain,
     409             :                                    input->dom_objname);
     410           8 :         break;
     411             :     case CACHE_REQ_USER_BY_FILTER:
     412             :     case CACHE_REQ_GROUP_BY_FILTER:
     413             :         /* Nothing to do, adding a wildcard request to ncache doesn't
     414             :          * make sense */
     415             :     case CACHE_REQ_USER_BY_ID:
     416             :     case CACHE_REQ_GROUP_BY_ID:
     417             :     case CACHE_REQ_USER_BY_CERT:
     418             :         /* Nothing to do. Those types must be unique among all domains so
     419             :          * the don't contain domain part. Therefore they must be set only
     420             :          * if all domains are search and the entry is not found. */
     421          22 :         ret = EOK;
     422          22 :         break;
     423             :     }
     424             : 
     425          46 :     if (ret != EOK) {
     426           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for [%s] [%d]: %s\n",
     427             :               input->debug_fqn, ret, sss_strerror(ret));
     428             : 
     429             :         /* not fatal */
     430             :     }
     431             : 
     432          46 :     return;
     433             : }
     434             : 
     435           9 : static void cache_req_add_to_ncache_global(struct cache_req_input *input,
     436             :                                            struct sss_nc_ctx *ncache)
     437             : {
     438           9 :     errno_t ret = ERR_INTERNAL;
     439             : 
     440           9 :     switch (input->type) {
     441             :     case CACHE_REQ_USER_BY_FILTER:
     442             :     case CACHE_REQ_GROUP_BY_FILTER:
     443             :         /* Nothing to do, adding a wildcard request to ncache doesn't
     444             :          * make sense */
     445             :     case CACHE_REQ_USER_BY_NAME:
     446             :     case CACHE_REQ_USER_BY_UPN:
     447             :     case CACHE_REQ_GROUP_BY_NAME:
     448             :     case CACHE_REQ_INITGROUPS:
     449             :     case CACHE_REQ_INITGROUPS_BY_UPN:
     450             :         /* Nothing to do. Those types are already in ncache for selected
     451             :          * domains. */
     452           5 :         ret = EOK;
     453           5 :         break;
     454             :     case CACHE_REQ_USER_BY_ID:
     455           1 :         ret = sss_ncache_set_uid(ncache, false, NULL, input->id);
     456           1 :         break;
     457             :     case CACHE_REQ_GROUP_BY_ID:
     458           1 :         ret = sss_ncache_set_gid(ncache, false, NULL, input->id);
     459           1 :         break;
     460             :     case CACHE_REQ_USER_BY_CERT:
     461           2 :         ret = sss_ncache_set_cert(ncache, false, input->cert);
     462           2 :         break;
     463             :     }
     464             : 
     465           9 :     if (ret != EOK) {
     466           0 :         DEBUG(SSSDBG_MINOR_FAILURE, "Cannot set negcache for [%s] [%d]: %s\n",
     467             :               input->debug_fqn, ret, sss_strerror(ret));
     468             : 
     469             :         /* not fatal */
     470             :     }
     471             : 
     472           9 :     return;
     473             : }
     474             : 
     475         139 : static errno_t cache_req_get_object(TALLOC_CTX *mem_ctx,
     476             :                                     struct cache_req_input *input,
     477             :                                     struct ldb_result **_result)
     478             : {
     479         139 :     struct ldb_result *result = NULL;
     480         139 :     bool one_item_only = false;
     481         139 :     errno_t ret = ERR_INTERNAL;
     482             : 
     483         139 :     DEBUG(SSSDBG_FUNC_DATA, "Requesting info for [%s]\n", input->debug_fqn);
     484             : 
     485         139 :     switch (input->type) {
     486             :     case CACHE_REQ_USER_BY_NAME:
     487          24 :         one_item_only = true;
     488          24 :         ret = sysdb_getpwnam_with_views(mem_ctx, input->domain,
     489             :                                         input->dom_objname, &result);
     490          24 :         break;
     491             :     case CACHE_REQ_USER_BY_UPN:
     492          23 :         one_item_only = true;
     493          23 :         ret = sysdb_getpwupn(mem_ctx, input->domain,
     494             :                              input->dom_objname, &result);
     495          23 :         break;
     496             :     case CACHE_REQ_USER_BY_ID:
     497          23 :         one_item_only = true;
     498          23 :         ret = sysdb_getpwuid_with_views(mem_ctx, input->domain,
     499             :                                         input->id, &result);
     500          23 :         break;
     501             :     case CACHE_REQ_GROUP_BY_NAME:
     502          24 :         one_item_only = true;
     503          24 :         ret = sysdb_getgrnam_with_views(mem_ctx, input->domain,
     504             :                                         input->dom_objname, &result);
     505          24 :         break;
     506             :     case CACHE_REQ_GROUP_BY_ID:
     507          23 :         one_item_only = true;
     508          23 :         ret = sysdb_getgrgid_with_views(mem_ctx, input->domain,
     509             :                                         input->id, &result);
     510          23 :         break;
     511             :     case CACHE_REQ_INITGROUPS:
     512           0 :         one_item_only = false;
     513           0 :         ret = sysdb_initgroups_with_views(mem_ctx, input->domain,
     514             :                                           input->dom_objname, &result);
     515           0 :         break;
     516             :     case CACHE_REQ_INITGROUPS_BY_UPN:
     517           0 :         one_item_only = false;
     518           0 :         ret = sysdb_initgroups_by_upn(mem_ctx, input->domain,
     519             :                                       input->dom_objname, &result);
     520           0 :         break;
     521             :     case CACHE_REQ_USER_BY_CERT:
     522          12 :         one_item_only = true;
     523          12 :         ret = sysdb_search_user_by_cert(mem_ctx, input->domain,
     524             :                                         input->cert, &result);
     525          12 :         break;
     526             :     case CACHE_REQ_USER_BY_FILTER:
     527           6 :         one_item_only = false;
     528           6 :         ret = updated_users_by_filter(mem_ctx, input->domain,
     529             :                                       input->dom_objname, input->req_start,
     530             :                                       &result);
     531           6 :         break;
     532             :     case CACHE_REQ_GROUP_BY_FILTER:
     533           4 :         one_item_only = false;
     534           4 :         ret = updated_groups_by_filter(mem_ctx, input->domain,
     535             :                                        input->dom_objname, input->req_start,
     536             :                                        &result);
     537           4 :         break;
     538             :     }
     539             : 
     540         139 :     if (ret != EOK) {
     541          25 :         goto done;
     542         114 :     } else if (result->count == 0) {
     543          77 :         ret = ENOENT;
     544          77 :         goto done;
     545          37 :     } else if (one_item_only && result->count > 1) {
     546           0 :         ret = ERR_INTERNAL;
     547           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Multiple objects were found when"
     548             :               "sysdb search expected only one!\n");
     549           0 :         goto done;
     550             :     }
     551             : 
     552          37 :     *_result = result;
     553             : 
     554             : done:
     555         139 :     return ret;
     556             : }
     557             : 
     558             : /* Return true if the request bypasses cache or false if the cache_req
     559             :  * code can leverage sysdb for this request.
     560             :  */
     561          22 : static bool cache_req_bypass_cache(struct cache_req_input *input)
     562             : {
     563          44 :     if (input->type == CACHE_REQ_USER_BY_FILTER ||
     564          22 :             input->type == CACHE_REQ_GROUP_BY_FILTER) {
     565           0 :         return true;
     566             :     }
     567             : 
     568          22 :     return false;
     569             : }
     570             : 
     571             : struct cache_req_cache_state {
     572             :     /* input data */
     573             :     struct tevent_context *ev;
     574             :     struct resp_ctx *rctx;
     575             :     struct sss_nc_ctx *ncache;
     576             :     int neg_timeout;
     577             :     int cache_refresh_percent;
     578             :     struct cache_req_input *input;
     579             : 
     580             :     /* output data */
     581             :     struct ldb_result *result;
     582             : };
     583             : 
     584             : static errno_t cache_req_cache_search(struct tevent_req *req);
     585             : static errno_t cache_req_cache_check(struct tevent_req *req);
     586             : static void cache_req_cache_done(struct tevent_req *subreq);
     587             : 
     588          83 : static struct tevent_req *cache_req_cache_send(TALLOC_CTX *mem_ctx,
     589             :                                                struct tevent_context *ev,
     590             :                                                struct resp_ctx *rctx,
     591             :                                                struct sss_nc_ctx *ncache,
     592             :                                                int neg_timeout,
     593             :                                                int cache_refresh_percent,
     594             :                                                struct cache_req_input *input)
     595             : {
     596          83 :     struct cache_req_cache_state *state = NULL;
     597          83 :     struct tevent_req *req = NULL;
     598             :     errno_t ret;
     599             : 
     600          83 :     req = tevent_req_create(mem_ctx, &state, struct cache_req_cache_state);
     601          83 :     if (req == NULL) {
     602           0 :         DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
     603           0 :         return NULL;
     604             :     }
     605             : 
     606          83 :     state->ev = ev;
     607          83 :     state->rctx = rctx;
     608          83 :     state->ncache = ncache;
     609          83 :     state->neg_timeout = neg_timeout;
     610          83 :     state->cache_refresh_percent = cache_refresh_percent;
     611          83 :     state->input = input;
     612             : 
     613             :     /* Check negative cache first. */
     614          83 :     ret = cache_req_check_ncache(state->input, state->ncache,
     615          83 :                                  state->neg_timeout);
     616          83 :     if (ret == EEXIST) {
     617           5 :         ret = ENOENT;
     618           5 :         goto immediately;
     619             :     }
     620             : 
     621             :     /* We will first search the cache. If we get cache miss or the entry
     622             :      * is expired we will contact data provider and then search again. */
     623          78 :     ret = cache_req_cache_search(req);
     624          78 :     if (ret != EAGAIN) {
     625          17 :         goto immediately;
     626             :     }
     627             : 
     628          61 :     return req;
     629             : 
     630             : immediately:
     631          22 :     if (ret == EOK) {
     632          17 :         tevent_req_done(req);
     633             :     } else {
     634           5 :         tevent_req_error(req, ret);
     635             :     }
     636          22 :     tevent_req_post(req, ev);
     637             : 
     638          22 :     return req;
     639             : }
     640             : 
     641          78 : static errno_t cache_req_cache_search(struct tevent_req *req)
     642             : {
     643          78 :     struct cache_req_cache_state *state = NULL;
     644             :     errno_t ret;
     645             : 
     646          78 :     state = tevent_req_data(req, struct cache_req_cache_state);
     647             : 
     648          78 :     ret = cache_req_get_object(state, state->input, &state->result);
     649          78 :     if (ret != EOK && ret != ENOENT) {
     650           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache "
     651             :               "[%d]: %s\n", ret, sss_strerror(ret));
     652           0 :         return ret;
     653             :     }
     654             : 
     655             :     /* Verify that the cache is up to date. */
     656          78 :     ret = cache_req_cache_check(req);
     657          78 :     if (req != EOK) {
     658          78 :         return ret;
     659             :     }
     660             : 
     661             :     /* One result found */
     662           0 :     DEBUG(SSSDBG_TRACE_FUNC, "Returning info for [%s]\n",
     663             :           state->input->debug_fqn);
     664           0 :     return EOK;
     665             : }
     666             : 
     667          78 : static errno_t cache_req_cache_check(struct tevent_req *req)
     668             : {
     669          78 :     struct cache_req_cache_state *state = NULL;
     670          78 :     struct tevent_req *subreq = NULL;
     671          78 :     const char *extra_flag = NULL;
     672          78 :     uint64_t cache_expire = 0;
     673             :     errno_t ret;
     674             :     const char *search_str;
     675             : 
     676          78 :     state = tevent_req_data(req, struct cache_req_cache_state);
     677             : 
     678         100 :     if (state->result == NULL || state->result->count == 0 ||
     679          22 :             cache_req_bypass_cache(state->input) == true) {
     680          56 :         ret = ENOENT;
     681             :     } else {
     682          22 :         if (state->input->type == CACHE_REQ_INITGROUPS) {
     683           0 :             cache_expire = ldb_msg_find_attr_as_uint64(state->result->msgs[0],
     684             :                                                        SYSDB_INITGR_EXPIRE, 0);
     685             :         } else {
     686          22 :             cache_expire = ldb_msg_find_attr_as_uint64(state->result->msgs[0],
     687             :                                                        SYSDB_CACHE_EXPIRE, 0);
     688             :         }
     689             : 
     690          22 :         ret = sss_cmd_check_cache(state->result->msgs[0],
     691             :                                   state->cache_refresh_percent, cache_expire);
     692             :     }
     693             : 
     694          78 :     search_str = state->input->dom_objname;
     695          78 :     if (state->input->type == CACHE_REQ_USER_BY_CERT) {
     696           6 :         search_str = state->input->cert;
     697             :     }
     698             : 
     699          78 :     if (DOM_HAS_VIEWS(state->input->domain)) {
     700           0 :         extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
     701          78 :     } else if (cache_req_input_is_upn(state->input)) {
     702          13 :         extra_flag = EXTRA_NAME_IS_UPN;
     703             :     }
     704             : 
     705          78 :     switch (ret) {
     706             :     case EOK:
     707          12 :         DEBUG(SSSDBG_TRACE_FUNC, "Cached entry is valid, returning...\n");
     708          12 :         return EOK;
     709             :     case EAGAIN:
     710             :         /* Out of band update. The calling function will return the cached
     711             :          * entry immediately. No callback is required. */
     712             : 
     713           5 :         DEBUG(SSSDBG_TRACE_FUNC, "Performing midpoint cache update\n");
     714             : 
     715          15 :         subreq = sss_dp_get_account_send(state, state->rctx,
     716           5 :                                          state->input->domain, true,
     717           5 :                                          state->input->dp_type,
     718             :                                          search_str,
     719           5 :                                          state->input->id, extra_flag);
     720           5 :         if (subreq == NULL) {
     721           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band "
     722             :                                        "data provider request\n");
     723             :             /* This is non-fatal, so we'll continue here */
     724             :         } else {
     725           5 :             DEBUG(SSSDBG_TRACE_FUNC, "Updating cache out-of-band\n");
     726             :         }
     727             : 
     728           5 :         return EOK;
     729             :     case ENOENT:
     730             :         /* Cache miss or the cache is expired. We need to get the updated
     731             :          * information before returning it. */
     732             : 
     733         183 :         subreq = sss_dp_get_account_send(state, state->rctx,
     734          61 :                                          state->input->domain, true,
     735          61 :                                          state->input->dp_type,
     736             :                                          search_str,
     737          61 :                                          state->input->id, extra_flag);
     738          61 :         if (subreq == NULL) {
     739           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     740             :                   "Out of memory sending data provider request\n");
     741           0 :             return ENOMEM;
     742             :         }
     743             : 
     744          61 :         tevent_req_set_callback(subreq, cache_req_cache_done, req);
     745          61 :         return EAGAIN;
     746             :     default:
     747             :         /* error */
     748           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Error checking cache [%d]: %s\n",
     749             :                                    ret, sss_strerror(ret));
     750           0 :         return ret;
     751             :     }
     752             : }
     753             : 
     754          61 : static void cache_req_cache_done(struct tevent_req *subreq)
     755             : {
     756          61 :     struct cache_req_cache_state *state = NULL;
     757          61 :     struct tevent_req *req = NULL;
     758          61 :     char *err_msg = NULL;
     759             :     dbus_uint16_t err_maj;
     760             :     dbus_uint32_t err_min;
     761             :     errno_t ret;
     762             : 
     763          61 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     764          61 :     state = tevent_req_data(req, struct cache_req_cache_state);
     765             : 
     766          61 :     ret = sss_dp_get_account_recv(state, subreq, &err_maj, &err_min, &err_msg);
     767          61 :     talloc_zfree(subreq);
     768          61 :     if (ret != EOK) {
     769           0 :         DEBUG(SSSDBG_OP_FAILURE, "Could not get account info [%d]: %s\n",
     770             :                                  ret, sss_strerror(ret));
     771             :     }
     772             : 
     773          61 :     if (err_maj) {
     774           0 :         DEBUG(SSSDBG_MINOR_FAILURE,
     775             :               "Unable to get information from Data Provider\n"
     776             :               "Error: %u, %u, %s\n"
     777             :               "Will try to return what we have in cache\n",
     778             :               (unsigned int)err_maj, (unsigned int)err_min, err_msg);
     779             :     }
     780             : 
     781             :     /* Get result from cache again. */
     782          61 :     ret = cache_req_get_object(state, state->input, &state->result);
     783          61 :     if (ret == ENOENT) {
     784          46 :         cache_req_add_to_ncache(state->input, state->ncache);
     785          46 :         ret = ENOENT;
     786          15 :     } else if (ret != EOK) {
     787           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to make request to our cache "
     788             :               "[%d]: %s\n", ret, sss_strerror(ret));
     789             :     }
     790             : 
     791          61 :     if (ret != EOK) {
     792          46 :         tevent_req_error(req, ret);
     793          46 :         return;
     794             :     }
     795             : 
     796             :     /* One result found */
     797          15 :     DEBUG(SSSDBG_TRACE_FUNC, "Returning info for [%s]\n",
     798             :           state->input->debug_fqn);
     799             : 
     800          15 :     tevent_req_done(req);
     801             : }
     802             : 
     803          83 : static errno_t cache_req_cache_recv(TALLOC_CTX *mem_ctx,
     804             :                                     struct tevent_req *req,
     805             :                                     struct ldb_result **_result)
     806             : {
     807          83 :     struct cache_req_cache_state *state = NULL;
     808          83 :     state = tevent_req_data(req, struct cache_req_cache_state);
     809             : 
     810         134 :     TEVENT_REQ_RETURN_ON_ERROR(req);
     811             : 
     812          32 :     *_result = talloc_steal(mem_ctx, state->result);
     813             : 
     814          32 :     return EOK;
     815             : }
     816             : 
     817             : 
     818             : struct cache_req_state {
     819             :     /* input data */
     820             :     struct tevent_context *ev;
     821             :     struct resp_ctx *rctx;
     822             :     struct sss_nc_ctx *ncache;
     823             :     int neg_timeout;
     824             :     int cache_refresh_percent;
     825             :     struct cache_req_input *input;
     826             : 
     827             :     /* work data */
     828             :     struct ldb_result *result;
     829             :     struct sss_domain_info *domain;
     830             :     struct sss_domain_info *selected_domain;
     831             :     bool check_next;
     832             : };
     833             : 
     834             : static void cache_req_input_parsed(struct tevent_req *subreq);
     835             : 
     836             : static errno_t cache_req_select_domains(struct tevent_req *req,
     837             :                                         const char *domain);
     838             : 
     839             : static errno_t cache_req_next_domain(struct tevent_req *req);
     840             : 
     841             : static void cache_req_done(struct tevent_req *subreq);
     842             : 
     843          53 : struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx,
     844             :                                   struct tevent_context *ev,
     845             :                                   struct resp_ctx *rctx,
     846             :                                   struct sss_nc_ctx *ncache,
     847             :                                   int neg_timeout,
     848             :                                   int cache_refresh_percent,
     849             :                                   const char *domain,
     850             :                                   struct cache_req_input *input)
     851             : {
     852          53 :     struct cache_req_state *state = NULL;
     853          53 :     struct tevent_req *req = NULL;
     854          53 :     struct tevent_req *subreq = NULL;
     855             :     errno_t ret;
     856             : 
     857          53 :     req = tevent_req_create(mem_ctx, &state, struct cache_req_state);
     858          53 :     if (req == NULL) {
     859           0 :         DEBUG(SSSDBG_CRIT_FAILURE, ("tevent_req_create() failed\n"));
     860           0 :         return NULL;
     861             :     }
     862             : 
     863          53 :     state->ev = ev;
     864          53 :     state->rctx = rctx;
     865          53 :     state->ncache = ncache;
     866          53 :     state->neg_timeout = neg_timeout;
     867          53 :     state->cache_refresh_percent = cache_refresh_percent;
     868          53 :     state->input = input;
     869             : 
     870          53 :     if (state->input->orig_name != NULL && domain == NULL) {
     871             :         /* Parse input name first, since it may contain domain name. */
     872          14 :         subreq = sss_parse_inp_send(state, rctx, input->orig_name);
     873          14 :         if (subreq == NULL) {
     874           0 :             ret = ENOMEM;
     875           0 :             goto immediately;
     876             :         }
     877             : 
     878          14 :         tevent_req_set_callback(subreq, cache_req_input_parsed, req);
     879             :     } else {
     880          39 :         if (input->orig_name != NULL) {
     881          17 :             ret = cache_req_input_set_name(input, input->orig_name);
     882          17 :             if (ret != EOK) {
     883           0 :                 goto immediately;
     884             :             }
     885             :         }
     886             : 
     887          39 :         ret = cache_req_select_domains(req, domain);
     888          39 :         if (ret != EAGAIN) {
     889           0 :             goto immediately;
     890             :         }
     891             :     }
     892             : 
     893          53 :     return req;
     894             : 
     895             : immediately:
     896           0 :     if (ret == EOK) {
     897           0 :         tevent_req_done(req);
     898             :     } else {
     899           0 :         tevent_req_error(req, ret);
     900             :     }
     901           0 :     tevent_req_post(req, ev);
     902             : 
     903           0 :     return req;
     904             : }
     905             : 
     906          14 : static void cache_req_input_parsed(struct tevent_req *subreq)
     907             : {
     908             :     struct tevent_req *req;
     909             :     struct cache_req_state *state;
     910             :     char *name;
     911             :     char *domain;
     912             :     errno_t ret;
     913             :     bool maybe_upn;
     914             : 
     915          14 :     req = tevent_req_callback_data(subreq, struct tevent_req);
     916          14 :     state = tevent_req_data(req, struct cache_req_state);
     917             : 
     918          14 :     ret = sss_parse_inp_recv(subreq, state, &name, &domain);
     919          14 :     switch (ret) {
     920             :     case EOK:
     921           6 :         ret = cache_req_input_set_name(state->input, name);
     922           6 :         if (ret != EOK) {
     923           0 :             tevent_req_error(req, ret);
     924           0 :             return;
     925             :         }
     926           6 :         break;
     927             :     case ERR_DOMAIN_NOT_FOUND:
     928           8 :         maybe_upn = cache_req_input_assume_upn(state->input);
     929           8 :         if (!maybe_upn) {
     930           0 :             tevent_req_error(req, ret);
     931           0 :             return;
     932             :         }
     933             : 
     934           8 :         domain = NULL;
     935           8 :         break;
     936             :     default:
     937           0 :         tevent_req_error(req, ret);
     938           0 :         return;
     939             :     }
     940             : 
     941          14 :     ret = cache_req_select_domains(req, domain);
     942          14 :     if (ret != EAGAIN) {
     943           0 :         tevent_req_error(req, ret);
     944           0 :         return;
     945             :     }
     946             : }
     947             : 
     948          53 : static errno_t cache_req_select_domains(struct tevent_req *req,
     949             :                                         const char *domain)
     950             : {
     951          53 :     struct cache_req_state *state = NULL;
     952             : 
     953          53 :     state = tevent_req_data(req, struct cache_req_state);
     954             : 
     955          53 :     if (domain != NULL) {
     956             :         /* single-domain search */
     957          31 :         state->domain = responder_get_domain(state->rctx, domain);
     958          31 :         if (state->domain == NULL) {
     959           0 :             return ERR_DOMAIN_NOT_FOUND;
     960             :         }
     961             : 
     962          31 :         state->check_next = false;
     963             :     } else {
     964             :         /* multi-domain search */
     965          22 :         state->domain = state->rctx->domains;
     966          22 :         state->check_next = true;
     967             :     }
     968             : 
     969          53 :     return cache_req_next_domain(req);
     970             : }
     971             : 
     972          92 : static errno_t cache_req_next_domain(struct tevent_req *req)
     973             : {
     974          92 :     struct cache_req_state *state = NULL;
     975          92 :     struct tevent_req *subreq = NULL;
     976             :     errno_t ret;
     977             : 
     978          92 :     state = tevent_req_data(req, struct cache_req_state);
     979             : 
     980          92 :     while (state->domain != NULL) {
     981             :        /* If it is a domainless search, skip domains that require fully
     982             :         * qualified names instead. */
     983         166 :         while (state->domain != NULL && state->check_next
     984          52 :                 && state->domain->fqnames
     985           0 :                 && !cache_req_input_is_upn(state->input)) {
     986           0 :             state->domain = get_next_domain(state->domain, false);
     987             :         }
     988             : 
     989          83 :         state->selected_domain = state->domain;
     990             : 
     991          83 :         if (state->domain == NULL) {
     992           0 :             break;
     993             :         }
     994             : 
     995          83 :         ret = cache_req_input_set_domain(state->input, state->domain,
     996             :                                          state->rctx);
     997          83 :         if (ret != EOK) {
     998           0 :             return ret;
     999             :         }
    1000             : 
    1001          83 :         subreq = cache_req_cache_send(state, state->ev, state->rctx,
    1002             :                                       state->ncache, state->neg_timeout,
    1003             :                                       state->cache_refresh_percent,
    1004             :                                       state->input);
    1005          83 :         if (subreq == NULL) {
    1006           0 :             return ENOMEM;
    1007             :         }
    1008             : 
    1009          83 :         tevent_req_set_callback(subreq, cache_req_done, req);
    1010             : 
    1011             :         /* we will continue with the following domain the next time */
    1012          83 :         if (state->check_next) {
    1013          52 :             if (cache_req_input_is_upn(state->input)) {
    1014          14 :                 state->domain = get_next_domain(state->domain, true);
    1015             :             } else {
    1016          38 :                 state->domain = get_next_domain(state->domain, false);
    1017             :             }
    1018             :         }
    1019             : 
    1020          83 :         return EAGAIN;
    1021             :     }
    1022             : 
    1023             :     /* If the object searched has to be unique among all maintained domains,
    1024             :      * we have to add it into negative cache here when all domains have
    1025             :      * been searched. */
    1026             : 
    1027           9 :     cache_req_add_to_ncache_global(state->input, state->ncache);
    1028             : 
    1029           9 :     return ENOENT;
    1030             : }
    1031             : 
    1032          83 : static void cache_req_done(struct tevent_req *subreq)
    1033             : {
    1034          83 :     struct cache_req_state *state = NULL;
    1035          83 :     struct tevent_req *req = NULL;
    1036             :     errno_t ret;
    1037             : 
    1038          83 :     req = tevent_req_callback_data(subreq, struct tevent_req);
    1039          83 :     state = tevent_req_data(req, struct cache_req_state);
    1040             : 
    1041          83 :     ret = cache_req_cache_recv(state, subreq, &state->result);
    1042          83 :     talloc_zfree(subreq);
    1043          83 :     if (ret == EOK) {
    1044          32 :         tevent_req_done(req);
    1045          32 :         return;
    1046             :     }
    1047             : 
    1048          51 :     if (state->check_next == false) {
    1049          12 :         if (ret == ENOENT && cache_req_input_assume_upn(state->input)) {
    1050             :             /* search by upn now */
    1051           0 :             cache_req_select_domains(req, NULL);
    1052           0 :             return;
    1053             :         }
    1054             : 
    1055          12 :         tevent_req_error(req, ret);
    1056          12 :         return;
    1057             :     }
    1058             : 
    1059          39 :     ret = cache_req_next_domain(req);
    1060          39 :     if (ret != EAGAIN) {
    1061           9 :         tevent_req_error(req, ret);
    1062             :     }
    1063             : 
    1064          39 :     return;
    1065             : }
    1066             : 
    1067          53 : errno_t cache_req_recv(TALLOC_CTX *mem_ctx,
    1068             :                        struct tevent_req *req,
    1069             :                        struct ldb_result **_result,
    1070             :                        struct sss_domain_info **_domain,
    1071             :                        char **_name)
    1072             : {
    1073          53 :     struct cache_req_state *state = NULL;
    1074             :     char *name;
    1075             : 
    1076          53 :     state = tevent_req_data(req, struct cache_req_state);
    1077             : 
    1078          74 :     TEVENT_REQ_RETURN_ON_ERROR(req);
    1079             : 
    1080          32 :     if (_name != NULL) {
    1081          17 :         if (state->input->dom_objname == NULL) {
    1082           0 :             *_name = NULL;
    1083             :         } else {
    1084          17 :             name = talloc_strdup(mem_ctx, state->input->name);
    1085          17 :             if (name == NULL) {
    1086           0 :                 return ENOMEM;
    1087             :             }
    1088             : 
    1089          17 :             *_name = name;
    1090             :         }
    1091             :     }
    1092             : 
    1093          32 :     if (_result != NULL) {
    1094          32 :         *_result = talloc_steal(mem_ctx, state->result);
    1095             :     }
    1096             : 
    1097          32 :     if (_domain != NULL) {
    1098          32 :         *_domain = state->selected_domain;
    1099             :     }
    1100             : 
    1101          32 :     return EOK;
    1102             : }
    1103             : 
    1104             : static struct tevent_req *
    1105          53 : cache_req_steal_input_and_send(TALLOC_CTX *mem_ctx,
    1106             :                                struct tevent_context *ev,
    1107             :                                struct resp_ctx *rctx,
    1108             :                                struct sss_nc_ctx *ncache,
    1109             :                                int neg_timeout,
    1110             :                                int cache_refresh_percent,
    1111             :                                const char *domain,
    1112             :                                struct cache_req_input *input)
    1113             : {
    1114             :     struct tevent_req *req;
    1115             : 
    1116          53 :     req = cache_req_send(mem_ctx, ev, rctx, ncache, neg_timeout,
    1117             :                          cache_refresh_percent, domain, input);
    1118          53 :     if (req == NULL) {
    1119           0 :         talloc_zfree(input);
    1120             :     }
    1121             : 
    1122          53 :     talloc_steal(req, input);
    1123             : 
    1124          53 :     return req;
    1125             : }
    1126             : 
    1127             : struct tevent_req *
    1128          17 : cache_req_user_by_name_send(TALLOC_CTX *mem_ctx,
    1129             :                             struct tevent_context *ev,
    1130             :                             struct resp_ctx *rctx,
    1131             :                             struct sss_nc_ctx *ncache,
    1132             :                             int neg_timeout,
    1133             :                             int cache_refresh_percent,
    1134             :                             const char *domain,
    1135             :                             const char *name)
    1136             : {
    1137             :     struct cache_req_input *input;
    1138             : 
    1139          17 :     input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_NAME, name, 0,
    1140             :                                    NULL);
    1141          17 :     if (input == NULL) {
    1142           0 :         return NULL;
    1143             :     }
    1144             : 
    1145          17 :     return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache,
    1146             :                                           neg_timeout, cache_refresh_percent,
    1147             :                                           domain, input);
    1148             : }
    1149             : 
    1150             : struct tevent_req *
    1151           8 : cache_req_user_by_id_send(TALLOC_CTX *mem_ctx,
    1152             :                           struct tevent_context *ev,
    1153             :                           struct resp_ctx *rctx,
    1154             :                           struct sss_nc_ctx *ncache,
    1155             :                           int neg_timeout,
    1156             :                           int cache_refresh_percent,
    1157             :                           const char *domain,
    1158             :                           uid_t uid)
    1159             : {
    1160             :     struct cache_req_input *input;
    1161             : 
    1162           8 :     input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_ID, NULL, uid,
    1163             :                                    NULL);
    1164           8 :     if (input == NULL) {
    1165           0 :         return NULL;
    1166             :     }
    1167             : 
    1168           8 :     return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache,
    1169             :                                           neg_timeout, cache_refresh_percent,
    1170             :                                           domain, input);
    1171             : }
    1172             : 
    1173             : struct tevent_req *
    1174           6 : cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx,
    1175             :                             struct tevent_context *ev,
    1176             :                             struct resp_ctx *rctx,
    1177             :                             struct sss_nc_ctx *ncache,
    1178             :                             int neg_timeout,
    1179             :                             int cache_refresh_percent,
    1180             :                             const char *domain,
    1181             :                             const char *pem_cert)
    1182             : {
    1183             :     struct cache_req_input *input;
    1184             : 
    1185           6 :     input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_CERT,
    1186             :                                    NULL, 0, pem_cert);
    1187           6 :     if (input == NULL) {
    1188           0 :         return NULL;
    1189             :     }
    1190             : 
    1191           6 :     return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache,
    1192             :                                           neg_timeout, cache_refresh_percent,
    1193             :                                           domain, input);
    1194             : }
    1195             : 
    1196             : struct tevent_req *
    1197           9 : cache_req_group_by_name_send(TALLOC_CTX *mem_ctx,
    1198             :                              struct tevent_context *ev,
    1199             :                              struct resp_ctx *rctx,
    1200             :                              struct sss_nc_ctx *ncache,
    1201             :                              int neg_timeout,
    1202             :                              int cache_refresh_percent,
    1203             :                              const char *domain,
    1204             :                              const char *name)
    1205             : {
    1206             :     struct cache_req_input *input;
    1207             : 
    1208           9 :     input = cache_req_input_create(mem_ctx, CACHE_REQ_GROUP_BY_NAME, name, 0,
    1209             :                                    NULL);
    1210           9 :     if (input == NULL) {
    1211           0 :         return NULL;
    1212             :     }
    1213             : 
    1214           9 :     return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache,
    1215             :                                           neg_timeout, cache_refresh_percent,
    1216             :                                           domain, input);
    1217             : }
    1218             : 
    1219             : struct tevent_req *
    1220           8 : cache_req_group_by_id_send(TALLOC_CTX *mem_ctx,
    1221             :                            struct tevent_context *ev,
    1222             :                            struct resp_ctx *rctx,
    1223             :                            struct sss_nc_ctx *ncache,
    1224             :                            int neg_timeout,
    1225             :                            int cache_refresh_percent,
    1226             :                            const char *domain,
    1227             :                            gid_t gid)
    1228             : {
    1229             :     struct cache_req_input *input;
    1230             : 
    1231           8 :     input = cache_req_input_create(mem_ctx, CACHE_REQ_GROUP_BY_ID, NULL, gid,
    1232             :                                    NULL);
    1233           8 :     if (input == NULL) {
    1234           0 :         return NULL;
    1235             :     }
    1236             : 
    1237           8 :     return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache,
    1238             :                                           neg_timeout, cache_refresh_percent,
    1239             :                                           domain, input);
    1240             : }
    1241             : 
    1242             : struct tevent_req *
    1243           0 : cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx,
    1244             :                               struct tevent_context *ev,
    1245             :                               struct resp_ctx *rctx,
    1246             :                               struct sss_nc_ctx *ncache,
    1247             :                               int neg_timeout,
    1248             :                               int cache_refresh_percent,
    1249             :                               const char *domain,
    1250             :                               const char *name)
    1251             : {
    1252             :     struct cache_req_input *input;
    1253             : 
    1254           0 :     input = cache_req_input_create(mem_ctx, CACHE_REQ_INITGROUPS, name, 0,
    1255             :                                    NULL);
    1256           0 :     if (input == NULL) {
    1257           0 :         return NULL;
    1258             :     }
    1259             : 
    1260           0 :     return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache,
    1261             :                                           neg_timeout, cache_refresh_percent,
    1262             :                                           domain, input);
    1263             : }
    1264             : 
    1265             : struct tevent_req *
    1266           3 : cache_req_user_by_filter_send(TALLOC_CTX *mem_ctx,
    1267             :                               struct tevent_context *ev,
    1268             :                               struct resp_ctx *rctx,
    1269             :                               const char *domain,
    1270             :                               const char *filter)
    1271             : {
    1272             :     struct cache_req_input *input;
    1273             : 
    1274           3 :     input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_FILTER,
    1275             :                                    filter, 0, NULL);
    1276           3 :     if (input == NULL) {
    1277           0 :         return NULL;
    1278             :     }
    1279             : 
    1280           3 :     return cache_req_steal_input_and_send(mem_ctx, ev, rctx, NULL,
    1281             :                                           0, 0, domain, input);
    1282             : }
    1283             : 
    1284             : struct tevent_req *
    1285           2 : cache_req_group_by_filter_send(TALLOC_CTX *mem_ctx,
    1286             :                                struct tevent_context *ev,
    1287             :                                struct resp_ctx *rctx,
    1288             :                                const char *domain,
    1289             :                                const char *filter)
    1290             : {
    1291             :     struct cache_req_input *input;
    1292             : 
    1293           2 :     input = cache_req_input_create(mem_ctx, CACHE_REQ_GROUP_BY_FILTER,
    1294             :                                    filter, 0, NULL);
    1295           2 :     if (input == NULL) {
    1296           0 :         return NULL;
    1297             :     }
    1298             : 
    1299           2 :     return cache_req_steal_input_and_send(mem_ctx, ev, rctx, NULL,
    1300             :                                           0, 0, domain, input);
    1301             : }

Generated by: LCOV version 1.10