LCOV - code coverage report
Current view: top level - db - sysdb_search.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 364 857 42.5 %
Date: 2015-10-19 Functions: 26 31 83.9 %

          Line data    Source code
       1             : /*
       2             :    SSSD
       3             : 
       4             :    System Database
       5             : 
       6             :    Copyright (C) Simo Sorce <ssorce@redhat.com>   2008
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "util/util.h"
      23             : #include "db/sysdb_private.h"
      24             : #include "confdb/confdb.h"
      25             : #include <time.h>
      26             : #include <ctype.h>
      27             : 
      28             : /* users */
      29             : 
      30         158 : int sysdb_getpwnam(TALLOC_CTX *mem_ctx,
      31             :                    struct sss_domain_info *domain,
      32             :                    const char *name,
      33             :                    struct ldb_result **_res)
      34             : {
      35             :     TALLOC_CTX *tmp_ctx;
      36             :     static const char *attrs[] = SYSDB_PW_ATTRS;
      37             :     struct ldb_dn *base_dn;
      38             :     struct ldb_result *res;
      39             :     char *sanitized_name;
      40             :     char *lc_sanitized_name;
      41             :     const char *src_name;
      42             :     int ret;
      43             : 
      44         158 :     tmp_ctx = talloc_new(NULL);
      45         158 :     if (!tmp_ctx) {
      46           0 :         return ENOMEM;
      47             :     }
      48             : 
      49         158 :     base_dn = sysdb_user_base_dn(tmp_ctx, domain);
      50         158 :     if (!base_dn) {
      51           0 :         ret = ENOMEM;
      52           0 :         goto done;
      53             :     }
      54             : 
      55             :     /* If this is a subdomain we need to use fully qualified names for the
      56             :      * search as well by default */
      57         158 :     src_name = sss_get_domain_name(tmp_ctx, name, domain);
      58         158 :     if (!src_name) {
      59           0 :         ret = ENOMEM;
      60           0 :         goto done;
      61             :     }
      62             : 
      63         158 :     ret = sss_filter_sanitize_for_dom(tmp_ctx, src_name, domain,
      64             :                                       &sanitized_name, &lc_sanitized_name);
      65         158 :     if (ret != EOK) {
      66           0 :         goto done;
      67             :     }
      68             : 
      69         158 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
      70             :                      LDB_SCOPE_SUBTREE, attrs, SYSDB_PWNAM_FILTER,
      71             :                      lc_sanitized_name,
      72             :                      sanitized_name, sanitized_name);
      73         158 :     if (ret) {
      74           0 :         ret = sysdb_error_to_errno(ret);
      75           0 :         goto done;
      76             :     }
      77             : 
      78         158 :     *_res = talloc_steal(mem_ctx, res);
      79             : 
      80             : done:
      81         158 :     talloc_zfree(tmp_ctx);
      82         158 :     return ret;
      83             : }
      84             : 
      85          72 : errno_t sysdb_getpwnam_with_views(TALLOC_CTX *mem_ctx,
      86             :                                   struct sss_domain_info *domain,
      87             :                                   const char *name,
      88             :                                   struct ldb_result **res)
      89             : {
      90             :     int ret;
      91          72 :     struct ldb_result *orig_obj = NULL;
      92          72 :     struct ldb_result *override_obj = NULL;
      93             :     TALLOC_CTX *tmp_ctx;
      94             : 
      95          72 :     tmp_ctx = talloc_new(NULL);
      96          72 :     if (tmp_ctx == NULL) {
      97           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
      98           0 :         return ENOMEM;
      99             :     }
     100             : 
     101             :     /* If there are views we first have to search the overrides for matches */
     102          72 :     if (DOM_HAS_VIEWS(domain)) {
     103           0 :         ret = sysdb_search_user_override_by_name(tmp_ctx, domain, name,
     104             :                                                  &override_obj, &orig_obj);
     105           0 :         if (ret != EOK && ret != ENOENT) {
     106           0 :             DEBUG(SSSDBG_OP_FAILURE,
     107             :                   "sysdb_search_override_by_name failed.\n");
     108           0 :             goto done;
     109             :         }
     110             :     }
     111             : 
     112             :     /* If there are no views or nothing was found in the overrides the
     113             :      * original objects are searched. */
     114          72 :     if (orig_obj == NULL) {
     115          72 :         ret = sysdb_getpwnam(tmp_ctx, domain, name, &orig_obj);
     116          72 :         if (ret != EOK) {
     117           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_getpwnam failed.\n");
     118           0 :             goto done;
     119             :         }
     120             :     }
     121             : 
     122             :     /* If there are views we have to check if override values must be added to
     123             :      * the original object. */
     124          72 :     if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) {
     125           0 :         ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0],
     126           0 :                           override_obj == NULL ? NULL : override_obj->msgs[0],
     127             :                           NULL);
     128           0 :         if (ret != EOK && ret != ENOENT) {
     129           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
     130           0 :             goto done;
     131             :         }
     132             : 
     133           0 :         if (ret == ENOENT) {
     134           0 :             *res = talloc_zero(mem_ctx, struct ldb_result);
     135           0 :             if (*res == NULL) {
     136           0 :                 DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
     137           0 :                 ret = ENOMEM;
     138             :             } else {
     139           0 :                 ret = EOK;
     140             :             }
     141           0 :             goto done;
     142             :         }
     143             :     }
     144             : 
     145          72 :     *res = talloc_steal(mem_ctx, orig_obj);
     146          72 :     ret = EOK;
     147             : 
     148             : done:
     149          72 :     talloc_free(tmp_ctx);
     150          72 :     return ret;
     151             : }
     152             : 
     153          43 : int sysdb_getpwuid(TALLOC_CTX *mem_ctx,
     154             :                    struct sss_domain_info *domain,
     155             :                    uid_t uid,
     156             :                    struct ldb_result **_res)
     157             : {
     158             :     TALLOC_CTX *tmp_ctx;
     159          43 :     unsigned long int ul_uid = uid;
     160             :     static const char *attrs[] = SYSDB_PW_ATTRS;
     161             :     struct ldb_dn *base_dn;
     162             :     struct ldb_result *res;
     163             :     int ret;
     164             : 
     165          43 :     tmp_ctx = talloc_new(NULL);
     166          43 :     if (!tmp_ctx) {
     167           0 :         return ENOMEM;
     168             :     }
     169             : 
     170          43 :     base_dn = sysdb_user_base_dn(tmp_ctx, domain);
     171          43 :     if (!base_dn) {
     172           0 :         ret = ENOMEM;
     173           0 :         goto done;
     174             :     }
     175             : 
     176          43 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
     177             :                      LDB_SCOPE_SUBTREE, attrs, SYSDB_PWUID_FILTER, ul_uid);
     178          43 :     if (ret) {
     179           0 :         ret = sysdb_error_to_errno(ret);
     180           0 :         goto done;
     181             :     }
     182             : 
     183          43 :     *_res = talloc_steal(mem_ctx, res);
     184             : 
     185             : done:
     186          43 :     talloc_zfree(tmp_ctx);
     187          43 :     return ret;
     188             : }
     189             : 
     190          30 : errno_t sysdb_getpwuid_with_views(TALLOC_CTX *mem_ctx,
     191             :                                   struct sss_domain_info *domain,
     192             :                                   uid_t uid,
     193             :                                   struct ldb_result **res)
     194             : {
     195             :     int ret;
     196          30 :     struct ldb_result *orig_obj = NULL;
     197          30 :     struct ldb_result *override_obj = NULL;
     198             :     TALLOC_CTX *tmp_ctx;
     199             : 
     200          30 :     tmp_ctx = talloc_new(NULL);
     201          30 :     if (tmp_ctx == NULL) {
     202           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
     203           0 :         return ENOMEM;
     204             :     }
     205             : 
     206             :     /* If there are views we first have to search the overrides for matches */
     207          30 :     if (DOM_HAS_VIEWS(domain)) {
     208           0 :         ret = sysdb_search_user_override_by_uid(tmp_ctx, domain, uid,
     209             :                                                 &override_obj, &orig_obj);
     210           0 :         if (ret != EOK && ret != ENOENT) {
     211           0 :             DEBUG(SSSDBG_OP_FAILURE,
     212             :                   "sysdb_search_user_override_by_uid failed.\n");
     213           0 :             goto done;
     214             :         }
     215             :     }
     216             : 
     217             :     /* If there are no views or nothing was found in the overrides the
     218             :      * original objects are searched. */
     219          30 :     if (orig_obj == NULL) {
     220          30 :         ret = sysdb_getpwuid(tmp_ctx, domain, uid, &orig_obj);
     221          30 :         if (ret != EOK) {
     222           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_getpwuid failed.\n");
     223           0 :             goto done;
     224             :         }
     225             :     }
     226             : 
     227             :     /* If there are views we have to check if override values must be added to
     228             :      * the original object. */
     229          30 :     if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) {
     230           0 :         ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0],
     231           0 :                            override_obj == NULL ? NULL : override_obj->msgs[0],
     232             :                            NULL);
     233           0 :         if (ret != EOK && ret != ENOENT) {
     234           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
     235           0 :             goto done;
     236             :         }
     237             : 
     238           0 :         if (ret == ENOENT) {
     239           0 :             *res = talloc_zero(mem_ctx, struct ldb_result);
     240           0 :             if (*res == NULL) {
     241           0 :                 DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
     242           0 :                 ret = ENOMEM;
     243             :             } else {
     244           0 :                 ret = EOK;
     245             :             }
     246           0 :             goto done;
     247             :         }
     248             :     }
     249             : 
     250          30 :     *res = talloc_steal(mem_ctx, orig_obj);
     251          30 :     ret = EOK;
     252             : 
     253             : done:
     254          30 :     talloc_free(tmp_ctx);
     255          30 :     return ret;
     256             : }
     257             : 
     258          38 : static char *enum_filter(TALLOC_CTX *mem_ctx,
     259             :                          const char *base_filter,
     260             :                          const char *name_filter,
     261             :                          const char *addtl_filter)
     262             : {
     263             :     char *filter;
     264          38 :     TALLOC_CTX *tmp_ctx = NULL;
     265             : 
     266          38 :     tmp_ctx = talloc_new(NULL);
     267          38 :     if (tmp_ctx == NULL) {
     268           0 :         return NULL;
     269             :     }
     270             : 
     271          38 :     if (name_filter == NULL && addtl_filter == NULL) {
     272           6 :         filter = talloc_strdup(tmp_ctx, base_filter);
     273             :     } else {
     274          32 :         filter = talloc_asprintf(tmp_ctx, "(&%s", base_filter);
     275             : 
     276          32 :         if (filter != NULL && name_filter != NULL) {
     277          32 :             filter = talloc_asprintf_append(filter, "(%s=%s)",
     278             :                                             SYSDB_NAME, name_filter);
     279             :         }
     280             : 
     281          32 :         if (filter != NULL && addtl_filter != NULL) {
     282          16 :             filter = talloc_asprintf_append(filter, "%s", addtl_filter);
     283             :         }
     284             : 
     285          32 :         if (filter != NULL) {
     286          32 :             filter = talloc_asprintf_append(filter, ")");
     287             :         }
     288             :     }
     289             : 
     290          38 :     if (filter) {
     291          38 :         talloc_steal(mem_ctx, filter);
     292             :     }
     293             : 
     294          38 :     talloc_free(tmp_ctx);
     295          38 :     return filter;
     296             : }
     297             : 
     298          23 : int sysdb_getpwupn(TALLOC_CTX *mem_ctx,
     299             :                    struct sss_domain_info *domain,
     300             :                    const char *upn,
     301             :                    struct ldb_result **_res)
     302             : {
     303             :     TALLOC_CTX *tmp_ctx;
     304             :     struct ldb_result *res;
     305             :     static const char *attrs[] = SYSDB_PW_ATTRS;
     306             :     errno_t ret;
     307             : 
     308          23 :     tmp_ctx = talloc_new(NULL);
     309          23 :     if (tmp_ctx == NULL) {
     310           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
     311           0 :         return ENOMEM;
     312             :     }
     313             : 
     314          23 :     ret = sysdb_search_user_by_upn_res(tmp_ctx, domain, upn, attrs, &res);
     315          23 :     if (ret != EOK && ret != ENOENT) {
     316           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn_res() failed.\n");
     317           0 :         goto done;
     318             :     }
     319             : 
     320          23 :     *_res = talloc_steal(mem_ctx, res);
     321             : 
     322             : done:
     323          23 :     talloc_free(tmp_ctx);
     324          23 :     return ret;
     325             : }
     326             : 
     327          20 : int sysdb_enumpwent_filter(TALLOC_CTX *mem_ctx,
     328             :                            struct sss_domain_info *domain,
     329             :                            const char *name_filter,
     330             :                            const char *addtl_filter,
     331             :                            struct ldb_result **_res)
     332             : {
     333             :     TALLOC_CTX *tmp_ctx;
     334             :     static const char *attrs[] = SYSDB_PW_ATTRS;
     335          20 :     char *filter = NULL;
     336             :     struct ldb_dn *base_dn;
     337             :     struct ldb_result *res;
     338             :     int ret;
     339             : 
     340          20 :     tmp_ctx = talloc_new(NULL);
     341          20 :     if (!tmp_ctx) {
     342           0 :         return ENOMEM;
     343             :     }
     344             : 
     345          20 :     base_dn = sysdb_user_base_dn(tmp_ctx, domain);
     346          20 :     if (!base_dn) {
     347           0 :         ret = ENOMEM;
     348           0 :         goto done;
     349             :     }
     350             : 
     351          20 :     filter = enum_filter(tmp_ctx, SYSDB_PWENT_FILTER,
     352             :                          name_filter, addtl_filter);
     353          20 :     if (filter == NULL) {
     354           0 :         ret = ENOMEM;
     355           0 :         goto done;
     356             :     }
     357          20 :     DEBUG(SSSDBG_TRACE_LIBS, "Searching cache with [%s]\n", filter);
     358             : 
     359          20 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
     360             :                      LDB_SCOPE_SUBTREE, attrs, "%s", filter);
     361          20 :     if (ret) {
     362           0 :         ret = sysdb_error_to_errno(ret);
     363           0 :         goto done;
     364             :     }
     365             : 
     366          20 :     *_res = talloc_steal(mem_ctx, res);
     367             : 
     368             : done:
     369          20 :     talloc_zfree(tmp_ctx);
     370          20 :     return ret;
     371             : }
     372             : 
     373           2 : int sysdb_enumpwent(TALLOC_CTX *mem_ctx,
     374             :                     struct sss_domain_info *domain,
     375             :                     struct ldb_result **_res)
     376             : {
     377           2 :     return sysdb_enumpwent_filter(mem_ctx, domain, NULL, 0, _res);
     378             : }
     379             : 
     380          12 : int sysdb_enumpwent_filter_with_views(TALLOC_CTX *mem_ctx,
     381             :                                       struct sss_domain_info *domain,
     382             :                                       const char *name_filter,
     383             :                                       const char *addtl_filter,
     384             :                                       struct ldb_result **_res)
     385             : {
     386             :     TALLOC_CTX *tmp_ctx;
     387             :     struct ldb_result *res;
     388             :     size_t c;
     389             :     int ret;
     390             : 
     391          12 :     tmp_ctx = talloc_new(NULL);
     392          12 :     if (tmp_ctx == NULL) {
     393           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
     394           0 :         return ENOMEM;
     395             :     }
     396             : 
     397          12 :     ret = sysdb_enumpwent_filter(tmp_ctx, domain, name_filter, addtl_filter, &res);
     398          12 :     if (ret != EOK) {
     399           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_enumpwent failed.\n");
     400           0 :         goto done;
     401             :     }
     402             : 
     403          12 :     if (DOM_HAS_VIEWS(domain)) {
     404          16 :         for (c = 0; c < res->count; c++) {
     405          10 :             ret = sysdb_add_overrides_to_object(domain, res->msgs[c], NULL,
     406             :                                                 NULL);
     407             :             /* enumeration assumes that the cache is up-to-date, hence we do not
     408             :              * need to handle ENOENT separately. */
     409          10 :             if (ret != EOK) {
     410           0 :                 DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
     411           0 :                 goto done;
     412             :             }
     413             :         }
     414             :     }
     415             : 
     416          12 :     *_res = talloc_steal(mem_ctx, res);
     417             : 
     418             : done:
     419          12 :     talloc_zfree(tmp_ctx);
     420          12 :     return ret;
     421             : }
     422             : 
     423           1 : int sysdb_enumpwent_with_views(TALLOC_CTX *mem_ctx,
     424             :                                struct sss_domain_info *domain,
     425             :                                struct ldb_result **_res)
     426             : {
     427           1 :     return sysdb_enumpwent_filter_with_views(mem_ctx, domain, NULL, NULL, _res);
     428             : }
     429             : 
     430             : /* groups */
     431             : 
     432          85 : static int mpg_convert(struct ldb_message *msg)
     433             : {
     434             :     struct ldb_message_element *el;
     435          85 :     struct ldb_val *val = NULL;
     436             :     int i;
     437             : 
     438          85 :     el = ldb_msg_find_element(msg, "objectClass");
     439          85 :     if (!el) return EINVAL;
     440             : 
     441             :     /* see if this is a user to convert to a group */
     442         160 :     for (i = 0; i < el->num_values; i++) {
     443          85 :         val = &(el->values[i]);
     444         170 :         if (strncasecmp(SYSDB_USER_CLASS,
     445          85 :                         (char *)val->data, val->length) == 0) {
     446          10 :             break;
     447             :         }
     448             :     }
     449             :     /* no, leave as is */
     450          85 :     if (i == el->num_values) return EOK;
     451             : 
     452             :     /* yes, convert */
     453          10 :     val->data = (uint8_t *)talloc_strdup(msg, SYSDB_GROUP_CLASS);
     454          10 :     if (val->data == NULL) return ENOMEM;
     455          10 :     val->length = strlen(SYSDB_GROUP_CLASS);
     456             : 
     457          10 :     return EOK;
     458             : }
     459             : 
     460         108 : static int mpg_res_convert(struct ldb_result *res)
     461             : {
     462             :     int ret;
     463             :     int i;
     464             : 
     465         193 :     for (i = 0; i < res->count; i++) {
     466          85 :         ret = mpg_convert(res->msgs[i]);
     467          85 :         if (ret) {
     468           0 :             return ret;
     469             :         }
     470             :     }
     471         108 :     return EOK;
     472             : }
     473             : 
     474          33 : int sysdb_getgrnam_with_views(TALLOC_CTX *mem_ctx,
     475             :                               struct sss_domain_info *domain,
     476             :                               const char *name,
     477             :                               struct ldb_result **res)
     478             : {
     479             :     TALLOC_CTX *tmp_ctx;
     480             :     int ret;
     481          33 :     struct ldb_result *orig_obj = NULL;
     482          33 :     struct ldb_result *override_obj = NULL;
     483             :     struct ldb_message_element *el;
     484             : 
     485          33 :     tmp_ctx = talloc_new(NULL);
     486          33 :     if (!tmp_ctx) {
     487           0 :         return ENOMEM;
     488             :     }
     489             : 
     490             :     /* If there are views we first have to search the overrides for matches */
     491          33 :     if (DOM_HAS_VIEWS(domain)) {
     492           0 :         ret = sysdb_search_group_override_by_name(tmp_ctx, domain, name,
     493             :                                                   &override_obj, &orig_obj);
     494           0 :         if (ret != EOK && ret != ENOENT) {
     495           0 :             DEBUG(SSSDBG_OP_FAILURE,
     496             :                   "sysdb_search_group_override_by_name failed.\n");
     497           0 :             goto done;
     498             :         }
     499             :     }
     500             : 
     501             :     /* If there are no views or nothing was found in the overrides the
     502             :      * original objects are searched. */
     503          33 :     if (orig_obj == NULL) {
     504          33 :         ret = sysdb_getgrnam(tmp_ctx, domain, name, &orig_obj);
     505          33 :         if (ret != EOK) {
     506           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_getgrnam failed.\n");
     507           0 :             goto done;
     508             :         }
     509             :     }
     510             : 
     511             :     /* If there are views we have to check if override values must be added to
     512             :      * the original object. */
     513          33 :     if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) {
     514           0 :         if (!is_local_view(domain->view_name)) {
     515           0 :             el = ldb_msg_find_element(orig_obj->msgs[0], SYSDB_GHOST);
     516           0 :             if (el != NULL && el->num_values != 0) {
     517           0 :                 DEBUG(SSSDBG_TRACE_ALL, "Group object [%s], contains ghost "
     518             :                       "entries which must be resolved before overrides can be "
     519             :                       "applied.\n",
     520             :                       ldb_dn_get_linearized(orig_obj->msgs[0]->dn));
     521           0 :                 ret = ENOENT;
     522           0 :                 goto done;
     523             :             }
     524             :         }
     525             : 
     526           0 :         ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0],
     527           0 :                           override_obj == NULL ? NULL : override_obj ->msgs[0],
     528             :                           NULL);
     529           0 :         if (ret != EOK) {
     530           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
     531           0 :             goto done;
     532             :         }
     533             : 
     534           0 :         ret = sysdb_add_group_member_overrides(domain, orig_obj->msgs[0]);
     535           0 :         if (ret != EOK) {
     536           0 :             DEBUG(SSSDBG_OP_FAILURE,
     537             :                   "sysdb_add_group_member_overrides failed.\n");
     538           0 :             goto done;
     539             :         }
     540             :     }
     541             : 
     542          33 :     *res = talloc_steal(mem_ctx, orig_obj);
     543          33 :     ret = EOK;
     544             : 
     545             : done:
     546          33 :     if (ret == ENOENT) {
     547           0 :         DEBUG(SSSDBG_TRACE_ALL, "Returning empty result.\n");
     548           0 :         *res = talloc_zero(mem_ctx, struct ldb_result);
     549           0 :         if (*res == NULL) {
     550           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
     551           0 :             ret = ENOMEM;
     552             :         } else {
     553           0 :             ret = EOK;
     554             :         }
     555             :     }
     556             : 
     557          33 :     talloc_free(tmp_ctx);
     558          33 :     return ret;
     559             : }
     560             : 
     561          57 : int sysdb_getgrnam(TALLOC_CTX *mem_ctx,
     562             :                    struct sss_domain_info *domain,
     563             :                    const char *name,
     564             :                    struct ldb_result **_res)
     565             : {
     566             :     TALLOC_CTX *tmp_ctx;
     567             :     static const char *attrs[] = SYSDB_GRSRC_ATTRS;
     568             :     const char *fmt_filter;
     569             :     char *sanitized_name;
     570             :     struct ldb_dn *base_dn;
     571             :     struct ldb_result *res;
     572             :     const char *src_name;
     573             :     char *lc_sanitized_name;
     574             :     int ret;
     575             : 
     576          57 :     tmp_ctx = talloc_new(NULL);
     577          57 :     if (!tmp_ctx) {
     578           0 :         return ENOMEM;
     579             :     }
     580             : 
     581          57 :     if (domain->mpg) {
     582          24 :         fmt_filter = SYSDB_GRNAM_MPG_FILTER;
     583          24 :         base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
     584             :                                  SYSDB_DOM_BASE, domain->name);
     585             :     } else {
     586          33 :         fmt_filter = SYSDB_GRNAM_FILTER;
     587          33 :         base_dn = sysdb_group_base_dn(tmp_ctx, domain);
     588             :     }
     589          57 :     if (!base_dn) {
     590           0 :         ret = ENOMEM;
     591           0 :         goto done;
     592             :     }
     593             : 
     594             :     /* If this is a subomain we need to use fully qualified names for the
     595             :      * search as well by default */
     596          57 :     src_name = sss_get_domain_name(tmp_ctx, name, domain);
     597          57 :     if (!src_name) {
     598           0 :         ret = ENOMEM;
     599           0 :         goto done;
     600             :     }
     601             : 
     602          57 :     ret = sss_filter_sanitize_for_dom(tmp_ctx, src_name, domain,
     603             :                                       &sanitized_name, &lc_sanitized_name);
     604          57 :     if (ret != EOK) {
     605           0 :         goto done;
     606             :     }
     607             : 
     608          57 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
     609             :                      LDB_SCOPE_SUBTREE, attrs, fmt_filter,
     610             :                      lc_sanitized_name, sanitized_name, sanitized_name);
     611          57 :     if (ret) {
     612           0 :         ret = sysdb_error_to_errno(ret);
     613           0 :         goto done;
     614             :     }
     615             : 
     616          57 :     ret = mpg_res_convert(res);
     617          57 :     if (ret) {
     618           0 :         goto done;
     619             :     }
     620             : 
     621          57 :     *_res = talloc_steal(mem_ctx, res);
     622             : 
     623             : done:
     624          57 :     talloc_zfree(tmp_ctx);
     625          57 :     return ret;
     626             : }
     627             : 
     628          23 : int sysdb_getgrgid_with_views(TALLOC_CTX *mem_ctx,
     629             :                               struct sss_domain_info *domain,
     630             :                               gid_t gid,
     631             :                               struct ldb_result **res)
     632             : {
     633             :     TALLOC_CTX *tmp_ctx;
     634             :     int ret;
     635          23 :     struct ldb_result *orig_obj = NULL;
     636          23 :     struct ldb_result *override_obj = NULL;
     637             :     struct ldb_message_element *el;
     638             : 
     639          23 :     tmp_ctx = talloc_new(NULL);
     640          23 :     if (!tmp_ctx) {
     641           0 :         return ENOMEM;
     642             :     }
     643             : 
     644             :     /* If there are views we first have to search the overrides for matches */
     645          23 :     if (DOM_HAS_VIEWS(domain)) {
     646           0 :         ret = sysdb_search_group_override_by_gid(tmp_ctx, domain, gid,
     647             :                                                  &override_obj, &orig_obj);
     648           0 :         if (ret != EOK && ret != ENOENT) {
     649           0 :             DEBUG(SSSDBG_OP_FAILURE,
     650             :                   "sysdb_search_group_override_by_gid failed.\n");
     651           0 :             goto done;
     652             :         }
     653             :     }
     654             : 
     655             :     /* If there are no views or nothing was found in the overrides the
     656             :      * original objects are searched. */
     657          23 :     if (orig_obj == NULL) {
     658          23 :         ret = sysdb_getgrgid(tmp_ctx, domain, gid, &orig_obj);
     659          23 :         if (ret != EOK) {
     660           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_getgrgid failed.\n");
     661           0 :             goto done;
     662             :         }
     663             :     }
     664             : 
     665             :     /* If there are views we have to check if override values must be added to
     666             :      * the original object. */
     667          23 :     if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) {
     668           0 :         if (!is_local_view(domain->view_name)) {
     669           0 :             el = ldb_msg_find_element(orig_obj->msgs[0], SYSDB_GHOST);
     670           0 :             if (el != NULL && el->num_values != 0) {
     671           0 :                 DEBUG(SSSDBG_TRACE_ALL, "Group object [%s], contains ghost "
     672             :                       "entries which must be resolved before overrides can be "
     673             :                       "applied.\n",
     674             :                       ldb_dn_get_linearized(orig_obj->msgs[0]->dn));
     675           0 :                 ret = ENOENT;
     676           0 :                 goto done;
     677             :             }
     678             :         }
     679             : 
     680           0 :         ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0],
     681           0 :                           override_obj == NULL ? NULL : override_obj ->msgs[0],
     682             :                           NULL);
     683           0 :         if (ret != EOK) {
     684           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
     685           0 :             goto done;
     686             :         }
     687             : 
     688           0 :         ret = sysdb_add_group_member_overrides(domain, orig_obj->msgs[0]);
     689           0 :         if (ret != EOK) {
     690           0 :             DEBUG(SSSDBG_OP_FAILURE,
     691             :                   "sysdb_add_group_member_overrides failed.\n");
     692           0 :             goto done;
     693             :         }
     694             :     }
     695             : 
     696          23 :     *res = talloc_steal(mem_ctx, orig_obj);
     697          23 :     ret = EOK;
     698             : 
     699             : done:
     700          23 :     if (ret == ENOENT) {
     701           0 :         DEBUG(SSSDBG_TRACE_ALL, "Returning empty result.\n");
     702           0 :         *res = talloc_zero(mem_ctx, struct ldb_result);
     703           0 :         if (*res == NULL) {
     704           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
     705           0 :             ret = ENOMEM;
     706             :         } else {
     707           0 :             ret = EOK;
     708             :         }
     709             :     }
     710             : 
     711          23 :     talloc_free(tmp_ctx);
     712          23 :     return ret;
     713             : }
     714             : 
     715          33 : int sysdb_getgrgid(TALLOC_CTX *mem_ctx,
     716             :                    struct sss_domain_info *domain,
     717             :                    gid_t gid,
     718             :                    struct ldb_result **_res)
     719             : {
     720             :     TALLOC_CTX *tmp_ctx;
     721          33 :     unsigned long int ul_gid = gid;
     722             :     static const char *attrs[] = SYSDB_GRSRC_ATTRS;
     723             :     const char *fmt_filter;
     724             :     struct ldb_dn *base_dn;
     725             :     struct ldb_result *res;
     726             :     int ret;
     727             : 
     728          33 :     tmp_ctx = talloc_new(NULL);
     729          33 :     if (!tmp_ctx) {
     730           0 :         return ENOMEM;
     731             :     }
     732             : 
     733          33 :     if (domain->mpg) {
     734          10 :         fmt_filter = SYSDB_GRGID_MPG_FILTER;
     735          10 :         base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
     736             :                                  SYSDB_DOM_BASE, domain->name);
     737             :     } else {
     738          23 :         fmt_filter = SYSDB_GRGID_FILTER;
     739          23 :         base_dn = sysdb_group_base_dn(tmp_ctx, domain);
     740             :     }
     741          33 :     if (!base_dn) {
     742           0 :         ret = ENOMEM;
     743           0 :         goto done;
     744             :     }
     745             : 
     746          33 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
     747             :                      LDB_SCOPE_SUBTREE, attrs, fmt_filter, ul_gid);
     748          33 :     if (ret) {
     749           0 :         ret = sysdb_error_to_errno(ret);
     750           0 :         goto done;
     751             :     }
     752             : 
     753          33 :     ret = mpg_res_convert(res);
     754          33 :     if (ret) {
     755           0 :         goto done;
     756             :     }
     757             : 
     758          33 :     *_res = talloc_steal(mem_ctx, res);
     759             : 
     760             : done:
     761          33 :     talloc_zfree(tmp_ctx);
     762          33 :     return ret;
     763             : }
     764             : 
     765          18 : int sysdb_enumgrent_filter(TALLOC_CTX *mem_ctx,
     766             :                            struct sss_domain_info *domain,
     767             :                            const char *name_filter,
     768             :                            const char *addtl_filter,
     769             :                            struct ldb_result **_res)
     770             : {
     771             :     TALLOC_CTX *tmp_ctx;
     772             :     static const char *attrs[] = SYSDB_GRSRC_ATTRS;
     773          18 :     const char *filter = NULL;
     774             :     const char *base_filter;
     775             :     struct ldb_dn *base_dn;
     776             :     struct ldb_result *res;
     777             :     int ret;
     778             : 
     779          18 :     tmp_ctx = talloc_new(NULL);
     780          18 :     if (!tmp_ctx) {
     781           0 :         return ENOMEM;
     782             :     }
     783             : 
     784          18 :     if (domain->mpg) {
     785          14 :         base_filter = SYSDB_GRENT_MPG_FILTER;
     786          14 :         base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
     787             :                                  SYSDB_DOM_BASE, domain->name);
     788             :     } else {
     789           4 :         base_filter = SYSDB_GRENT_FILTER;
     790           4 :         base_dn = sysdb_group_base_dn(tmp_ctx, domain);
     791             :     }
     792          18 :     if (!base_dn) {
     793           0 :         ret = ENOMEM;
     794           0 :         goto done;
     795             :     }
     796             : 
     797          18 :     filter = enum_filter(tmp_ctx, base_filter,
     798             :                          name_filter, addtl_filter);
     799          18 :     if (filter == NULL) {
     800           0 :         ret = ENOMEM;
     801           0 :         goto done;
     802             :     }
     803          18 :     DEBUG(SSSDBG_TRACE_LIBS, "Searching cache with [%s]\n", filter);
     804             : 
     805          18 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
     806             :                      LDB_SCOPE_SUBTREE, attrs, "%s", filter);
     807          18 :     if (ret) {
     808           0 :         ret = sysdb_error_to_errno(ret);
     809           0 :         goto done;
     810             :     }
     811             : 
     812          18 :     ret = mpg_res_convert(res);
     813          18 :     if (ret) {
     814           0 :         goto done;
     815             :     }
     816             : 
     817          18 :     *_res = talloc_steal(mem_ctx, res);
     818             : 
     819             : done:
     820          18 :     talloc_zfree(tmp_ctx);
     821          18 :     return ret;
     822             : }
     823             : 
     824           2 : int sysdb_enumgrent(TALLOC_CTX *mem_ctx,
     825             :                     struct sss_domain_info *domain,
     826             :                     struct ldb_result **_res)
     827             : {
     828           2 :     return sysdb_enumgrent_filter(mem_ctx, domain, NULL, 0, _res);
     829             : }
     830             : 
     831          10 : int sysdb_enumgrent_filter_with_views(TALLOC_CTX *mem_ctx,
     832             :                                       struct sss_domain_info *domain,
     833             :                                       const char *name_filter,
     834             :                                       const char *addtl_filter,
     835             :                                       struct ldb_result **_res)
     836             : {
     837             :     TALLOC_CTX *tmp_ctx;
     838             :     struct ldb_result *res;
     839             :     size_t c;
     840             :     int ret;
     841             : 
     842          10 :     tmp_ctx = talloc_new(NULL);
     843          10 :     if (tmp_ctx == NULL) {
     844           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
     845           0 :         return ENOMEM;
     846             :     }
     847             : 
     848          10 :     ret = sysdb_enumgrent_filter(tmp_ctx, domain, name_filter, addtl_filter, &res);
     849          10 :     if (ret != EOK) {
     850           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_enumgrent failed.\n");
     851           0 :         goto done;
     852             :     }
     853             : 
     854          10 :     if (DOM_HAS_VIEWS(domain)) {
     855          16 :         for (c = 0; c < res->count; c++) {
     856          10 :             ret = sysdb_add_overrides_to_object(domain, res->msgs[c], NULL,
     857             :                                                 NULL);
     858             :             /* enumeration assumes that the cache is up-to-date, hence we do not
     859             :              * need to handle ENOENT separately. */
     860          10 :             if (ret != EOK) {
     861           0 :                 DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
     862           0 :                 goto done;
     863             :             }
     864             : 
     865          10 :             ret = sysdb_add_group_member_overrides(domain, res->msgs[c]);
     866          10 :             if (ret != EOK) {
     867           0 :                 DEBUG(SSSDBG_OP_FAILURE,
     868             :                       "sysdb_add_group_member_overrides failed.\n");
     869           0 :                 goto done;
     870             :             }
     871             :         }
     872             :     }
     873             : 
     874             : 
     875          10 :     *_res = talloc_steal(mem_ctx, res);
     876             : 
     877             : done:
     878          10 :     talloc_zfree(tmp_ctx);
     879          10 :     return ret;
     880             : }
     881             : 
     882           1 : int sysdb_enumgrent_with_views(TALLOC_CTX *mem_ctx,
     883             :                                struct sss_domain_info *domain,
     884             :                                struct ldb_result **_res)
     885             : {
     886           1 :     return sysdb_enumgrent_filter_with_views(mem_ctx, domain, NULL, NULL, _res);
     887             : }
     888             : 
     889          11 : int sysdb_initgroups(TALLOC_CTX *mem_ctx,
     890             :                      struct sss_domain_info *domain,
     891             :                      const char *name,
     892             :                      struct ldb_result **_res)
     893             : {
     894             :     TALLOC_CTX *tmp_ctx;
     895             :     struct ldb_result *res;
     896             :     struct ldb_dn *user_dn;
     897             :     struct ldb_request *req;
     898             :     struct ldb_control **ctrl;
     899             :     struct ldb_asq_control *control;
     900             :     static const char *attrs[] = SYSDB_INITGR_ATTRS;
     901             :     int ret;
     902             : 
     903          11 :     tmp_ctx = talloc_new(NULL);
     904          11 :     if (!tmp_ctx) {
     905           0 :         return ENOMEM;
     906             :     }
     907             : 
     908          11 :     ret = sysdb_getpwnam(tmp_ctx, domain, name, &res);
     909          11 :     if (ret != EOK) {
     910           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_getpwnam failed: [%d][%s]\n",
     911             :                   ret, strerror(ret));
     912           0 :         goto done;
     913             :     }
     914             : 
     915          11 :     if (res->count == 0) {
     916             :         /* User is not cached yet */
     917           0 :         *_res = talloc_steal(mem_ctx, res);
     918           0 :         ret = EOK;
     919           0 :         goto done;
     920             : 
     921          11 :     } else if (res->count != 1) {
     922           0 :         ret = EIO;
     923           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     924             :               "sysdb_getpwnam returned count: [%d]\n", res->count);
     925           0 :         goto done;
     926             :     }
     927             : 
     928             :     /* no need to steal the dn, we are not freeing the result */
     929          11 :     user_dn = res->msgs[0]->dn;
     930             : 
     931             :     /* note we count on the fact that the default search callback
     932             :      * will just keep appending values. This is by design and can't
     933             :      * change so it is ok to already have a result (from the getpwnam)
     934             :      * even before we call the next search */
     935             : 
     936          11 :     ctrl = talloc_array(tmp_ctx, struct ldb_control *, 2);
     937          11 :     if (!ctrl) {
     938           0 :         ret = ENOMEM;
     939           0 :         goto done;
     940             :     }
     941          11 :     ctrl[1] = NULL;
     942          11 :     ctrl[0] = talloc(ctrl, struct ldb_control);
     943          11 :     if (!ctrl[0]) {
     944           0 :         ret = ENOMEM;
     945           0 :         goto done;
     946             :     }
     947          11 :     ctrl[0]->oid = LDB_CONTROL_ASQ_OID;
     948          11 :     ctrl[0]->critical = 1;
     949          11 :     control = talloc(ctrl[0], struct ldb_asq_control);
     950          11 :     if (!control) {
     951           0 :         ret = ENOMEM;
     952           0 :         goto done;
     953             :     }
     954          11 :     control->request = 1;
     955          11 :     control->source_attribute = talloc_strdup(control, SYSDB_INITGR_ATTR);
     956          11 :     if (!control->source_attribute) {
     957           0 :         ret = ENOMEM;
     958           0 :         goto done;
     959             :     }
     960          11 :     control->src_attr_len = strlen(control->source_attribute);
     961          11 :     ctrl[0]->data = control;
     962             : 
     963          11 :     ret = ldb_build_search_req(&req, domain->sysdb->ldb, tmp_ctx,
     964             :                                user_dn, LDB_SCOPE_BASE,
     965             :                                SYSDB_INITGR_FILTER, attrs, ctrl,
     966             :                                res, ldb_search_default_callback,
     967             :                                NULL);
     968          11 :     if (ret != LDB_SUCCESS) {
     969           0 :         ret = sysdb_error_to_errno(ret);
     970           0 :         goto done;
     971             :     }
     972             : 
     973          11 :     ret = ldb_request(domain->sysdb->ldb, req);
     974          11 :     if (ret == LDB_SUCCESS) {
     975          11 :         ret = ldb_wait(req->handle, LDB_WAIT_ALL);
     976             :     }
     977          11 :     if (ret != LDB_SUCCESS) {
     978           0 :         ret = sysdb_error_to_errno(ret);
     979           0 :         goto done;
     980             :     }
     981             : 
     982          11 :     *_res = talloc_steal(mem_ctx, res);
     983             : 
     984             : done:
     985          11 :     talloc_zfree(tmp_ctx);
     986          11 :     return ret;
     987             : }
     988             : 
     989           0 : int sysdb_initgroups_by_upn(TALLOC_CTX *mem_ctx,
     990             :                              struct sss_domain_info *domain,
     991             :                              const char *upn,
     992             :                              struct ldb_result **_res)
     993             : {
     994             :     TALLOC_CTX *tmp_ctx;
     995             :     struct ldb_message *msg;
     996             :     struct ldb_result *res;
     997             :     const char *sysdb_name;
     998             :     static const char *attrs[] = SYSDB_INITGR_ATTRS;
     999             :     size_t i;
    1000             :     errno_t ret;
    1001             : 
    1002           0 :     tmp_ctx = talloc_new(NULL);
    1003           0 :     if (tmp_ctx == NULL) {
    1004           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
    1005           0 :         return ENOMEM;
    1006             :     }
    1007             : 
    1008           0 :     ret = sysdb_search_user_by_upn(tmp_ctx, domain, upn, attrs, &msg);
    1009           0 :     if (ret != EOK && ret != ENOENT) {
    1010           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_upn() failed.\n");
    1011           0 :         goto done;
    1012             :     }
    1013             : 
    1014           0 :     res = talloc_zero(tmp_ctx, struct ldb_result);
    1015           0 :     if (res == NULL) {
    1016           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_zero() failed.\n");
    1017           0 :         ret = ENOMEM;
    1018           0 :         goto done;
    1019             :     }
    1020             : 
    1021           0 :     if (ret == ENOENT) {
    1022           0 :         res->count = 0;
    1023           0 :         res->msgs = NULL;
    1024             :     } else {
    1025           0 :         sysdb_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
    1026           0 :         if (sysdb_name == NULL) {
    1027           0 :             DEBUG(SSSDBG_OP_FAILURE, "Sysdb entry does not have a name.\n");
    1028           0 :             return EINVAL;
    1029             :         }
    1030             : 
    1031           0 :         ret = sysdb_initgroups(tmp_ctx, domain, sysdb_name, &res);
    1032           0 :         if (ret == EOK && DOM_HAS_VIEWS(domain)) {
    1033           0 :             for (i = 0; i < res->count; i++) {
    1034           0 :                 ret = sysdb_add_overrides_to_object(domain, res->msgs[i],
    1035             :                                                     NULL, NULL);
    1036           0 :                 if (ret != EOK) {
    1037           0 :                     DEBUG(SSSDBG_OP_FAILURE,
    1038             :                         "sysdb_add_overrides_to_object() failed.\n");
    1039           0 :                     return ret;
    1040             :                 }
    1041             :             }
    1042             :         }
    1043             :     }
    1044             : 
    1045           0 :     *_res = talloc_steal(mem_ctx, res);
    1046           0 :     ret = EOK;
    1047             : 
    1048             : done:
    1049           0 :     talloc_free(tmp_ctx);
    1050           0 :     return ret;
    1051             : }
    1052             : 
    1053           9 : int sysdb_initgroups_with_views(TALLOC_CTX *mem_ctx,
    1054             :                                 struct sss_domain_info *domain,
    1055             :                                 const char *name,
    1056             :                                 struct ldb_result **_res)
    1057             : {
    1058             :     TALLOC_CTX *tmp_ctx;
    1059             :     struct ldb_result *res;
    1060             :     struct ldb_dn *user_dn;
    1061             :     struct ldb_request *req;
    1062             :     struct ldb_control **ctrl;
    1063             :     struct ldb_asq_control *control;
    1064             :     static const char *attrs[] = SYSDB_INITGR_ATTRS;
    1065             :     int ret;
    1066             :     size_t c;
    1067             : 
    1068           9 :     tmp_ctx = talloc_new(NULL);
    1069           9 :     if (!tmp_ctx) {
    1070           0 :         return ENOMEM;
    1071             :     }
    1072             : 
    1073           9 :     ret = sysdb_getpwnam_with_views(tmp_ctx, domain, name, &res);
    1074           9 :     if (ret != EOK) {
    1075           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_getpwnam failed: [%d][%s]\n",
    1076             :                   ret, strerror(ret));
    1077           0 :         goto done;
    1078             :     }
    1079             : 
    1080           9 :     if (res->count == 0) {
    1081             :         /* User is not cached yet */
    1082           3 :         *_res = talloc_steal(mem_ctx, res);
    1083           3 :         ret = EOK;
    1084           3 :         goto done;
    1085             : 
    1086           6 :     } else if (res->count != 1) {
    1087           0 :         ret = EIO;
    1088           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
    1089             :               "sysdb_getpwnam returned count: [%d]\n", res->count);
    1090           0 :         goto done;
    1091             :     }
    1092             : 
    1093             :     /* no need to steal the dn, we are not freeing the result */
    1094           6 :     user_dn = res->msgs[0]->dn;
    1095             : 
    1096             :     /* note we count on the fact that the default search callback
    1097             :      * will just keep appending values. This is by design and can't
    1098             :      * change so it is ok to already have a result (from the getpwnam)
    1099             :      * even before we call the next search */
    1100             : 
    1101           6 :     ctrl = talloc_array(tmp_ctx, struct ldb_control *, 2);
    1102           6 :     if (!ctrl) {
    1103           0 :         ret = ENOMEM;
    1104           0 :         goto done;
    1105             :     }
    1106           6 :     ctrl[1] = NULL;
    1107           6 :     ctrl[0] = talloc(ctrl, struct ldb_control);
    1108           6 :     if (!ctrl[0]) {
    1109           0 :         ret = ENOMEM;
    1110           0 :         goto done;
    1111             :     }
    1112           6 :     ctrl[0]->oid = LDB_CONTROL_ASQ_OID;
    1113           6 :     ctrl[0]->critical = 1;
    1114           6 :     control = talloc(ctrl[0], struct ldb_asq_control);
    1115           6 :     if (!control) {
    1116           0 :         ret = ENOMEM;
    1117           0 :         goto done;
    1118             :     }
    1119           6 :     control->request = 1;
    1120           6 :     control->source_attribute = talloc_strdup(control, SYSDB_INITGR_ATTR);
    1121           6 :     if (!control->source_attribute) {
    1122           0 :         ret = ENOMEM;
    1123           0 :         goto done;
    1124             :     }
    1125           6 :     control->src_attr_len = strlen(control->source_attribute);
    1126           6 :     ctrl[0]->data = control;
    1127             : 
    1128           6 :     ret = ldb_build_search_req(&req, domain->sysdb->ldb, tmp_ctx,
    1129             :                                user_dn, LDB_SCOPE_BASE,
    1130             :                                SYSDB_INITGR_FILTER, attrs, ctrl,
    1131             :                                res, ldb_search_default_callback,
    1132             :                                NULL);
    1133           6 :     if (ret != LDB_SUCCESS) {
    1134           0 :         ret = sysdb_error_to_errno(ret);
    1135           0 :         goto done;
    1136             :     }
    1137             : 
    1138           6 :     ret = ldb_request(domain->sysdb->ldb, req);
    1139           6 :     if (ret == LDB_SUCCESS) {
    1140           6 :         ret = ldb_wait(req->handle, LDB_WAIT_ALL);
    1141             :     }
    1142           6 :     if (ret != LDB_SUCCESS) {
    1143           0 :         ret = sysdb_error_to_errno(ret);
    1144           0 :         goto done;
    1145             :     }
    1146             : 
    1147           6 :     if (DOM_HAS_VIEWS(domain)) {
    1148             :         /* Skip user entry because it already has override values added */
    1149           0 :         for (c = 1; c < res->count; c++) {
    1150           0 :             ret = sysdb_add_overrides_to_object(domain, res->msgs[c], NULL,
    1151             :                                                 NULL);
    1152           0 :             if (ret != EOK) {
    1153           0 :                 DEBUG(SSSDBG_OP_FAILURE,
    1154             :                       "sysdb_add_overrides_to_object failed.\n");
    1155           0 :                 goto done;
    1156             :             }
    1157             :         }
    1158             :     }
    1159             : 
    1160           6 :     *_res = talloc_steal(mem_ctx, res);
    1161             : 
    1162             : done:
    1163           9 :     talloc_zfree(tmp_ctx);
    1164           9 :     return ret;
    1165             : }
    1166             : 
    1167          24 : int sysdb_get_user_attr(TALLOC_CTX *mem_ctx,
    1168             :                         struct sss_domain_info *domain,
    1169             :                         const char *name,
    1170             :                         const char **attributes,
    1171             :                         struct ldb_result **_res)
    1172             : {
    1173             :     TALLOC_CTX *tmp_ctx;
    1174             :     struct ldb_dn *base_dn;
    1175             :     struct ldb_result *res;
    1176             :     const char *src_name;
    1177             :     char *sanitized_name;
    1178             :     char *lc_sanitized_name;
    1179             :     int ret;
    1180             : 
    1181          24 :     tmp_ctx = talloc_new(NULL);
    1182          24 :     if (!tmp_ctx) {
    1183           0 :         return ENOMEM;
    1184             :     }
    1185             : 
    1186          24 :     base_dn = sysdb_user_base_dn(tmp_ctx, domain);
    1187          24 :     if (!base_dn) {
    1188           0 :         ret = ENOMEM;
    1189           0 :         goto done;
    1190             :     }
    1191             : 
    1192             :     /* If this is a subdomain we need to use fully qualified names for the
    1193             :      * search as well by default */
    1194          24 :     src_name = sss_get_domain_name(tmp_ctx, name, domain);
    1195          24 :     if (!src_name) {
    1196           0 :         ret = ENOMEM;
    1197           0 :         goto done;
    1198             :     }
    1199             : 
    1200          24 :     ret = sss_filter_sanitize_for_dom(tmp_ctx, src_name, domain,
    1201             :                                       &sanitized_name, &lc_sanitized_name);
    1202          24 :     if (ret != EOK) {
    1203           0 :         goto done;
    1204             :     }
    1205             : 
    1206          24 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, base_dn,
    1207             :                      LDB_SCOPE_SUBTREE, attributes,
    1208             :                      SYSDB_PWNAM_FILTER, lc_sanitized_name, sanitized_name,
    1209             :                      sanitized_name);
    1210          24 :     if (ret) {
    1211           0 :         ret = sysdb_error_to_errno(ret);
    1212           0 :         goto done;
    1213             :     }
    1214             : 
    1215          24 :     *_res = talloc_steal(mem_ctx, res);
    1216             : 
    1217             : done:
    1218          24 :     talloc_zfree(tmp_ctx);
    1219          24 :     return ret;
    1220             : }
    1221             : 
    1222           0 : int sysdb_get_user_attr_with_views(TALLOC_CTX *mem_ctx,
    1223             :                                    struct sss_domain_info *domain,
    1224             :                                    const char *name,
    1225             :                                    const char **attributes,
    1226             :                                    struct ldb_result **_res)
    1227             : {
    1228             :     int ret;
    1229           0 :     struct ldb_result *orig_obj = NULL;
    1230           0 :     struct ldb_result *override_obj = NULL;
    1231           0 :     const char **attrs = NULL;
    1232           0 :     const char *mandatory_override_attrs[] = {SYSDB_OVERRIDE_DN,
    1233             :                                               SYSDB_OVERRIDE_OBJECT_DN,
    1234             :                                               NULL};
    1235             :     TALLOC_CTX *tmp_ctx;
    1236             : 
    1237           0 :     tmp_ctx = talloc_new(NULL);
    1238           0 :     if (tmp_ctx == NULL) {
    1239           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
    1240           0 :         return ENOMEM;
    1241             :     }
    1242             : 
    1243           0 :     attrs = attributes;
    1244             : 
    1245             :     /* If there are views we first have to search the overrides for matches */
    1246           0 :     if (DOM_HAS_VIEWS(domain)) {
    1247           0 :         ret = add_strings_lists(tmp_ctx, attributes, mandatory_override_attrs,
    1248             :                                 false, discard_const(&attrs));
    1249           0 :         if (ret != EOK) {
    1250           0 :             DEBUG(SSSDBG_OP_FAILURE, "add_strings_lists failed.\n");
    1251           0 :             goto done;
    1252             :         }
    1253             : 
    1254           0 :         ret = sysdb_search_user_override_attrs_by_name(tmp_ctx, domain, name,
    1255             :                                             attrs, &override_obj, &orig_obj);
    1256           0 :         if (ret != EOK && ret != ENOENT) {
    1257           0 :             DEBUG(SSSDBG_OP_FAILURE,
    1258             :                   "sysdb_search_user_override_attrs_by_name failed.\n");
    1259           0 :             return ret;
    1260             :         }
    1261             :     }
    1262             : 
    1263             :     /* If there are no views or nothing was found in the overrides the
    1264             :      * original objects are searched. */
    1265           0 :     if (orig_obj == NULL) {
    1266           0 :         ret = sysdb_get_user_attr(tmp_ctx, domain, name, attrs, &orig_obj);
    1267           0 :         if (ret != EOK) {
    1268           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_user_attr failed.\n");
    1269           0 :             return ret;
    1270             :         }
    1271             :     }
    1272             : 
    1273             :     /* If there are views we have to check if override values must be added to
    1274             :      * the original object. */
    1275           0 :     if (DOM_HAS_VIEWS(domain) && orig_obj->count == 1) {
    1276           0 :         ret = sysdb_add_overrides_to_object(domain, orig_obj->msgs[0],
    1277           0 :                           override_obj == NULL ? NULL : override_obj ->msgs[0],
    1278             :                           attrs);
    1279           0 :         if (ret != EOK && ret != ENOENT) {
    1280           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_add_overrides_to_object failed.\n");
    1281           0 :             return ret;
    1282             :         }
    1283             : 
    1284           0 :         if (ret == ENOENT) {
    1285           0 :             *_res = talloc_zero(mem_ctx, struct ldb_result);
    1286           0 :             if (*_res == NULL) {
    1287           0 :                 DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
    1288           0 :                 ret = ENOMEM;
    1289             :             } else {
    1290           0 :                 ret = EOK;
    1291             :             }
    1292           0 :             goto done;
    1293             :         }
    1294             :     }
    1295             : 
    1296           0 :     *_res = talloc_steal(mem_ctx, orig_obj);
    1297           0 :     ret = EOK;
    1298             : 
    1299             : done:
    1300           0 :     talloc_free(tmp_ctx);
    1301           0 :     return ret;
    1302             : }
    1303             : 
    1304             : /* This function splits a three-tuple into three strings
    1305             :  * It assumes that any whitespace between the parentheses
    1306             :  * and commas are intentional and does not attempt to
    1307             :  * strip them out. Leading and trailing whitespace is
    1308             :  * ignored.
    1309             :  *
    1310             :  * This behavior is compatible with nss_ldap's
    1311             :  * implementation.
    1312             :  */
    1313           0 : static errno_t sysdb_netgr_split_triple(TALLOC_CTX *mem_ctx,
    1314             :                                         const char *triple,
    1315             :                                         char **hostname,
    1316             :                                         char **username,
    1317             :                                         char **domainname)
    1318             : {
    1319             :     errno_t ret;
    1320             :     TALLOC_CTX *tmp_ctx;
    1321           0 :     const char *p = triple;
    1322             :     const char *p_host;
    1323             :     const char *p_user;
    1324             :     const char *p_domain;
    1325             :     size_t len;
    1326             : 
    1327           0 :     char *host = NULL;
    1328           0 :     char *user = NULL;
    1329           0 :     char *domain = NULL;
    1330             : 
    1331             :     /* Pre-set the values to NULL here so if they are not
    1332             :      * copied, we don't return garbage below.
    1333             :      */
    1334           0 :     *hostname = NULL;
    1335           0 :     *username = NULL;
    1336           0 :     *domainname = NULL;
    1337             : 
    1338           0 :     tmp_ctx = talloc_new(NULL);
    1339           0 :     if (!tmp_ctx) {
    1340           0 :         return ENOMEM;
    1341             :     }
    1342             : 
    1343             :     /* Remove any leading whitespace */
    1344           0 :     while (*p && isspace(*p)) p++;
    1345             : 
    1346           0 :     if (*p != '(') {
    1347             :         /* Triple must start and end with parentheses */
    1348           0 :         ret = EINVAL;
    1349           0 :         goto done;
    1350             :     }
    1351           0 :     p++;
    1352           0 :     p_host = p;
    1353             : 
    1354             :     /* Find the first comma */
    1355           0 :     while (*p && *p != ',') p++;
    1356             : 
    1357           0 :     if (!*p) {
    1358             :         /* No comma was found: parse error */
    1359           0 :         ret = EINVAL;
    1360           0 :         goto done;
    1361             :     }
    1362             : 
    1363           0 :     len = p - p_host;
    1364             : 
    1365           0 :     if (len > 0) {
    1366             :         /* Copy the host string */
    1367           0 :         host = talloc_strndup(tmp_ctx, p_host, len);
    1368           0 :         if (!host) {
    1369           0 :             ret = ENOMEM;
    1370           0 :             goto done;
    1371             :         }
    1372             :     }
    1373           0 :     p++;
    1374           0 :     p_user = p;
    1375             : 
    1376             :     /* Find the second comma */
    1377           0 :     while (*p && *p != ',') p++;
    1378             : 
    1379           0 :     if (!*p) {
    1380             :         /* No comma was found: parse error */
    1381           0 :         ret = EINVAL;
    1382           0 :         goto done;
    1383             :     }
    1384             : 
    1385           0 :     len = p - p_user;
    1386             : 
    1387           0 :     if (len > 0) {
    1388             :         /* Copy the user string */
    1389           0 :         user = talloc_strndup(tmp_ctx, p_user, len);
    1390           0 :         if (!user) {
    1391           0 :             ret = ENOMEM;
    1392           0 :             goto done;
    1393             :         }
    1394             :     }
    1395           0 :     p++;
    1396           0 :     p_domain = p;
    1397             : 
    1398             :     /* Find the closing parenthesis */
    1399           0 :     while (*p && *p != ')') p++;
    1400           0 :     if (*p != ')') {
    1401             :         /* No trailing parenthesis: parse error */
    1402           0 :         ret = EINVAL;
    1403           0 :         goto done;
    1404             :     }
    1405             : 
    1406           0 :     len = p - p_domain;
    1407             : 
    1408           0 :     if (len > 0) {
    1409             :         /* Copy the domain string */
    1410           0 :         domain = talloc_strndup(tmp_ctx, p_domain, len);
    1411           0 :         if (!domain) {
    1412           0 :             ret = ENOMEM;
    1413           0 :             goto done;
    1414             :         }
    1415             :     }
    1416           0 :     p++;
    1417             : 
    1418             :     /* skip trailing whitespace */
    1419           0 :     while (*p && isspace(*p)) p++;
    1420             : 
    1421           0 :     if (*p) {
    1422             :         /* Extra data after the closing parenthesis
    1423             :          * is a parse error
    1424             :          */
    1425           0 :         ret = EINVAL;
    1426           0 :         goto done;
    1427             :     }
    1428             : 
    1429             :     /* Return any non-NULL values */
    1430           0 :     if (host) {
    1431           0 :         *hostname = talloc_steal(mem_ctx, host);
    1432             :     }
    1433             : 
    1434           0 :     if (user) {
    1435           0 :         *username = talloc_steal(mem_ctx, user);
    1436             :     }
    1437             : 
    1438           0 :     if (domain) {
    1439           0 :         *domainname = talloc_steal(mem_ctx, domain);
    1440             :     }
    1441             : 
    1442           0 :     ret = EOK;
    1443             : 
    1444             : done:
    1445           0 :     talloc_free(tmp_ctx);
    1446           0 :     return ret;
    1447             : }
    1448             : 
    1449           0 : errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx,
    1450             :                                struct ldb_result *res,
    1451             :                                struct sysdb_netgroup_ctx ***entries)
    1452             : {
    1453             :     errno_t ret;
    1454           0 :     size_t size = 0;
    1455           0 :     size_t c = 0;
    1456             :     char *triple_str;
    1457             :     TALLOC_CTX *tmp_ctx;
    1458           0 :     struct sysdb_netgroup_ctx **tmp_entry = NULL;
    1459             :     struct ldb_message_element *el;
    1460             :     int i, j;
    1461             : 
    1462           0 :     if(!res || res->count == 0) {
    1463           0 :         return ENOENT;
    1464             :     }
    1465             : 
    1466           0 :     tmp_ctx = talloc_new(NULL);
    1467           0 :     if (!tmp_ctx) {
    1468           0 :         return ENOMEM;
    1469             :     }
    1470             : 
    1471           0 :     for (i=0; i < res->count; i++) {
    1472           0 :         el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_TRIPLE);
    1473           0 :         if (el != NULL) {
    1474           0 :             size += el->num_values;
    1475             :         }
    1476           0 :         el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_MEMBER);
    1477           0 :         if (el != NULL) {
    1478           0 :             size += el->num_values;
    1479             :         }
    1480             :     }
    1481             : 
    1482           0 :     tmp_entry = talloc_array(tmp_ctx, struct sysdb_netgroup_ctx *, size + 1);
    1483           0 :     if (tmp_entry == NULL) {
    1484           0 :         ret = ENOMEM;
    1485           0 :         goto done;
    1486             :     }
    1487             : 
    1488           0 :     if (size != 0) {
    1489           0 :         for (i=0; i < res->count; i++) {
    1490           0 :             el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_TRIPLE);
    1491           0 :             if (el != NULL) {
    1492             :                 /* Copy in all of the entries */
    1493           0 :                 for(j = 0; j < el->num_values; j++) {
    1494           0 :                     triple_str = talloc_strndup(tmp_ctx,
    1495           0 :                                                 (const char *)el->values[j].data,
    1496           0 :                                                 el->values[j].length);
    1497           0 :                     if (!triple_str) {
    1498           0 :                         ret = ENOMEM;
    1499           0 :                         goto done;
    1500             :                     }
    1501             : 
    1502           0 :                     tmp_entry[c] = talloc_zero(tmp_entry,
    1503             :                                                   struct sysdb_netgroup_ctx);
    1504           0 :                     if (!tmp_entry[c]) {
    1505           0 :                         ret = ENOMEM;
    1506           0 :                         goto done;
    1507             :                     }
    1508             : 
    1509           0 :                     tmp_entry[c]->type = SYSDB_NETGROUP_TRIPLE_VAL;
    1510           0 :                     ret = sysdb_netgr_split_triple(tmp_entry[c],
    1511             :                                         triple_str,
    1512           0 :                                         &tmp_entry[c]->value.triple.hostname,
    1513           0 :                                         &tmp_entry[c]->value.triple.username,
    1514           0 :                                         &tmp_entry[c]->value.triple.domainname);
    1515           0 :                     if (ret != EOK) {
    1516           0 :                         DEBUG(SSSDBG_IMPORTANT_INFO,
    1517             :                               "Cannot split netgroup triple [%s], "
    1518             :                                "this attribute will be skipped \n",
    1519             :                                triple_str);
    1520           0 :                         continue;
    1521             :                     }
    1522             : 
    1523           0 :                     c++;
    1524             :                 }
    1525             :             }
    1526           0 :             el = ldb_msg_find_element(res->msgs[i], SYSDB_NETGROUP_MEMBER);
    1527           0 :             if (el != NULL) {
    1528           0 :                 for(j = 0; j < el->num_values; j++) {
    1529           0 :                     tmp_entry[c] = talloc_zero(tmp_entry,
    1530             :                                                   struct sysdb_netgroup_ctx);
    1531           0 :                     if (!tmp_entry[c]) {
    1532           0 :                         ret = ENOMEM;
    1533           0 :                         goto done;
    1534             :                     }
    1535             : 
    1536           0 :                     tmp_entry[c]->type = SYSDB_NETGROUP_GROUP_VAL;
    1537           0 :                     tmp_entry[c]->value.groupname = talloc_strndup(tmp_entry[c],
    1538           0 :                                                (const char *)el->values[j].data,
    1539           0 :                                                el->values[j].length);
    1540           0 :                     if (tmp_entry[c]->value.groupname == NULL) {
    1541           0 :                         ret = ENOMEM;
    1542           0 :                         goto done;
    1543             :                     }
    1544             : 
    1545           0 :                     c++;
    1546             :                 }
    1547             :             }
    1548             :         }
    1549             :     }
    1550             : 
    1551             :     /* Add NULL terminator */
    1552           0 :     tmp_entry[c] = NULL;
    1553             : 
    1554           0 :     *entries = talloc_steal(mem_ctx, tmp_entry);
    1555           0 :     ret = EOK;
    1556             : 
    1557             : done:
    1558           0 :     talloc_free(tmp_ctx);
    1559           0 :     return ret;
    1560             : }
    1561             : 
    1562           2 : errno_t sysdb_getnetgr(TALLOC_CTX *mem_ctx,
    1563             :                        struct sss_domain_info *domain,
    1564             :                        const char *netgroup,
    1565             :                        struct ldb_result **res)
    1566             : {
    1567             :     TALLOC_CTX *tmp_ctx;
    1568             :     static const char *attrs[] = SYSDB_NETGR_ATTRS;
    1569             :     struct ldb_dn *base_dn;
    1570           2 :     struct ldb_result *result = NULL;
    1571             :     char *sanitized_netgroup;
    1572             :     char *lc_sanitized_netgroup;
    1573             :     char *netgroup_dn;
    1574             :     errno_t ret;
    1575             : 
    1576           2 :     tmp_ctx = talloc_new(NULL);
    1577           2 :     if (!tmp_ctx) {
    1578           0 :         return ENOMEM;
    1579             :     }
    1580             : 
    1581           2 :     base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
    1582             :                              SYSDB_TMPL_NETGROUP_BASE,
    1583             :                              domain->name);
    1584           2 :     if (!base_dn) {
    1585           0 :         ret = ENOMEM;
    1586           0 :         goto done;
    1587             :     }
    1588             : 
    1589           2 :     ret = sss_filter_sanitize_for_dom(tmp_ctx, netgroup, domain,
    1590             :                                       &sanitized_netgroup,
    1591             :                                       &lc_sanitized_netgroup);
    1592           2 :     if (ret != EOK) {
    1593           0 :         goto done;
    1594             :     }
    1595             : 
    1596           2 :     netgroup_dn = talloc_asprintf(tmp_ctx, SYSDB_TMPL_NETGROUP,
    1597             :                                   sanitized_netgroup, domain->name);
    1598           2 :     if (!netgroup_dn) {
    1599           0 :         ret = ENOMEM;
    1600           0 :         goto done;
    1601             :     }
    1602             : 
    1603           2 :     SSS_LDB_SEARCH(ret, domain->sysdb->ldb, tmp_ctx, &result, base_dn,
    1604             :                    LDB_SCOPE_SUBTREE, attrs,
    1605             :                    SYSDB_NETGR_TRIPLES_FILTER, lc_sanitized_netgroup,
    1606             :                    sanitized_netgroup, sanitized_netgroup,
    1607             :                    netgroup_dn);
    1608             : 
    1609           2 :     if (ret == EOK || ret == ENOENT) {
    1610           2 :         *res = talloc_steal(mem_ctx, result);
    1611             :     }
    1612             : 
    1613             : done:
    1614           2 :     talloc_zfree(tmp_ctx);
    1615           2 :     return ret;
    1616             : }
    1617             : 
    1618          11 : int sysdb_get_netgroup_attr(TALLOC_CTX *mem_ctx,
    1619             :                             struct sss_domain_info *domain,
    1620             :                             const char *netgrname,
    1621             :                             const char **attributes,
    1622             :                             struct ldb_result **res)
    1623             : {
    1624             :     TALLOC_CTX *tmp_ctx;
    1625             :     struct ldb_dn *base_dn;
    1626             :     struct ldb_result *result;
    1627             :     char *sanitized_netgroup;
    1628             :     char *lc_sanitized_netgroup;
    1629             :     int ret;
    1630             : 
    1631          11 :     tmp_ctx = talloc_new(NULL);
    1632          11 :     if (!tmp_ctx) {
    1633           0 :         return ENOMEM;
    1634             :     }
    1635             : 
    1636          11 :     base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
    1637             :                              SYSDB_TMPL_NETGROUP_BASE, domain->name);
    1638          11 :     if (!base_dn) {
    1639           0 :         ret = ENOMEM;
    1640           0 :         goto done;
    1641             :     }
    1642             : 
    1643          11 :     ret = sss_filter_sanitize_for_dom(tmp_ctx, netgrname, domain,
    1644             :                                       &sanitized_netgroup,
    1645             :                                       &lc_sanitized_netgroup);
    1646          11 :     if (ret != EOK) {
    1647           0 :         goto done;
    1648             :     }
    1649             : 
    1650          11 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &result, base_dn,
    1651             :                      LDB_SCOPE_SUBTREE, attributes,
    1652             :                      SYSDB_NETGR_FILTER,
    1653             :                      lc_sanitized_netgroup,
    1654             :                      sanitized_netgroup,
    1655             :                      sanitized_netgroup);
    1656          11 :     if (ret) {
    1657           0 :         ret = sysdb_error_to_errno(ret);
    1658           0 :         goto done;
    1659             :     }
    1660             : 
    1661          11 :     *res = talloc_steal(mem_ctx, result);
    1662             : done:
    1663          11 :     talloc_zfree(tmp_ctx);
    1664          11 :     return ret;
    1665             : }
    1666             : 
    1667           0 : errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx,
    1668             :                                  struct sss_domain_info *dom,
    1669             :                                  enum sysdb_member_type mtype,
    1670             :                                  const char *name,
    1671             :                                  char ***_direct_parents)
    1672             : {
    1673             :     errno_t ret;
    1674             :     const char *dn;
    1675             :     char *sanitized_dn;
    1676             :     struct ldb_dn *basedn;
    1677             :     static const char *group_attrs[] = { SYSDB_NAME, NULL };
    1678             :     const char *member_filter;
    1679           0 :     size_t direct_sysdb_count = 0;
    1680           0 :     struct ldb_message **direct_sysdb_groups = NULL;
    1681           0 :     char **direct_parents = NULL;
    1682           0 :     TALLOC_CTX *tmp_ctx = NULL;
    1683             :     int i, pi;
    1684             :     const char *tmp_str;
    1685             : 
    1686           0 :     tmp_ctx = talloc_new(NULL);
    1687           0 :     if (!tmp_ctx) return ENOMEM;
    1688             : 
    1689           0 :     if (mtype == SYSDB_MEMBER_USER) {
    1690           0 :         dn = sysdb_user_strdn(tmp_ctx, dom->name, name);
    1691           0 :     } else if (mtype == SYSDB_MEMBER_GROUP) {
    1692           0 :         dn = sysdb_group_strdn(tmp_ctx, dom->name, name);
    1693             :     } else {
    1694           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unknown member type\n");
    1695           0 :         ret = EINVAL;
    1696           0 :         goto done;
    1697             :     }
    1698             : 
    1699           0 :     if (!dn) {
    1700           0 :         ret = ENOMEM;
    1701           0 :         goto done;
    1702             :     }
    1703             : 
    1704           0 :     ret = sss_filter_sanitize(tmp_ctx, dn, &sanitized_dn);
    1705           0 :     if (ret != EOK) {
    1706           0 :         goto done;
    1707             :     }
    1708             : 
    1709           0 :     member_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%s))",
    1710             :                                     SYSDB_OBJECTCLASS, SYSDB_GROUP_CLASS,
    1711             :                                     SYSDB_MEMBER, sanitized_dn);
    1712           0 :     if (!member_filter) {
    1713           0 :         ret = ENOMEM;
    1714           0 :         goto done;
    1715             :     }
    1716             : 
    1717           0 :     basedn = sysdb_group_base_dn(tmp_ctx, dom);
    1718           0 :     if (!basedn) {
    1719           0 :         ret = ENOMEM;
    1720           0 :         goto done;
    1721             :     }
    1722             : 
    1723           0 :     DEBUG(SSSDBG_TRACE_INTERNAL,
    1724             :           "searching sysdb with filter [%s]\n", member_filter);
    1725             : 
    1726           0 :     ret = sysdb_search_entry(tmp_ctx, dom->sysdb, basedn,
    1727             :                              LDB_SCOPE_SUBTREE, member_filter, group_attrs,
    1728             :                              &direct_sysdb_count, &direct_sysdb_groups);
    1729           0 :     if (ret == ENOENT) {
    1730           0 :         direct_sysdb_count = 0;
    1731           0 :     } else if (ret != EOK) {
    1732           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed: [%d]: %s\n",
    1733             :                   ret, strerror(ret));
    1734           0 :         goto done;
    1735             :     }
    1736             : 
    1737             :     /* EOK */
    1738             :     /* Get the list of sysdb groups by name */
    1739           0 :     direct_parents = talloc_array(tmp_ctx, char *, direct_sysdb_count+1);
    1740           0 :     if (!direct_parents) {
    1741           0 :         ret = ENOMEM;
    1742           0 :         goto done;
    1743             :     }
    1744             : 
    1745           0 :     pi = 0;
    1746           0 :     for(i = 0; i < direct_sysdb_count; i++) {
    1747           0 :         tmp_str = ldb_msg_find_attr_as_string(direct_sysdb_groups[i],
    1748             :                                                 SYSDB_NAME, NULL);
    1749           0 :         if (!tmp_str) {
    1750             :             /* This should never happen, but if it does, just continue */
    1751           0 :             continue;
    1752             :         }
    1753             : 
    1754           0 :         direct_parents[pi] = talloc_strdup(direct_parents, tmp_str);
    1755           0 :         if (!direct_parents[pi]) {
    1756           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "A group with no name?\n");
    1757           0 :             ret = EIO;
    1758           0 :             goto done;
    1759             :         }
    1760           0 :         pi++;
    1761             :     }
    1762           0 :     direct_parents[pi] = NULL;
    1763             : 
    1764           0 :     DEBUG(SSSDBG_TRACE_LIBS, "%s is a member of %zu sysdb groups\n",
    1765             :               name, direct_sysdb_count);
    1766           0 :     *_direct_parents = talloc_steal(mem_ctx, direct_parents);
    1767           0 :     ret = EOK;
    1768             : done:
    1769           0 :     talloc_free(tmp_ctx);
    1770           0 :     return ret;
    1771             : }
    1772             : 
    1773           5 : errno_t sysdb_get_real_name(TALLOC_CTX *mem_ctx,
    1774             :                             struct sss_domain_info *domain,
    1775             :                             const char *name_or_upn_or_sid,
    1776             :                             const char **_cname)
    1777             : {
    1778             :     errno_t ret;
    1779             :     TALLOC_CTX *tmp_ctx;
    1780             :     struct ldb_result *res;
    1781             :     const char *cname;
    1782             :     struct ldb_message *msg;
    1783             : 
    1784           5 :     tmp_ctx = talloc_new(NULL);
    1785           5 :     if (!tmp_ctx) {
    1786           0 :         return ENOMEM;
    1787             :     }
    1788             : 
    1789           5 :     ret = sysdb_getpwnam(tmp_ctx, domain, name_or_upn_or_sid, &res);
    1790           5 :     if (ret != EOK) {
    1791           0 :         DEBUG(SSSDBG_OP_FAILURE, "Cannot canonicalize username\n");
    1792           0 :         goto done;
    1793             :     }
    1794             : 
    1795           5 :     if (res->count == 0) {
    1796           4 :         ret = sysdb_search_user_by_upn(tmp_ctx, domain, name_or_upn_or_sid,
    1797             :                                        NULL, &msg);
    1798           4 :         if (ret == ENOENT) {
    1799           3 :             ret = sysdb_search_user_by_sid_str(tmp_ctx, domain,
    1800             :                                                name_or_upn_or_sid, NULL, &msg);
    1801           3 :             if (ret == ENOENT) {
    1802           2 :                 ret = sysdb_search_object_by_uuid(tmp_ctx, domain,
    1803             :                                                   name_or_upn_or_sid, NULL,
    1804             :                                                   &res);
    1805           2 :                 if (ret == EOK && res->count == 1) {
    1806           1 :                     msg = res->msgs[0];
    1807           1 :                 } else if (ret != ENOENT) {
    1808           0 :                     DEBUG(SSSDBG_OP_FAILURE,
    1809             :                           "sysdb_search_object_by_uuid failed or returned "
    1810             :                           "more than one result [%d][%s].\n",
    1811             :                           ret, sss_strerror(ret));
    1812           0 :                     ret = ENOENT;
    1813           0 :                     goto done;
    1814             :                 }
    1815             :             }
    1816             :         }
    1817           4 :         if (ret != EOK) {
    1818             :             /* User cannot be found in cache */
    1819           1 :             DEBUG(SSSDBG_OP_FAILURE, "Cannot find user [%s] in cache\n",
    1820             :                                      name_or_upn_or_sid);
    1821           1 :             goto done;
    1822             :         }
    1823           1 :     } else if (res->count == 1) {
    1824           1 :         msg = res->msgs[0];
    1825             :     } else {
    1826           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
    1827             :               "sysdb_getpwnam returned count: [%d]\n", res->count);
    1828           0 :         ret = EIO;
    1829           0 :         goto done;
    1830             :     }
    1831             : 
    1832           4 :     cname = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
    1833           4 :     if (!cname) {
    1834           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "A user with no name?\n");
    1835           0 :         ret = ENOENT;
    1836           0 :         goto done;
    1837             :     }
    1838             : 
    1839           4 :     ret = EOK;
    1840           4 :     *_cname = talloc_steal(mem_ctx, cname);
    1841             : done:
    1842           5 :     talloc_free(tmp_ctx);
    1843           5 :     return ret;
    1844             : }

Generated by: LCOV version 1.10