LCOV - code coverage report
Current view: top level - db - sysdb.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 370 722 51.2 %
Date: 2012-11-29 Functions: 40 60 66.7 %
Branches: 136 969 14.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :    SSSD
       3                 :            : 
       4                 :            :    System Database
       5                 :            : 
       6                 :            :    Copyright (C) 2008-2011 Simo Sorce <ssorce@redhat.com>
       7                 :            :    Copyright (C) 2008-2011 Stephen Gallagher <ssorce@redhat.com>
       8                 :            : 
       9                 :            :    This program is free software; you can redistribute it and/or modify
      10                 :            :    it under the terms of the GNU General Public License as published by
      11                 :            :    the Free Software Foundation; either version 3 of the License, or
      12                 :            :    (at your option) any later version.
      13                 :            : 
      14                 :            :    This program is distributed in the hope that it will be useful,
      15                 :            :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16                 :            :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17                 :            :    GNU General Public License for more details.
      18                 :            : 
      19                 :            :    You should have received a copy of the GNU General Public License
      20                 :            :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21                 :            : */
      22                 :            : 
      23                 :            : #include "util/util.h"
      24                 :            : #include "util/strtonum.h"
      25                 :            : #include "util/sss_utf8.h"
      26                 :            : #include "db/sysdb_private.h"
      27                 :            : #include "confdb/confdb.h"
      28                 :            : #include <time.h>
      29                 :            : 
      30                 :            : #define LDB_MODULES_PATH "LDB_MODULES_PATH"
      31                 :            : 
      32                 :        646 : errno_t sysdb_ldb_connect(TALLOC_CTX *mem_ctx, const char *filename,
      33                 :            :                           struct ldb_context **_ldb)
      34                 :            : {
      35                 :            :     int ret;
      36                 :            :     struct ldb_context *ldb;
      37                 :            :     const char *mod_path;
      38                 :            : 
      39         [ +  - ]:        646 :     if (_ldb == NULL) {
      40                 :            :         return EINVAL;
      41                 :            :     }
      42                 :            : 
      43                 :        646 :     ldb = ldb_init(mem_ctx, NULL);
      44         [ +  - ]:        646 :     if (!ldb) {
      45                 :            :         return EIO;
      46                 :            :     }
      47                 :            : 
      48                 :        646 :     ret = ldb_set_debug(ldb, ldb_debug_messages, NULL);
      49         [ +  - ]:        646 :     if (ret != LDB_SUCCESS) {
      50                 :            :         return EIO;
      51                 :            :     }
      52                 :            : 
      53                 :        646 :     mod_path = getenv(LDB_MODULES_PATH);
      54         [ +  - ]:        646 :     if (mod_path != NULL) {
      55 [ +  - ][ +  - ]:        646 :         DEBUG(9, ("Setting ldb module path to [%s].\n", mod_path));
         [ -  + ][ #  # ]
                 [ #  # ]
      56                 :        646 :         ldb_set_modules_dir(ldb, mod_path);
      57                 :            :     }
      58                 :            : 
      59                 :        646 :     ret = ldb_connect(ldb, filename, 0, NULL);
      60         [ +  - ]:        646 :     if (ret != LDB_SUCCESS) {
      61                 :            :         return EIO;
      62                 :            :     }
      63                 :            : 
      64                 :        646 :     *_ldb = ldb;
      65                 :            : 
      66                 :        646 :     return EOK;
      67                 :            : }
      68                 :            : 
      69                 :       1158 : errno_t sysdb_dn_sanitize(TALLOC_CTX *mem_ctx, const char *input,
      70                 :            :                           char **sanitized)
      71                 :            : {
      72                 :            :     struct ldb_val val;
      73                 :       1158 :     errno_t ret = EOK;
      74                 :            : 
      75                 :       1158 :     val.data = (uint8_t *)talloc_strdup(mem_ctx, input);
      76         [ +  - ]:       1158 :     if (!val.data) {
      77                 :            :         return ENOMEM;
      78                 :            :     }
      79                 :            : 
      80                 :            :     /* We can't include the trailing NULL because it would
      81                 :            :      * be escaped and result in an unterminated string
      82                 :            :      */
      83                 :       1158 :     val.length = strlen(input);
      84                 :            : 
      85                 :       1158 :     *sanitized = ldb_dn_escape_value(mem_ctx, val);
      86         [ -  + ]:       1158 :     if (!*sanitized) {
      87                 :          0 :         ret = ENOMEM;
      88                 :            :     }
      89                 :            : 
      90                 :       1158 :     talloc_free(val.data);
      91                 :            :     return ret;
      92                 :            : }
      93                 :            : 
      94                 :         24 : struct ldb_dn *sysdb_custom_subtree_dn(struct sysdb_ctx *sysdb,
      95                 :            :                                        TALLOC_CTX *mem_ctx,
      96                 :            :                                        const char *subtree_name)
      97                 :            : {
      98                 :            :     errno_t ret;
      99                 :            :     char *clean_subtree;
     100                 :         24 :     struct ldb_dn *dn = NULL;
     101                 :            :     TALLOC_CTX *tmp_ctx;
     102                 :            : 
     103                 :         24 :     tmp_ctx = talloc_new(NULL);
     104         [ +  - ]:         24 :     if (!tmp_ctx) return NULL;
     105                 :            : 
     106                 :         24 :     ret = sysdb_dn_sanitize(tmp_ctx, subtree_name, &clean_subtree);
     107         [ -  + ]:         24 :     if (ret != EOK) {
     108                 :          0 :         talloc_free(tmp_ctx);
     109                 :            :         return NULL;
     110                 :            :     }
     111                 :            : 
     112                 :         24 :     dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE,
     113                 :         24 :                         clean_subtree, sysdb->domain->name);
     114         [ +  - ]:         24 :     if (dn) {
     115                 :         24 :         talloc_steal(mem_ctx, dn);
     116                 :            :     }
     117                 :         24 :     talloc_free(tmp_ctx);
     118                 :            : 
     119                 :            :     return dn;
     120                 :            : }
     121                 :            : 
     122                 :         71 : struct ldb_dn *sysdb_custom_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx,
     123                 :            :                                const char *object_name,
     124                 :            :                                const char *subtree_name)
     125                 :            : {
     126                 :            :     errno_t ret;
     127                 :            :     TALLOC_CTX *tmp_ctx;
     128                 :            :     char *clean_name;
     129                 :            :     char *clean_subtree;
     130                 :         71 :     struct ldb_dn *dn = NULL;
     131                 :            : 
     132                 :         71 :     tmp_ctx = talloc_new(NULL);
     133         [ +  - ]:         71 :     if (!tmp_ctx) {
     134                 :            :         return NULL;
     135                 :            :     }
     136                 :            : 
     137                 :         71 :     ret = sysdb_dn_sanitize(tmp_ctx, object_name, &clean_name);
     138         [ +  - ]:         71 :     if (ret != EOK) {
     139                 :            :         goto done;
     140                 :            :     }
     141                 :            : 
     142                 :         71 :     ret = sysdb_dn_sanitize(tmp_ctx, subtree_name, &clean_subtree);
     143         [ +  - ]:         71 :     if (ret != EOK) {
     144                 :            :         goto done;
     145                 :            :     }
     146                 :            : 
     147                 :         71 :     dn = ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_CUSTOM, clean_name,
     148                 :         71 :                         clean_subtree, sysdb->domain->name);
     149                 :            : 
     150                 :            : done:
     151                 :         71 :     talloc_free(tmp_ctx);
     152                 :            :     return dn;
     153                 :            : }
     154                 :            : 
     155                 :        348 : struct ldb_dn *sysdb_user_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx,
     156                 :            :                              const char *name)
     157                 :            : {
     158                 :            :     errno_t ret;
     159                 :            :     char *clean_name;
     160                 :            :     struct ldb_dn *dn;
     161                 :            : 
     162                 :        348 :     ret = sysdb_dn_sanitize(NULL, name, &clean_name);
     163         [ +  - ]:        348 :     if (ret != EOK) {
     164                 :            :         return NULL;
     165                 :            :     }
     166                 :            : 
     167                 :        348 :     dn = ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_USER,
     168                 :        348 :                         clean_name, sysdb->domain->name);
     169                 :        348 :     talloc_free(clean_name);
     170                 :            : 
     171                 :            :     return dn;
     172                 :            : }
     173                 :            : 
     174                 :        328 : struct ldb_dn *sysdb_group_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx,
     175                 :            :                               const char *name)
     176                 :            : {
     177                 :            :     errno_t ret;
     178                 :            :     char *clean_name;
     179                 :            :     struct ldb_dn *dn;
     180                 :            : 
     181                 :        328 :     ret = sysdb_dn_sanitize(NULL, name, &clean_name);
     182         [ +  - ]:        328 :     if (ret != EOK) {
     183                 :            :         return NULL;
     184                 :            :     }
     185                 :            : 
     186                 :        328 :     dn = ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_GROUP,
     187                 :        328 :                         clean_name, sysdb->domain->name);
     188                 :        328 :     talloc_free(clean_name);
     189                 :            : 
     190                 :            :     return dn;
     191                 :            : }
     192                 :            : 
     193                 :         90 : struct ldb_dn *sysdb_netgroup_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx,
     194                 :            :                                  const char *name)
     195                 :            : {
     196                 :            :     errno_t ret;
     197                 :            :     char *clean_name;
     198                 :            :     struct ldb_dn *dn;
     199                 :            : 
     200                 :         90 :     ret = sysdb_dn_sanitize(NULL, name, &clean_name);
     201         [ +  - ]:         90 :     if (ret != EOK) {
     202                 :            :         return NULL;
     203                 :            :     }
     204                 :            : 
     205                 :         90 :     dn = ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_NETGROUP,
     206                 :         90 :                         clean_name, sysdb->domain->name);
     207                 :         90 :     talloc_free(clean_name);
     208                 :            : 
     209                 :            :     return dn;
     210                 :            : }
     211                 :            : 
     212                 :          0 : struct ldb_dn *sysdb_netgroup_base_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx)
     213                 :            : {
     214                 :          0 :     return ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_NETGROUP_BASE,
     215                 :          0 :                           sysdb->domain->name);
     216                 :            : }
     217                 :            : 
     218                 :         10 : errno_t sysdb_get_rdn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx,
     219                 :            :                       const char *_dn, char **_name, char **_val)
     220                 :            : {
     221                 :            :     errno_t ret;
     222                 :            :     struct ldb_dn *dn;
     223                 :         10 :     const char *attr_name = NULL;
     224                 :            :     const struct ldb_val *val;
     225                 :            :     TALLOC_CTX *tmp_ctx;
     226                 :            : 
     227                 :            :     /* We have to create a tmp_ctx here because
     228                 :            :      * ldb_dn_new_fmt() fails if mem_ctx is NULL
     229                 :            :      */
     230                 :         10 :     tmp_ctx = talloc_new(NULL);
     231         [ +  - ]:         10 :     if (!tmp_ctx) {
     232                 :            :         return ENOMEM;
     233                 :            :     }
     234                 :            : 
     235                 :         10 :     dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, "%s", _dn);
     236         [ +  - ]:         10 :     if (dn == NULL) {
     237                 :            :         ret = ENOMEM;
     238                 :            :         goto done;
     239                 :            :     }
     240                 :            : 
     241         [ -  + ]:         10 :     if (_name) {
     242                 :          0 :         attr_name = ldb_dn_get_rdn_name(dn);
     243         [ #  # ]:          0 :         if (attr_name == NULL) {
     244                 :            :             ret = EINVAL;
     245                 :            :             goto done;
     246                 :            :         }
     247                 :            : 
     248                 :          0 :         *_name = talloc_strdup(mem_ctx, attr_name);
     249         [ #  # ]:          0 :         if (!*_name) {
     250                 :            :             ret = ENOMEM;
     251                 :            :             goto done;
     252                 :            :         }
     253                 :            :     }
     254                 :            : 
     255                 :         10 :     val = ldb_dn_get_rdn_val(dn);
     256         [ -  + ]:         10 :     if (val == NULL) {
     257                 :          0 :         ret = EINVAL;
     258         [ #  # ]:          0 :         if (_name) talloc_free(*_name);
     259                 :            :         goto done;
     260                 :            :     }
     261                 :            : 
     262                 :         10 :     *_val = talloc_strndup(mem_ctx, (char *) val->data, val->length);
     263         [ -  + ]:         10 :     if (!*_val) {
     264                 :          0 :         ret = ENOMEM;
     265         [ #  # ]:          0 :         if (_name) talloc_free(*_name);
     266                 :            :         goto done;
     267                 :            :     }
     268                 :            : 
     269                 :            :     ret = EOK;
     270                 :            : 
     271                 :            : done:
     272                 :         10 :     talloc_zfree(tmp_ctx);
     273                 :         10 :     return ret;
     274                 :            : }
     275                 :            : 
     276                 :         10 : errno_t sysdb_group_dn_name(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx,
     277                 :            :                             const char *_dn, char **_name)
     278                 :            : {
     279                 :         10 :     return sysdb_get_rdn(sysdb, mem_ctx, _dn, NULL, _name);
     280                 :            : }
     281                 :            : 
     282                 :          1 : struct ldb_dn *sysdb_domain_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx)
     283                 :            : {
     284                 :          1 :     return ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_DOM_BASE, sysdb->domain->name);
     285                 :            : }
     286                 :          0 : struct ldb_dn *sysdb_base_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx)
     287                 :            : {
     288                 :          0 :     return ldb_dn_new(mem_ctx, sysdb->ldb, SYSDB_BASE);
     289                 :            : }
     290                 :            : 
     291                 :          0 : struct ldb_context *sysdb_ctx_get_ldb(struct sysdb_ctx *sysdb)
     292                 :            : {
     293                 :          0 :     return sysdb->ldb;
     294                 :            : }
     295                 :            : 
     296                 :          0 : struct sss_domain_info *sysdb_ctx_get_domain(struct sysdb_ctx *sysdb)
     297                 :            : {
     298                 :          0 :     return sysdb->domain;
     299                 :            : }
     300                 :            : 
     301                 :        306 : struct sysdb_attrs *sysdb_new_attrs(TALLOC_CTX *mem_ctx)
     302                 :            : {
     303                 :        306 :     return talloc_zero(mem_ctx, struct sysdb_attrs);
     304                 :            : }
     305                 :            : 
     306                 :       1197 : int sysdb_attrs_get_el_ext(struct sysdb_attrs *attrs, const char *name,
     307                 :            :                            bool alloc, struct ldb_message_element **el)
     308                 :            : {
     309                 :       1197 :     struct ldb_message_element *e = NULL;
     310                 :            :     int i;
     311                 :            : 
     312         [ +  + ]:       2997 :     for (i = 0; i < attrs->num; i++) {
     313         [ +  + ]:       1800 :         if (strcasecmp(name, attrs->a[i].name) == 0)
     314                 :         37 :             e = &(attrs->a[i]);
     315                 :            :     }
     316                 :            : 
     317         [ +  + ]:       1197 :     if (!e && alloc) {
     318                 :       1097 :         e = talloc_realloc(attrs, attrs->a,
     319                 :            :                            struct ldb_message_element, attrs->num+1);
     320         [ +  - ]:       1097 :         if (!e) return ENOMEM;
     321                 :       1097 :         attrs->a = e;
     322                 :            : 
     323                 :       1097 :         e[attrs->num].name = talloc_strdup(e, name);
     324         [ +  - ]:       1097 :         if (!e[attrs->num].name) return ENOMEM;
     325                 :            : 
     326                 :       1097 :         e[attrs->num].num_values = 0;
     327                 :       1097 :         e[attrs->num].values = NULL;
     328                 :       1097 :         e[attrs->num].flags = 0;
     329                 :            : 
     330                 :       1097 :         e = &(attrs->a[attrs->num]);
     331                 :       1097 :         attrs->num++;
     332                 :            :     }
     333                 :            : 
     334         [ +  + ]:       1197 :     if (!e) {
     335                 :            :         return ENOENT;
     336                 :            :     }
     337                 :            : 
     338                 :       1134 :     *el = e;
     339                 :            : 
     340                 :       1197 :     return EOK;
     341                 :            : }
     342                 :            : 
     343                 :       1134 : int sysdb_attrs_get_el(struct sysdb_attrs *attrs, const char *name,
     344                 :            :                        struct ldb_message_element **el)
     345                 :            : {
     346                 :       1134 :     return sysdb_attrs_get_el_ext(attrs, name, true, el);
     347                 :            : }
     348                 :            : 
     349                 :          0 : int sysdb_attrs_get_string(struct sysdb_attrs *attrs, const char *name,
     350                 :            :                            const char **string)
     351                 :            : {
     352                 :            :     struct ldb_message_element *el;
     353                 :            :     int ret;
     354                 :            : 
     355                 :          0 :     ret = sysdb_attrs_get_el_ext(attrs, name, false, &el);
     356         [ #  # ]:          0 :     if (ret) {
     357                 :            :         return ret;
     358                 :            :     }
     359                 :            : 
     360         [ #  # ]:          0 :     if (el->num_values != 1) {
     361                 :            :         return ERANGE;
     362                 :            :     }
     363                 :            : 
     364                 :          0 :     *string = (const char *)el->values[0].data;
     365                 :            :     return EOK;
     366                 :            : }
     367                 :            : 
     368                 :          0 : int sysdb_attrs_get_uint32_t(struct sysdb_attrs *attrs, const char *name,
     369                 :            :                              uint32_t *value)
     370                 :            : {
     371                 :            :     struct ldb_message_element *el;
     372                 :            :     int ret;
     373                 :            :     char *endptr;
     374                 :            :     uint32_t val;
     375                 :            : 
     376                 :          0 :     ret = sysdb_attrs_get_el_ext(attrs, name, false, &el);
     377         [ #  # ]:          0 :     if (ret) {
     378                 :            :         return ret;
     379                 :            :     }
     380                 :            : 
     381         [ #  # ]:          0 :     if (el->num_values != 1) {
     382                 :            :         return ERANGE;
     383                 :            :     }
     384                 :            : 
     385                 :          0 :     errno = 0;
     386                 :          0 :     val = strtouint32((const char *) el->values[0].data, &endptr, 10);
     387         [ #  # ]:          0 :     if (errno != 0) return errno;
     388         [ #  # ]:          0 :     if (*endptr) return EINVAL;
     389                 :            : 
     390                 :          0 :     *value = val;
     391                 :            :     return EOK;
     392                 :            : }
     393                 :            : 
     394                 :          0 : int sysdb_attrs_get_uint16_t(struct sysdb_attrs *attrs, const char *name,
     395                 :            :                              uint16_t *value)
     396                 :            : {
     397                 :            :     struct ldb_message_element *el;
     398                 :            :     int ret;
     399                 :            :     char *endptr;
     400                 :            :     uint16_t val;
     401                 :            : 
     402                 :          0 :     ret = sysdb_attrs_get_el_ext(attrs, name, false, &el);
     403         [ #  # ]:          0 :     if (ret) {
     404                 :            :         return ret;
     405                 :            :     }
     406                 :            : 
     407         [ #  # ]:          0 :     if (el->num_values != 1) {
     408                 :            :         return ERANGE;
     409                 :            :     }
     410                 :            : 
     411                 :          0 :     errno = 0;
     412                 :          0 :     val = strtouint16((const char *) el->values[0].data, &endptr, 10);
     413         [ #  # ]:          0 :     if (errno != 0) return errno;
     414         [ #  # ]:          0 :     if (*endptr) return EINVAL;
     415                 :            : 
     416                 :          0 :     *value = val;
     417                 :            :     return EOK;
     418                 :            : }
     419                 :            : 
     420                 :         63 : errno_t sysdb_attrs_get_bool(struct sysdb_attrs *attrs, const char *name,
     421                 :            :                              bool *value)
     422                 :            : {
     423                 :            :     struct ldb_message_element *el;
     424                 :            :     int ret;
     425                 :            : 
     426                 :         63 :     ret = sysdb_attrs_get_el_ext(attrs, name, false, &el);
     427         [ -  + ]:         63 :     if (ret) {
     428                 :            :         return ret;
     429                 :            :     }
     430                 :            : 
     431         [ #  # ]:          0 :     if (el->num_values != 1) {
     432                 :            :         return ERANGE;
     433                 :            :     }
     434                 :            : 
     435         [ #  # ]:          0 :     if (strcmp((const char *)el->values[0].data, "TRUE") == 0)
     436                 :          0 :         *value = true;
     437                 :            :     else
     438                 :         63 :         *value = false;
     439                 :            :     return EOK;
     440                 :            : }
     441                 :            : 
     442                 :          0 : int sysdb_attrs_get_string_array(struct sysdb_attrs *attrs, const char *name,
     443                 :            :                                  TALLOC_CTX *mem_ctx, const char ***string)
     444                 :            : {
     445                 :            :     struct ldb_message_element *el;
     446                 :            :     int ret;
     447                 :            :     unsigned int u;
     448                 :            :     const char **a;
     449                 :            : 
     450                 :          0 :     ret = sysdb_attrs_get_el_ext(attrs, name, false, &el);
     451         [ #  # ]:          0 :     if (ret) {
     452                 :            :         return ret;
     453                 :            :     }
     454                 :            : 
     455                 :          0 :     a = talloc_array(mem_ctx, const char *, el->num_values + 1);
     456         [ #  # ]:          0 :     if (a == NULL) {
     457                 :            :         return ENOMEM;
     458                 :            :     }
     459                 :            : 
     460                 :          0 :     memset(a, 0, sizeof(const char *) * (el->num_values + 1));
     461                 :            : 
     462         [ #  # ]:          0 :     for(u = 0; u < el->num_values; u++) {
     463                 :          0 :         a[u] = talloc_strndup(a, (const char *)el->values[u].data,
     464                 :          0 :                               el->values[u].length);
     465         [ #  # ]:          0 :         if (a[u] == NULL) {
     466                 :          0 :             talloc_free(a);
     467                 :            :             return ENOMEM;
     468                 :            :         }
     469                 :            :     }
     470                 :            : 
     471                 :          0 :     *string = a;
     472                 :            :     return EOK;
     473                 :            : }
     474                 :            : 
     475                 :       1009 : int sysdb_attrs_add_val(struct sysdb_attrs *attrs,
     476                 :            :                         const char *name, const struct ldb_val *val)
     477                 :            : {
     478                 :       1009 :     struct ldb_message_element *el = NULL;
     479                 :            :     struct ldb_val *vals;
     480                 :            :     int ret;
     481                 :            : 
     482                 :       1009 :     ret = sysdb_attrs_get_el(attrs, name, &el);
     483         [ +  - ]:       1009 :     if (ret != EOK) {
     484                 :            :         return ret;
     485                 :            :     }
     486                 :            : 
     487                 :       1009 :     vals = talloc_realloc(attrs->a, el->values,
     488                 :            :                           struct ldb_val, el->num_values+1);
     489         [ +  - ]:       1009 :     if (!vals) return ENOMEM;
     490                 :            : 
     491                 :       1009 :     vals[el->num_values] = ldb_val_dup(vals, val);
     492 [ -  + ][ #  # ]:       1009 :     if (vals[el->num_values].data == NULL &&
     493                 :          0 :         vals[el->num_values].length != 0) {
     494                 :            :         return ENOMEM;
     495                 :            :     }
     496                 :            : 
     497                 :       1009 :     el->values = vals;
     498                 :       1009 :     el->num_values++;
     499                 :            : 
     500                 :            :     return EOK;
     501                 :            : }
     502                 :            : 
     503                 :        651 : int sysdb_attrs_add_string(struct sysdb_attrs *attrs,
     504                 :            :                            const char *name, const char *str)
     505                 :            : {
     506                 :            :     struct ldb_val v;
     507                 :            : 
     508                 :        651 :     v.data = (uint8_t *)discard_const(str);
     509                 :        651 :     v.length = strlen(str);
     510                 :            : 
     511                 :        651 :     return sysdb_attrs_add_val(attrs, name, &v);
     512                 :            : }
     513                 :            : 
     514                 :         76 : int sysdb_attrs_add_bool(struct sysdb_attrs *attrs,
     515                 :            :                          const char *name, bool value)
     516                 :            : {
     517         [ +  - ]:         76 :     if(value) {
     518                 :         76 :         return sysdb_attrs_add_string(attrs, name, "TRUE");
     519                 :            :     }
     520                 :            : 
     521                 :         76 :     return sysdb_attrs_add_string(attrs, name, "FALSE");
     522                 :            : }
     523                 :            : 
     524                 :         84 : int sysdb_attrs_steal_string(struct sysdb_attrs *attrs,
     525                 :            :                              const char *name, char *str)
     526                 :            : {
     527                 :         84 :     struct ldb_message_element *el = NULL;
     528                 :            :     struct ldb_val *vals;
     529                 :            :     int ret;
     530                 :            : 
     531                 :         84 :     ret = sysdb_attrs_get_el(attrs, name, &el);
     532         [ +  - ]:         84 :     if (ret != EOK) {
     533                 :            :         return ret;
     534                 :            :     }
     535                 :            : 
     536                 :         84 :     vals = talloc_realloc(attrs->a, el->values,
     537                 :            :                           struct ldb_val, el->num_values+1);
     538         [ +  - ]:         84 :     if (!vals) return ENOMEM;
     539                 :         84 :     el->values = vals;
     540                 :            : 
     541                 :            :     /* now steal and assign the string */
     542                 :         84 :     talloc_steal(el->values, str);
     543                 :            : 
     544                 :         84 :     el->values[el->num_values].data = (uint8_t *)str;
     545                 :         84 :     el->values[el->num_values].length = strlen(str);
     546                 :         84 :     el->num_values++;
     547                 :            : 
     548                 :            :     return EOK;
     549                 :            : }
     550                 :            : 
     551                 :          1 : int sysdb_attrs_add_long(struct sysdb_attrs *attrs,
     552                 :            :                          const char *name, long value)
     553                 :            : {
     554                 :            :     struct ldb_val v;
     555                 :            :     char *str;
     556                 :            :     int ret;
     557                 :            : 
     558                 :          1 :     str = talloc_asprintf(attrs, "%ld", value);
     559         [ +  - ]:          1 :     if (!str) return ENOMEM;
     560                 :            : 
     561                 :          1 :     v.data = (uint8_t *)str;
     562                 :          1 :     v.length = strlen(str);
     563                 :            : 
     564                 :          1 :     ret = sysdb_attrs_add_val(attrs, name, &v);
     565                 :          1 :     talloc_free(str);
     566                 :            : 
     567                 :            :     return ret;
     568                 :            : }
     569                 :            : 
     570                 :         46 : int sysdb_attrs_add_uint32(struct sysdb_attrs *attrs,
     571                 :            :                            const char *name, uint32_t value)
     572                 :            : {
     573                 :         46 :     unsigned long val = value;
     574                 :            :     struct ldb_val v;
     575                 :            :     char *str;
     576                 :            :     int ret;
     577                 :            : 
     578                 :         46 :     str = talloc_asprintf(attrs, "%lu", val);
     579         [ +  - ]:         46 :     if (!str) return ENOMEM;
     580                 :            : 
     581                 :         46 :     v.data = (uint8_t *)str;
     582                 :         46 :     v.length = strlen(str);
     583                 :            : 
     584                 :         46 :     ret = sysdb_attrs_add_val(attrs, name, &v);
     585                 :         46 :     talloc_free(str);
     586                 :            : 
     587                 :            :     return ret;
     588                 :            : }
     589                 :            : 
     590                 :        311 : int sysdb_attrs_add_time_t(struct sysdb_attrs *attrs,
     591                 :            :                            const char *name, time_t value)
     592                 :            : {
     593                 :        311 :     long long val = value;
     594                 :            :     struct ldb_val v;
     595                 :            :     char *str;
     596                 :            :     int ret;
     597                 :            : 
     598                 :        311 :     str = talloc_asprintf(attrs, "%lld", val);
     599         [ +  - ]:        311 :     if (!str) return ENOMEM;
     600                 :            : 
     601                 :        311 :     v.data = (uint8_t *)str;
     602                 :        311 :     v.length = strlen(str);
     603                 :            : 
     604                 :        311 :     ret = sysdb_attrs_add_val(attrs, name, &v);
     605                 :        311 :     talloc_free(str);
     606                 :            : 
     607                 :            :     return ret;
     608                 :            : }
     609                 :            : 
     610                 :          0 : int sysdb_attrs_copy_values(struct sysdb_attrs *src,
     611                 :            :                             struct sysdb_attrs *dst,
     612                 :            :                             const char *name)
     613                 :            : {
     614                 :          0 :     int ret = EOK;
     615                 :            :     int i;
     616                 :            :     struct ldb_message_element *src_el;
     617                 :            : 
     618                 :          0 :     ret = sysdb_attrs_get_el(src, name, &src_el);
     619         [ #  # ]:          0 :     if (ret != EOK) {
     620                 :            :         goto done;
     621                 :            :     }
     622                 :            : 
     623         [ #  # ]:          0 :     for (i = 0; i < src_el->num_values; i++) {
     624                 :          0 :         ret = sysdb_attrs_add_val(dst, name, &src_el->values[i]);
     625         [ #  # ]:          0 :         if (ret != EOK) {
     626                 :            :             goto done;
     627                 :            :         }
     628                 :            :     }
     629                 :            : 
     630                 :            : done:
     631                 :          0 :     return ret;
     632                 :            : }
     633                 :            : 
     634                 :          0 : int sysdb_attrs_users_from_str_list(struct sysdb_attrs *attrs,
     635                 :            :                                     const char *attr_name,
     636                 :            :                                     const char *domain,
     637                 :            :                                     const char *const *list)
     638                 :            : {
     639                 :          0 :     struct ldb_message_element *el = NULL;
     640                 :            :     struct ldb_val *vals;
     641                 :            :     int i, j, num;
     642                 :            :     char *member;
     643                 :            :     int ret;
     644                 :            : 
     645                 :          0 :     ret = sysdb_attrs_get_el(attrs, attr_name, &el);
     646         [ #  # ]:          0 :     if (ret) {
     647                 :            :         return ret;
     648                 :            :     }
     649                 :            : 
     650         [ #  # ]:          0 :     for (num = 0; list[num]; num++) /* count */ ;
     651                 :            : 
     652                 :          0 :     vals = talloc_realloc(attrs->a, el->values,
     653                 :            :                           struct ldb_val, el->num_values + num);
     654         [ #  # ]:          0 :     if (!vals) {
     655                 :            :         return ENOMEM;
     656                 :            :     }
     657                 :          0 :     el->values = vals;
     658                 :            : 
     659 [ #  # ][ #  # ]:          0 :     DEBUG(9, ("Adding %d members to existing %d ones\n",
         [ #  # ][ #  # ]
                 [ #  # ]
     660                 :            :               num, el->num_values));
     661                 :            : 
     662         [ #  # ]:          0 :     for (i = 0, j = el->num_values; i < num; i++) {
     663                 :            : 
     664                 :          0 :         member = sysdb_user_strdn(el->values, domain, list[i]);
     665         [ #  # ]:          0 :         if (!member) {
     666 [ #  # ][ #  # ]:          0 :             DEBUG(4, ("Failed to get user dn for [%s]\n", list[i]));
         [ #  # ][ #  # ]
                 [ #  # ]
     667                 :          0 :             continue;
     668                 :            :         }
     669                 :          0 :         el->values[j].data = (uint8_t *)member;
     670                 :          0 :         el->values[j].length = strlen(member);
     671                 :          0 :         j++;
     672                 :            : 
     673 [ #  # ][ #  # ]:          0 :         DEBUG(7, ("    member #%d: [%s]\n", i, member));
         [ #  # ][ #  # ]
                 [ #  # ]
     674                 :            :     }
     675                 :          0 :     el->num_values = j;
     676                 :            : 
     677                 :            :     return EOK;
     678                 :            : }
     679                 :            : 
     680                 :         29 : static char *build_dom_dn_str_escape(TALLOC_CTX *mem_ctx, const char *template,
     681                 :            :                                      const char *domain, const char *name)
     682                 :            : {
     683                 :            :     char *ret;
     684                 :            :     int l;
     685                 :            : 
     686                 :         29 :     l = strcspn(name, ",=\n+<>#;\\\"");
     687         [ -  + ]:         29 :     if (name[l] != '\0') {
     688                 :            :         struct ldb_val v;
     689                 :            :         char *tmp;
     690                 :            : 
     691                 :          0 :         v.data = discard_const_p(uint8_t, name);
     692                 :          0 :         v.length = strlen(name);
     693                 :            : 
     694                 :          0 :         tmp = ldb_dn_escape_value(mem_ctx, v);
     695         [ #  # ]:          0 :         if (!tmp) {
     696                 :            :             return NULL;
     697                 :            :         }
     698                 :            : 
     699                 :          0 :         ret = talloc_asprintf(mem_ctx, template, tmp, domain);
     700                 :          0 :         talloc_zfree(tmp);
     701         [ #  # ]:          0 :         if (!ret) {
     702                 :            :             return NULL;
     703                 :            :         }
     704                 :            : 
     705                 :            :         return ret;
     706                 :            :     }
     707                 :            : 
     708                 :         29 :     ret = talloc_asprintf(mem_ctx, template, name, domain);
     709         [ +  - ]:         29 :     if (!ret) {
     710                 :            :         return NULL;
     711                 :            :     }
     712                 :            : 
     713                 :         29 :     return ret;
     714                 :            : }
     715                 :            : 
     716                 :          0 : char *sysdb_user_strdn(TALLOC_CTX *mem_ctx,
     717                 :            :                        const char *domain, const char *name)
     718                 :            : {
     719                 :          0 :     return build_dom_dn_str_escape(mem_ctx, SYSDB_TMPL_USER, domain, name);
     720                 :            : }
     721                 :            : 
     722                 :         29 : char *sysdb_group_strdn(TALLOC_CTX *mem_ctx,
     723                 :            :                         const char *domain, const char *name)
     724                 :            : {
     725                 :         29 :     return build_dom_dn_str_escape(mem_ctx, SYSDB_TMPL_GROUP, domain, name);
     726                 :            : }
     727                 :            : 
     728                 :            : /* TODO: make a more complete and precise mapping */
     729                 :        855 : int sysdb_error_to_errno(int ldberr)
     730                 :            : {
     731   [ -  -  -  -  :        855 :     switch (ldberr) {
                -  -  + ]
     732                 :            :     case LDB_SUCCESS:
     733                 :            :         return EOK;
     734                 :            :     case LDB_ERR_OPERATIONS_ERROR:
     735                 :          0 :         return EIO;
     736                 :            :     case LDB_ERR_NO_SUCH_OBJECT:
     737                 :          0 :         return ENOENT;
     738                 :            :     case LDB_ERR_BUSY:
     739                 :          0 :         return EBUSY;
     740                 :            :     case LDB_ERR_ENTRY_ALREADY_EXISTS:
     741                 :          0 :         return EEXIST;
     742                 :            :     case LDB_ERR_INVALID_ATTRIBUTE_SYNTAX:
     743                 :          0 :         return EINVAL;
     744                 :            :     default:
     745 [ #  # ][ #  # ]:        855 :         DEBUG(SSSDBG_CRIT_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     746                 :            :               ("LDB returned unexpected error: [%s]\n",
     747                 :            :                ldb_strerror(ldberr)));
     748                 :            :         return EFAULT;
     749                 :            :     }
     750                 :            : }
     751                 :            : 
     752                 :            : /* =Transactions========================================================== */
     753                 :            : 
     754                 :         70 : int sysdb_transaction_start(struct sysdb_ctx *sysdb)
     755                 :            : {
     756                 :            :     int ret;
     757                 :            : 
     758                 :         70 :     ret = ldb_transaction_start(sysdb->ldb);
     759         [ -  + ]:         70 :     if (ret != LDB_SUCCESS) {
     760 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Failed to start ldb transaction! (%d)\n", ret));
         [ #  # ][ #  # ]
                 [ #  # ]
     761                 :            :     }
     762                 :         70 :     return sysdb_error_to_errno(ret);
     763                 :            : }
     764                 :            : 
     765                 :         70 : int sysdb_transaction_commit(struct sysdb_ctx *sysdb)
     766                 :            : {
     767                 :            :     int ret;
     768                 :            : 
     769                 :         70 :     ret = ldb_transaction_commit(sysdb->ldb);
     770         [ -  + ]:         70 :     if (ret != LDB_SUCCESS) {
     771 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Failed to commit ldb transaction! (%d)\n", ret));
         [ #  # ][ #  # ]
                 [ #  # ]
     772                 :            :     }
     773                 :         70 :     return sysdb_error_to_errno(ret);
     774                 :            : }
     775                 :            : 
     776                 :          0 : int sysdb_transaction_cancel(struct sysdb_ctx *sysdb)
     777                 :            : {
     778                 :            :     int ret;
     779                 :            : 
     780                 :          0 :     ret = ldb_transaction_cancel(sysdb->ldb);
     781         [ #  # ]:          0 :     if (ret != LDB_SUCCESS) {
     782 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Failed to cancel ldb transaction! (%d)\n", ret));
         [ #  # ][ #  # ]
                 [ #  # ]
     783                 :            :     }
     784                 :          0 :     return sysdb_error_to_errno(ret);
     785                 :            : }
     786                 :            : 
     787                 :            : /* =Initialization======================================================== */
     788                 :            : 
     789                 :        643 : int sysdb_get_db_file(TALLOC_CTX *mem_ctx,
     790                 :            :                       const char *provider, const char *name,
     791                 :            :                       const char *base_path, char **_ldb_file)
     792                 :            : {
     793                 :            :     char *ldb_file;
     794                 :            : 
     795                 :            :     /* special case for the local domain */
     796         [ +  - ]:        643 :     if (strcasecmp(provider, "local") == 0) {
     797                 :        643 :         ldb_file = talloc_asprintf(mem_ctx, "%s/"LOCAL_SYSDB_FILE,
     798                 :            :                                    base_path);
     799                 :            :     } else {
     800                 :          0 :         ldb_file = talloc_asprintf(mem_ctx, "%s/"CACHE_SYSDB_FILE,
     801                 :            :                                    base_path, name);
     802                 :            :     }
     803         [ +  - ]:        643 :     if (!ldb_file) {
     804                 :            :         return ENOMEM;
     805                 :            :     }
     806                 :            : 
     807                 :        643 :     *_ldb_file = ldb_file;
     808                 :        643 :     return EOK;
     809                 :            : }
     810                 :            : 
     811                 :          6 : errno_t sysdb_domain_create(struct sysdb_ctx *sysdb, const char *domain_name)
     812                 :            : {
     813                 :            :     struct ldb_message *msg;
     814                 :            :     TALLOC_CTX *tmp_ctx;
     815                 :            :     int ret;
     816                 :            : 
     817                 :          6 :     tmp_ctx = talloc_new(NULL);
     818         [ +  - ]:          6 :     if (tmp_ctx == NULL) {
     819                 :            :         ret = ENOMEM;
     820                 :            :         goto done;
     821                 :            :     }
     822                 :            : 
     823                 :            :     /* == create base domain object == */
     824                 :            : 
     825                 :          6 :     msg = ldb_msg_new(tmp_ctx);
     826         [ +  - ]:          6 :     if (!msg) {
     827                 :            :         ret = ENOMEM;
     828                 :            :         goto done;
     829                 :            :     }
     830                 :          6 :     msg->dn = ldb_dn_new_fmt(msg, sysdb->ldb, SYSDB_DOM_BASE, domain_name);
     831         [ +  - ]:          6 :     if (!msg->dn) {
     832                 :            :         ret = ENOMEM;
     833                 :            :         goto done;
     834                 :            :     }
     835                 :          6 :     ret = ldb_msg_add_string(msg, "cn", domain_name);
     836         [ +  - ]:          6 :     if (ret != LDB_SUCCESS) {
     837                 :            :         ret = EIO;
     838                 :            :         goto done;
     839                 :            :     }
     840                 :            :     /* do a synchronous add */
     841                 :          6 :     ret = ldb_add(sysdb->ldb, msg);
     842         [ -  + ]:          6 :     if (ret != LDB_SUCCESS) {
     843 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to initialize DB (%d, [%s]) "
         [ #  # ][ #  # ]
                 [ #  # ]
     844                 :            :                                      "for domain %s!\n",
     845                 :            :                                      ret, ldb_errstring(sysdb->ldb),
     846                 :            :                                      domain_name));
     847                 :            :         ret = EIO;
     848                 :            :         goto done;
     849                 :            :     }
     850                 :          6 :     talloc_zfree(msg);
     851                 :            : 
     852                 :            :     /* == create Users tree == */
     853                 :            : 
     854                 :          6 :     msg = ldb_msg_new(tmp_ctx);
     855         [ +  - ]:          6 :     if (!msg) {
     856                 :            :         ret = ENOMEM;
     857                 :            :         goto done;
     858                 :            :     }
     859                 :          6 :     msg->dn = ldb_dn_new_fmt(msg, sysdb->ldb,
     860                 :            :                              SYSDB_TMPL_USER_BASE, domain_name);
     861         [ +  - ]:          6 :     if (!msg->dn) {
     862                 :            :         ret = ENOMEM;
     863                 :            :         goto done;
     864                 :            :     }
     865                 :          6 :     ret = ldb_msg_add_string(msg, "cn", "Users");
     866         [ +  - ]:          6 :     if (ret != LDB_SUCCESS) {
     867                 :            :         ret = EIO;
     868                 :            :         goto done;
     869                 :            :     }
     870                 :            :     /* do a synchronous add */
     871                 :          6 :     ret = ldb_add(sysdb->ldb, msg);
     872         [ -  + ]:          6 :     if (ret != LDB_SUCCESS) {
     873 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to initialize DB (%d, [%s]) "
         [ #  # ][ #  # ]
                 [ #  # ]
     874                 :            :                                      "for domain %s!\n",
     875                 :            :                                      ret, ldb_errstring(sysdb->ldb),
     876                 :            :                                      domain_name));
     877                 :            :         ret = EIO;
     878                 :            :         goto done;
     879                 :            :     }
     880                 :          6 :     talloc_zfree(msg);
     881                 :            : 
     882                 :            :     /* == create Groups tree == */
     883                 :            : 
     884                 :          6 :     msg = ldb_msg_new(tmp_ctx);
     885         [ +  - ]:          6 :     if (!msg) {
     886                 :            :         ret = ENOMEM;
     887                 :            :         goto done;
     888                 :            :     }
     889                 :          6 :     msg->dn = ldb_dn_new_fmt(msg, sysdb->ldb,
     890                 :            :                              SYSDB_TMPL_GROUP_BASE, domain_name);
     891         [ +  - ]:          6 :     if (!msg->dn) {
     892                 :            :         ret = ENOMEM;
     893                 :            :         goto done;
     894                 :            :     }
     895                 :          6 :     ret = ldb_msg_add_string(msg, "cn", "Groups");
     896         [ +  - ]:          6 :     if (ret != LDB_SUCCESS) {
     897                 :            :         ret = EIO;
     898                 :            :         goto done;
     899                 :            :     }
     900                 :            :     /* do a synchronous add */
     901                 :          6 :     ret = ldb_add(sysdb->ldb, msg);
     902         [ -  + ]:          6 :     if (ret != LDB_SUCCESS) {
     903 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to initialize DB (%d, [%s]) for "
         [ #  # ][ #  # ]
                 [ #  # ]
     904                 :            :                                      "domain %s!\n",
     905                 :            :                                      ret, ldb_errstring(sysdb->ldb),
     906                 :            :                                      domain_name));
     907                 :            :         ret = EIO;
     908                 :            :         goto done;
     909                 :            :     }
     910                 :          6 :     talloc_zfree(msg);
     911                 :            : 
     912                 :          6 :     ret = EOK;
     913                 :            : 
     914                 :            : done:
     915                 :          6 :     talloc_zfree(tmp_ctx);
     916                 :          6 :     return ret;
     917                 :            : }
     918                 :            : 
     919                 :        633 : static int remove_sysdb_from_domain(void *mem)
     920                 :            : {
     921                 :        633 :     struct sysdb_ctx *ctx = talloc_get_type(mem, struct sysdb_ctx);
     922                 :            : 
     923 [ +  - ][ +  - ]:        633 :     if (ctx->domain != NULL && ctx->domain->sysdb == ctx) {
     924                 :        633 :         ctx->domain->sysdb = NULL;
     925                 :            :     }
     926                 :            : 
     927                 :        633 :     return 0;
     928                 :            : }
     929                 :            : 
     930                 :        643 : errno_t sysdb_add_to_domain(struct sss_domain_info *domain,
     931                 :            :                             struct sysdb_ctx *ctx)
     932                 :            : {
     933         [ -  + ]:        643 :     if (domain == NULL || ctx == NULL) {
     934 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_OP_FAILURE, ("Missing domain or sysdb context.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     935                 :            :         return EINVAL;
     936                 :            :     }
     937                 :            : 
     938         [ -  + ]:        643 :     if (domain->sysdb != NULL) {
     939 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_OP_FAILURE, ("Sysdb context already set.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     940                 :            :         return EINVAL;
     941                 :            :     }
     942                 :            : 
     943                 :        643 :     domain->sysdb = ctx;
     944                 :            : 
     945                 :        643 :     talloc_set_destructor((TALLOC_CTX *) ctx, remove_sysdb_from_domain);
     946                 :            : 
     947                 :        643 :     return EOK;
     948                 :            : }
     949                 :            : 
     950                 :            : /* Compare versions of sysdb, returns ERRNO accordingly */
     951                 :            : static errno_t
     952                 :          0 : sysdb_version_check(const char *expected,
     953                 :            :                     const char *received)
     954                 :            : {
     955                 :            :     int ret;
     956                 :            :     unsigned int exp_major, exp_minor, recv_major, recv_minor;
     957                 :            : 
     958                 :          0 :     ret = sscanf(expected, "%u.%u", &exp_major, &exp_minor);
     959         [ #  # ]:          0 :     if (ret != 2) {
     960                 :            :         return EINVAL;
     961                 :            :     }
     962                 :          0 :     ret = sscanf(received, "%u.%u", &recv_major, &recv_minor);
     963         [ #  # ]:          0 :     if (ret != 2) {
     964                 :            :         return EINVAL;
     965                 :            :     }
     966                 :            : 
     967         [ #  # ]:          0 :     if (recv_major > exp_major) {
     968                 :            :         return EUCLEAN;
     969         [ #  # ]:          0 :     } else if (recv_major < exp_major) {
     970                 :            :         return EMEDIUMTYPE;
     971                 :            :     }
     972                 :            : 
     973         [ #  # ]:          0 :     if (recv_minor > exp_minor) {
     974                 :            :         return EUCLEAN;
     975         [ #  # ]:          0 :     } else if (recv_minor < exp_minor) {
     976                 :            :         return EMEDIUMTYPE;
     977                 :            :     }
     978                 :            : 
     979                 :            :     return EOK;
     980                 :            : }
     981                 :            : 
     982                 :        643 : int sysdb_domain_init_internal(TALLOC_CTX *mem_ctx,
     983                 :            :                                struct sss_domain_info *domain,
     984                 :            :                                const char *db_path,
     985                 :            :                                bool allow_upgrade,
     986                 :            :                                struct sysdb_ctx **_ctx)
     987                 :            : {
     988                 :        643 :     TALLOC_CTX *tmp_ctx = NULL;
     989                 :            :     struct sysdb_ctx *sysdb;
     990                 :            :     const char *base_ldif;
     991                 :            :     struct ldb_ldif *ldif;
     992                 :            :     struct ldb_message_element *el;
     993                 :            :     struct ldb_result *res;
     994                 :            :     struct ldb_dn *verdn;
     995                 :        643 :     const char *version = NULL;
     996                 :            :     int ret;
     997                 :            : 
     998                 :        643 :     sysdb = talloc_zero(mem_ctx, struct sysdb_ctx);
     999         [ +  - ]:        643 :     if (!sysdb) {
    1000                 :            :         return ENOMEM;
    1001                 :            :     }
    1002                 :        643 :     sysdb->domain = domain;
    1003                 :            : 
    1004                 :            :     /* The local provider s the only true MPG,
    1005                 :            :      * for the other domains, the provider actually unrolls MPGs */
    1006         [ +  - ]:        643 :     if (strcasecmp(domain->provider, "local") == 0) {
    1007                 :        643 :         sysdb->mpg = true;
    1008                 :            :     }
    1009                 :            : 
    1010                 :        643 :     ret = sysdb_get_db_file(sysdb, domain->provider,
    1011                 :        643 :                             domain->name, db_path,
    1012                 :            :                             &sysdb->ldb_file);
    1013         [ +  - ]:        643 :     if (ret != EOK) {
    1014                 :            :         goto done;
    1015                 :            :     }
    1016 [ +  - ][ +  - ]:        643 :     DEBUG(5, ("DB File for %s: %s\n", domain->name, sysdb->ldb_file));
         [ -  + ][ #  # ]
                 [ #  # ]
    1017                 :            : 
    1018                 :        643 :     ret = sysdb_ldb_connect(sysdb, sysdb->ldb_file, &sysdb->ldb);
    1019         [ -  + ]:        643 :     if (ret != EOK) {
    1020 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("sysdb_ldb_connect failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1021                 :            :         goto done;
    1022                 :            :     }
    1023                 :            : 
    1024                 :        643 :     tmp_ctx = talloc_new(NULL);
    1025         [ +  - ]:        643 :     if (!tmp_ctx) {
    1026                 :            :         ret = ENOMEM;
    1027                 :            :         goto done;
    1028                 :            :     }
    1029                 :            : 
    1030                 :        643 :     verdn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE);
    1031         [ +  - ]:        643 :     if (!verdn) {
    1032                 :            :         ret = EIO;
    1033                 :            :         goto done;
    1034                 :            :     }
    1035                 :            : 
    1036                 :        643 :     ret = ldb_search(sysdb->ldb, tmp_ctx, &res,
    1037                 :            :                      verdn, LDB_SCOPE_BASE,
    1038                 :            :                      NULL, NULL);
    1039         [ +  - ]:        643 :     if (ret != LDB_SUCCESS) {
    1040                 :            :         ret = EIO;
    1041                 :            :         goto done;
    1042                 :            :     }
    1043         [ +  - ]:        643 :     if (res->count > 1) {
    1044                 :            :         ret = EIO;
    1045                 :            :         goto done;
    1046                 :            :     }
    1047                 :            : 
    1048         [ +  + ]:        643 :     if (res->count == 1) {
    1049                 :        640 :         el = ldb_msg_find_element(res->msgs[0], "version");
    1050         [ +  - ]:        640 :         if (!el) {
    1051                 :            :             ret = EIO;
    1052                 :            :             goto done;
    1053                 :            :         }
    1054                 :            : 
    1055         [ +  - ]:        640 :         if (el->num_values != 1) {
    1056                 :            :             ret = EINVAL;
    1057                 :            :             goto done;
    1058                 :            :         }
    1059                 :        640 :         version = talloc_strndup(tmp_ctx,
    1060                 :        640 :                                  (char *)(el->values[0].data),
    1061                 :        640 :                                  el->values[0].length);
    1062         [ +  - ]:        640 :         if (!version) {
    1063                 :            :             ret = ENOMEM;
    1064                 :            :             goto done;
    1065                 :            :         }
    1066                 :            : 
    1067         [ -  + ]:        640 :         if (strcmp(version, SYSDB_VERSION) == 0) {
    1068                 :            :             /* all fine, return */
    1069                 :            :             ret = EOK;
    1070                 :            :             goto done;
    1071                 :            :         }
    1072                 :            : 
    1073         [ #  # ]:          0 :         if (!allow_upgrade) {
    1074 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_FATAL_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
    1075                 :            :                   ("Wrong DB version (got %s expected %s)\n",
    1076                 :            :                    version, SYSDB_VERSION));
    1077                 :          0 :             ret = sysdb_version_check(SYSDB_VERSION, version);
    1078                 :          0 :             goto done;
    1079                 :            :         }
    1080                 :            : 
    1081 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CONF_SETTINGS, ("Upgrading DB [%s] from version: %s\n",
         [ #  # ][ #  # ]
                 [ #  # ]
    1082                 :            :                   domain->name, version));
    1083                 :            : 
    1084 [ #  # ][ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_3) == 0) {
         [ #  # ][ #  # ]
    1085                 :          0 :             ret = sysdb_upgrade_03(sysdb, &version);
    1086         [ #  # ]:          0 :             if (ret != EOK) {
    1087                 :            :                 goto done;
    1088                 :            :             }
    1089                 :            :         }
    1090                 :            : 
    1091 [ #  # ][ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_4) == 0) {
         [ #  # ][ #  # ]
    1092                 :          0 :             ret = sysdb_upgrade_04(sysdb, &version);
    1093         [ #  # ]:          0 :             if (ret != EOK) {
    1094                 :            :                 goto done;
    1095                 :            :             }
    1096                 :            :         }
    1097                 :            : 
    1098 [ #  # ][ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_5) == 0) {
         [ #  # ][ #  # ]
    1099                 :          0 :             ret = sysdb_upgrade_05(sysdb, &version);
    1100         [ #  # ]:          0 :             if (ret != EOK) {
    1101                 :            :                 goto done;
    1102                 :            :             }
    1103                 :            :         }
    1104                 :            : 
    1105 [ #  # ][ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_6) == 0) {
         [ #  # ][ #  # ]
    1106                 :          0 :             ret = sysdb_upgrade_06(sysdb, &version);
    1107         [ #  # ]:          0 :             if (ret != EOK) {
    1108                 :            :                 goto done;
    1109                 :            :             }
    1110                 :            :         }
    1111                 :            : 
    1112 [ #  # ][ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_7) == 0) {
         [ #  # ][ #  # ]
    1113                 :          0 :             ret = sysdb_upgrade_07(sysdb, &version);
    1114         [ #  # ]:          0 :             if (ret != EOK) {
    1115                 :            :                 goto done;
    1116                 :            :             }
    1117                 :            :         }
    1118                 :            : 
    1119 [ #  # ][ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_8) == 0) {
         [ #  # ][ #  # ]
    1120                 :          0 :             ret = sysdb_upgrade_08(sysdb, &version);
    1121         [ #  # ]:          0 :             if (ret != EOK) {
    1122                 :            :                 goto done;
    1123                 :            :             }
    1124                 :            :         }
    1125                 :            : 
    1126 [ #  # ][ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_9) == 0) {
         [ #  # ][ #  # ]
    1127                 :          0 :             ret = sysdb_upgrade_09(sysdb, &version);
    1128         [ #  # ]:          0 :             if (ret != EOK) {
    1129                 :            :                 goto done;
    1130                 :            :             }
    1131                 :            :         }
    1132                 :            : 
    1133         [ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_10) == 0) {
    1134                 :          0 :             ret = sysdb_upgrade_10(sysdb, &version);
    1135         [ #  # ]:          0 :             if (ret != EOK) {
    1136                 :            :                 goto done;
    1137                 :            :             }
    1138                 :            :         }
    1139                 :            : 
    1140         [ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_11) == 0) {
    1141                 :          0 :             ret = sysdb_upgrade_11(sysdb, &version);
    1142         [ #  # ]:          0 :             if (ret != EOK) {
    1143                 :            :                 goto done;
    1144                 :            :             }
    1145                 :            :         }
    1146                 :            : 
    1147         [ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_12) == 0) {
    1148                 :          0 :             ret = sysdb_upgrade_12(sysdb, &version);
    1149         [ #  # ]:          0 :             if (ret != EOK) {
    1150                 :            :                 goto done;
    1151                 :            :             }
    1152                 :            :         }
    1153                 :            : 
    1154         [ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION_0_13) == 0) {
    1155                 :          0 :             ret = sysdb_upgrade_13(sysdb, &version);
    1156         [ #  # ]:          0 :             if (ret != EOK) {
    1157                 :            :                 goto done;
    1158                 :            :             }
    1159                 :            :         }
    1160                 :            : 
    1161                 :            :         /* The version should now match SYSDB_VERSION.
    1162                 :            :          * If not, it means we didn't match any of the
    1163                 :            :          * known older versions. The DB might be
    1164                 :            :          * corrupt or generated by a newer version of
    1165                 :            :          * SSSD.
    1166                 :            :          */
    1167         [ #  # ]:          0 :         if (strcmp(version, SYSDB_VERSION) == 0) {
    1168                 :            :             /* The cache has been upgraded.
    1169                 :            :              * We need to reopen the LDB to ensure that
    1170                 :            :              * any changes made above take effect.
    1171                 :            :              */
    1172                 :          0 :             talloc_zfree(sysdb->ldb);
    1173                 :          0 :             ret = sysdb_ldb_connect(sysdb, sysdb->ldb_file, &sysdb->ldb);
    1174         [ #  # ]:          0 :             if (ret != EOK) {
    1175 [ #  # ][ #  # ]:          0 :                 DEBUG(SSSDBG_CRIT_FAILURE, ("sysdb_ldb_connect failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1176                 :            :             }
    1177                 :            :             goto done;
    1178                 :            :         }
    1179                 :            : 
    1180 [ #  # ][ #  # ]:          0 :         DEBUG(0,("Unknown DB version [%s], expected [%s] for domain %s!\n",
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1181                 :            :                  version?version:"not found", SYSDB_VERSION, domain->name));
    1182                 :          0 :         ret = sysdb_version_check(SYSDB_VERSION, version);
    1183                 :          0 :         goto done;
    1184                 :            :     }
    1185                 :            : 
    1186                 :            :     /* SYSDB_BASE does not exists, means db is empty, populate */
    1187                 :            : 
    1188                 :          3 :     base_ldif = SYSDB_BASE_LDIF;
    1189         [ +  + ]:         15 :     while ((ldif = ldb_ldif_read_string(sysdb->ldb, &base_ldif))) {
    1190                 :         12 :         ret = ldb_add(sysdb->ldb, ldif->msg);
    1191         [ -  + ]:         12 :         if (ret != LDB_SUCCESS) {
    1192 [ #  # ][ #  # ]:          0 :             DEBUG(0, ("Failed to initialize DB (%d, [%s]) for domain %s!\n",
         [ #  # ][ #  # ]
                 [ #  # ]
    1193                 :            :                       ret, ldb_errstring(sysdb->ldb), domain->name));
    1194                 :            :             ret = EIO;
    1195                 :            :             goto done;
    1196                 :            :         }
    1197                 :         12 :         ldb_ldif_read_free(sysdb->ldb, ldif);
    1198                 :            :     }
    1199                 :            : 
    1200                 :          3 :     ret = sysdb_domain_create(sysdb, domain->name);
    1201         [ +  - ]:          3 :     if (ret != EOK) {
    1202                 :            :         goto done;
    1203                 :            :     }
    1204                 :            : 
    1205                 :            :     /* The cache has been newly created.
    1206                 :            :      * We need to reopen the LDB to ensure that
    1207                 :            :      * all of the special values take effect
    1208                 :            :      * (such as enabling the memberOf plugin and
    1209                 :            :      * the various indexes).
    1210                 :            :      */
    1211                 :          3 :     talloc_zfree(sysdb->ldb);
    1212                 :          3 :     ret = sysdb_ldb_connect(sysdb, sysdb->ldb_file, &sysdb->ldb);
    1213         [ -  + ]:          3 :     if (ret != EOK) {
    1214 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("sysdb_ldb_connect failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1215                 :            :     }
    1216                 :            : 
    1217                 :            : done:
    1218                 :        643 :     talloc_free(tmp_ctx);
    1219         [ +  - ]:        643 :     if (ret == EOK) {
    1220                 :        643 :         *_ctx = sysdb;
    1221                 :            :     } else {
    1222                 :        643 :         talloc_free(sysdb);
    1223                 :            :     }
    1224                 :            :     return ret;
    1225                 :            : }
    1226                 :            : 
    1227                 :          0 : int sysdb_init(TALLOC_CTX *mem_ctx,
    1228                 :            :                struct confdb_ctx *cdb,
    1229                 :            :                const char *alt_db_path,
    1230                 :            :                bool allow_upgrade,
    1231                 :            :                struct sysdb_ctx_list **_ctx_list)
    1232                 :            : {
    1233                 :            :     struct sysdb_ctx_list *ctx_list;
    1234                 :            :     struct sss_domain_info *domains, *dom;
    1235                 :            :     struct sysdb_ctx *sysdb;
    1236                 :            :     int ret;
    1237                 :            : 
    1238                 :          0 :     ctx_list = talloc_zero(mem_ctx, struct sysdb_ctx_list);
    1239         [ #  # ]:          0 :     if (!ctx_list) {
    1240                 :            :         return ENOMEM;
    1241                 :            :     }
    1242                 :            : 
    1243         [ #  # ]:          0 :     if (alt_db_path) {
    1244                 :          0 :         ctx_list->db_path = talloc_strdup(ctx_list, alt_db_path);
    1245                 :            :     } else {
    1246                 :          0 :         ctx_list->db_path = talloc_strdup(ctx_list, DB_PATH);
    1247                 :            :     }
    1248         [ #  # ]:          0 :     if (!ctx_list->db_path) {
    1249                 :          0 :         talloc_zfree(ctx_list);
    1250                 :            :         return ENOMEM;
    1251                 :            :     }
    1252                 :            : 
    1253                 :            :     /* open a db for each backend */
    1254                 :          0 :     ret = confdb_get_domains(cdb, &domains);
    1255         [ #  # ]:          0 :     if (ret != EOK) {
    1256                 :          0 :         talloc_zfree(ctx_list);
    1257                 :            :         return ret;
    1258                 :            :     }
    1259                 :            : 
    1260         [ #  # ]:          0 :     if (allow_upgrade) {
    1261                 :            :         /* check if we have an old sssd.ldb to upgrade */
    1262                 :          0 :         ret = sysdb_check_upgrade_02(domains, ctx_list->db_path);
    1263         [ #  # ]:          0 :         if (ret != EOK) {
    1264                 :          0 :             talloc_zfree(ctx_list);
    1265                 :            :             return ret;
    1266                 :            :         }
    1267                 :            :     }
    1268                 :            : 
    1269         [ #  # ]:          0 :     for (dom = domains; dom; dom = dom->next) {
    1270                 :            : 
    1271                 :          0 :         ctx_list->dbs = talloc_realloc(ctx_list, ctx_list->dbs,
    1272                 :            :                                        struct sysdb_ctx *,
    1273                 :            :                                        ctx_list->num_dbs + 1);
    1274         [ #  # ]:          0 :         if (!ctx_list->dbs) {
    1275                 :          0 :             talloc_zfree(ctx_list);
    1276                 :            :             return ENOMEM;
    1277                 :            :         }
    1278                 :            : 
    1279                 :          0 :         ret = sysdb_domain_init_internal(ctx_list, dom,
    1280                 :          0 :                                          ctx_list->db_path,
    1281                 :            :                                          allow_upgrade, &sysdb);
    1282         [ #  # ]:          0 :         if (ret != EOK) {
    1283                 :          0 :             talloc_zfree(ctx_list);
    1284                 :            :             return ret;
    1285                 :            :         }
    1286                 :            : 
    1287                 :          0 :         ret = sysdb_add_to_domain(dom, sysdb);
    1288         [ #  # ]:          0 :         if (ret != EOK) {
    1289                 :          0 :             talloc_zfree(ctx_list);
    1290                 :            :             return ret;
    1291                 :            :         }
    1292                 :            : 
    1293                 :          0 :         ctx_list->dbs[ctx_list->num_dbs] = sysdb;
    1294                 :          0 :         ctx_list->num_dbs++;
    1295                 :            :     }
    1296         [ #  # ]:          0 :     if (ctx_list->num_dbs == 0) {
    1297                 :            :         /* what? .. */
    1298                 :          0 :         talloc_zfree(ctx_list);
    1299                 :            :         return ENOENT;
    1300                 :            :     }
    1301                 :            : 
    1302                 :          0 :     *_ctx_list = ctx_list;
    1303                 :            : 
    1304                 :            :     return EOK;
    1305                 :            : }
    1306                 :            : 
    1307                 :        643 : int sysdb_domain_init(TALLOC_CTX *mem_ctx,
    1308                 :            :                       struct sss_domain_info *domain,
    1309                 :            :                       const char *db_path,
    1310                 :            :                       struct sysdb_ctx **_ctx)
    1311                 :            : {
    1312                 :        643 :     return sysdb_domain_init_internal(mem_ctx, domain,
    1313                 :            :                                       db_path, false, _ctx);
    1314                 :            : }
    1315                 :            : 
    1316                 :        643 : errno_t sysdb_init_domain_and_sysdb(TALLOC_CTX *mem_ctx,
    1317                 :            :                                     struct confdb_ctx *cdb,
    1318                 :            :                                     const char *domain_name,
    1319                 :            :                                     const char *db_path,
    1320                 :            :                                     struct sss_domain_info **_domain,
    1321                 :            :                                     struct sysdb_ctx **_ctx)
    1322                 :            : {
    1323                 :            :     int ret;
    1324                 :            :     struct sss_domain_info *dom;
    1325                 :            :     struct sysdb_ctx *ctx;
    1326                 :            : 
    1327                 :        643 :     ret = confdb_get_domain(cdb, domain_name, &dom);
    1328         [ -  + ]:        643 :     if (ret != EOK) {
    1329 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_OP_FAILURE, ("Error retrieving domain configuration.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1330                 :            :         return ret;
    1331                 :            :     }
    1332                 :            : 
    1333                 :        643 :     ret = sysdb_domain_init(mem_ctx, dom, db_path, &ctx);
    1334         [ -  + ]:        643 :     if (ret != EOK) {
    1335 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_OP_FAILURE, ("Error opening cache database.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1336                 :            :         return ret;
    1337                 :            :     }
    1338                 :            : 
    1339                 :        643 :     ret = sysdb_add_to_domain(dom, ctx);
    1340         [ -  + ]:        643 :     if (ret != EOK) {
    1341 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_OP_FAILURE, ("Error storing cache database context.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1342                 :            :         return ret;
    1343                 :            :     }
    1344                 :            : 
    1345                 :        643 :     *_domain = dom;
    1346                 :        643 :     *_ctx = ctx;
    1347                 :            : 
    1348                 :            :     return EOK;
    1349                 :            : }
    1350                 :            : 
    1351                 :          0 : int sysdb_list_init(TALLOC_CTX *mem_ctx,
    1352                 :            :                     const char *path,
    1353                 :            :                     struct sysdb_ctx *sysdb,
    1354                 :            :                     struct sysdb_ctx_list **_list)
    1355                 :            : {
    1356                 :            :     struct sysdb_ctx_list *list;
    1357                 :            :     int ret;
    1358                 :            : 
    1359                 :          0 :     list = talloc_zero(mem_ctx, struct sysdb_ctx_list);
    1360         [ #  # ]:          0 :     if (!list) {
    1361 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_zero failed\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1362                 :            :         return ENOMEM;
    1363                 :            :     }
    1364                 :            : 
    1365                 :          0 :     list->db_path = talloc_strdup(list, path);
    1366         [ #  # ]:          0 :     if (!list->db_path) {
    1367 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_strdup failed\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1368                 :            :         ret = ENOMEM;
    1369                 :            :         goto fail;
    1370                 :            :     }
    1371                 :            : 
    1372         [ #  # ]:          0 :     if (sysdb) {
    1373                 :          0 :         list->num_dbs = 1;
    1374                 :          0 :         list->dbs = talloc_array(list, struct sysdb_ctx *, list->num_dbs);
    1375         [ #  # ]:          0 :         if (!list->dbs) {
    1376 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("talloc_array failed\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1377                 :            :             ret = ENOMEM;
    1378                 :            :             goto fail;
    1379                 :            :         }
    1380                 :            : 
    1381                 :          0 :         list->dbs[0] = talloc_steal(list, sysdb);
    1382                 :            :     }
    1383                 :            : 
    1384                 :          0 :     *_list = list;
    1385                 :          0 :     return EOK;
    1386                 :            : 
    1387                 :            : fail:
    1388                 :          0 :     talloc_free(list);
    1389                 :          0 :     return ret;
    1390                 :            : }
    1391                 :            : 
    1392                 :         35 : int compare_ldb_dn_comp_num(const void *m1, const void *m2)
    1393                 :            : {
    1394                 :         35 :     struct ldb_message *msg1 = talloc_get_type(*(void **) discard_const(m1),
    1395                 :            :                                                struct ldb_message);
    1396                 :         35 :     struct ldb_message *msg2 = talloc_get_type(*(void **) discard_const(m2),
    1397                 :            :                                                struct ldb_message);
    1398                 :            : 
    1399                 :         35 :     return ldb_dn_get_comp_num(msg2->dn) - ldb_dn_get_comp_num(msg1->dn);
    1400                 :            : }
    1401                 :            : 
    1402                 :          2 : int sysdb_attrs_replace_name(struct sysdb_attrs *attrs, const char *oldname,
    1403                 :            :                              const char *newname)
    1404                 :            : {
    1405                 :          2 :     struct ldb_message_element *e = NULL;
    1406                 :            :     int i;
    1407                 :            :     const char *dummy;
    1408                 :            : 
    1409 [ +  - ][ +  - ]:          2 :     if (attrs == NULL || oldname == NULL || newname == NULL) return EINVAL;
    1410                 :            : 
    1411         [ +  + ]:          7 :     for (i = 0; i < attrs->num; i++) {
    1412         [ +  + ]:          6 :         if (strcasecmp(oldname, attrs->a[i].name) == 0) {
    1413                 :          2 :             e = &(attrs->a[i]);
    1414                 :            :         }
    1415         [ +  + ]:          6 :         if (strcasecmp(newname, attrs->a[i].name) == 0) {
    1416 [ +  - ][ +  - ]:          1 :             DEBUG(3, ("New attribute name [%s] already exists.\n", newname));
         [ -  + ][ #  # ]
                 [ #  # ]
    1417                 :            :             return EEXIST;
    1418                 :            :         }
    1419                 :            :     }
    1420                 :            : 
    1421         [ +  - ]:          1 :     if (e != NULL) {
    1422                 :          1 :         dummy = talloc_strdup(attrs, newname);
    1423         [ -  + ]:          1 :         if (dummy == NULL) {
    1424 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("talloc_strdup failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1425                 :            :             return ENOMEM;
    1426                 :            :         }
    1427                 :            : 
    1428                 :          1 :         talloc_free(discard_const(e->name));
    1429                 :          2 :         e->name = dummy;
    1430                 :            :     }
    1431                 :            : 
    1432                 :            :     return EOK;
    1433                 :            : }
    1434                 :            : 
    1435                 :            : /* Search for all incidences of attr_name in a list of
    1436                 :            :  * sysdb_attrs and add their value to a list
    1437                 :            :  *
    1438                 :            :  * TODO: Currently only works for single-valued
    1439                 :            :  * attributes. Multi-valued attributes will return
    1440                 :            :  * only the first entry
    1441                 :            :  */
    1442                 :          1 : errno_t sysdb_attrs_to_list(TALLOC_CTX *mem_ctx,
    1443                 :            :                             struct sysdb_attrs **attrs,
    1444                 :            :                             int attr_count,
    1445                 :            :                             const char *attr_name,
    1446                 :            :                             char ***_list)
    1447                 :            : {
    1448                 :            :     int attr_idx;
    1449                 :            :     int i;
    1450                 :            :     char **list;
    1451                 :            :     char **tmp_list;
    1452                 :            :     int list_idx;
    1453                 :            : 
    1454                 :          1 :     *_list = NULL;
    1455                 :            : 
    1456                 :            :     /* Assume that every attrs entry contains the attr_name
    1457                 :            :      * This may waste a little memory if some entries don't
    1458                 :            :      * have the attribute, but it will save us the trouble
    1459                 :            :      * of continuously resizing the array.
    1460                 :            :      */
    1461                 :          1 :     list = talloc_array(mem_ctx, char *, attr_count+1);
    1462         [ +  - ]:          1 :     if (!list) {
    1463                 :            :         return ENOMEM;
    1464                 :            :     }
    1465                 :            : 
    1466                 :            :     list_idx = 0;
    1467                 :            :     /* Loop through all entries in attrs */
    1468         [ +  + ]:          4 :     for (attr_idx = 0; attr_idx < attr_count; attr_idx++) {
    1469                 :            :         /* Examine each attribute within the entry */
    1470         [ +  + ]:          4 :         for (i = 0; i < attrs[attr_idx]->num; i++) {
    1471         [ +  + ]:          3 :             if (strcasecmp(attrs[attr_idx]->a[i].name, attr_name) == 0) {
    1472                 :            :                 /* Attribute name matches the requested name
    1473                 :            :                  * Copy it to the output list
    1474                 :            :                  */
    1475                 :          2 :                 list[list_idx] = talloc_strdup(
    1476                 :            :                         list,
    1477                 :          2 :                         (const char *)attrs[attr_idx]->a[i].values[0].data);
    1478         [ -  + ]:          2 :                 if (!list[list_idx]) {
    1479                 :          0 :                     talloc_free(list);
    1480                 :          0 :                     return ENOMEM;
    1481                 :            :                 }
    1482                 :          2 :                 list_idx++;
    1483                 :            : 
    1484                 :            :                 /* We only support single-valued attributes
    1485                 :            :                  * Break here and go on to the next entry
    1486                 :            :                  */
    1487                 :          2 :                 break;
    1488                 :            :             }
    1489                 :            :         }
    1490                 :            :     }
    1491                 :            : 
    1492                 :          1 :     list[list_idx] = NULL;
    1493                 :            : 
    1494                 :            :     /* if list_idx < attr_count, do a realloc to
    1495                 :            :      * reclaim unused memory
    1496                 :            :      */
    1497         [ +  - ]:          1 :     if (list_idx < attr_count) {
    1498                 :          1 :         tmp_list = talloc_realloc(mem_ctx, list, char *, list_idx+1);
    1499         [ -  + ]:          1 :         if (!tmp_list) {
    1500                 :          0 :             talloc_zfree(list);
    1501                 :          0 :             return ENOMEM;
    1502                 :            :         }
    1503                 :            :         list = tmp_list;
    1504                 :            :     }
    1505                 :            : 
    1506                 :          1 :     *_list = list;
    1507                 :          1 :     return EOK;
    1508                 :            : }
    1509                 :            : 
    1510                 :          2 : errno_t sysdb_get_bool(struct sysdb_ctx *sysdb,
    1511                 :            :                        struct ldb_dn *dn,
    1512                 :            :                        const char *attr_name,
    1513                 :            :                        bool *value)
    1514                 :            : {
    1515                 :            :     TALLOC_CTX *tmp_ctx;
    1516                 :            :     struct ldb_result *res;
    1517                 :            :     errno_t ret;
    1518                 :            :     int lret;
    1519                 :          2 :     const char *attrs[2] = {attr_name, NULL};
    1520                 :            : 
    1521                 :          2 :     tmp_ctx = talloc_new(NULL);
    1522         [ +  - ]:          2 :     if (tmp_ctx == NULL) {
    1523                 :            :         return ENOMEM;
    1524                 :            :     }
    1525                 :            : 
    1526                 :          2 :     lret = ldb_search(sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
    1527                 :            :                       attrs, NULL);
    1528         [ -  + ]:          2 :     if (lret != LDB_SUCCESS) {
    1529                 :          0 :         ret = sysdb_error_to_errno(lret);
    1530                 :            :         goto done;
    1531                 :            :     }
    1532                 :            : 
    1533         [ +  + ]:          2 :     if (res->count == 0) {
    1534                 :            :         /* This entry has not been populated in LDB
    1535                 :            :          * This is a common case, as unlike LDAP,
    1536                 :            :          * LDB does not need to have all of its parent
    1537                 :            :          * objects actually exist.
    1538                 :            :          * This object in the sysdb exists mostly just
    1539                 :            :          * to contain this attribute.
    1540                 :            :          */
    1541                 :          1 :         *value = false;
    1542                 :          1 :         ret = EOK;
    1543                 :          1 :         goto done;
    1544         [ -  + ]:          1 :     } else if (res->count != 1) {
    1545 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
    1546                 :            :               ("Got more than one reply for base search!\n"));
    1547                 :            :         ret = EIO;
    1548                 :            :         goto done;
    1549                 :            :     }
    1550                 :            : 
    1551                 :          1 :     *value = ldb_msg_find_attr_as_bool(res->msgs[0], attr_name, false);
    1552                 :            : 
    1553                 :          1 :     ret = EOK;
    1554                 :            : 
    1555                 :            : done:
    1556                 :          2 :     talloc_free(tmp_ctx);
    1557                 :            :     return ret;
    1558                 :            : }
    1559                 :            : 
    1560                 :          1 : errno_t sysdb_set_bool(struct sysdb_ctx *sysdb,
    1561                 :            :                        struct ldb_dn *dn,
    1562                 :            :                        const char *cn_value,
    1563                 :            :                        const char *attr_name,
    1564                 :            :                        bool value)
    1565                 :            : {
    1566                 :          1 :     TALLOC_CTX *tmp_ctx = NULL;
    1567                 :          1 :     struct ldb_message *msg = NULL;
    1568                 :          1 :     struct ldb_result *res = NULL;
    1569                 :            :     errno_t ret;
    1570                 :            :     int lret;
    1571                 :            : 
    1572 [ +  - ][ +  - ]:          1 :     if (dn == NULL || cn_value == NULL || attr_name == NULL) {
    1573                 :            :         return EINVAL;
    1574                 :            :     }
    1575                 :            : 
    1576                 :          1 :     tmp_ctx = talloc_new(NULL);
    1577         [ +  - ]:          1 :     if (tmp_ctx == NULL) {
    1578                 :            :         return ENOMEM;
    1579                 :            :     }
    1580                 :            : 
    1581                 :          1 :     lret = ldb_search(sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE,
    1582                 :            :                       NULL, NULL);
    1583         [ -  + ]:          1 :     if (lret != LDB_SUCCESS) {
    1584                 :          0 :         ret = sysdb_error_to_errno(lret);
    1585                 :            :         goto done;
    1586                 :            :     }
    1587                 :            : 
    1588                 :          1 :     msg = ldb_msg_new(tmp_ctx);
    1589         [ +  - ]:          1 :     if (msg == NULL) {
    1590                 :            :         ret = ENOMEM;
    1591                 :            :         goto done;
    1592                 :            :     }
    1593                 :          1 :     msg->dn = dn;
    1594                 :            : 
    1595         [ +  - ]:          1 :     if (res->count == 0) {
    1596                 :          1 :         lret = ldb_msg_add_string(msg, "cn", cn_value);
    1597         [ -  + ]:          1 :         if (lret != LDB_SUCCESS) {
    1598                 :          0 :             ret = sysdb_error_to_errno(lret);
    1599                 :            :             goto done;
    1600                 :            :         }
    1601         [ #  # ]:          0 :     } else if (res->count != 1) {
    1602 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
    1603                 :            :               ("Got more than one reply for base search!\n"));
    1604                 :            :         ret = EIO;
    1605                 :            :         goto done;
    1606                 :            :     } else {
    1607                 :          0 :         lret = ldb_msg_add_empty(msg, attr_name, LDB_FLAG_MOD_REPLACE, NULL);
    1608         [ #  # ]:          0 :         if (lret != LDB_SUCCESS) {
    1609                 :          0 :             ret = sysdb_error_to_errno(lret);
    1610                 :            :             goto done;
    1611                 :            :         }
    1612                 :            :     }
    1613                 :            : 
    1614         [ -  + ]:          1 :     lret = ldb_msg_add_string(msg, attr_name, value ? "TRUE" : "FALSE");
    1615         [ -  + ]:          1 :     if (lret != LDB_SUCCESS) {
    1616                 :          0 :         ret = sysdb_error_to_errno(lret);
    1617                 :            :         goto done;
    1618                 :            :     }
    1619                 :            : 
    1620         [ -  + ]:          1 :     if (res->count) {
    1621                 :          0 :         lret = ldb_modify(sysdb->ldb, msg);
    1622                 :            :     } else {
    1623                 :          1 :         lret = ldb_add(sysdb->ldb, msg);
    1624                 :            :     }
    1625                 :            : 
    1626                 :          1 :     ret = sysdb_error_to_errno(lret);
    1627                 :            : 
    1628                 :            : done:
    1629                 :          1 :     talloc_free(tmp_ctx);
    1630                 :            :     return ret;
    1631                 :            : }
    1632                 :            : 
    1633                 :          2 : errno_t sysdb_has_enumerated(struct sysdb_ctx *sysdb,
    1634                 :            :                              bool *has_enumerated)
    1635                 :            : {
    1636                 :            :     errno_t ret;
    1637                 :            :     struct ldb_dn *dn;
    1638                 :            :     TALLOC_CTX *tmp_ctx;
    1639                 :            : 
    1640                 :            : 
    1641                 :          2 :     tmp_ctx = talloc_new(NULL);
    1642         [ +  - ]:          2 :     if (!tmp_ctx) {
    1643                 :            :         ret = ENOMEM;
    1644                 :            :         goto done;
    1645                 :            :     }
    1646                 :            : 
    1647                 :          2 :     dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
    1648                 :            :                         SYSDB_DOM_BASE,
    1649                 :          2 :                         sysdb->domain->name);
    1650         [ +  - ]:          2 :     if (!dn) {
    1651                 :            :         ret = ENOMEM;
    1652                 :            :         goto done;
    1653                 :            :     }
    1654                 :            : 
    1655                 :          2 :     ret = sysdb_get_bool(sysdb, dn, SYSDB_HAS_ENUMERATED, has_enumerated);
    1656                 :            : 
    1657                 :            : done:
    1658                 :          2 :     talloc_free(tmp_ctx);
    1659                 :          2 :     return ret;
    1660                 :            : }
    1661                 :            : 
    1662                 :          1 : errno_t sysdb_set_enumerated(struct sysdb_ctx *sysdb,
    1663                 :            :                              bool enumerated)
    1664                 :            : {
    1665                 :            :     errno_t ret;
    1666                 :            :     TALLOC_CTX *tmp_ctx;
    1667                 :            :     struct ldb_dn *dn;
    1668                 :            : 
    1669                 :          1 :     tmp_ctx = talloc_new(NULL);
    1670         [ +  - ]:          1 :     if (!tmp_ctx) {
    1671                 :            :         ret = ENOMEM;
    1672                 :            :         goto done;
    1673                 :            :     }
    1674                 :            : 
    1675                 :          1 :     dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
    1676                 :            :                         SYSDB_DOM_BASE,
    1677                 :          1 :                         sysdb->domain->name);
    1678         [ +  - ]:          1 :     if (!dn) {
    1679                 :            :         ret = ENOMEM;
    1680                 :            :         goto done;
    1681                 :            :     }
    1682                 :            : 
    1683                 :          1 :     ret = sysdb_set_bool(sysdb, dn, sysdb->domain->name,
    1684                 :            :                          SYSDB_HAS_ENUMERATED, enumerated);
    1685                 :            : 
    1686                 :            : done:
    1687                 :          1 :     talloc_free(tmp_ctx);
    1688                 :          1 :     return ret;
    1689                 :            : }
    1690                 :            : 
    1691                 :          0 : errno_t sysdb_attrs_primary_name(struct sysdb_ctx *sysdb,
    1692                 :            :                                  struct sysdb_attrs *attrs,
    1693                 :            :                                  const char *ldap_attr,
    1694                 :            :                                  const char **_primary)
    1695                 :            : {
    1696                 :            :     errno_t ret;
    1697                 :          0 :     char *rdn_attr = NULL;
    1698                 :          0 :     char *rdn_val = NULL;
    1699                 :            :     struct ldb_message_element *sysdb_name_el;
    1700                 :            :     struct ldb_message_element *orig_dn_el;
    1701                 :            :     size_t i;
    1702                 :          0 :     TALLOC_CTX *tmp_ctx = NULL;
    1703                 :            : 
    1704                 :          0 :     tmp_ctx = talloc_new(NULL);
    1705         [ #  # ]:          0 :     if (!tmp_ctx) {
    1706                 :            :         return ENOMEM;
    1707                 :            :     }
    1708                 :            : 
    1709                 :          0 :     ret = sysdb_attrs_get_el(attrs,
    1710                 :            :                              SYSDB_NAME,
    1711                 :            :                              &sysdb_name_el);
    1712 [ #  # ][ #  # ]:          0 :     if (ret != EOK || sysdb_name_el->num_values == 0) {
    1713                 :            :         ret = EINVAL;
    1714                 :            :         goto done;
    1715                 :            :     }
    1716                 :            : 
    1717         [ #  # ]:          0 :     if (sysdb_name_el->num_values == 1) {
    1718                 :            :         /* Entry contains only one name. Just return that */
    1719                 :          0 :         *_primary = (const char *)sysdb_name_el->values[0].data;
    1720                 :          0 :         ret = EOK;
    1721                 :          0 :         goto done;
    1722                 :            :     }
    1723                 :            : 
    1724                 :            :     /* Multiple values for name. Check whether one matches the RDN */
    1725                 :            : 
    1726                 :          0 :     ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &orig_dn_el);
    1727         [ #  # ]:          0 :     if (ret) {
    1728                 :            :         goto done;
    1729                 :            :     }
    1730         [ #  # ]:          0 :     if (orig_dn_el->num_values == 0) {
    1731 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Original DN is not available.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1732                 :            :         ret = EINVAL;
    1733                 :            :         goto done;
    1734         [ #  # ]:          0 :     } else if (orig_dn_el->num_values == 1) {
    1735                 :          0 :         ret = sysdb_get_rdn(sysdb, tmp_ctx,
    1736                 :          0 :                             (const char *) orig_dn_el->values[0].data,
    1737                 :            :                             &rdn_attr,
    1738                 :            :                             &rdn_val);
    1739         [ #  # ]:          0 :         if (ret != EOK) {
    1740 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("Could not get rdn from [%s]\n",
         [ #  # ][ #  # ]
                 [ #  # ]
    1741                 :            :                       (const char *) orig_dn_el->values[0].data));
    1742                 :            :             goto done;
    1743                 :            :         }
    1744                 :            :     } else {
    1745 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Should not have more than one origDN\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1746                 :            :         ret = EINVAL;
    1747                 :            :         goto done;
    1748                 :            :     }
    1749                 :            : 
    1750                 :            :     /* First check whether the attribute name matches */
    1751 [ #  # ][ #  # ]:          0 :     DEBUG(8, ("Comparing attribute names [%s] and [%s]\n",
         [ #  # ][ #  # ]
                 [ #  # ]
    1752                 :            :               rdn_attr, ldap_attr));
    1753         [ #  # ]:          0 :     if (strcasecmp(rdn_attr, ldap_attr) != 0) {
    1754                 :            :         /* Multiple entries, and the RDN attribute doesn't match.
    1755                 :            :          * We have no way of resolving this deterministically,
    1756                 :            :          * so we'll use the first value as a fallback.
    1757                 :            :          */
    1758 [ #  # ][ #  # ]:          0 :         DEBUG(3, ("The entry has multiple names and the RDN attribute does "
         [ #  # ][ #  # ]
                 [ #  # ]
    1759                 :            :                   "not match. Will use the first value as fallback.\n"));
    1760                 :          0 :         *_primary = (const char *)sysdb_name_el->values[0].data;
    1761                 :          0 :         ret = EOK;
    1762                 :          0 :         goto done;
    1763                 :            :     }
    1764                 :            : 
    1765         [ #  # ]:          0 :     for (i = 0; i < sysdb_name_el->num_values; i++) {
    1766         [ #  # ]:          0 :         if (strcasecmp(rdn_val,
    1767                 :          0 :                        (const char *)sysdb_name_el->values[i].data) == 0) {
    1768                 :            :             /* This name matches the RDN. Use it */
    1769                 :            :             break;
    1770                 :            :         }
    1771                 :            :     }
    1772         [ #  # ]:          0 :     if (i < sysdb_name_el->num_values) {
    1773                 :            :         /* Match was found */
    1774                 :          0 :         *_primary = (const char *)sysdb_name_el->values[i].data;
    1775                 :            :     } else {
    1776                 :            :         /* If we can't match the name to the RDN, we just have to
    1777                 :            :          * throw up our hands. There's no deterministic way to
    1778                 :            :          * decide which name is correct.
    1779                 :            :          */
    1780 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Cannot save entry. Unable to determine groupname\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1781                 :            :         ret = EINVAL;
    1782                 :            :         goto done;
    1783                 :            :     }
    1784                 :            : 
    1785                 :          0 :     ret = EOK;
    1786                 :            : 
    1787                 :            : done:
    1788         [ #  # ]:          0 :     if (ret != EOK) {
    1789 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("Could not determine primary name: [%d][%s]\n",
         [ #  # ][ #  # ]
                 [ #  # ]
    1790                 :            :                   ret, strerror(ret)));
    1791                 :            :     }
    1792                 :          0 :     talloc_free(tmp_ctx);
    1793                 :            :     return ret;
    1794                 :            : }
    1795                 :            : 
    1796                 :            : /*
    1797                 :            :  * An entity with multiple names would have multiple SYSDB_NAME attributes
    1798                 :            :  * after being translated into sysdb names using a map.
    1799                 :            :  * Given a primary name returned by sysdb_attrs_primary_name(), this function
    1800                 :            :  * returns the other SYSDB_NAME attribute values so they can be saved as
    1801                 :            :  * SYSDB_NAME_ALIAS into cache.
    1802                 :            :  *
    1803                 :            :  * If lowercase is set, all aliases are duplicated in lowercase as well.
    1804                 :            :  */
    1805                 :          0 : errno_t sysdb_attrs_get_aliases(TALLOC_CTX *mem_ctx,
    1806                 :            :                                 struct sysdb_attrs *attrs,
    1807                 :            :                                 const char *primary,
    1808                 :            :                                 bool lowercase,
    1809                 :            :                                 const char ***_aliases)
    1810                 :            : {
    1811                 :          0 :     TALLOC_CTX *tmp_ctx = NULL;
    1812                 :            :     struct ldb_message_element *sysdb_name_el;
    1813                 :            :     size_t i, j, ai;
    1814                 :            :     errno_t ret;
    1815                 :          0 :     const char **aliases = NULL;
    1816                 :            :     const char *name;
    1817                 :            :     char *lower;
    1818                 :            : 
    1819         [ #  # ]:          0 :     if (_aliases == NULL) return EINVAL;
    1820                 :            : 
    1821                 :          0 :     tmp_ctx = talloc_new(NULL);
    1822         [ #  # ]:          0 :     if (!tmp_ctx) {
    1823                 :            :         return ENOMEM;
    1824                 :            :     }
    1825                 :            : 
    1826                 :          0 :     ret = sysdb_attrs_get_el(attrs,
    1827                 :            :                              SYSDB_NAME,
    1828                 :            :                              &sysdb_name_el);
    1829 [ #  # ][ #  # ]:          0 :     if (ret != EOK || sysdb_name_el->num_values == 0) {
    1830                 :            :         ret = EINVAL;
    1831                 :            :         goto done;
    1832                 :            :     }
    1833                 :            : 
    1834                 :          0 :     aliases = talloc_array(tmp_ctx, const char *,
    1835                 :            :                            sysdb_name_el->num_values + 1);
    1836         [ #  # ]:          0 :     if (!aliases) {
    1837                 :            :         ret = ENOMEM;
    1838                 :            :         goto done;
    1839                 :            :     }
    1840                 :            : 
    1841         [ #  # ]:          0 :     if (lowercase) {
    1842 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_TRACE_INTERNAL,
         [ #  # ][ #  # ]
                 [ #  # ]
    1843                 :            :               ("Domain is case-insensitive; will add lowercased aliases\n"));
    1844                 :            :     }
    1845                 :            : 
    1846                 :            :     ai = 0;
    1847         [ #  # ]:          0 :     for (i=0; i < sysdb_name_el->num_values; i++) {
    1848                 :          0 :         name = (const char *)sysdb_name_el->values[i].data;
    1849                 :            : 
    1850         [ #  # ]:          0 :         if (lowercase) {
    1851                 :            :             /* Domain is case-insensitive. Save the lower-cased version */
    1852                 :          0 :             lower = sss_tc_utf8_str_tolower(tmp_ctx, name);
    1853         [ #  # ]:          0 :             if (!lower) {
    1854                 :            :                 ret = ENOMEM;
    1855                 :            :                 goto done;
    1856                 :            :             }
    1857                 :            : 
    1858         [ #  # ]:          0 :             for (j=0; j < ai; j++) {
    1859         [ #  # ]:          0 :                 if (sss_utf8_case_eq((const uint8_t *) aliases[j],
    1860                 :            :                                      (const uint8_t *) lower) == ENOMATCH) {
    1861                 :            :                     break;
    1862                 :            :                 }
    1863                 :            :             }
    1864                 :            : 
    1865         [ #  # ]:          0 :             if (ai == 0 || j < ai) {
    1866                 :          0 :                 aliases[ai] = talloc_strdup(aliases, lower);
    1867         [ #  # ]:          0 :                 if (!aliases[ai]) {
    1868                 :            :                     ret = ENOMEM;
    1869                 :            :                     goto done;
    1870                 :            :                 }
    1871                 :          0 :                 ai++;
    1872                 :            :             }
    1873                 :            :         } else {
    1874                 :            :             /* Domain is case-sensitive. Save it as-is */
    1875         [ #  # ]:          0 :             if (strcmp(primary, name) != 0) {
    1876                 :          0 :                 aliases[ai] = talloc_strdup(aliases, name);
    1877         [ #  # ]:          0 :                 if (!aliases[ai]) {
    1878                 :            :                     ret = ENOMEM;
    1879                 :            :                     goto done;
    1880                 :            :                 }
    1881                 :          0 :                 ai++;
    1882                 :            :             }
    1883                 :            :         }
    1884                 :            :     }
    1885                 :            : 
    1886                 :          0 :     aliases[ai] = NULL;
    1887                 :            : 
    1888                 :          0 :     ret = EOK;
    1889                 :            : 
    1890                 :            : done:
    1891                 :          0 :     *_aliases = talloc_steal(mem_ctx, aliases);
    1892                 :          0 :     talloc_free(tmp_ctx);
    1893                 :            :     return ret;
    1894                 :            : }
    1895                 :            : 
    1896                 :          0 : errno_t sysdb_attrs_primary_name_list(struct sysdb_ctx *sysdb,
    1897                 :            :                                       TALLOC_CTX *mem_ctx,
    1898                 :            :                                       struct sysdb_attrs **attr_list,
    1899                 :            :                                       size_t attr_count,
    1900                 :            :                                       const char *ldap_attr,
    1901                 :            :                                       char ***name_list)
    1902                 :            : {
    1903                 :            :     errno_t ret;
    1904                 :            :     size_t i, j;
    1905                 :            :     char **list;
    1906                 :            :     const char *name;
    1907                 :            : 
    1908                 :            :     /* Assume that every entry has a primary name */
    1909                 :          0 :     list = talloc_array(mem_ctx, char *, attr_count+1);
    1910         [ #  # ]:          0 :     if (!list) {
    1911                 :            :         return ENOMEM;
    1912                 :            :     }
    1913                 :            : 
    1914                 :            :     j = 0;
    1915         [ #  # ]:          0 :     for (i = 0; i < attr_count; i++) {
    1916                 :          0 :         ret = sysdb_attrs_primary_name(sysdb,
    1917                 :          0 :                                        attr_list[i],
    1918                 :            :                                        ldap_attr,
    1919                 :            :                                        &name);
    1920         [ #  # ]:          0 :         if (ret != EOK) {
    1921 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("Could not determine primary name\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1922                 :            :             /* Skip and continue. Don't advance 'j' */
    1923                 :          0 :             continue;
    1924                 :            :         }
    1925                 :            : 
    1926                 :          0 :         list[j] = talloc_strdup(list, name);
    1927         [ #  # ]:          0 :         if (!list[j]) {
    1928                 :            :             ret = ENOMEM;
    1929                 :            :             goto done;
    1930                 :            :         }
    1931                 :            : 
    1932                 :          0 :         j++;
    1933                 :            :     }
    1934                 :            : 
    1935                 :            :     /* NULL-terminate the list */
    1936                 :          0 :     list[j] = NULL;
    1937                 :            : 
    1938                 :          0 :     *name_list = list;
    1939                 :            : 
    1940                 :          0 :     ret = EOK;
    1941                 :            : 
    1942                 :            : done:
    1943         [ #  # ]:          0 :     if (ret != EOK) {
    1944                 :          0 :         talloc_free(list);
    1945                 :            :     }
    1946                 :            :     return ret;
    1947                 :            : }
    1948                 :            : 
    1949                 :          0 : errno_t sysdb_get_real_name(TALLOC_CTX *mem_ctx,
    1950                 :            :                             struct sysdb_ctx *sysdb,
    1951                 :            :                             const char *name,
    1952                 :            :                             const char **_cname)
    1953                 :            : {
    1954                 :            :     errno_t ret;
    1955                 :            :     TALLOC_CTX *tmp_ctx;
    1956                 :            :     struct ldb_result *res;
    1957                 :            :     const char *cname;
    1958                 :            : 
    1959                 :          0 :     tmp_ctx = talloc_new(NULL);
    1960         [ #  # ]:          0 :     if (!tmp_ctx) {
    1961                 :            :         return ENOMEM;
    1962                 :            :     }
    1963                 :            : 
    1964                 :          0 :     ret = sysdb_getpwnam(tmp_ctx, sysdb, name, &res);
    1965         [ #  # ]:          0 :     if (ret != EOK) {
    1966 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_OP_FAILURE, ("Cannot canonicalize username\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1967                 :            :         goto done;
    1968                 :            :     }
    1969                 :            : 
    1970         [ #  # ]:          0 :     if (res->count == 0) {
    1971                 :            :         /* User is not cached yet */
    1972                 :            :         ret = ENOENT;
    1973                 :            :         goto done;
    1974         [ #  # ]:          0 :     } else if (res->count != 1) {
    1975 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
    1976                 :            :               ("sysdb_getpwnam returned count: [%d]\n", res->count));
    1977                 :            :         ret = EIO;
    1978                 :            :         goto done;
    1979                 :            :     }
    1980                 :            : 
    1981                 :          0 :     cname = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL);
    1982         [ #  # ]:          0 :     if (!cname) {
    1983 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE, ("A user with no name?\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    1984                 :            :         ret = ENOENT;
    1985                 :            :         goto done;
    1986                 :            :     }
    1987                 :            : 
    1988                 :          0 :     ret = EOK;
    1989                 :          0 :     *_cname = talloc_steal(mem_ctx, cname);
    1990                 :            : done:
    1991                 :          0 :     talloc_free(tmp_ctx);
    1992                 :            :     return ret;
    1993                 :            : }
    1994                 :            : 
    1995                 :          0 : errno_t sysdb_msg2attrs(TALLOC_CTX *mem_ctx, size_t count,
    1996                 :            :                         struct ldb_message **msgs,
    1997                 :            :                         struct sysdb_attrs ***attrs)
    1998                 :            : {
    1999                 :            :     int i;
    2000                 :            :     struct sysdb_attrs **a;
    2001                 :            : 
    2002                 :          0 :     a = talloc_array(mem_ctx, struct sysdb_attrs *, count);
    2003         [ #  # ]:          0 :     if (a == NULL) {
    2004 [ #  # ][ #  # ]:          0 :         DEBUG(1, ("talloc_array failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    2005                 :            :         return ENOMEM;
    2006                 :            :     }
    2007                 :            : 
    2008         [ #  # ]:          0 :     for (i = 0; i < count; i++) {
    2009                 :          0 :         a[i] = talloc(a, struct sysdb_attrs);
    2010         [ #  # ]:          0 :         if (a[i] == NULL) {
    2011 [ #  # ][ #  # ]:          0 :             DEBUG(1, ("talloc failed.\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
    2012                 :          0 :             talloc_free(a);
    2013                 :          0 :             return ENOMEM;
    2014                 :            :         }
    2015                 :          0 :         a[i]->num = msgs[i]->num_elements;
    2016                 :          0 :         a[i]->a = talloc_steal(a[i], msgs[i]->elements);
    2017                 :            :     }
    2018                 :            : 
    2019                 :          0 :     *attrs = a;
    2020                 :            : 
    2021                 :          0 :     return EOK;
    2022                 :            : }

Generated by: LCOV version 1.9