LCOV - code coverage report
Current view: top level - db - sysdb_views.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 234 746 31.4 %
Date: 2015-10-19 Functions: 11 22 50.0 %

          Line data    Source code
       1             : /*
       2             :    SSSD
       3             : 
       4             :    System Database - View and Override related calls
       5             : 
       6             :    Copyright (C) 2014 Sumit Bose <sbose@redhat.com>
       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             : 
      25             : /* In general is should not be possible that there is a view container without
      26             :  * a view name set. But to be on the safe side we return both information
      27             :  * separately. */
      28          23 : static errno_t sysdb_get_view_name_ex(TALLOC_CTX *mem_ctx,
      29             :                                       struct sysdb_ctx *sysdb,
      30             :                                       char **_view_name,
      31             :                                       bool *view_container_exists)
      32             : {
      33             :     errno_t ret;
      34             :     TALLOC_CTX *tmp_ctx;
      35             :     const char *tmp_str;
      36             :     struct ldb_dn *view_base_dn;
      37             :     struct ldb_result *res;
      38          23 :     const char *attrs[] = {SYSDB_VIEW_NAME,
      39             :                            NULL};
      40             : 
      41          23 :     tmp_ctx = talloc_new(NULL);
      42          23 :     if (tmp_ctx == NULL) {
      43           0 :         return ENOMEM;
      44             :     }
      45             : 
      46          23 :     view_base_dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_TMPL_VIEW_BASE);
      47          23 :     if (view_base_dn == NULL) {
      48           0 :         ret = EIO;
      49           0 :         goto done;
      50             :     }
      51          23 :     ret = ldb_search(sysdb->ldb, tmp_ctx, &res, view_base_dn, LDB_SCOPE_BASE,
      52             :                      attrs, NULL);
      53          23 :     if (ret != LDB_SUCCESS) {
      54           0 :         ret = EIO;
      55           0 :         goto done;
      56             :     }
      57             : 
      58          23 :     if (res->count > 1) {
      59           0 :         DEBUG(SSSDBG_OP_FAILURE, "Base search returned [%d] results, "
      60             :                                  "expected 1.\n", res->count);
      61           0 :         ret = EINVAL;
      62           0 :         goto done;
      63             :     }
      64             : 
      65          23 :     if (res->count == 0) {
      66          22 :         *view_container_exists = false;
      67          22 :         ret = ENOENT;
      68          22 :         goto done;
      69             :     } else {
      70           1 :         *view_container_exists = true;
      71           1 :         tmp_str = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_VIEW_NAME,
      72             :                                               NULL);
      73           1 :         if (tmp_str == NULL) {
      74           0 :             ret = ENOENT;
      75           0 :             goto done;
      76             :         }
      77             :     }
      78             : 
      79           1 :     *_view_name = talloc_steal(mem_ctx, discard_const(tmp_str));
      80           1 :     ret = EOK;
      81             : 
      82             : done:
      83          23 :     talloc_free(tmp_ctx);
      84          23 :     return ret;
      85             : }
      86             : 
      87          21 : errno_t sysdb_get_view_name(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
      88             :                             char **view_name)
      89             : {
      90             :     bool view_container_exists;
      91             : 
      92          21 :     return sysdb_get_view_name_ex(mem_ctx, sysdb, view_name,
      93             :                                   &view_container_exists);
      94             : }
      95             : 
      96           2 : errno_t sysdb_update_view_name(struct sysdb_ctx *sysdb,
      97             :                                const char *view_name)
      98             : {
      99             :     errno_t ret;
     100             :     TALLOC_CTX *tmp_ctx;
     101             :     char *tmp_str;
     102           2 :     bool view_container_exists = false;
     103           2 :     bool add_view_name = false;
     104             :     struct ldb_message *msg;
     105             : 
     106           2 :     tmp_ctx = talloc_new(NULL);
     107           2 :     if (tmp_ctx == NULL) {
     108           0 :         return ENOMEM;
     109             :     }
     110             : 
     111           2 :     ret = sysdb_get_view_name_ex(tmp_ctx, sysdb, &tmp_str,
     112             :                                  &view_container_exists);
     113           2 :     if (ret != EOK && ret != ENOENT) {
     114           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_view_name_ex failed.\n");
     115           0 :         goto done;
     116             :     }
     117             : 
     118           2 :     if (ret == EOK) {
     119           1 :         if (strcmp(tmp_str, view_name) == 0) {
     120             :             /* view name already known, nothing to do */
     121           1 :             DEBUG(SSSDBG_TRACE_ALL, "View name already in place.\n");
     122           1 :             ret = EOK;
     123           1 :             goto done;
     124             :         } else {
     125             :             /* view name changed */
     126           0 :             DEBUG(SSSDBG_CONF_SETTINGS,
     127             :                   "View name changed from [%s] to [%s].\n", tmp_str, view_name);
     128             :         }
     129             :     } else {
     130           1 :         add_view_name = true;
     131             :     }
     132             : 
     133           1 :     msg = ldb_msg_new(tmp_ctx);
     134           1 :     if (msg == NULL) {
     135           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n");
     136           0 :         ret = ENOMEM;
     137           0 :         goto done;
     138             :     }
     139             : 
     140           1 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_TMPL_VIEW_BASE);
     141           1 :     if (msg->dn == NULL) {
     142           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
     143           0 :         ret = EIO;
     144           0 :         goto done;
     145             :     }
     146             : 
     147           1 :     ret = ldb_msg_add_empty(msg, SYSDB_VIEW_NAME,
     148             :                             add_view_name ? LDB_FLAG_MOD_ADD
     149             :                                           : LDB_FLAG_MOD_REPLACE,
     150             :                             NULL);
     151           1 :     if (ret != LDB_SUCCESS) {
     152           0 :         ret = sysdb_error_to_errno(ret);
     153           0 :         goto done;
     154             :     }
     155             : 
     156           1 :     ret = ldb_msg_add_string(msg, SYSDB_VIEW_NAME, view_name);
     157           1 :     if (ret != LDB_SUCCESS) {
     158           0 :         ret = sysdb_error_to_errno(ret);
     159           0 :         goto done;
     160             :     }
     161             : 
     162           1 :     if (view_container_exists) {
     163           0 :         ret = ldb_modify(sysdb->ldb, msg);
     164             :     } else {
     165           1 :         ret = ldb_add(sysdb->ldb, msg);
     166             :     }
     167           1 :     if (ret != LDB_SUCCESS) {
     168           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     169             :               "Failed to %s view container [%s](%d)[%s]\n",
     170             :               view_container_exists ? "modify" : "add",
     171             :               ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb));
     172           0 :         ret = sysdb_error_to_errno(ret);
     173           0 :         goto done;
     174             :     }
     175             : 
     176             : done:
     177           2 :     talloc_free(tmp_ctx);
     178           2 :     return ret;
     179             : }
     180             : 
     181           2 : errno_t sysdb_delete_view_tree(struct sysdb_ctx *sysdb, const char *view_name)
     182             : {
     183             :     struct ldb_dn *dn;
     184             :     TALLOC_CTX *tmp_ctx;
     185             :     int ret;
     186             : 
     187           2 :     tmp_ctx = talloc_new(NULL);
     188           2 :     if (tmp_ctx == NULL) {
     189           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
     190           0 :         return ENOMEM;
     191             :     }
     192             : 
     193           2 :     dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_VIEW_SEARCH_BASE,
     194             :                         view_name);
     195           2 :     if (dn == NULL) {
     196           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n");
     197           0 :         ret = EIO;
     198           0 :         goto done;
     199             :     }
     200             : 
     201           2 :     ret = sysdb_delete_recursive(sysdb, dn, true);
     202           2 :     if (ret != EOK) {
     203           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_recursive failed.\n");
     204           0 :         goto done;
     205             :     }
     206             : 
     207           2 :     ret = EOK;
     208             : 
     209             : done:
     210           2 :     talloc_free(tmp_ctx);
     211             : 
     212           2 :     return ret;
     213             : }
     214             : 
     215           2 : errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb)
     216             : {
     217             :     int ret;
     218             :     int sret;
     219             :     TALLOC_CTX *tmp_ctx;
     220           2 :     bool in_transaction = false;
     221             :     struct ldb_result *res;
     222             :     size_t c;
     223             :     struct ldb_message *msg;
     224             :     struct ldb_dn *base_dn;
     225             : 
     226           2 :     tmp_ctx = talloc_new(NULL);
     227           2 :     if (tmp_ctx == NULL) {
     228           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
     229           0 :         return ENOMEM;
     230             :     }
     231             : 
     232           2 :     msg = ldb_msg_new(tmp_ctx);
     233           2 :     if (msg == NULL) {
     234           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n");
     235           0 :         ret = ENOMEM;
     236           0 :         goto done;
     237             :     }
     238             : 
     239           2 :     base_dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE);
     240           2 :     if (base_dn == NULL) {
     241           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed\n");
     242           0 :         ret = ENOMEM;
     243           0 :         goto done;
     244             :     }
     245             : 
     246           2 :     ret = ldb_msg_add_empty(msg, SYSDB_CACHE_EXPIRE, LDB_FLAG_MOD_REPLACE,
     247             :                             NULL);
     248           2 :     if (ret != LDB_SUCCESS) {
     249           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n");
     250           0 :         ret = sysdb_error_to_errno(ret);
     251           0 :         goto done;
     252             :     }
     253           2 :     ret = ldb_msg_add_string(msg, SYSDB_CACHE_EXPIRE, "1");
     254           2 :     if (ret != LDB_SUCCESS) {
     255           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n");
     256           0 :         ret = sysdb_error_to_errno(ret);
     257           0 :         goto done;
     258             :     }
     259             : 
     260           2 :     ret = ldb_msg_add_empty(msg, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_DELETE, NULL);
     261           2 :     if (ret != LDB_SUCCESS) {
     262           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n");
     263           0 :         ret = sysdb_error_to_errno(ret);
     264           0 :         goto done;
     265             :     }
     266             : 
     267           2 :     ret = sysdb_transaction_start(sysdb);
     268           2 :     if (ret != EOK) {
     269           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start failed.\n");
     270           0 :         goto done;
     271             :     }
     272           2 :     in_transaction = true;
     273             : 
     274           2 :     ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE,
     275             :                      NULL, "%s", SYSDB_UC);
     276           2 :     if (ret != LDB_SUCCESS) {
     277           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed.\n");
     278           0 :         ret = sysdb_error_to_errno(ret);
     279           0 :         goto done;
     280             :     }
     281             : 
     282           4 :     for (c = 0; c < res->count; c++) {
     283           2 :         msg->dn = res->msgs[c]->dn;
     284             : 
     285           2 :         ret = ldb_modify(sysdb->ldb, msg);
     286           2 :         if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) {
     287           0 :             DEBUG(SSSDBG_OP_FAILURE,
     288             :                   "ldb_modify failed: [%s](%d)[%s]\n",
     289             :                   ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb));
     290           0 :             ret = sysdb_error_to_errno(ret);
     291           0 :             goto done;
     292             :         }
     293             :     }
     294             : 
     295           2 :     talloc_free(res);
     296             : 
     297           2 :     ret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn, LDB_SCOPE_SUBTREE,
     298             :                      NULL, "%s", SYSDB_GC);
     299           2 :     if (ret != LDB_SUCCESS) {
     300           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed.\n");
     301           0 :         ret = sysdb_error_to_errno(ret);
     302           0 :         goto done;
     303             :     }
     304             : 
     305           2 :     for (c = 0; c < res->count; c++) {
     306           0 :         msg->dn = res->msgs[c]->dn;
     307             : 
     308           0 :         ret = ldb_modify(sysdb->ldb, msg);
     309           0 :         if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) {
     310           0 :             DEBUG(SSSDBG_OP_FAILURE,
     311             :                   "ldb_modify failed: [%s](%d)[%s]\n",
     312             :                   ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb));
     313           0 :             ret = sysdb_error_to_errno(ret);
     314           0 :             goto done;
     315             :         }
     316             :     }
     317             : 
     318           2 :     ret = EOK;
     319             : 
     320             : done:
     321           2 :     if (in_transaction) {
     322           2 :         if (ret == EOK) {
     323           2 :             sret = sysdb_transaction_commit(sysdb);
     324           2 :             if (sret != EOK) {
     325           0 :                 DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_commit failed, " \
     326             :                                          "nothing we can do about.\n");
     327           0 :                 ret = sret;
     328             :             }
     329             :         } else {
     330           0 :             sret = sysdb_transaction_cancel(sysdb);
     331           0 :             if (sret != EOK) {
     332           0 :                 DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_cancel failed, " \
     333             :                                          "nothing we can do about.\n");
     334             :             }
     335             :         }
     336             :     }
     337             : 
     338           2 :     talloc_free(tmp_ctx);
     339             : 
     340           2 :     return ret;
     341             : }
     342             : 
     343             : static errno_t
     344           0 : add_name_and_aliases_for_name_override(struct sss_domain_info *domain,
     345             :                                        struct sysdb_attrs *attrs,
     346             :                                        bool add_name,
     347             :                                        const char *name_override)
     348             : {
     349           0 :     char *fq_name = NULL;
     350             :     int ret;
     351             : 
     352           0 :     if (strchr(name_override, '@') == NULL) {
     353           0 :         fq_name = sss_tc_fqname(attrs, domain->names, domain, name_override);
     354           0 :         if (fq_name == NULL) {
     355           0 :             DEBUG(SSSDBG_OP_FAILURE, "sss_tc_fqname failed.\n");
     356           0 :             return ENOMEM;
     357             :         }
     358             : 
     359           0 :         if (!domain->case_sensitive) {
     360           0 :             ret = sysdb_attrs_add_lc_name_alias(attrs, fq_name);
     361             :         } else {
     362           0 :             ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS,
     363             :                                          fq_name);
     364             :         }
     365           0 :         if (ret != EOK) {
     366           0 :             DEBUG(SSSDBG_OP_FAILURE,
     367             :                   "sysdb_attrs_add_lc_name_alias failed.\n");
     368           0 :             goto done;
     369             :         }
     370             :     }
     371             : 
     372           0 :     if (add_name) {
     373           0 :         ret = sysdb_attrs_add_string(attrs, SYSDB_DEFAULT_OVERRIDE_NAME,
     374             :                                      fq_name == NULL ? name_override : fq_name);
     375           0 :         if (ret != EOK) {
     376           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_lc_name_alias failed.\n");
     377           0 :             goto done;
     378             :         }
     379             :     }
     380             : 
     381           0 :     if (!domain->case_sensitive) {
     382           0 :         ret = sysdb_attrs_add_lc_name_alias(attrs, name_override);
     383             :     } else {
     384           0 :         ret = sysdb_attrs_add_string(attrs, SYSDB_NAME_ALIAS, name_override);
     385             :     }
     386           0 :     if (ret != EOK) {
     387           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_lc_name_alias failed.\n");
     388           0 :         goto done;
     389             :     }
     390             : 
     391           0 :     ret = EOK;
     392             : 
     393             : done:
     394           0 :     talloc_free(fq_name);
     395           0 :     return ret;
     396             : }
     397             : 
     398          29 : errno_t sysdb_store_override(struct sss_domain_info *domain,
     399             :                              const char *view_name,
     400             :                              enum sysdb_member_type type,
     401             :                              struct sysdb_attrs *attrs, struct ldb_dn *obj_dn)
     402             : {
     403             :     TALLOC_CTX *tmp_ctx;
     404             :     const char *anchor;
     405             :     int ret;
     406             :     struct ldb_dn *override_dn;
     407             :     const char *override_dn_str;
     408             :     const char *obj_dn_str;
     409          29 :     const char *obj_attrs[] = { SYSDB_OBJECTCLASS,
     410             :                                 SYSDB_OVERRIDE_DN,
     411             :                                 NULL};
     412          29 :     size_t count = 0;
     413             :     struct ldb_message **msgs;
     414          29 :     struct ldb_message *msg = NULL;
     415             :     const char *obj_override_dn;
     416          29 :     bool add_ref = true;
     417             :     size_t c;
     418          29 :     bool in_transaction = false;
     419          29 :     bool has_override = true;
     420             :     const char *name_override;
     421             : 
     422          29 :     tmp_ctx = talloc_new(NULL);
     423          29 :     if (tmp_ctx == NULL) {
     424           0 :         ret = ENOMEM;
     425           0 :         goto done;
     426             :     }
     427             : 
     428          29 :     if (attrs != NULL) {
     429          28 :         has_override = true;
     430          28 :         ret = sysdb_attrs_get_string(attrs, SYSDB_OVERRIDE_ANCHOR_UUID,
     431             :                                      &anchor);
     432          28 :         if (ret != EOK) {
     433           1 :             DEBUG(SSSDBG_CRIT_FAILURE,
     434             :                   "Missing anchor in override attributes.\n");
     435           1 :             ret = EINVAL;
     436           1 :             goto done;
     437             :         }
     438             : 
     439          27 :         override_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
     440             :                                      SYSDB_TMPL_OVERRIDE, anchor, view_name);
     441          27 :         if (override_dn == NULL) {
     442           0 :             DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n");
     443           0 :             ret = ENOMEM;
     444           0 :             goto done;
     445             :         }
     446             :     } else {
     447             :         /* if there is no override for the given object, just store the DN of
     448             :          * the object iself in the SYSDB_OVERRIDE_DN attribute to indicate
     449             :          * that it was checked if an override exists and none was found. */
     450           1 :         has_override = false;
     451           1 :         override_dn = obj_dn;
     452             :     }
     453             : 
     454          28 :     override_dn_str = ldb_dn_get_linearized(override_dn);
     455          28 :     obj_dn_str = ldb_dn_get_linearized(obj_dn);
     456          28 :     if (override_dn_str == NULL || obj_dn_str == NULL) {
     457           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_get_linearized failed.\n");
     458           0 :         ret = ENOMEM;
     459           0 :         goto done;
     460             :     }
     461             : 
     462          28 :     ret = sysdb_search_entry(tmp_ctx, domain->sysdb, obj_dn, LDB_SCOPE_BASE,
     463             :                              NULL, obj_attrs, &count, &msgs);
     464          28 :     if (ret != EOK) {
     465           0 :         if (ret == ENOENT) {
     466           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Object to override does not exists.\n");
     467             :         } else {
     468           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_entry failed.\n");
     469             :         }
     470           0 :         goto done;
     471             :     }
     472          28 :     if (count != 1) {
     473           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Base searched returned more than one object.\n");
     474           0 :         ret = EINVAL;
     475           0 :         goto done;
     476             :     }
     477             : 
     478          28 :     obj_override_dn = ldb_msg_find_attr_as_string(msgs[0], SYSDB_OVERRIDE_DN,
     479             :                                                   NULL);
     480          28 :     if (obj_override_dn != NULL) {
     481           2 :         if (strcmp(obj_override_dn, override_dn_str) != 0) {
     482           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     483             :                   "Existing [%s] and new [%s] override DN do not match.\n",
     484             :                    obj_override_dn, override_dn_str);
     485           0 :             ret = EINVAL;
     486           0 :             goto done;
     487             :         }
     488             : 
     489           2 :         add_ref = false;
     490             :     }
     491             : 
     492          28 :     ret = ldb_transaction_start(domain->sysdb->ldb);
     493          28 :     if (ret != EOK) {
     494           0 :         return sysdb_error_to_errno(ret);
     495             :     }
     496          28 :     in_transaction = true;
     497             : 
     498          28 :     if (has_override) {
     499          27 :         ret = ldb_delete(domain->sysdb->ldb, override_dn);
     500          27 :         if (ret != EOK) {
     501           8 :             DEBUG(SSSDBG_TRACE_ALL,
     502             :                   "ldb_delete failed, maybe object did not exist. Ignoring.\n");
     503             :         }
     504             : 
     505          27 :         ret = sysdb_attrs_get_string(attrs, SYSDB_NAME, &name_override);
     506          27 :         if (ret == EOK) {
     507           0 :             ret = add_name_and_aliases_for_name_override(domain, attrs, false,
     508             :                                                          name_override);
     509           0 :             if (ret != EOK) {
     510           0 :                 DEBUG(SSSDBG_OP_FAILURE,
     511             :                       "add_name_and_aliases_for_name_override failed.\n");
     512           0 :                 goto done;
     513             :             }
     514          27 :         } else if (ret != ENOENT) {
     515           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
     516           0 :             goto done;
     517             :         }
     518             : 
     519          27 :         msg = ldb_msg_new(tmp_ctx);
     520          27 :         if (msg == NULL) {
     521           0 :             ret = ENOMEM;
     522           0 :             goto done;
     523             :         }
     524             : 
     525          27 :         msg->dn = override_dn;
     526             : 
     527          27 :         msg->elements = talloc_array(msg, struct ldb_message_element,
     528             :                                      attrs->num);
     529          27 :         if (msg->elements == NULL) {
     530           0 :             ret = ENOMEM;
     531           0 :             goto done;
     532             :         }
     533             : 
     534          78 :         for (c = 0; c < attrs->num; c++) {
     535             :             /* Set num_values to 1 because by default user and group overrides
     536             :              * use the same attribute name for the GID and this cause SSSD
     537             :              * machinery to add the same value twice */
     538          51 :             if (attrs->a[c].num_values > 1
     539           0 :                     && strcmp(attrs->a[c].name, SYSDB_GIDNUM) == 0) {
     540           0 :                 attrs->a[c].num_values = 1;
     541             :             }
     542          51 :             msg->elements[c] = attrs->a[c];
     543          51 :             msg->elements[c].flags = LDB_FLAG_MOD_ADD;
     544             :         }
     545          27 :         msg->num_elements = attrs->num;
     546             : 
     547          27 :         ret = ldb_msg_add_empty(msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_ADD, NULL);
     548          27 :         if (ret != LDB_SUCCESS) {
     549           0 :             DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n");
     550           0 :             ret = sysdb_error_to_errno(ret);
     551           0 :             goto done;
     552             :         }
     553             : 
     554          27 :         switch(type) {
     555             :         case SYSDB_MEMBER_USER:
     556          15 :             ret = ldb_msg_add_string(msg, SYSDB_OBJECTCLASS,
     557             :                                      SYSDB_OVERRIDE_USER_CLASS);
     558          15 :             break;
     559             :         case SYSDB_MEMBER_GROUP:
     560          12 :             ret = ldb_msg_add_string(msg, SYSDB_OBJECTCLASS,
     561             :                                      SYSDB_OVERRIDE_GROUP_CLASS);
     562          12 :             break;
     563             :         default:
     564           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected object type.\n");
     565           0 :             ret = EINVAL;
     566           0 :             goto done;
     567             :         }
     568          27 :         if (ret != LDB_SUCCESS) {
     569           0 :             ret = sysdb_error_to_errno(ret);
     570           0 :             goto done;
     571             :         }
     572             : 
     573          27 :         ret = ldb_msg_add_empty(msg, SYSDB_OVERRIDE_OBJECT_DN, LDB_FLAG_MOD_ADD,
     574             :                                 NULL);
     575          27 :         if (ret != LDB_SUCCESS) {
     576           0 :             DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n");
     577           0 :             ret = sysdb_error_to_errno(ret);
     578           0 :             goto done;
     579             :         }
     580             : 
     581          27 :         ret = ldb_msg_add_string(msg, SYSDB_OVERRIDE_OBJECT_DN, obj_dn_str);
     582          27 :         if (ret != LDB_SUCCESS) {
     583           0 :             ret = sysdb_error_to_errno(ret);
     584           0 :             goto done;
     585             :         }
     586             : 
     587          27 :         ret = ldb_add(domain->sysdb->ldb, msg);
     588          27 :         if (ret != LDB_SUCCESS) {
     589           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     590             :                   "Failed to store override entry: %s(%d)[%s]\n",
     591             :                   ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb));
     592           0 :             ret = sysdb_error_to_errno(ret);
     593           0 :             goto done;
     594             :         }
     595             :     }
     596             : 
     597          28 :     if (add_ref) {
     598          26 :         talloc_free(msg);
     599          26 :         msg = ldb_msg_new(tmp_ctx);
     600          26 :         if (msg == NULL) {
     601           0 :             ret = ENOMEM;
     602           0 :             goto done;
     603             :         }
     604             : 
     605          26 :         msg->dn = obj_dn;
     606             : 
     607          26 :         ret = ldb_msg_add_empty(msg, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_ADD,
     608             :                                 NULL);
     609          26 :         if (ret != LDB_SUCCESS) {
     610           0 :             DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n");
     611           0 :             ret = sysdb_error_to_errno(ret);
     612           0 :             goto done;
     613             :         }
     614             : 
     615          26 :         ret = ldb_msg_add_string(msg, SYSDB_OVERRIDE_DN, override_dn_str);
     616          26 :         if (ret != LDB_SUCCESS) {
     617           0 :             ret = sysdb_error_to_errno(ret);
     618           0 :             goto done;
     619             :         }
     620             : 
     621          26 :         ret = ldb_modify(domain->sysdb->ldb, msg);
     622          26 :         if (ret != LDB_SUCCESS) {
     623           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     624             :                   "Failed to store override DN: %s(%d)[%s]\n",
     625             :                   ldb_strerror(ret), ret, ldb_errstring(domain->sysdb->ldb));
     626           0 :             ret = sysdb_error_to_errno(ret);
     627           0 :             goto done;
     628             :         }
     629             :     }
     630             : 
     631          28 :     ret = EOK;
     632             : 
     633             : done:
     634          29 :     if (in_transaction) {
     635          28 :         if (ret != EOK) {
     636           0 :             DEBUG(SSSDBG_TRACE_FUNC, "Error: %d (%s)\n", ret, strerror(ret));
     637           0 :             ldb_transaction_cancel(domain->sysdb->ldb);
     638             :         } else {
     639          28 :             ret = ldb_transaction_commit(domain->sysdb->ldb);
     640          28 :             ret = sysdb_error_to_errno(ret);
     641             :         }
     642             :     }
     643             : 
     644          29 :     talloc_zfree(tmp_ctx);
     645          29 :     return ret;
     646             : }
     647             : 
     648           0 : static errno_t safe_original_attributes(struct sss_domain_info *domain,
     649             :                                         struct sysdb_attrs *attrs,
     650             :                                         struct ldb_dn *obj_dn,
     651             :                                         const char **allowed_attrs)
     652             : {
     653             :     int ret;
     654             :     size_t c;
     655             :     TALLOC_CTX *tmp_ctx;
     656             :     struct ldb_result *orig_obj;
     657             :     char *orig_attr_name;
     658           0 :     struct ldb_message_element *el = NULL;
     659             : 
     660           0 :     tmp_ctx = talloc_new(NULL);
     661           0 :     if (tmp_ctx == NULL) {
     662           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
     663           0 :         return ENOMEM;
     664             :     }
     665             : 
     666           0 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &orig_obj, obj_dn,
     667             :                      LDB_SCOPE_BASE, NULL, NULL);
     668           0 :     if (ret != EOK || orig_obj->count != 1) {
     669           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Original object not found.\n");
     670           0 :         goto done;
     671             :     }
     672             : 
     673             :     /* Safe orginal values in attributes prefixed by OriginalAD. */
     674           0 :     for (c = 0; allowed_attrs[c] != NULL; c++) {
     675           0 :         el = ldb_msg_find_element(orig_obj->msgs[0], allowed_attrs[c]);
     676           0 :         if (el != NULL) {
     677           0 :             orig_attr_name = talloc_asprintf(tmp_ctx, "%s%s",
     678             :                                              ORIGINALAD_PREFIX,
     679           0 :                                              allowed_attrs[c]);
     680           0 :             if (orig_attr_name == NULL) {
     681           0 :                 DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
     682           0 :                 ret = ENOMEM;
     683           0 :                 goto done;
     684             :             }
     685             : 
     686           0 :             ret = sysdb_attrs_add_val(attrs, orig_attr_name,
     687           0 :                                       &el->values[0]);
     688           0 :             if (ret != EOK) {
     689           0 :                 DEBUG(SSSDBG_OP_FAILURE,
     690             :                       "sysdb_attrs_add_val failed.\n");
     691           0 :                 goto done;
     692             :             }
     693             :         } else {
     694           0 :             DEBUG(SSSDBG_TRACE_ALL,
     695             :                   "Original object does not have [%s] set.\n",
     696             :                   allowed_attrs[c]);
     697             :         }
     698             :     }
     699             : 
     700             :     /* Add existing aliases to new ones */
     701           0 :     el = ldb_msg_find_element(orig_obj->msgs[0], SYSDB_NAME_ALIAS);
     702           0 :     if (el != NULL) {
     703           0 :         for (c = 0; c < el->num_values; c++) {
     704             :             /* To avoid issue with ldb_modify if e.g. the orginal and the
     705             :              * override name are the same, we use the *_safe version here. */
     706           0 :             ret = sysdb_attrs_add_val_safe(attrs, SYSDB_NAME_ALIAS,
     707           0 :                                            &el->values[c]);
     708           0 :             if (ret != EOK) {
     709           0 :                 DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_val failed.\n");
     710           0 :                 goto done;
     711             :             }
     712             :         }
     713             :     }
     714             : 
     715           0 :     ret = EOK;
     716             : done:
     717           0 :     talloc_free(tmp_ctx);
     718           0 :     return ret;
     719             : }
     720             : 
     721           0 : errno_t sysdb_apply_default_override(struct sss_domain_info *domain,
     722             :                                      struct sysdb_attrs *override_attrs,
     723             :                                      struct ldb_dn *obj_dn)
     724             : {
     725             :     int ret;
     726             :     TALLOC_CTX *tmp_ctx;
     727             :     struct sysdb_attrs *attrs;
     728             :     size_t c;
     729             :     size_t d;
     730             :     size_t num_values;
     731           0 :     struct ldb_message_element *el = NULL;
     732           0 :     const char *allowed_attrs[] = { SYSDB_UIDNUM,
     733             :                                     SYSDB_GIDNUM,
     734             :                                     SYSDB_GECOS,
     735             :                                     SYSDB_HOMEDIR,
     736             :                                     SYSDB_SHELL,
     737             :                                     SYSDB_NAME,
     738             :                                     SYSDB_SSH_PUBKEY,
     739             :                                     NULL };
     740           0 :     bool override_attrs_found = false;
     741             : 
     742           0 :     if (override_attrs == NULL) {
     743             :         /* nothing to do */
     744           0 :         return EOK;
     745             :     }
     746             : 
     747           0 :     tmp_ctx = talloc_new(NULL);
     748           0 :     if (tmp_ctx == NULL) {
     749           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
     750           0 :         return ENOMEM;
     751             :     }
     752             : 
     753           0 :     attrs = sysdb_new_attrs(tmp_ctx);
     754           0 :     if (attrs == NULL) {
     755           0 :         DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n");
     756           0 :         ret = ENOMEM;
     757           0 :         goto done;
     758             :     }
     759             : 
     760           0 :     for (c = 0; allowed_attrs[c] != NULL; c++) {
     761           0 :         ret = sysdb_attrs_get_el_ext(override_attrs, allowed_attrs[c], false,
     762             :                                      &el);
     763           0 :         if (ret == EOK) {
     764           0 :             override_attrs_found = true;
     765             : 
     766           0 :             if (strcmp(allowed_attrs[c], SYSDB_NAME) == 0) {
     767           0 :                 if (el->values[0].data[el->values[0].length] != '\0') {
     768           0 :                     DEBUG(SSSDBG_CRIT_FAILURE,
     769             :                           "String attribute does not end with \\0.\n");
     770           0 :                     ret = EINVAL;
     771           0 :                     goto done;
     772             :                 }
     773             : 
     774           0 :                 ret = add_name_and_aliases_for_name_override(domain, attrs,
     775             :                                                    true,
     776           0 :                                                    (char *) el->values[0].data);
     777           0 :                 if (ret != EOK) {
     778           0 :                     DEBUG(SSSDBG_OP_FAILURE,
     779             :                           "add_name_and_aliases_for_name_override failed.\n");
     780           0 :                     goto done;
     781             :                 }
     782             :             } else {
     783           0 :                 num_values = el->num_values;
     784             :                 /* Only SYSDB_SSH_PUBKEY is allowed to have multiple values. */
     785           0 :                 if (strcmp(allowed_attrs[c], SYSDB_SSH_PUBKEY) != 0
     786           0 :                         && num_values != 1) {
     787           0 :                     DEBUG(SSSDBG_MINOR_FAILURE,
     788             :                           "Override attribute for [%s] has more [%zd] " \
     789             :                           "than one value, using only the first.\n",
     790             :                           allowed_attrs[c], num_values);
     791           0 :                     num_values = 1;
     792             :                 }
     793             : 
     794           0 :                 for (d = 0; d < num_values; d++) {
     795           0 :                     ret = sysdb_attrs_add_val(attrs,  allowed_attrs[c],
     796           0 :                                               &el->values[d]);
     797           0 :                     if (ret != EOK) {
     798           0 :                         DEBUG(SSSDBG_OP_FAILURE,
     799             :                               "sysdb_attrs_add_val failed.\n");
     800           0 :                         goto done;
     801             :                     }
     802           0 :                     DEBUG(SSSDBG_TRACE_ALL,
     803             :                           "Override [%s] with [%.*s] for [%s].\n",
     804             :                           allowed_attrs[c], (int) el->values[d].length,
     805             :                           el->values[d].data, ldb_dn_get_linearized(obj_dn));
     806             :                 }
     807             :             }
     808           0 :         } else if (ret != ENOENT) {
     809           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el_ext failed.\n");
     810           0 :             goto done;
     811             :         }
     812             :     }
     813             : 
     814           0 :     if (override_attrs_found) {
     815           0 :         ret = safe_original_attributes(domain, attrs, obj_dn, allowed_attrs);
     816           0 :         if (ret != EOK) {
     817           0 :             DEBUG(SSSDBG_OP_FAILURE, "safe_original_attributes failed.\n");
     818           0 :             goto done;
     819             :         }
     820             : 
     821           0 :         ret = sysdb_set_entry_attr(domain->sysdb, obj_dn, attrs, SYSDB_MOD_REP);
     822           0 :         if (ret != EOK) {
     823           0 :             DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_entry_attr failed.\n");
     824           0 :             goto done;
     825             :         }
     826             :     }
     827             : 
     828           0 :     ret = EOK;
     829             : 
     830             : done:
     831           0 :     talloc_free(tmp_ctx);
     832           0 :     return ret;
     833             : }
     834             : 
     835             : 
     836             : #define SYSDB_USER_NAME_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_USER_CLASS")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))"
     837             : #define SYSDB_USER_UID_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_USER_CLASS")("SYSDB_UIDNUM"=%lu))"
     838             : #define SYSDB_GROUP_NAME_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_GROUP_CLASS")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))"
     839             : #define SYSDB_GROUP_GID_OVERRIDE_FILTER "(&(objectClass="SYSDB_OVERRIDE_GROUP_CLASS")("SYSDB_GIDNUM"=%lu))"
     840             : 
     841             : enum override_object_type {
     842             :     OO_TYPE_UNDEF = 0,
     843             :     OO_TYPE_USER,
     844             :     OO_TYPE_GROUP
     845             : };
     846             : 
     847           0 : static errno_t sysdb_search_override_by_name(TALLOC_CTX *mem_ctx,
     848             :                                              struct sss_domain_info *domain,
     849             :                                              const char *name,
     850             :                                              const char *filter,
     851             :                                              const char **attrs,
     852             :                                              struct ldb_result **override_obj,
     853             :                                              struct ldb_result **orig_obj)
     854             : {
     855             :     TALLOC_CTX *tmp_ctx;
     856             :     struct ldb_dn *base_dn;
     857             :     struct ldb_result *override_res;
     858             :     struct ldb_result *orig_res;
     859             :     char *sanitized_name;
     860             :     char *lc_sanitized_name;
     861             :     const char *src_name;
     862             :     int ret;
     863             :     const char *orig_obj_dn;
     864             : 
     865           0 :     tmp_ctx = talloc_new(NULL);
     866           0 :     if (!tmp_ctx) {
     867           0 :         return ENOMEM;
     868             :     }
     869             : 
     870           0 :     base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
     871             :                              SYSDB_TMPL_VIEW_SEARCH_BASE, domain->view_name);
     872           0 :     if (base_dn == NULL) {
     873           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n");
     874           0 :         ret = ENOMEM;
     875           0 :         goto done;
     876             :     }
     877             : 
     878             :     /* If this is a subdomain we need to use fully qualified names for the
     879             :      * search as well by default */
     880           0 :     src_name = sss_get_domain_name(tmp_ctx, name, domain);
     881           0 :     if (src_name == NULL) {
     882           0 :         DEBUG(SSSDBG_OP_FAILURE, "sss_get_domain_name failed.\n");
     883           0 :         ret = ENOMEM;
     884           0 :         goto done;
     885             :     }
     886             : 
     887           0 :     ret = sss_filter_sanitize_for_dom(tmp_ctx, src_name, domain,
     888             :                                       &sanitized_name, &lc_sanitized_name);
     889           0 :     if (ret != EOK) {
     890           0 :         DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize_for_dom failed.\n");
     891           0 :         goto done;
     892             :     }
     893             : 
     894           0 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &override_res, base_dn,
     895             :                      LDB_SCOPE_SUBTREE, attrs, filter,
     896             :                      lc_sanitized_name,
     897             :                      sanitized_name, sanitized_name);
     898           0 :     if (ret != LDB_SUCCESS) {
     899           0 :         ret = sysdb_error_to_errno(ret);
     900           0 :         goto done;
     901             :     }
     902             : 
     903           0 :     if (override_res->count == 0) {
     904           0 :         DEBUG(SSSDBG_TRACE_FUNC, "No user override found for name [%s].\n",
     905             :                                  name);
     906           0 :         ret = ENOENT;
     907           0 :         goto done;
     908           0 :     } else if (override_res->count > 1) {
     909           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     910             :               "Found more than one override for name [%s].\n", name);
     911           0 :         ret = EINVAL;
     912           0 :         goto done;
     913             :     }
     914             : 
     915           0 :     if (orig_obj != NULL) {
     916           0 :         orig_obj_dn = ldb_msg_find_attr_as_string(override_res->msgs[0],
     917             :                                                   SYSDB_OVERRIDE_OBJECT_DN,
     918             :                                                   NULL);
     919           0 :         if (orig_obj_dn == NULL) {
     920           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     921             :                   "Missing link to original object in override [%s].\n",
     922             :                   ldb_dn_get_linearized(override_res->msgs[0]->dn));
     923           0 :             ret = EINVAL;
     924           0 :             goto done;
     925             :         }
     926             : 
     927           0 :         base_dn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, orig_obj_dn);
     928           0 :         if (base_dn == NULL) {
     929           0 :             DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
     930           0 :             ret = ENOMEM;
     931           0 :             goto done;
     932             :         }
     933             : 
     934           0 :         ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &orig_res, base_dn,
     935             :                          LDB_SCOPE_BASE, attrs, NULL);
     936           0 :         if (ret != LDB_SUCCESS) {
     937           0 :             ret = sysdb_error_to_errno(ret);
     938           0 :             goto done;
     939             :         }
     940             : 
     941           0 :         *orig_obj = talloc_steal(mem_ctx, orig_res);
     942             :     }
     943             : 
     944             : 
     945           0 :     *override_obj = talloc_steal(mem_ctx, override_res);
     946             : 
     947           0 :     ret = EOK;
     948             : 
     949             : done:
     950           0 :     talloc_zfree(tmp_ctx);
     951           0 :     return ret;
     952             : }
     953             : 
     954           0 : errno_t sysdb_search_user_override_attrs_by_name(TALLOC_CTX *mem_ctx,
     955             :                                              struct sss_domain_info *domain,
     956             :                                              const char *name,
     957             :                                              const char **attrs,
     958             :                                              struct ldb_result **override_obj,
     959             :                                              struct ldb_result **orig_obj)
     960             : {
     961             : 
     962           0 :     return sysdb_search_override_by_name(mem_ctx, domain, name,
     963             :                                          SYSDB_USER_NAME_OVERRIDE_FILTER,
     964             :                                          attrs, override_obj, orig_obj);
     965             : }
     966             : 
     967           0 : errno_t sysdb_search_group_override_attrs_by_name(TALLOC_CTX *mem_ctx,
     968             :                                             struct sss_domain_info *domain,
     969             :                                             const char *name,
     970             :                                             const char **attrs,
     971             :                                             struct ldb_result **override_obj,
     972             :                                             struct ldb_result **orig_obj)
     973             : {
     974           0 :     return sysdb_search_override_by_name(mem_ctx, domain, name,
     975             :                                          SYSDB_GROUP_NAME_OVERRIDE_FILTER,
     976             :                                          attrs, override_obj, orig_obj);
     977             : }
     978             : 
     979           0 : errno_t sysdb_search_user_override_by_name(TALLOC_CTX *mem_ctx,
     980             :                                            struct sss_domain_info *domain,
     981             :                                            const char *name,
     982             :                                            struct ldb_result **override_obj,
     983             :                                            struct ldb_result **orig_obj)
     984             : {
     985           0 :     const char *attrs[] = SYSDB_PW_ATTRS;
     986             : 
     987           0 :     return sysdb_search_override_by_name(mem_ctx, domain, name,
     988             :                                          SYSDB_USER_NAME_OVERRIDE_FILTER,
     989             :                                          attrs, override_obj, orig_obj);
     990             : }
     991             : 
     992           0 : errno_t sysdb_search_group_override_by_name(TALLOC_CTX *mem_ctx,
     993             :                                             struct sss_domain_info *domain,
     994             :                                             const char *name,
     995             :                                             struct ldb_result **override_obj,
     996             :                                             struct ldb_result **orig_obj)
     997             : {
     998           0 :     const char *attrs[] = SYSDB_GRSRC_ATTRS;
     999             : 
    1000           0 :     return sysdb_search_override_by_name(mem_ctx, domain, name,
    1001             :                                          SYSDB_GROUP_NAME_OVERRIDE_FILTER,
    1002             :                                          attrs, override_obj, orig_obj);
    1003             : }
    1004             : 
    1005           0 : static errno_t sysdb_search_override_by_id(TALLOC_CTX *mem_ctx,
    1006             :                                            struct sss_domain_info *domain,
    1007             :                                            unsigned long int id,
    1008             :                                            enum override_object_type type,
    1009             :                                            struct ldb_result **override_obj,
    1010             :                                            struct ldb_result **orig_obj)
    1011             : {
    1012             :     TALLOC_CTX *tmp_ctx;
    1013             :     static const char *user_attrs[] = SYSDB_PW_ATTRS;
    1014             :     static const char *group_attrs[] = SYSDB_GRSRC_ATTRS;
    1015             :     const char **attrs;
    1016             :     struct ldb_dn *base_dn;
    1017             :     struct ldb_result *override_res;
    1018             :     struct ldb_result *orig_res;
    1019             :     int ret;
    1020             :     const char *orig_obj_dn;
    1021             :     const char *filter;
    1022             : 
    1023           0 :     tmp_ctx = talloc_new(NULL);
    1024           0 :     if (!tmp_ctx) {
    1025           0 :         return ENOMEM;
    1026             :     }
    1027             : 
    1028           0 :     base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb,
    1029             :                              SYSDB_TMPL_VIEW_SEARCH_BASE, domain->view_name);
    1030           0 :     if (base_dn == NULL) {
    1031           0 :         DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n");
    1032           0 :         ret = ENOMEM;
    1033           0 :         goto done;
    1034             :     }
    1035             : 
    1036           0 :     switch(type) {
    1037             :     case OO_TYPE_USER:
    1038           0 :         filter = SYSDB_USER_UID_OVERRIDE_FILTER;
    1039           0 :         attrs = user_attrs;
    1040           0 :         break;
    1041             :     case OO_TYPE_GROUP:
    1042           0 :         filter = SYSDB_GROUP_GID_OVERRIDE_FILTER;
    1043           0 :         attrs = group_attrs;
    1044           0 :         break;
    1045             :     default:
    1046           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected override object type [%d].\n",
    1047             :                                    type);
    1048           0 :         ret = EINVAL;
    1049           0 :         goto done;
    1050             :     }
    1051             : 
    1052           0 :     ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &override_res, base_dn,
    1053             :                      LDB_SCOPE_SUBTREE, attrs, filter, id);
    1054           0 :     if (ret != LDB_SUCCESS) {
    1055           0 :         ret = sysdb_error_to_errno(ret);
    1056           0 :         goto done;
    1057             :     }
    1058             : 
    1059           0 :     if (override_res->count == 0) {
    1060           0 :         DEBUG(SSSDBG_TRACE_FUNC,
    1061             :               "No user override found for %s with id [%lu].\n",
    1062             :               (type == OO_TYPE_USER ? "user" : "group"), id);
    1063           0 :         ret = ENOENT;
    1064           0 :         goto done;
    1065           0 :     } else if (override_res->count > 1) {
    1066           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
    1067             :               "Found more than one override for id [%lu].\n", id);
    1068           0 :         ret = EINVAL;
    1069           0 :         goto done;
    1070             :     }
    1071             : 
    1072           0 :     if (orig_obj != NULL) {
    1073           0 :         orig_obj_dn = ldb_msg_find_attr_as_string(override_res->msgs[0],
    1074             :                                                   SYSDB_OVERRIDE_OBJECT_DN,
    1075             :                                                   NULL);
    1076           0 :         if (orig_obj_dn == NULL) {
    1077           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
    1078             :                   "Missing link to original object in override [%s].\n",
    1079             :                   ldb_dn_get_linearized(override_res->msgs[0]->dn));
    1080           0 :             ret = EINVAL;
    1081           0 :             goto done;
    1082             :         }
    1083             : 
    1084           0 :         base_dn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, orig_obj_dn);
    1085           0 :         if (base_dn == NULL) {
    1086           0 :             DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
    1087           0 :             ret = ENOMEM;
    1088           0 :             goto done;
    1089             :         }
    1090             : 
    1091           0 :         ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &orig_res, base_dn,
    1092             :                          LDB_SCOPE_BASE, attrs, NULL);
    1093           0 :         if (ret != LDB_SUCCESS) {
    1094           0 :             ret = sysdb_error_to_errno(ret);
    1095           0 :             goto done;
    1096             :         }
    1097             : 
    1098           0 :         *orig_obj = talloc_steal(mem_ctx, orig_res);
    1099             :     }
    1100             : 
    1101             : 
    1102           0 :     *override_obj = talloc_steal(mem_ctx, override_res);
    1103             : 
    1104           0 :     ret = EOK;
    1105             : 
    1106             : done:
    1107           0 :     talloc_zfree(tmp_ctx);
    1108           0 :     return ret;
    1109             : }
    1110             : 
    1111           0 : errno_t sysdb_search_user_override_by_uid(TALLOC_CTX *mem_ctx,
    1112             :                                           struct sss_domain_info *domain,
    1113             :                                           uid_t uid,
    1114             :                                            struct ldb_result **override_obj,
    1115             :                                            struct ldb_result **orig_obj)
    1116             : {
    1117           0 :     return sysdb_search_override_by_id(mem_ctx, domain, uid, OO_TYPE_USER,
    1118             :                                        override_obj, orig_obj);
    1119             : }
    1120             : 
    1121           0 : errno_t sysdb_search_group_override_by_gid(TALLOC_CTX *mem_ctx,
    1122             :                                             struct sss_domain_info *domain,
    1123             :                                             gid_t gid,
    1124             :                                             struct ldb_result **override_obj,
    1125             :                                             struct ldb_result **orig_obj)
    1126             : {
    1127           0 :     return sysdb_search_override_by_id(mem_ctx, domain, gid, OO_TYPE_GROUP,
    1128             :                                        override_obj, orig_obj);
    1129             : }
    1130             : 
    1131             : /**
    1132             :  * @brief Add override data to the original object
    1133             :  *
    1134             :  * @param[in] domain Domain struct, needed to access the cache
    1135             :  * @oaram[in] obj The original object
    1136             :  * @param[in] override_obj The object with the override data, may be NULL
    1137             :  * @param[in] req_attrs List of attributes to be requested, if not set a
    1138             :  *                      default list dependig on the object type will be used
    1139             :  *
    1140             :  * @return EOK - Override data was added successfully
    1141             :  * @return ENOMEM - There was insufficient memory to complete the operation
    1142             :  * @return ENOENT - The original object did not have the SYSDB_OVERRIDE_DN
    1143             :  *                  attribute or the value of the attribute points an object
    1144             :  *                  which does not exists. Both conditions indicate that the
    1145             :  *                  cache must be refreshed.
    1146             :  */
    1147          23 : errno_t sysdb_add_overrides_to_object(struct sss_domain_info *domain,
    1148             :                                       struct ldb_message *obj,
    1149             :                                       struct ldb_message *override_obj,
    1150             :                                       const char **req_attrs)
    1151             : {
    1152             :     int ret;
    1153             :     const char *override_dn_str;
    1154             :     struct ldb_dn *override_dn;
    1155             :     TALLOC_CTX *tmp_ctx;
    1156             :     struct ldb_result *res;
    1157             :     struct ldb_message *override;
    1158             :     uint64_t uid;
    1159             :     static const char *user_attrs[] = SYSDB_PW_ATTRS;
    1160             :     static const char *group_attrs[] = SYSDB_GRSRC_ATTRS;
    1161             :     const char **attrs;
    1162             :     struct attr_map {
    1163             :         const char *attr;
    1164             :         const char *new_attr;
    1165          23 :     } attr_map[] = {
    1166             :         {SYSDB_UIDNUM, OVERRIDE_PREFIX SYSDB_UIDNUM},
    1167             :         {SYSDB_GIDNUM, OVERRIDE_PREFIX SYSDB_GIDNUM},
    1168             :         {SYSDB_GECOS, OVERRIDE_PREFIX SYSDB_GECOS},
    1169             :         {SYSDB_HOMEDIR, OVERRIDE_PREFIX SYSDB_HOMEDIR},
    1170             :         {SYSDB_SHELL, OVERRIDE_PREFIX SYSDB_SHELL},
    1171             :         {SYSDB_NAME, OVERRIDE_PREFIX SYSDB_NAME},
    1172             :         {SYSDB_SSH_PUBKEY, OVERRIDE_PREFIX SYSDB_SSH_PUBKEY},
    1173             :         {NULL, NULL}
    1174             :     };
    1175             :     size_t c;
    1176             :     size_t d;
    1177             :     struct ldb_message_element *tmp_el;
    1178             : 
    1179          23 :     tmp_ctx = talloc_new(NULL);
    1180          23 :     if (tmp_ctx == NULL) {
    1181           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
    1182           0 :         return ENOMEM;
    1183             :     }
    1184             : 
    1185          23 :     if (override_obj == NULL) {
    1186          22 :         override_dn_str = ldb_msg_find_attr_as_string(obj,
    1187             :                                                       SYSDB_OVERRIDE_DN, NULL);
    1188          22 :         if (override_dn_str == NULL) {
    1189           2 :             if (is_local_view(domain->view_name)) {
    1190             :                 /* LOCAL view doesn't have to have overrideDN specified. */
    1191           1 :                 ret = EOK;
    1192           1 :                 goto done;
    1193             :             }
    1194             : 
    1195           1 :             DEBUG(SSSDBG_CRIT_FAILURE,
    1196             :                   "Missing override DN for object [%s].\n",
    1197             :                   ldb_dn_get_linearized(obj->dn));
    1198             : 
    1199           1 :             ret = ENOENT;
    1200           1 :             goto done;
    1201             :         }
    1202             : 
    1203          20 :         override_dn = ldb_dn_new(tmp_ctx, domain->sysdb->ldb, override_dn_str);
    1204          20 :         if (override_dn == NULL) {
    1205           0 :             DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
    1206           0 :             ret = ENOMEM;
    1207           0 :             goto done;
    1208             :         }
    1209             : 
    1210          20 :         if (ldb_dn_compare(obj->dn, override_dn) == 0) {
    1211           0 :             DEBUG(SSSDBG_TRACE_ALL, "Object [%s] has no overrides.\n",
    1212             :                                     ldb_dn_get_linearized(obj->dn));
    1213           0 :             ret = EOK;
    1214           0 :             goto done;
    1215             :         }
    1216             : 
    1217          20 :         attrs = req_attrs;
    1218          20 :         if (attrs == NULL) {
    1219          20 :             uid = ldb_msg_find_attr_as_uint64(obj, SYSDB_UIDNUM, 0);
    1220          20 :             if (uid == 0) {
    1221             :                 /* No UID hence group object */
    1222          10 :                 attrs = group_attrs;
    1223             :             } else {
    1224          10 :                 attrs = user_attrs;
    1225             :             }
    1226             :         }
    1227             : 
    1228          20 :         ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, override_dn,
    1229             :                          LDB_SCOPE_BASE, attrs, NULL);
    1230          20 :         if (ret != LDB_SUCCESS) {
    1231           0 :             ret = sysdb_error_to_errno(ret);
    1232           0 :             goto done;
    1233             :         }
    1234             : 
    1235          20 :         if (res->count == 1) {
    1236          20 :             override = res->msgs[0];
    1237           0 :         } else if (res->count == 0) {
    1238           0 :             DEBUG(SSSDBG_TRACE_FUNC, "Override object [%s] does not exists.\n",
    1239             :                                      override_dn_str);
    1240           0 :             ret = ENOENT;
    1241           0 :             goto done;
    1242             :         } else {
    1243           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
    1244             :                   "Base search for override object returned [%d] results.\n",
    1245             :                   res->count);
    1246           0 :             ret = EINVAL;
    1247           0 :             goto done;
    1248             :         }
    1249             :     } else {
    1250           1 :         override = override_obj;
    1251             :     }
    1252             : 
    1253         168 :     for (c = 0; attr_map[c].attr != NULL; c++) {
    1254         147 :         tmp_el = ldb_msg_find_element(override, attr_map[c].attr);
    1255         147 :         if (tmp_el != NULL) {
    1256          47 :             for (d = 0; d < tmp_el->num_values; d++) {
    1257          24 :                 ret = ldb_msg_add_steal_value(obj, attr_map[c].new_attr,
    1258          24 :                                               &tmp_el->values[d]);
    1259          24 :                 if (ret != LDB_SUCCESS) {
    1260           0 :                     DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_value failed.\n");
    1261           0 :                     ret = sysdb_error_to_errno(ret);
    1262           0 :                     goto done;
    1263             :                 }
    1264             :             }
    1265             :         }
    1266             :     }
    1267             : 
    1268          21 :     ret = EOK;
    1269             : done:
    1270          23 :     talloc_free(tmp_ctx);
    1271             : 
    1272          23 :     return ret;
    1273             : }
    1274             : 
    1275          10 : errno_t sysdb_add_group_member_overrides(struct sss_domain_info *domain,
    1276             :                                          struct ldb_message *obj)
    1277             : {
    1278             :     int ret;
    1279             :     size_t c;
    1280             :     struct ldb_message_element *members;
    1281             :     TALLOC_CTX *tmp_ctx;
    1282             :     struct ldb_dn *member_dn;
    1283             :     struct ldb_result *member_obj;
    1284             :     struct ldb_result *override_obj;
    1285             :     static const char *member_attrs[] = SYSDB_PW_ATTRS;
    1286             :     const char *override_dn_str;
    1287             :     struct ldb_dn *override_dn;
    1288             :     const char *memberuid;
    1289             :     const char *orig_name;
    1290             :     char *orig_domain;
    1291             :     char *val;
    1292             :     struct sss_domain_info *orig_dom;
    1293             : 
    1294          10 :     members = ldb_msg_find_element(obj, SYSDB_MEMBER);
    1295          10 :     if (members == NULL || members->num_values == 0) {
    1296          10 :         DEBUG(SSSDBG_TRACE_ALL, "Group has no members.\n");
    1297          10 :         return EOK;
    1298             :     }
    1299             : 
    1300           0 :     tmp_ctx = talloc_new(NULL);
    1301           0 :     if (tmp_ctx == NULL) {
    1302           0 :         DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
    1303           0 :         ret = ENOMEM;
    1304           0 :         goto done;
    1305             :     }
    1306             : 
    1307           0 :     for (c = 0; c < members->num_values; c++) {
    1308           0 :         member_dn = ldb_dn_from_ldb_val(tmp_ctx, domain->sysdb->ldb,
    1309           0 :                                         &members->values[c]);
    1310           0 :         if (member_dn == NULL) {
    1311           0 :             DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_from_ldb_val failed.\n");
    1312           0 :             ret = ENOMEM;
    1313           0 :             goto done;
    1314             :         }
    1315             : 
    1316           0 :         ret = ldb_search(domain->sysdb->ldb, member_dn, &member_obj, member_dn,
    1317             :                          LDB_SCOPE_BASE, member_attrs, NULL);
    1318           0 :         if (ret != LDB_SUCCESS) {
    1319           0 :             ret = sysdb_error_to_errno(ret);
    1320           0 :             goto done;
    1321             :         }
    1322             : 
    1323           0 :         if (member_obj->count != 1) {
    1324           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
    1325             :                   "Base search for member object returned [%d] results.\n",
    1326             :                   member_obj->count);
    1327           0 :             ret = EINVAL;
    1328           0 :             goto done;
    1329             :         }
    1330             : 
    1331           0 :         if (ldb_msg_find_attr_as_uint64(member_obj->msgs[0],
    1332             :                                         SYSDB_UIDNUM, 0) == 0) {
    1333             :             /* Skip non-POSIX-user members i.e. groups and non-POSIX users */
    1334           0 :             continue;
    1335             :         }
    1336             : 
    1337           0 :         override_dn_str = ldb_msg_find_attr_as_string(member_obj->msgs[0],
    1338             :                                                       SYSDB_OVERRIDE_DN, NULL);
    1339           0 :         if (override_dn_str == NULL) {
    1340           0 :             if (is_local_view(domain->view_name)) {
    1341             :                 /* LOCAL view doesn't have to have overrideDN specified. */
    1342           0 :                 ret = EOK;
    1343           0 :                 goto done;
    1344             :             }
    1345             : 
    1346           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
    1347             :                   "Missing override DN for object [%s].\n",
    1348             :                   ldb_dn_get_linearized(member_obj->msgs[0]->dn));
    1349           0 :             ret = ENOENT;
    1350           0 :             goto done;
    1351             :         }
    1352             : 
    1353           0 :         override_dn = ldb_dn_new(member_obj, domain->sysdb->ldb,
    1354             :                                  override_dn_str);
    1355           0 :         if (override_dn == NULL) {
    1356           0 :             DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
    1357           0 :             ret = ENOMEM;
    1358           0 :             goto done;
    1359             :         }
    1360             : 
    1361           0 :         orig_name = ldb_msg_find_attr_as_string(member_obj->msgs[0],
    1362             :                                                 SYSDB_NAME,
    1363             :                                                 NULL);
    1364           0 :         if (orig_name == NULL) {
    1365           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Object [%s] has no name.\n",
    1366             :                   ldb_dn_get_linearized(member_obj->msgs[0]->dn));
    1367           0 :             ret = EINVAL;
    1368           0 :             goto done;
    1369             :         }
    1370             : 
    1371           0 :         memberuid = NULL;
    1372           0 :         if (ldb_dn_compare(member_obj->msgs[0]->dn, override_dn) != 0) {
    1373           0 :             DEBUG(SSSDBG_TRACE_ALL, "Checking override for object [%s].\n",
    1374             :                   ldb_dn_get_linearized(member_obj->msgs[0]->dn));
    1375             : 
    1376           0 :             ret = ldb_search(domain->sysdb->ldb, member_obj, &override_obj,
    1377             :                              override_dn, LDB_SCOPE_BASE, member_attrs, NULL);
    1378           0 :             if (ret != LDB_SUCCESS) {
    1379           0 :                 ret = sysdb_error_to_errno(ret);
    1380           0 :                 goto done;
    1381             :             }
    1382             : 
    1383           0 :             if (override_obj->count != 1) {
    1384           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
    1385             :                      "Base search for override object returned [%d] results.\n",
    1386             :                      member_obj->count);
    1387           0 :                 ret = EINVAL;
    1388           0 :                 goto done;
    1389             :             }
    1390             : 
    1391           0 :             memberuid = ldb_msg_find_attr_as_string(override_obj->msgs[0],
    1392             :                                                     SYSDB_NAME,
    1393             :                                                     NULL);
    1394             : 
    1395           0 :             if (memberuid != NULL) {
    1396           0 :                 ret = sss_parse_name(tmp_ctx, domain->names, orig_name,
    1397             :                                      &orig_domain, NULL);
    1398           0 :                 if (ret != EOK) {
    1399           0 :                     DEBUG(SSSDBG_OP_FAILURE,
    1400             :                          "sss_parse_name failed to split original name [%s].\n",
    1401             :                          orig_name);
    1402           0 :                     goto done;
    1403             :                 }
    1404             : 
    1405           0 :                 if (orig_domain != NULL) {
    1406           0 :                     orig_dom = find_domain_by_name(get_domains_head(domain),
    1407             :                                                    orig_domain, true);
    1408           0 :                     if (orig_dom == NULL) {
    1409           0 :                         DEBUG(SSSDBG_CRIT_FAILURE,
    1410             :                               "Cannot find domain with name [%s].\n",
    1411             :                               orig_domain);
    1412           0 :                         ret = EINVAL;
    1413           0 :                         goto done;
    1414             :                     }
    1415           0 :                     memberuid = sss_get_domain_name(tmp_ctx, memberuid,
    1416             :                                                     orig_dom);
    1417           0 :                     if (memberuid == NULL) {
    1418           0 :                         DEBUG(SSSDBG_OP_FAILURE,
    1419             :                               "sss_get_domain_name failed.\n");
    1420           0 :                         ret = ENOMEM;
    1421           0 :                         goto done;
    1422             :                     }
    1423             :                 }
    1424             :             }
    1425             :         }
    1426             : 
    1427           0 :         if (memberuid == NULL) {
    1428           0 :             DEBUG(SSSDBG_TRACE_ALL, "No override name available.\n");
    1429             : 
    1430           0 :             memberuid = orig_name;
    1431             :         }
    1432             : 
    1433           0 :         val = talloc_strdup(obj, memberuid);
    1434           0 :         if (val == NULL) {
    1435           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
    1436           0 :             ret = ENOMEM;
    1437           0 :             goto done;
    1438             :         }
    1439             : 
    1440           0 :         ret = ldb_msg_add_string(obj, OVERRIDE_PREFIX SYSDB_MEMBERUID, val);
    1441           0 :         if (ret != LDB_SUCCESS) {
    1442           0 :             DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n");
    1443           0 :             ret = sysdb_error_to_errno(ret);
    1444           0 :             goto done;
    1445             :         }
    1446           0 :         DEBUG(SSSDBG_TRACE_ALL, "Added [%s] to [%s].\n", memberuid,
    1447             :                                 OVERRIDE_PREFIX SYSDB_MEMBERUID);
    1448             : 
    1449             :         /* Free all temporary data of the current member to avoid memory usage
    1450             :          * spikes. All temporary data should be allocated below member_dn. */
    1451           0 :         talloc_free(member_dn);
    1452             :     }
    1453             : 
    1454           0 :     ret = EOK;
    1455             : 
    1456             : done:
    1457           0 :     talloc_free(tmp_ctx);
    1458             : 
    1459           0 :     return ret;
    1460             : }
    1461             : 
    1462             : struct ldb_message_element *
    1463           9 : sss_view_ldb_msg_find_element(struct sss_domain_info *dom,
    1464             :                                               const struct ldb_message *msg,
    1465             :                                               const char *attr_name)
    1466             : {
    1467           9 :     TALLOC_CTX *tmp_ctx = NULL;
    1468             :     struct ldb_message_element *val;
    1469             :     char *override_attr_name;
    1470             : 
    1471           9 :     if (DOM_HAS_VIEWS(dom)) {
    1472           0 :         tmp_ctx = talloc_new(NULL);
    1473           0 :         if (tmp_ctx == NULL) {
    1474           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
    1475           0 :             val = NULL;
    1476           0 :             goto done;
    1477             :         }
    1478             : 
    1479           0 :         override_attr_name = talloc_asprintf(tmp_ctx, "%s%s", OVERRIDE_PREFIX,
    1480             :                                                               attr_name);
    1481           0 :         if (override_attr_name == NULL) {
    1482           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
    1483           0 :             val = NULL;
    1484           0 :             goto done;
    1485             :         }
    1486             : 
    1487           0 :         val = ldb_msg_find_element(msg, override_attr_name);
    1488           0 :         if (val != NULL) {
    1489           0 :             goto done;
    1490             :         }
    1491             :     }
    1492             : 
    1493           9 :     val = ldb_msg_find_element(msg, attr_name);
    1494             : 
    1495             : done:
    1496           9 :     talloc_free(tmp_ctx);
    1497           9 :     return val;
    1498             : }
    1499             : 
    1500          36 : uint64_t sss_view_ldb_msg_find_attr_as_uint64(struct sss_domain_info *dom,
    1501             :                                               const struct ldb_message *msg,
    1502             :                                               const char *attr_name,
    1503             :                                               uint64_t default_value)
    1504             : {
    1505          36 :     TALLOC_CTX *tmp_ctx = NULL;
    1506             :     uint64_t val;
    1507             :     char *override_attr_name;
    1508             : 
    1509          36 :     if (DOM_HAS_VIEWS(dom)) {
    1510           0 :         tmp_ctx = talloc_new(NULL);
    1511           0 :         if (tmp_ctx == NULL) {
    1512           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
    1513           0 :             val = default_value;
    1514           0 :             goto done;
    1515             :         }
    1516             : 
    1517           0 :         override_attr_name = talloc_asprintf(tmp_ctx, "%s%s", OVERRIDE_PREFIX,
    1518             :                                                               attr_name);
    1519           0 :         if (override_attr_name == NULL) {
    1520           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
    1521           0 :             val = default_value;
    1522           0 :             goto done;
    1523             :         }
    1524             : 
    1525           0 :         if (ldb_msg_find_element(msg, override_attr_name) != NULL) {
    1526           0 :             val = ldb_msg_find_attr_as_uint64(msg, override_attr_name,
    1527             :                                               default_value);
    1528           0 :             goto done;
    1529             :         }
    1530             :     }
    1531             : 
    1532          36 :     val = ldb_msg_find_attr_as_uint64(msg, attr_name, default_value);
    1533             : 
    1534             : done:
    1535          36 :     talloc_free(tmp_ctx);
    1536          36 :     return val;
    1537             : }
    1538             : 
    1539          36 : const char *sss_view_ldb_msg_find_attr_as_string(struct sss_domain_info *dom,
    1540             :                                                  const struct ldb_message *msg,
    1541             :                                                  const char *attr_name,
    1542             :                                                  const char * default_value)
    1543             : {
    1544          36 :     TALLOC_CTX *tmp_ctx = NULL;
    1545             :     const char *val;
    1546             :     char *override_attr_name;
    1547             : 
    1548          36 :     if (DOM_HAS_VIEWS(dom)) {
    1549           0 :         tmp_ctx = talloc_new(NULL);
    1550           0 :         if (tmp_ctx == NULL) {
    1551           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
    1552           0 :             val = default_value;
    1553           0 :             goto done;
    1554             :         }
    1555             : 
    1556           0 :         override_attr_name = talloc_asprintf(tmp_ctx, "%s%s", OVERRIDE_PREFIX,
    1557             :                                                               attr_name);
    1558           0 :         if (override_attr_name == NULL) {
    1559           0 :             DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
    1560           0 :             val = default_value;
    1561           0 :             goto done;
    1562             :         }
    1563             : 
    1564           0 :         if (ldb_msg_find_element(msg, override_attr_name) != NULL) {
    1565           0 :             val = ldb_msg_find_attr_as_string(msg, override_attr_name,
    1566             :                                               default_value);
    1567           0 :             goto done;
    1568             :         }
    1569             :     }
    1570             : 
    1571          36 :     val = ldb_msg_find_attr_as_string(msg, attr_name, default_value);
    1572             : 
    1573             : done:
    1574          36 :     talloc_free(tmp_ctx);
    1575          36 :     return val;
    1576             : }

Generated by: LCOV version 1.10