LCOV - code coverage report
Current view: top level - db - sysdb_services.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 176 252 69.8 %
Date: 2012-11-29 Functions: 8 10 80.0 %
Branches: 102 426 23.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :     SSSD
       3                 :            : 
       4                 :            :     Authors:
       5                 :            :         Stephen Gallagher <sgallagh@redhat.com>
       6                 :            : 
       7                 :            :     Copyright (C) 2012 Red Hat
       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                 :            : 
      24                 :            : #include "util/util.h"
      25                 :            : #include "db/sysdb.h"
      26                 :            : #include "db/sysdb_private.h"
      27                 :            : #include "db/sysdb_services.h"
      28                 :            : 
      29                 :            : errno_t
      30                 :            : sysdb_svc_add(TALLOC_CTX *mem_ctx,
      31                 :            :               struct sysdb_ctx *sysdb,
      32                 :            :               const char *primary_name,
      33                 :            :               int port,
      34                 :            :               const char **aliases,
      35                 :            :               const char **protocols,
      36                 :            :               struct ldb_dn **dn);
      37                 :            : 
      38                 :            : static errno_t
      39                 :            : sysdb_svc_update(struct sysdb_ctx *sysdb,
      40                 :            :                  struct ldb_dn *dn,
      41                 :            :                  int port,
      42                 :            :                  const char **aliases,
      43                 :            :                  const char **protocols);
      44                 :            : 
      45                 :            : errno_t
      46                 :            : sysdb_svc_remove_alias(struct sysdb_ctx *sysdb,
      47                 :            :                        struct ldb_dn *dn,
      48                 :            :                        const char *alias);
      49                 :            : 
      50                 :            : errno_t
      51                 :         11 : sysdb_getservbyname(TALLOC_CTX *mem_ctx,
      52                 :            :                     struct sysdb_ctx *sysdb,
      53                 :            :                     const char *name,
      54                 :            :                     const char *proto,
      55                 :            :                     struct ldb_result **_res)
      56                 :            : {
      57                 :            :     errno_t ret;
      58                 :            :     int lret;
      59                 :            :     TALLOC_CTX *tmp_ctx;
      60                 :            :     static const char *attrs[] = SYSDB_SVC_ATTRS;
      61                 :            :     struct ldb_dn *base_dn;
      62                 :            :     struct ldb_result *res;
      63                 :            :     char *sanitized_name;
      64                 :            :     char *sanitized_proto;
      65                 :            : 
      66                 :         11 :     *_res = NULL;
      67                 :            : 
      68                 :         11 :     tmp_ctx = talloc_new(NULL);
      69         [ +  - ]:         11 :     if (!tmp_ctx) {
      70                 :            :         return ENOMEM;
      71                 :            :     }
      72                 :            : 
      73                 :         11 :     base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
      74                 :            :                              SYSDB_TMPL_SVC_BASE,
      75                 :         11 :                              sysdb->domain->name);
      76         [ +  - ]:         11 :     if (!base_dn) {
      77                 :            :         ret = ENOMEM;
      78                 :            :         goto done;
      79                 :            :     }
      80                 :            : 
      81                 :         11 :     ret = sss_filter_sanitize(tmp_ctx, name, &sanitized_name);
      82         [ +  - ]:         11 :     if (ret != EOK) {
      83                 :            :         goto done;
      84                 :            :     }
      85                 :            : 
      86         [ -  + ]:         11 :     if (proto) {
      87                 :          0 :         ret = sss_filter_sanitize(tmp_ctx, proto, &sanitized_proto);
      88         [ #  # ]:          0 :         if (ret != EOK) {
      89                 :            :             goto done;
      90                 :            :         }
      91                 :            :     }
      92                 :            : 
      93         [ -  + ]:         11 :     lret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn,
      94                 :            :                       LDB_SCOPE_SUBTREE, attrs,
      95                 :            :                       SYSDB_SVC_BYNAME_FILTER,
      96                 :            :                       proto?sanitized_proto:"*",
      97                 :            :                       sanitized_name, sanitized_name);
      98         [ -  + ]:         11 :     if (lret != LDB_SUCCESS) {
      99                 :          0 :         ret = sysdb_error_to_errno(lret);
     100                 :            :         goto done;
     101                 :            :     }
     102                 :            : 
     103         [ +  + ]:         11 :     if (res->count == 0) {
     104                 :            :         ret = ENOENT;
     105                 :            :         goto done;
     106                 :            :     }
     107                 :            : 
     108                 :          8 :     *_res = talloc_steal(mem_ctx, res);
     109                 :            : 
     110                 :          8 :     ret = EOK;
     111                 :            : 
     112                 :            : done:
     113                 :         11 :     talloc_free(tmp_ctx);
     114                 :            :     return ret;
     115                 :            : }
     116                 :            : 
     117                 :            : errno_t
     118                 :         11 : sysdb_getservbyport(TALLOC_CTX *mem_ctx,
     119                 :            :                     struct sysdb_ctx *sysdb,
     120                 :            :                     int port,
     121                 :            :                     const char *proto,
     122                 :            :                     struct ldb_result **_res)
     123                 :            : {
     124                 :            :     errno_t ret;
     125                 :            :     int lret;
     126                 :            :     TALLOC_CTX *tmp_ctx;
     127                 :            :     static const char *attrs[] = SYSDB_SVC_ATTRS;
     128                 :            :     struct ldb_dn *base_dn;
     129                 :            :     struct ldb_result *res;
     130                 :         11 :     char *sanitized_proto = NULL;
     131                 :            : 
     132         [ +  - ]:         11 :     if (port <= 0) {
     133                 :            :         return EINVAL;
     134                 :            :     }
     135                 :            : 
     136                 :         11 :     tmp_ctx = talloc_new(NULL);
     137         [ +  - ]:         11 :     if (!tmp_ctx) {
     138                 :            :         return ENOMEM;
     139                 :            :     }
     140                 :            : 
     141                 :         11 :     base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
     142                 :            :                              SYSDB_TMPL_SVC_BASE,
     143                 :         11 :                              sysdb->domain->name);
     144         [ +  - ]:         11 :     if (!base_dn) {
     145                 :            :         ret = ENOMEM;
     146                 :            :         goto done;
     147                 :            :     }
     148                 :            : 
     149         [ -  + ]:         11 :     if (proto) {
     150                 :          0 :         ret = sss_filter_sanitize(tmp_ctx, proto, &sanitized_proto);
     151         [ #  # ]:          0 :         if (ret != EOK) {
     152                 :            :             goto done;
     153                 :            :         }
     154                 :            :     }
     155                 :            : 
     156         [ -  + ]:         11 :     lret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn,
     157                 :            :                       LDB_SCOPE_SUBTREE, attrs,
     158                 :            :                       SYSDB_SVC_BYPORT_FILTER,
     159                 :         11 :                       sanitized_proto?sanitized_proto:"*",
     160                 :            :                       (unsigned int) port);
     161         [ -  + ]:         11 :     if (lret) {
     162                 :          0 :         ret = sysdb_error_to_errno(lret);
     163                 :            :         goto done;
     164                 :            :     }
     165                 :            : 
     166         [ +  + ]:         11 :     if (res->count == 0) {
     167                 :            :         ret = ENOENT;
     168                 :            :         goto done;
     169                 :            :     }
     170                 :            : 
     171                 :          9 :     *_res = talloc_steal(mem_ctx, res);
     172                 :            : 
     173                 :          9 :     ret = EOK;
     174                 :            : 
     175                 :            : done:
     176                 :         11 :     talloc_free(tmp_ctx);
     177                 :            :     return ret;
     178                 :            : }
     179                 :            : 
     180                 :            : errno_t
     181                 :          4 : sysdb_store_service(struct sysdb_ctx *sysdb,
     182                 :            :                     const char *primary_name,
     183                 :            :                     int port,
     184                 :            :                     const char **aliases,
     185                 :            :                     const char **protocols,
     186                 :            :                     struct sysdb_attrs *extra_attrs,
     187                 :            :                     char **remove_attrs,
     188                 :            :                     uint64_t cache_timeout,
     189                 :            :                     time_t now)
     190                 :            : {
     191                 :            :     errno_t ret;
     192                 :            :     errno_t sret;
     193                 :            :     TALLOC_CTX *tmp_ctx;
     194                 :          4 :     bool in_transaction = false;
     195                 :          4 :     struct ldb_result *res = NULL;
     196                 :            :     const char *name;
     197                 :            :     unsigned int i;
     198                 :          4 :     struct ldb_dn *update_dn = NULL;
     199                 :            :     struct sysdb_attrs *attrs;
     200                 :            : 
     201                 :          4 :     tmp_ctx = talloc_new(NULL);
     202         [ +  - ]:          4 :     if (!tmp_ctx) return ENOMEM;
     203                 :            : 
     204                 :          4 :     ret = sysdb_transaction_start(sysdb);
     205         [ -  + ]:          4 :     if (ret != EOK) {
     206 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to start transaction\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     207                 :            :         goto done;
     208                 :            :     }
     209                 :            : 
     210                 :          4 :     in_transaction = true;
     211                 :            : 
     212                 :            :     /* Check that the port is unique
     213                 :            :      * If the port appears for any service other than
     214                 :            :      * the one matching the primary_name, we need to
     215                 :            :      * remove them so that getservbyport() can work
     216                 :            :      * properly. Last entry saved to the cache should
     217                 :            :      * always "win".
     218                 :            :      */
     219                 :          4 :     ret = sysdb_getservbyport(tmp_ctx, sysdb, port, NULL, &res);
     220         [ +  - ]:          4 :     if (ret != EOK && ret != ENOENT) {
     221                 :            :         goto done;
     222         [ +  + ]:          4 :     } else if (ret != ENOENT) {
     223         [ -  + ]:          2 :         if (res->count != 1) {
     224                 :            :             /* Somehow the cache has multiple entries with
     225                 :            :              * the same port. This is corrupted. We'll delete
     226                 :            :              * them all to sort it out.
     227                 :            :              */
     228         [ #  # ]:          0 :             for (i = 0; i < res->count; i++) {
     229 [ #  # ][ #  # ]:          0 :                 DEBUG(SSSDBG_TRACE_FUNC,
         [ #  # ][ #  # ]
                 [ #  # ]
     230                 :            :                       ("Corrupt cache entry [%s] detected. Deleting\n",
     231                 :            :                        ldb_dn_canonical_string(tmp_ctx,
     232                 :            :                                                res->msgs[i]->dn)));
     233                 :            : 
     234                 :          0 :                 ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true);
     235         [ #  # ]:          0 :                 if (ret != EOK) {
     236 [ #  # ][ #  # ]:          0 :                     DEBUG(SSSDBG_MINOR_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     237                 :            :                           ("Could not delete corrupt cache entry [%s]\n",
     238                 :            :                            ldb_dn_canonical_string(tmp_ctx,
     239                 :            :                                                    res->msgs[i]->dn)));
     240                 :            :                     goto done;
     241                 :            :                 }
     242                 :            :             }
     243                 :            :         } else {
     244                 :            :             /* Check whether this is the same name as we're currently
     245                 :            :              * saving to the cache.
     246                 :            :              */
     247                 :          2 :             name = ldb_msg_find_attr_as_string(res->msgs[0],
     248                 :            :                                                SYSDB_NAME,
     249                 :            :                                                NULL);
     250 [ +  - ][ +  - ]:          2 :             if (!name || strcmp(name, primary_name) != 0) {
     251                 :            : 
     252         [ -  + ]:          2 :                 if (!name) {
     253 [ #  # ][ #  # ]:          0 :                     DEBUG(SSSDBG_CRIT_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     254                 :            :                           ("A service with no name?\n"));
     255                 :            :                     /* Corrupted */
     256                 :            :                 }
     257                 :            : 
     258                 :            :                 /* Either this is a corrupt entry or it's another service
     259                 :            :                  * claiming ownership of this port. In order to account
     260                 :            :                  * for port reassignments, we need to delete the old entry.
     261                 :            :                  */
     262 [ +  - ][ +  - ]:          2 :                 DEBUG(SSSDBG_TRACE_FUNC,
         [ -  + ][ #  # ]
                 [ #  # ]
     263                 :            :                       ("Corrupt or replaced cache entry [%s] detected. "
     264                 :            :                        "Deleting\n",
     265                 :            :                        ldb_dn_canonical_string(tmp_ctx,
     266                 :            :                                                res->msgs[0]->dn)));
     267                 :            : 
     268                 :          2 :                 ret = sysdb_delete_entry(sysdb, res->msgs[0]->dn, true);
     269         [ -  + ]:          2 :                 if (ret != EOK) {
     270 [ #  # ][ #  # ]:          0 :                     DEBUG(SSSDBG_MINOR_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     271                 :            :                           ("Could not delete cache entry [%s]\n",
     272                 :            :                            ldb_dn_canonical_string(tmp_ctx,
     273                 :            :                                                    res->msgs[0]->dn)));
     274                 :            :                 }
     275                 :            :             }
     276                 :            :         }
     277                 :            :     }
     278                 :          4 :     talloc_zfree(res);
     279                 :            : 
     280                 :            :     /* Ok, ports should now be unique. Now look
     281                 :            :      * the service up by name to determine if we
     282                 :            :      * need to update existing entries or modify
     283                 :            :      * aliases.
     284                 :            :      */
     285                 :          4 :     ret = sysdb_getservbyname(tmp_ctx, sysdb, primary_name, NULL, &res);
     286         [ +  - ]:          4 :     if (ret != EOK && ret != ENOENT) {
     287                 :            :         goto done;
     288         [ +  + ]:          4 :     } else if (ret != ENOENT) { /* Found entries */
     289         [ +  + ]:          2 :         for (i = 0; i < res->count; i++) {
     290                 :            :             /* Check whether this is the same name as we're currently
     291                 :            :              * saving to the cache.
     292                 :            :              */
     293                 :          1 :             name = ldb_msg_find_attr_as_string(res->msgs[i],
     294                 :            :                                                SYSDB_NAME,
     295                 :            :                                                NULL);
     296         [ -  + ]:          1 :             if (!name) {
     297                 :            : 
     298                 :            :                 /* Corrupted */
     299 [ #  # ][ #  # ]:          0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     300                 :            :                       ("A service with no name?\n"));
     301 [ #  # ][ #  # ]:          0 :                 DEBUG(SSSDBG_TRACE_FUNC,
         [ #  # ][ #  # ]
                 [ #  # ]
     302                 :            :                       ("Corrupt cache entry [%s] detected. Deleting\n",
     303                 :            :                        ldb_dn_canonical_string(tmp_ctx,
     304                 :            :                                                res->msgs[i]->dn)));
     305                 :            : 
     306                 :          0 :                 ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true);
     307         [ #  # ]:          0 :                 if (ret != EOK) {
     308 [ #  # ][ #  # ]:          0 :                     DEBUG(SSSDBG_MINOR_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     309                 :            :                           ("Could not delete corrupt cache entry [%s]\n",
     310                 :            :                            ldb_dn_canonical_string(tmp_ctx,
     311                 :            :                                                    res->msgs[i]->dn)));
     312                 :            :                     goto done;
     313                 :            :                 }
     314         [ +  - ]:          1 :             } else if (strcmp(name, primary_name) == 0) {
     315                 :            :                 /* This is the same service name, so we need
     316                 :            :                  * to update this entry with the values
     317                 :            :                  * provided.
     318                 :            :                  */
     319         [ -  + ]:          1 :                 if(update_dn) {
     320 [ #  # ][ #  # ]:          0 :                     DEBUG(SSSDBG_CRIT_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     321                 :            :                           ("Two existing services with the same name: [%s]? "
     322                 :            :                            "Deleting both.\n",
     323                 :            :                            primary_name));
     324                 :            : 
     325                 :            :                     /* Delete the entry from the previous pass */
     326                 :          0 :                     ret = sysdb_delete_entry(sysdb, update_dn, true);
     327         [ #  # ]:          0 :                     if (ret != EOK) {
     328 [ #  # ][ #  # ]:          0 :                         DEBUG(SSSDBG_MINOR_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     329                 :            :                               ("Could not delete cache entry [%s]\n",
     330                 :            :                                ldb_dn_canonical_string(tmp_ctx,
     331                 :            :                                                        update_dn)));
     332                 :            :                         goto done;
     333                 :            :                     }
     334                 :            : 
     335                 :            :                     /* Delete the new entry as well */
     336                 :          0 :                     ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, true);
     337         [ #  # ]:          0 :                     if (ret != EOK) {
     338 [ #  # ][ #  # ]:          0 :                         DEBUG(SSSDBG_MINOR_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     339                 :            :                               ("Could not delete cache entry [%s]\n",
     340                 :            :                                ldb_dn_canonical_string(tmp_ctx,
     341                 :            :                                                        res->msgs[i]->dn)));
     342                 :            :                         goto done;
     343                 :            :                     }
     344                 :            : 
     345                 :          0 :                     update_dn = NULL;
     346                 :            :                 } else {
     347                 :          1 :                     update_dn = talloc_steal(tmp_ctx, res->msgs[i]->dn);
     348                 :            :                 }
     349                 :            :             } else {
     350                 :            :                 /* Another service is claiming this name as an alias.
     351                 :            :                  * In order to account for aliases being promoted to
     352                 :            :                  * primary names, we need to make sure to remove the
     353                 :            :                  * old alias entry.
     354                 :            :                  */
     355                 :          0 :                 ret = sysdb_svc_remove_alias(sysdb,
     356                 :          0 :                                              res->msgs[i]->dn,
     357                 :            :                                              primary_name);
     358         [ #  # ]:          0 :                 if (ret != EOK) goto done;
     359                 :            :             }
     360                 :            :         }
     361                 :          1 :         talloc_zfree(res);
     362                 :            :     }
     363                 :            : 
     364         [ +  + ]:          4 :     if (update_dn) {
     365                 :            :         /* Update the existing entry */
     366                 :          1 :         ret = sysdb_svc_update(sysdb, update_dn, port, aliases, protocols);
     367                 :            :     } else {
     368                 :            :         /* Add a new entry */
     369                 :          3 :         ret = sysdb_svc_add(tmp_ctx, sysdb, primary_name, port,
     370                 :            :                             aliases, protocols, &update_dn);
     371                 :            :     }
     372         [ +  - ]:          4 :     if (ret != EOK) goto done;
     373                 :            : 
     374                 :            :     /* Set the cache timeout */
     375         [ +  - ]:          4 :     if (!extra_attrs) {
     376                 :          4 :         attrs = sysdb_new_attrs(tmp_ctx);
     377         [ +  - ]:          4 :         if (!attrs) {
     378                 :            :             ret = ENOMEM;
     379                 :            :             goto done;
     380                 :            :         }
     381                 :            :     } else {
     382                 :            :         attrs = extra_attrs;
     383                 :            :     }
     384                 :            : 
     385                 :          4 :     ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now);
     386         [ +  - ]:          4 :     if (ret) goto done;
     387                 :            : 
     388         [ +  - ]:          4 :     ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
     389                 :            :                                  ((cache_timeout) ?
     390                 :          4 :                                   (now + cache_timeout) : 0));
     391         [ +  - ]:          4 :     if (ret) goto done;
     392                 :            : 
     393                 :          4 :     ret = sysdb_set_entry_attr(sysdb, update_dn, attrs, SYSDB_MOD_REP);
     394         [ +  - ]:          4 :     if (ret != EOK) goto done;
     395                 :            : 
     396         [ -  + ]:          4 :     if (remove_attrs) {
     397                 :          0 :         ret = sysdb_remove_attrs(sysdb, primary_name,
     398                 :            :                                  SYSDB_MEMBER_SERVICE,
     399                 :            :                                  remove_attrs);
     400         [ #  # ]:          0 :         if (ret != EOK) {
     401 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_MINOR_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     402                 :            :                   ("Could not remove missing attributes: [%s]\n",
     403                 :            :                    strerror(ret)));
     404                 :            :             goto done;
     405                 :            :         }
     406                 :            :     }
     407                 :            : 
     408                 :          4 :     ret = sysdb_transaction_commit(sysdb);
     409         [ -  + ]:          4 :     if (ret != EOK) {
     410 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     411                 :            :         goto done;
     412                 :            :     }
     413                 :            :     in_transaction = false;
     414                 :            : 
     415                 :            : done:
     416         [ -  + ]:          4 :     if (in_transaction) {
     417                 :          0 :         sret = sysdb_transaction_cancel(sysdb);
     418         [ #  # ]:          0 :         if (sret != EOK) {
     419 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_CRIT_FAILURE, ("Could not cancel transaction\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     420                 :            :         }
     421                 :            :     }
     422                 :          4 :     talloc_free(tmp_ctx);
     423                 :            :     return ret;
     424                 :            : }
     425                 :            : 
     426                 :            : struct ldb_dn *
     427                 :          6 : sysdb_svc_dn(struct sysdb_ctx *sysdb, TALLOC_CTX *mem_ctx,
     428                 :            :              const char *domain, const char *name)
     429                 :            : {
     430                 :            :     errno_t ret;
     431                 :            :     char *clean_name;
     432                 :            :     struct ldb_dn *dn;
     433                 :            : 
     434                 :          6 :     ret = sysdb_dn_sanitize(NULL, name, &clean_name);
     435         [ +  - ]:          6 :     if (ret != EOK) {
     436                 :            :         return NULL;
     437                 :            :     }
     438                 :            : 
     439                 :          6 :     dn = ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_SVC,
     440                 :            :                         clean_name, domain);
     441                 :          6 :     talloc_free(clean_name);
     442                 :            : 
     443                 :            :     return dn;
     444                 :            : }
     445                 :            : 
     446                 :            : errno_t
     447                 :          5 : sysdb_svc_add(TALLOC_CTX *mem_ctx,
     448                 :            :               struct sysdb_ctx *sysdb,
     449                 :            :               const char *primary_name,
     450                 :            :               int port,
     451                 :            :               const char **aliases,
     452                 :            :               const char **protocols,
     453                 :            :               struct ldb_dn **dn)
     454                 :            : {
     455                 :            :     errno_t ret;
     456                 :            :     int lret;
     457                 :            :     TALLOC_CTX *tmp_ctx;
     458                 :            :     struct ldb_message *msg;
     459                 :            :     unsigned long i;
     460                 :            : 
     461                 :          5 :     tmp_ctx = talloc_new(NULL);
     462         [ +  - ]:          5 :     if (!tmp_ctx) return ENOMEM;
     463                 :            : 
     464                 :          5 :     msg = ldb_msg_new(tmp_ctx);
     465         [ +  - ]:          5 :     if (!msg) {
     466                 :            :         ret = ENOMEM;
     467                 :            :         goto done;
     468                 :            :     }
     469                 :            : 
     470                 :            :     /* svc dn */
     471                 :          5 :     msg->dn = sysdb_svc_dn(sysdb, msg, sysdb->domain->name, primary_name);
     472         [ +  - ]:          5 :     if (!msg->dn) {
     473                 :            :         ret = ENOMEM;
     474                 :            :         goto done;
     475                 :            :     }
     476                 :            : 
     477                 :            :     /* Objectclass */
     478                 :          5 :     ret = add_string(msg, LDB_FLAG_MOD_ADD,
     479                 :            :                      SYSDB_OBJECTCLASS, SYSDB_SVC_CLASS);
     480         [ +  - ]:          5 :     if (ret != EOK) goto done;
     481                 :            : 
     482                 :            :     /* Set the primary name */
     483                 :          5 :     ret = add_string(msg, LDB_FLAG_MOD_ADD,
     484                 :            :                      SYSDB_NAME, primary_name);
     485         [ +  - ]:          5 :     if (ret != EOK) goto done;
     486                 :            : 
     487                 :            :     /* Set the port number */
     488                 :          5 :     ret = add_ulong(msg, LDB_FLAG_MOD_ADD,
     489                 :            :                     SYSDB_SVC_PORT, port);
     490         [ +  - ]:          5 :     if (ret != EOK) goto done;
     491                 :            : 
     492                 :            :     /* If this service has any aliases, include them */
     493 [ +  - ][ +  - ]:          5 :     if (aliases && aliases[0]) {
     494                 :            :         /* Set the name aliases */
     495                 :          5 :         lret = ldb_msg_add_empty(msg, SYSDB_NAME_ALIAS,
     496                 :            :                                  LDB_FLAG_MOD_ADD, NULL);
     497         [ +  - ]:          5 :         if (lret != LDB_SUCCESS) {
     498                 :          0 :             ret = sysdb_error_to_errno(lret);
     499                 :          0 :             goto done;
     500                 :            :         }
     501         [ +  + ]:         15 :         for (i=0; aliases[i]; i++) {
     502                 :         10 :             lret = ldb_msg_add_string(msg, SYSDB_NAME_ALIAS, aliases[i]);
     503         [ -  + ]:         10 :             if (lret != LDB_SUCCESS) {
     504                 :          0 :                 ret = sysdb_error_to_errno(lret);
     505                 :          0 :                 goto done;
     506                 :            :             }
     507                 :            :         }
     508                 :            :     }
     509                 :            : 
     510                 :            :     /* Set the protocols */
     511                 :          5 :     lret = ldb_msg_add_empty(msg, SYSDB_SVC_PROTO,
     512                 :            :                              LDB_FLAG_MOD_ADD, NULL);
     513         [ +  - ]:          5 :     if (lret != LDB_SUCCESS) {
     514                 :          0 :         ret = sysdb_error_to_errno(lret);
     515                 :          0 :         goto done;
     516                 :            :     }
     517         [ +  + ]:         15 :     for (i=0; protocols[i]; i++) {
     518                 :         10 :         lret = ldb_msg_add_string(msg, SYSDB_SVC_PROTO, protocols[i]);
     519         [ -  + ]:         10 :         if (lret != LDB_SUCCESS) {
     520                 :          0 :             ret = sysdb_error_to_errno(lret);
     521                 :          0 :             goto done;
     522                 :            :         }
     523                 :            :     }
     524                 :            : 
     525                 :            :     /* creation time */
     526                 :          5 :     ret = add_ulong(msg, LDB_FLAG_MOD_ADD, SYSDB_CREATE_TIME,
     527                 :          5 :                     (unsigned long)time(NULL));
     528         [ +  - ]:          5 :     if (ret) goto done;
     529                 :            : 
     530                 :          5 :     lret = ldb_add(sysdb->ldb, msg);
     531                 :          5 :     ret = sysdb_error_to_errno(lret);
     532                 :            : 
     533         [ +  + ]:          5 :     if (ret == EOK && dn) {
     534                 :          3 :         *dn = talloc_steal(mem_ctx, msg->dn);
     535                 :            :     }
     536                 :            : 
     537                 :            : done:
     538         [ -  + ]:          5 :     if (ret) {
     539 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_TRACE_INTERNAL,
         [ #  # ][ #  # ]
                 [ #  # ]
     540                 :            :               ("Error: %d (%s)\n", ret, strerror(ret)));
     541                 :            :     }
     542                 :          5 :     talloc_free(tmp_ctx);
     543                 :          5 :     return ret;
     544                 :            : }
     545                 :            : 
     546                 :            : static errno_t
     547                 :          1 : sysdb_svc_update(struct sysdb_ctx *sysdb,
     548                 :            :                  struct ldb_dn *dn,
     549                 :            :                  int port,
     550                 :            :                  const char **aliases,
     551                 :            :                  const char **protocols)
     552                 :            : {
     553                 :            :     errno_t ret;
     554                 :            :     struct ldb_message *msg;
     555                 :            :     int lret;
     556                 :            :     unsigned int i;
     557                 :            : 
     558 [ +  - ][ +  - ]:          1 :     if (!dn || !protocols || !protocols[0]) {
     559                 :            :         return EINVAL;
     560                 :            :     }
     561                 :            : 
     562                 :          1 :     msg = ldb_msg_new(NULL);
     563         [ +  - ]:          1 :     if (!msg) {
     564                 :            :         ret = ENOMEM;
     565                 :            :         goto done;
     566                 :            :     }
     567                 :            : 
     568                 :          1 :     msg->dn = dn;
     569                 :            : 
     570                 :            :     /* Update the port */
     571                 :          1 :     ret = add_ulong(msg, SYSDB_MOD_REP,
     572                 :            :                     SYSDB_SVC_PORT, port);
     573         [ +  - ]:          1 :     if (ret != EOK) goto done;
     574                 :            : 
     575 [ +  - ][ +  - ]:          1 :     if (aliases && aliases[0]) {
     576                 :            :         /* Update the aliases */
     577                 :          1 :         lret = ldb_msg_add_empty(msg, SYSDB_NAME_ALIAS, SYSDB_MOD_REP, NULL);
     578         [ +  - ]:          1 :         if (lret != LDB_SUCCESS) {
     579                 :            :             ret = ENOMEM;
     580                 :            :             goto done;
     581                 :            :         }
     582                 :            : 
     583         [ +  + ]:          3 :         for (i = 0; aliases[i]; i++) {
     584                 :          2 :             lret = ldb_msg_add_string(msg, SYSDB_NAME_ALIAS, aliases[i]);
     585         [ +  - ]:          2 :             if (lret != LDB_SUCCESS) {
     586                 :            :                 ret = EINVAL;
     587                 :            :                 goto done;
     588                 :            :             }
     589                 :            :         }
     590                 :            :     }
     591                 :            : 
     592                 :            :     /* Update the protocols */
     593                 :          1 :     lret = ldb_msg_add_empty(msg, SYSDB_SVC_PROTO, SYSDB_MOD_REP, NULL);
     594         [ +  - ]:          1 :     if (lret != LDB_SUCCESS) {
     595                 :            :         ret = ENOMEM;
     596                 :            :         goto done;
     597                 :            :     }
     598                 :            : 
     599         [ +  + ]:          3 :     for (i = 0; protocols[i]; i++) {
     600                 :          2 :         lret = ldb_msg_add_string(msg, SYSDB_SVC_PROTO, protocols[i]);
     601         [ +  - ]:          2 :         if (lret != LDB_SUCCESS) {
     602                 :            :             ret = EINVAL;
     603                 :            :             goto done;
     604                 :            :         }
     605                 :            :     }
     606                 :            : 
     607                 :          1 :     lret = ldb_modify(sysdb->ldb, msg);
     608                 :          1 :     ret = sysdb_error_to_errno(lret);
     609                 :            : 
     610                 :            : done:
     611         [ -  + ]:          1 :     if (ret) {
     612 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_TRACE_INTERNAL,
         [ #  # ][ #  # ]
                 [ #  # ]
     613                 :            :               ("Error: %d (%s)\n", ret, strerror(ret)));
     614                 :            :     }
     615                 :          1 :     talloc_free(msg);
     616                 :            :     return ret;
     617                 :            : }
     618                 :            : 
     619                 :            : errno_t
     620                 :          1 : sysdb_svc_remove_alias(struct sysdb_ctx *sysdb,
     621                 :            :                        struct ldb_dn *dn,
     622                 :            :                        const char *alias)
     623                 :            : {
     624                 :            :     errno_t ret;
     625                 :            :     struct ldb_message *msg;
     626                 :            :     int lret;
     627                 :            : 
     628                 :          1 :     msg = ldb_msg_new(NULL);
     629         [ +  - ]:          1 :     if (!msg) {
     630                 :            :         ret = ENOMEM;
     631                 :            :         goto done;
     632                 :            :     }
     633                 :            : 
     634                 :          1 :     msg->dn = dn;
     635                 :            : 
     636                 :          1 :     ret = add_string(msg, SYSDB_MOD_DEL,
     637                 :            :                      SYSDB_NAME_ALIAS, alias);
     638         [ +  - ]:          1 :     if (ret != EOK) goto done;
     639                 :            : 
     640                 :          1 :     lret = ldb_modify(sysdb->ldb, msg);
     641                 :          1 :     ret = sysdb_error_to_errno(lret);
     642                 :            : 
     643                 :            : done:
     644         [ -  + ]:          1 :     if (ret) {
     645 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_TRACE_INTERNAL,
         [ #  # ][ #  # ]
                 [ #  # ]
     646                 :            :               ("Error: %d (%s)\n", ret, strerror(ret)));
     647                 :            :     }
     648                 :          1 :     talloc_zfree(msg);
     649                 :          1 :     return ret;
     650                 :            : }
     651                 :            : 
     652                 :            : errno_t
     653                 :          2 : sysdb_svc_delete(struct sysdb_ctx *sysdb,
     654                 :            :                  const char *name,
     655                 :            :                  int port,
     656                 :            :                  const char *proto)
     657                 :            : {
     658                 :            :     errno_t ret, sret;
     659                 :            :     TALLOC_CTX *tmp_ctx;
     660                 :            :     struct ldb_result *res;
     661                 :            :     unsigned int i;
     662                 :          2 :     bool in_transaction = false;
     663                 :            : 
     664                 :          2 :     tmp_ctx = talloc_new(NULL);
     665         [ +  - ]:          2 :     if (!tmp_ctx) {
     666                 :            :         return ENOMEM;
     667                 :            :     }
     668                 :            : 
     669                 :          2 :     ret = sysdb_transaction_start(sysdb);
     670         [ -  + ]:          2 :     if (ret != EOK) {
     671 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to start transaction\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     672                 :            :         goto done;
     673                 :            :     }
     674                 :            : 
     675                 :          2 :     in_transaction = true;
     676                 :            : 
     677         [ +  + ]:          2 :     if (name) {
     678                 :          1 :         ret = sysdb_getservbyname(tmp_ctx, sysdb, name, proto, &res);
     679         [ +  - ]:          1 :         if (ret != EOK && ret != ENOENT) goto done;
     680         [ +  - ]:          1 :         if (ret == ENOENT) {
     681                 :            :             /* Doesn't exist in the DB. Nothing to do */
     682                 :            :             ret = EOK;
     683                 :            :             goto done;
     684                 :            :         }
     685                 :            :     } else {
     686                 :          1 :         ret = sysdb_getservbyport(tmp_ctx, sysdb, port, proto, &res);
     687         [ +  - ]:          1 :         if (ret != EOK && ret != ENOENT) goto done;
     688         [ +  - ]:          2 :         if (ret == ENOENT) {
     689                 :            :             /* Doesn't exist in the DB. Nothing to do */
     690                 :            :             ret = EOK;
     691                 :            :             goto done;
     692                 :            :         }
     693                 :            :     }
     694                 :            : 
     695                 :            :     /* There should only be one matching entry,
     696                 :            :      * but if there are multiple, we should delete
     697                 :            :      * them all to de-corrupt the DB.
     698                 :            :      */
     699         [ +  + ]:          4 :     for (i = 0; i < res->count; i++) {
     700                 :          2 :         ret = sysdb_delete_entry(sysdb, res->msgs[i]->dn, false);
     701         [ +  - ]:          2 :         if (ret != EOK) goto done;
     702                 :            :     }
     703                 :            : 
     704                 :          2 :     ret = sysdb_transaction_commit(sysdb);
     705         [ -  + ]:          2 :     if (ret != EOK) {
     706 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     707                 :            :         goto done;
     708                 :            :     }
     709                 :            :     in_transaction = false;
     710                 :            : 
     711                 :            : done:
     712         [ -  + ]:          2 :     if (in_transaction) {
     713                 :          0 :         sret = sysdb_transaction_cancel(sysdb);
     714         [ #  # ]:          0 :         if (sret != EOK) {
     715 [ #  # ][ #  # ]:          0 :             DEBUG(SSSDBG_CRIT_FAILURE,
         [ #  # ][ #  # ]
                 [ #  # ]
     716                 :            :                   ("Could not cancel transaction\n"));
     717                 :            :         }
     718                 :            :     }
     719                 :            : 
     720         [ -  + ]:          2 :     if (ret != EOK && ret != ENOENT) {
     721 [ #  # ][ #  # ]:          0 :         DEBUG(SSSDBG_TRACE_INTERNAL,
         [ #  # ][ #  # ]
                 [ #  # ]
     722                 :            :               ("Error: %d (%s)\n", ret, strerror(ret)));
     723                 :            :     }
     724                 :          2 :     talloc_zfree(tmp_ctx);
     725                 :            :     return ret;
     726                 :            : }
     727                 :            : 
     728                 :            : 
     729                 :            : errno_t
     730                 :          0 : sysdb_enumservent(TALLOC_CTX *mem_ctx,
     731                 :            :                   struct sysdb_ctx *sysdb,
     732                 :            :                   struct ldb_result **_res)
     733                 :            : {
     734                 :            :     errno_t ret;
     735                 :            :     int lret;
     736                 :            :     TALLOC_CTX *tmp_ctx;
     737                 :            :     static const char *attrs[] = SYSDB_SVC_ATTRS;
     738                 :            :     struct ldb_dn *base_dn;
     739                 :            :     struct ldb_result *res;
     740                 :            : 
     741                 :          0 :     *_res = NULL;
     742                 :            : 
     743                 :          0 :     tmp_ctx = talloc_new(NULL);
     744         [ #  # ]:          0 :     if (!tmp_ctx) {
     745                 :            :         return ENOMEM;
     746                 :            :     }
     747                 :            : 
     748                 :          0 :     base_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
     749                 :            :                              SYSDB_TMPL_SVC_BASE,
     750                 :          0 :                              sysdb->domain->name);
     751         [ #  # ]:          0 :     if (!base_dn) {
     752                 :            :         ret = ENOMEM;
     753                 :            :         goto done;
     754                 :            :     }
     755                 :            : 
     756                 :          0 :     lret = ldb_search(sysdb->ldb, tmp_ctx, &res, base_dn,
     757                 :            :                       LDB_SCOPE_SUBTREE, attrs,
     758                 :            :                       SYSDB_SC);
     759         [ #  # ]:          0 :     if (lret != LDB_SUCCESS) {
     760                 :          0 :         ret = sysdb_error_to_errno(lret);
     761                 :            :         goto done;
     762                 :            :     }
     763                 :            : 
     764         [ #  # ]:          0 :     if (res->count == 0) {
     765                 :            :         ret = ENOENT;
     766                 :            :         goto done;
     767                 :            :     }
     768                 :            : 
     769                 :          0 :     *_res = talloc_steal(mem_ctx, res);
     770                 :            : 
     771                 :          0 :     ret = EOK;
     772                 :            : 
     773                 :            : done:
     774                 :          0 :     talloc_free(tmp_ctx);
     775                 :            :     return ret;
     776                 :            : }
     777                 :            : 
     778                 :            : errno_t
     779                 :          0 : sysdb_set_service_attr(struct sysdb_ctx *sysdb,
     780                 :            :                        const char *name,
     781                 :            :                        struct sysdb_attrs *attrs,
     782                 :            :                        int mod_op)
     783                 :            : {
     784                 :            :     errno_t ret;
     785                 :            :     struct ldb_dn *dn;
     786                 :            :     TALLOC_CTX *tmp_ctx;
     787                 :            : 
     788                 :          0 :     tmp_ctx = talloc_new(NULL);
     789         [ #  # ]:          0 :     if (!tmp_ctx) {
     790                 :            :         return ENOMEM;
     791                 :            :     }
     792                 :            : 
     793                 :          0 :     dn = sysdb_svc_dn(sysdb, tmp_ctx, sysdb->domain->name, name);
     794         [ #  # ]:          0 :     if (!dn) {
     795                 :            :         ret = ENOMEM;
     796                 :            :         goto done;
     797                 :            :     }
     798                 :            : 
     799                 :          0 :     ret = sysdb_set_entry_attr(sysdb, dn, attrs, mod_op);
     800                 :            : 
     801                 :            : done:
     802                 :          0 :     talloc_free(tmp_ctx);
     803                 :          0 :     return ret;
     804                 :          1 : }

Generated by: LCOV version 1.9