LCOV - code coverage report
Current view: top level - confdb - confdb_setup.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 0 144 0.0 %
Date: 2015-10-19 Functions: 0 4 0.0 %

          Line data    Source code
       1             : /*
       2             :    SSSD
       3             : 
       4             :    Configuration Database
       5             : 
       6             :    Copyright (C) Stephen Gallagher <sgallagh@redhat.com>  2009
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "config.h"
      23             : #include <sys/stat.h>
      24             : #include "util/util.h"
      25             : #include "db/sysdb.h"
      26             : #include "confdb.h"
      27             : #include "confdb_private.h"
      28             : #include "confdb_setup.h"
      29             : #include "util/sss_ini.h"
      30             : 
      31             : 
      32           0 : int confdb_test(struct confdb_ctx *cdb)
      33             : {
      34             :     char **values;
      35             :     int ret;
      36             : 
      37           0 :     ret = confdb_get_param(cdb, cdb,
      38             :                            "config",
      39             :                            "version",
      40             :                            &values);
      41           0 :     if (ret != EOK) {
      42           0 :         return ret;
      43             :     }
      44             : 
      45           0 :     if (values[0] == NULL) {
      46             :         /* empty database, will need to init */
      47           0 :         talloc_free(values);
      48           0 :         return ENOENT;
      49             :     }
      50             : 
      51           0 :     if (values[1] != NULL) {
      52             :         /* more than 1 value ?? */
      53           0 :         talloc_free(values);
      54           0 :         return EIO;
      55             :     }
      56             : 
      57           0 :     if (strcmp(values[0], CONFDB_VERSION) != 0) {
      58             :         /* Existing version does not match executable version */
      59           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Upgrading confdb version from %s to %s\n",
      60             :                   values[0], CONFDB_VERSION);
      61             : 
      62             :         /* This is recoverable, since we purge the confdb file
      63             :          * when we re-initialize it.
      64             :          */
      65           0 :         talloc_free(values);
      66           0 :         return ENOENT;
      67             :     }
      68             : 
      69           0 :     talloc_free(values);
      70           0 :     return EOK;
      71             : }
      72             : 
      73           0 : static int confdb_purge(struct confdb_ctx *cdb)
      74             : {
      75             :     int ret, i;
      76             :     TALLOC_CTX *tmp_ctx;
      77             :     struct ldb_result *res;
      78             :     struct ldb_dn *dn;
      79           0 :     const char *attrs[] = { "dn", NULL };
      80             : 
      81           0 :     tmp_ctx = talloc_new(NULL);
      82             : 
      83           0 :     dn = ldb_dn_new(tmp_ctx, cdb->ldb, "cn=config");
      84             : 
      85             :     /* Get the list of all DNs */
      86           0 :     ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn,
      87             :                      LDB_SCOPE_SUBTREE, attrs, NULL);
      88           0 :     if (ret != LDB_SUCCESS) {
      89           0 :         ret = sysdb_error_to_errno(ret);
      90           0 :         goto done;
      91             :     }
      92             : 
      93           0 :     for(i=0; i<res->count; i++) {
      94             :         /* Delete this DN */
      95           0 :         ret = ldb_delete(cdb->ldb, res->msgs[i]->dn);
      96           0 :         if (ret != LDB_SUCCESS) {
      97           0 :             ret = sysdb_error_to_errno(ret);
      98           0 :             goto done;
      99             :         }
     100             :     }
     101             : 
     102             : done:
     103           0 :     talloc_free(tmp_ctx);
     104           0 :     return ret;
     105             : }
     106             : 
     107           0 : int confdb_create_base(struct confdb_ctx *cdb)
     108             : {
     109             :     int ret;
     110             :     struct ldb_ldif *ldif;
     111             : 
     112           0 :     const char *base_ldif = CONFDB_BASE_LDIF;
     113             : 
     114           0 :     while ((ldif = ldb_ldif_read_string(cdb->ldb, &base_ldif))) {
     115           0 :         ret = ldb_add(cdb->ldb, ldif->msg);
     116           0 :         if (ret != LDB_SUCCESS) {
     117           0 :             DEBUG(SSSDBG_FATAL_FAILURE,
     118             :                   "Failed to initialize DB (%d,[%s]), aborting!\n",
     119             :                       ret, ldb_errstring(cdb->ldb));
     120           0 :             return EIO;
     121             :         }
     122           0 :         ldb_ldif_read_free(cdb->ldb, ldif);
     123             :     }
     124             : 
     125           0 :     return EOK;
     126             : }
     127             : 
     128           0 : int confdb_init_db(const char *config_file, struct confdb_ctx *cdb)
     129             : {
     130             :     TALLOC_CTX *tmp_ctx;
     131             :     int ret;
     132           0 :     int sret = EOK;
     133             :     int version;
     134             :     char timestr[21];
     135             :     char *lasttimestr;
     136           0 :     bool in_transaction = false;
     137             :     const char *config_ldif;
     138           0 :     const char *vals[2] = { timestr, NULL };
     139             :     struct ldb_ldif *ldif;
     140             :     struct sss_ini_initdata *init_data;
     141             : 
     142             : 
     143           0 :     tmp_ctx = talloc_new(cdb);
     144           0 :     if (tmp_ctx == NULL) {
     145           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory.\n");
     146           0 :         return ENOMEM;
     147             :     }
     148             : 
     149           0 :     init_data = sss_ini_initdata_init(tmp_ctx);
     150           0 :     if (!init_data) {
     151           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory.\n");
     152           0 :         ret = ENOMEM;
     153           0 :         goto done;
     154             :     }
     155             : 
     156             :     /* Open config file */
     157           0 :     ret = sss_ini_config_file_open(init_data, config_file);
     158           0 :     if (ret != EOK) {
     159           0 :         DEBUG(SSSDBG_TRACE_FUNC,
     160             :               "sss_ini_config_file_open failed: %s [%d]\n", strerror(ret),
     161             :                ret);
     162           0 :         if (ret == ENOENT) {
     163             :             /* sss specific error denoting missing configuration file */
     164           0 :             ret = ERR_MISSING_CONF;
     165             :         }
     166           0 :         goto done;
     167             :     }
     168             : 
     169           0 :     ret = sss_ini_config_access_check(init_data);
     170           0 :     if (ret != EOK) {
     171           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     172             :               "Permission check on config file failed.\n");
     173           0 :         ret = EPERM;
     174           0 :         goto done;
     175             :     }
     176             : 
     177             :     /* Determine if the conf file has changed since we last updated
     178             :      * the confdb
     179             :      */
     180           0 :     ret = sss_ini_get_stat(init_data);
     181           0 :     if (ret != EOK) {
     182           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     183             :               "Status check on config file failed.\n");
     184           0 :         ret = errno;
     185           0 :         goto done;
     186             :     }
     187             : 
     188           0 :     errno = 0;
     189             : 
     190           0 :     ret = sss_ini_get_mtime(init_data, sizeof(timestr), timestr);
     191           0 :     if (ret <= 0 || ret >= sizeof(timestr)) {
     192           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     193             :               "Failed to convert time_t to string ??\n");
     194           0 :         ret = errno ? errno : EFAULT;
     195             :     }
     196           0 :     ret = confdb_get_string(cdb, tmp_ctx, "config", "lastUpdate",
     197             :                             NULL, &lasttimestr);
     198           0 :     if (ret == EOK) {
     199             : 
     200             :         /* check if we lastUpdate and last file modification change differ*/
     201           0 :         if ((lasttimestr != NULL) && (strcmp(lasttimestr, timestr) == 0)) {
     202             :             /* not changed, get out, nothing more to do */
     203           0 :             ret = EOK;
     204           0 :             goto done;
     205             :         }
     206             :     } else {
     207           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get lastUpdate attribute.\n");
     208           0 :         goto done;
     209             :     }
     210             : 
     211           0 :     ret = sss_ini_get_config(init_data, config_file);
     212           0 :     if (ret != EOK) {
     213           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load configuration\n");
     214           0 :         goto done;
     215             :     }
     216             : 
     217             :     /* Make sure that the config file version matches the confdb version */
     218           0 :     ret = sss_ini_get_cfgobj(init_data, "sssd", "config_file_version");
     219           0 :     if (ret != EOK) {
     220           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     221             :               "Internal error determining config_file_version\n");
     222           0 :         goto done;
     223             :     }
     224             : 
     225           0 :     ret = sss_ini_check_config_obj(init_data);
     226           0 :     if (ret != EOK) {
     227             :         /* No known version. Use default. */
     228           0 :         DEBUG(SSSDBG_CONF_SETTINGS,
     229             :               "Value of config_file_version option not found. "
     230             :               "Assumed to be version %d.\n", CONFDB_DEFAULT_CFG_FILE_VER);
     231             :     } else {
     232           0 :         version = sss_ini_get_int_config_value(init_data,
     233             :                                                CONFDB_DEFAULT_CFG_FILE_VER,
     234             :                                                -1, &ret);
     235           0 :         if (ret != EOK) {
     236           0 :             DEBUG(SSSDBG_FATAL_FAILURE,
     237             :                   "Config file version could not be determined\n");
     238           0 :             goto done;
     239           0 :         } else if (version < CONFDB_VERSION_INT) {
     240           0 :             DEBUG(SSSDBG_FATAL_FAILURE,
     241             :                   "Config file is an old version. "
     242             :                   "Please run configuration upgrade script.\n");
     243           0 :             ret = EINVAL;
     244           0 :             goto done;
     245           0 :         } else if (version > CONFDB_VERSION_INT) {
     246           0 :             DEBUG(SSSDBG_FATAL_FAILURE,
     247             :                   "Config file version is newer than confdb\n");
     248           0 :             ret = EINVAL;
     249           0 :             goto done;
     250             :         }
     251             :     }
     252             : 
     253             :     /* Set up a transaction to replace the configuration */
     254           0 :     ret = ldb_transaction_start(cdb->ldb);
     255           0 :     if (ret != LDB_SUCCESS) {
     256           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     257             :               "Failed to start a transaction for "
     258             :                "updating the configuration\n");
     259           0 :         ret = sysdb_error_to_errno(ret);
     260           0 :         goto done;
     261             :     }
     262           0 :     in_transaction = true;
     263             : 
     264             :     /* Purge existing database */
     265           0 :     ret = confdb_purge(cdb);
     266           0 :     if (ret != EOK) {
     267           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     268             :               "Could not purge existing configuration\n");
     269           0 :         goto done;
     270             :     }
     271             : 
     272           0 :     ret = sss_confdb_create_ldif(tmp_ctx, init_data, &config_ldif);
     273           0 :     if (ret != EOK) {
     274           0 :         DEBUG(SSSDBG_FATAL_FAILURE, "Could not create LDIF for confdb\n");
     275           0 :         goto done;
     276             :     }
     277             : 
     278           0 :     DEBUG(SSSDBG_TRACE_LIBS, "LDIF file to import: \n%s\n", config_ldif);
     279             : 
     280           0 :     while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) {
     281           0 :         ret = ldb_add(cdb->ldb, ldif->msg);
     282           0 :         if (ret != LDB_SUCCESS) {
     283           0 :             DEBUG(SSSDBG_FATAL_FAILURE,
     284             :                     "Failed to initialize DB (%d,[%s]), aborting!\n",
     285             :                      ret, ldb_errstring(cdb->ldb));
     286           0 :             ret = EIO;
     287           0 :             goto done;
     288             :         }
     289           0 :         ldb_ldif_read_free(cdb->ldb, ldif);
     290             :     }
     291             : 
     292             :     /* now store the lastUpdate time so that we do not re-init if nothing
     293             :      * changed on restart */
     294             : 
     295           0 :     ret = confdb_add_param(cdb, true, "config", "lastUpdate", vals);
     296           0 :     if (ret != EOK) {
     297           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
     298             :                 "Failed to set last update time on db!\n");
     299           0 :         goto done;
     300             :     }
     301             : 
     302           0 :     ret = ldb_transaction_commit(cdb->ldb);
     303           0 :     if (ret != EOK) {
     304           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
     305           0 :         goto done;
     306             :     }
     307           0 :     in_transaction = false;
     308             : 
     309           0 :     ret = EOK;
     310             : 
     311             : done:
     312           0 :     if (in_transaction) {
     313           0 :         sret = ldb_transaction_cancel(cdb->ldb);
     314           0 :         if (sret != EOK) {
     315           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
     316             :         }
     317             :     }
     318             : 
     319           0 :     sss_ini_config_destroy(init_data);
     320           0 :     sss_ini_close_file(init_data);
     321             : 
     322           0 :     talloc_zfree(tmp_ctx);
     323           0 :     return ret;
     324             : }

Generated by: LCOV version 1.10