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

          Line data    Source code
       1             : /*
       2             :     SSSD
       3             : 
       4             :     Authors:
       5             :         Simo Sorce <ssorce@redhat.com>
       6             :         Stephen Gallagher <sgallagh@redhat.com>
       7             : 
       8             :     Copyright (C) 2008-2011 Simo Sorce <ssorce@redhat.com>
       9             :     Copyright (C) 2008-2011 Stephen Gallagher
      10             : 
      11             :     This program is free software; you can redistribute it and/or modify
      12             :     it under the terms of the GNU General Public License as published by
      13             :     the Free Software Foundation; either version 3 of the License, or
      14             :     (at your option) any later version.
      15             : 
      16             :     This program is distributed in the hope that it will be useful,
      17             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :     GNU General Public License for more details.
      20             : 
      21             :     You should have received a copy of the GNU General Public License
      22             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "util/util.h"
      26             : #include "db/sysdb_private.h"
      27             : #include "db/sysdb_autofs.h"
      28             : 
      29             : struct upgrade_ctx {
      30             :     struct ldb_context *ldb;
      31             :     const char *new_version;
      32             : };
      33             : 
      34           0 : static errno_t commence_upgrade(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
      35             :                                 const char *new_ver, struct upgrade_ctx **_ctx)
      36             : {
      37             :     struct upgrade_ctx *ctx;
      38             :     int ret;
      39             : 
      40           0 :     DEBUG(SSSDBG_CRIT_FAILURE, "UPGRADING DB TO VERSION %s\n", new_ver);
      41             : 
      42           0 :     ctx = talloc(mem_ctx, struct upgrade_ctx);
      43           0 :     if (!ctx) {
      44           0 :         return ENOMEM;
      45             :     }
      46             : 
      47           0 :     ctx->ldb = ldb;
      48           0 :     ctx->new_version = new_ver;
      49             : 
      50           0 :     ret = ldb_transaction_start(ldb);
      51           0 :     if (ret != LDB_SUCCESS) {
      52           0 :         ret = EIO;
      53           0 :         goto done;
      54             :     }
      55             : 
      56           0 :     ret = EOK;
      57             : 
      58             : done:
      59           0 :     if (ret != EOK) {
      60           0 :         talloc_free(ctx);
      61             :     } else {
      62           0 :         *_ctx = ctx;
      63             :     }
      64           0 :     return ret;
      65             : }
      66             : 
      67           0 : static errno_t update_version(struct upgrade_ctx *ctx)
      68             : {
      69           0 :     struct ldb_message *msg = NULL;
      70             :     errno_t ret;
      71             : 
      72           0 :     msg = ldb_msg_new(ctx);
      73           0 :     if (!msg) {
      74           0 :         ret = ENOMEM;
      75           0 :         goto done;
      76             :     }
      77           0 :     msg->dn = ldb_dn_new(msg, ctx->ldb, SYSDB_BASE);
      78           0 :     if (!msg->dn) {
      79           0 :         ret = ENOMEM;
      80           0 :         goto done;
      81             :     }
      82             : 
      83           0 :     ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL);
      84           0 :     if (ret != LDB_SUCCESS) {
      85           0 :         ret = ENOMEM;
      86           0 :         goto done;
      87             :     }
      88             : 
      89           0 :     ret = ldb_msg_add_string(msg, "version", ctx->new_version);
      90           0 :     if (ret != LDB_SUCCESS) {
      91           0 :         ret = ENOMEM;
      92           0 :         goto done;
      93             :     }
      94             : 
      95           0 :     ret = ldb_modify(ctx->ldb, msg);
      96           0 :     if (ret != LDB_SUCCESS) {
      97           0 :         ret = sysdb_error_to_errno(ret);
      98           0 :         goto done;
      99             :     }
     100             : 
     101           0 :     ret = EOK;
     102             : 
     103             : done:
     104           0 :     talloc_free(msg);
     105           0 :     return ret;
     106             : }
     107             : 
     108           0 : static int finish_upgrade(int ret, struct upgrade_ctx **ctx, const char **ver)
     109             : {
     110             :     int lret;
     111             : 
     112           0 :     if (ret == EOK) {
     113           0 :         lret = ldb_transaction_commit((*ctx)->ldb);
     114           0 :         ret = sysdb_error_to_errno(lret);
     115           0 :         if (ret == EOK) {
     116           0 :             *ver = (*ctx)->new_version;
     117             :         }
     118             :     }
     119             : 
     120           0 :     if (ret != EOK) {
     121           0 :         lret = ldb_transaction_cancel((*ctx)->ldb);
     122           0 :         if (lret != LDB_SUCCESS) {
     123           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     124             :                   "Could not cancel transaction! [%s]\n",
     125             :                    ldb_strerror(lret));
     126             :             /* Do not overwrite ret here, we want to return
     127             :              * the original failure, not the failure of the
     128             :              * transaction cancellation.
     129             :              */
     130             :         }
     131             :     }
     132             : 
     133           0 :     talloc_zfree(*ctx);
     134           0 :     return ret;
     135             : }
     136             : 
     137             : /* serach all groups that have a memberUid attribute.
     138             :  * change it into a member attribute for a user of same domain.
     139             :  * remove the memberUid attribute
     140             :  * add the new member attribute
     141             :  * finally stop indexing memberUid
     142             :  * upgrade version to 0.2
     143             :  */
     144           0 : int sysdb_upgrade_01(struct ldb_context *ldb, const char **ver)
     145             : {
     146             :     struct ldb_message_element *el;
     147             :     struct ldb_result *res;
     148             :     struct ldb_dn *basedn;
     149             :     struct ldb_dn *mem_dn;
     150             :     struct ldb_message *msg;
     151             :     const struct ldb_val *val;
     152           0 :     const char *filter = "(&(memberUid=*)(objectclass=group))";
     153           0 :     const char *attrs[] = { "memberUid", NULL };
     154             :     const char *mdn;
     155             :     char *domain;
     156             :     int ret, i, j;
     157             :     TALLOC_CTX *tmp_ctx;
     158             :     struct upgrade_ctx *ctx;
     159             : 
     160           0 :     tmp_ctx = talloc_new(NULL);
     161           0 :     if (!tmp_ctx) {
     162           0 :         return ENOMEM;
     163             :     }
     164             : 
     165           0 :     ret = commence_upgrade(tmp_ctx, ldb, SYSDB_VERSION_0_2, &ctx);
     166           0 :     if (ret) {
     167           0 :         talloc_free(tmp_ctx);
     168           0 :         return ret;
     169             :     }
     170             : 
     171           0 :     basedn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE);
     172           0 :     if (!basedn) {
     173           0 :         ret = EIO;
     174           0 :         goto done;
     175             :     }
     176             : 
     177           0 :     ret = ldb_search(ldb, tmp_ctx, &res,
     178             :                      basedn, LDB_SCOPE_SUBTREE,
     179             :                      attrs, "%s", filter);
     180           0 :     if (ret != LDB_SUCCESS) {
     181           0 :         ret = EIO;
     182           0 :         goto done;
     183             :     }
     184             : 
     185           0 :     for (i = 0; i < res->count; i++) {
     186           0 :         el = ldb_msg_find_element(res->msgs[i], "memberUid");
     187           0 :         if (!el) {
     188           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     189             :                   "memberUid is missing from message [%s], skipping\n",
     190             :                       ldb_dn_get_linearized(res->msgs[i]->dn));
     191           0 :             continue;
     192             :         }
     193             : 
     194             :         /* create modification message */
     195           0 :         msg = ldb_msg_new(tmp_ctx);
     196           0 :         if (!msg) {
     197           0 :             ret = ENOMEM;
     198           0 :             goto done;
     199             :         }
     200           0 :         msg->dn = res->msgs[i]->dn;
     201             : 
     202           0 :         ret = ldb_msg_add_empty(msg, "memberUid", LDB_FLAG_MOD_DELETE, NULL);
     203           0 :         if (ret != LDB_SUCCESS) {
     204           0 :             ret = ENOMEM;
     205           0 :             goto done;
     206             :         }
     207             : 
     208           0 :         ret = ldb_msg_add_empty(msg, SYSDB_MEMBER, LDB_FLAG_MOD_ADD, NULL);
     209           0 :         if (ret != LDB_SUCCESS) {
     210           0 :             ret = ENOMEM;
     211           0 :             goto done;
     212             :         }
     213             : 
     214             :         /* get domain name component value */
     215           0 :         val = ldb_dn_get_component_val(res->msgs[i]->dn, 2);
     216           0 :         domain = talloc_strndup(tmp_ctx, (const char *)val->data, val->length);
     217           0 :         if (!domain) {
     218           0 :             ret = ENOMEM;
     219           0 :             goto done;
     220             :         }
     221             : 
     222           0 :         for (j = 0; j < el->num_values; j++) {
     223           0 :             mem_dn = ldb_dn_new_fmt(tmp_ctx, ldb, SYSDB_TMPL_USER,
     224           0 :                                     (const char *)el->values[j].data, domain);
     225           0 :             if (!mem_dn) {
     226           0 :                 ret = ENOMEM;
     227           0 :                 goto done;
     228             :             }
     229             : 
     230           0 :             mdn = talloc_strdup(msg, ldb_dn_get_linearized(mem_dn));
     231           0 :             if (!mdn) {
     232           0 :                 ret = ENOMEM;
     233           0 :                 goto done;
     234             :             }
     235           0 :             ret = ldb_msg_add_string(msg, SYSDB_MEMBER, mdn);
     236           0 :             if (ret != LDB_SUCCESS) {
     237           0 :                 ret = ENOMEM;
     238           0 :                 goto done;
     239             :             }
     240             : 
     241           0 :             talloc_zfree(mem_dn);
     242             :         }
     243             : 
     244             :         /* ok now we are ready to modify the entry */
     245           0 :         ret = ldb_modify(ldb, msg);
     246           0 :         if (ret != LDB_SUCCESS) {
     247           0 :             ret = sysdb_error_to_errno(ret);
     248           0 :             goto done;
     249             :         }
     250             : 
     251           0 :         talloc_zfree(msg);
     252             :     }
     253             : 
     254             :     /* conversion done, update version number */
     255           0 :     ret = update_version(ctx);
     256             : 
     257             : done:
     258           0 :     ret = finish_upgrade(ret, &ctx, ver);
     259           0 :     talloc_free(tmp_ctx);
     260           0 :     return ret;
     261             : }
     262             : 
     263           0 : int sysdb_check_upgrade_02(struct sss_domain_info *domains,
     264             :                            const char *db_path)
     265             : {
     266           0 :     TALLOC_CTX *tmp_ctx = NULL;
     267             :     struct ldb_context *ldb;
     268             :     char *ldb_file;
     269             :     struct sysdb_ctx *sysdb;
     270             :     struct sss_domain_info *dom;
     271             :     struct ldb_message_element *el;
     272             :     struct ldb_message *msg;
     273             :     struct ldb_result *res;
     274             :     struct ldb_dn *verdn;
     275           0 :     const char *version = NULL;
     276           0 :     bool do_02_upgrade = false;
     277           0 :     bool ctx_trans = false;
     278             :     int ret;
     279             : 
     280           0 :     tmp_ctx = talloc_new(NULL);
     281           0 :     if (!tmp_ctx) {
     282           0 :         return ENOMEM;
     283             :     }
     284             : 
     285           0 :     ret = sysdb_get_db_file(tmp_ctx,
     286             :                             "local", "UPGRADE",
     287             :                             db_path, &ldb_file);
     288           0 :     if (ret != EOK) {
     289           0 :         goto exit;
     290             :     }
     291             : 
     292           0 :     ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb);
     293           0 :     if (ret != EOK) {
     294           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n");
     295           0 :         return ret;
     296             :     }
     297             : 
     298           0 :     verdn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE);
     299           0 :     if (!verdn) {
     300           0 :         ret = EIO;
     301           0 :         goto exit;
     302             :     }
     303             : 
     304           0 :     ret = ldb_search(ldb, tmp_ctx, &res,
     305             :                      verdn, LDB_SCOPE_BASE,
     306             :                      NULL, NULL);
     307           0 :     if (ret != LDB_SUCCESS) {
     308           0 :         ret = EIO;
     309           0 :         goto exit;
     310             :     }
     311           0 :     if (res->count > 1) {
     312           0 :         ret = EIO;
     313           0 :         goto exit;
     314             :     }
     315             : 
     316           0 :     if (res->count == 1) {
     317           0 :         el = ldb_msg_find_element(res->msgs[0], "version");
     318           0 :         if (el) {
     319           0 :             if (el->num_values != 1) {
     320           0 :                 ret = EINVAL;
     321           0 :                 goto exit;
     322             :             }
     323           0 :             version = talloc_strndup(tmp_ctx,
     324           0 :                                      (char *)(el->values[0].data),
     325           0 :                                      el->values[0].length);
     326           0 :             if (!version) {
     327           0 :                 ret = ENOMEM;
     328           0 :                 goto exit;
     329             :             }
     330             : 
     331           0 :             if (strcmp(version, SYSDB_VERSION) == 0) {
     332             :                 /* all fine, return */
     333           0 :                 ret = EOK;
     334           0 :                 goto exit;
     335             :             }
     336             : 
     337           0 :             DEBUG(SSSDBG_CONF_SETTINGS,
     338             :                   "Upgrading DB from version: %s\n", version);
     339             : 
     340           0 :             if (strcmp(version, SYSDB_VERSION_0_1) == 0) {
     341             :                 /* convert database */
     342           0 :                 ret = sysdb_upgrade_01(ldb, &version);
     343           0 :                 if (ret != EOK) goto exit;
     344             :             }
     345             : 
     346           0 :             if (strcmp(version, SYSDB_VERSION_0_2) == 0) {
     347             :                 /* need to convert database to split files */
     348           0 :                 do_02_upgrade = true;
     349             :             }
     350             : 
     351             :         }
     352             :     }
     353             : 
     354           0 :     if (!do_02_upgrade) {
     355             :         /* not a v2 upgrade, return and let the normal code take over any
     356             :         * further upgrade */
     357           0 :         ret = EOK;
     358           0 :         goto exit;
     359             :     }
     360             : 
     361             :     /* == V2->V3 UPGRADE == */
     362             : 
     363           0 :     DEBUG(SSSDBG_FATAL_FAILURE,
     364             :           "UPGRADING DB TO VERSION %s\n", SYSDB_VERSION_0_3);
     365             : 
     366             :     /* ldb uses posix locks,
     367             :      * posix is stupid and kills all locks when you close *any* file
     368             :      * descriptor associated to the same file.
     369             :      * Therefore we must close and reopen the ldb file here */
     370             : 
     371             :     /* == Backup and reopen ldb == */
     372             : 
     373             :     /* close */
     374           0 :     talloc_zfree(ldb);
     375             : 
     376             :     /* backup*/
     377           0 :     ret = backup_file(ldb_file, SSSDBG_FATAL_FAILURE);
     378           0 :     if (ret != EOK) {
     379           0 :         goto exit;
     380             :     }
     381             : 
     382             :     /* reopen */
     383           0 :     ret = sysdb_ldb_connect(tmp_ctx, ldb_file, &ldb);
     384           0 :     if (ret != EOK) {
     385           0 :         DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_ldb_connect failed.\n");
     386           0 :         return ret;
     387             :     }
     388             : 
     389             :     /* open a transaction */
     390           0 :     ret = ldb_transaction_start(ldb);
     391           0 :     if (ret != LDB_SUCCESS) {
     392           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     393             :               "Failed to start ldb transaction! (%d)\n", ret);
     394           0 :         ret = EIO;
     395           0 :         goto exit;
     396             :     }
     397             : 
     398             :     /* == Upgrade contents == */
     399             : 
     400           0 :     for (dom = domains; dom; dom = dom->next) {
     401             :         struct ldb_dn *domain_dn;
     402             :         struct ldb_dn *users_dn;
     403             :         struct ldb_dn *groups_dn;
     404             :         int i;
     405             : 
     406             :         /* skip local */
     407           0 :         if (strcasecmp(dom->provider, "local") == 0) {
     408           0 :             continue;
     409             :         }
     410             : 
     411             :         /* create new dom db */
     412           0 :         ret = sysdb_domain_init_internal(tmp_ctx, dom,
     413             :                                          db_path, false, &sysdb);
     414           0 :         if (ret != EOK) {
     415           0 :             goto done;
     416             :         }
     417             : 
     418           0 :         ret = ldb_transaction_start(sysdb->ldb);
     419           0 :         if (ret != LDB_SUCCESS) {
     420           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     421             :                   "Failed to start ldb transaction! (%d)\n", ret);
     422           0 :             ret = EIO;
     423           0 :             goto done;
     424             :         }
     425           0 :         ctx_trans = true;
     426             : 
     427             :         /* search all entries for this domain in local,
     428             :          * copy them all in the new database,
     429             :          * then remove them from local */
     430             : 
     431           0 :         domain_dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
     432             :                                    SYSDB_DOM_BASE, dom->name);
     433           0 :         if (!domain_dn) {
     434           0 :             ret = ENOMEM;
     435           0 :             goto done;
     436             :         }
     437             : 
     438           0 :         ret = ldb_search(ldb, tmp_ctx, &res,
     439             :                          domain_dn, LDB_SCOPE_SUBTREE,
     440             :                          NULL, NULL);
     441           0 :         if (ret != LDB_SUCCESS) {
     442           0 :             ret = EIO;
     443           0 :             goto done;
     444             :         }
     445             : 
     446           0 :         users_dn = sysdb_user_base_dn(tmp_ctx, dom);
     447           0 :         if (!users_dn) {
     448           0 :             ret = ENOMEM;
     449           0 :             goto done;
     450             :         }
     451           0 :         groups_dn = sysdb_group_base_dn(tmp_ctx, dom);
     452           0 :         if (!groups_dn) {
     453           0 :             ret = ENOMEM;
     454           0 :             goto done;
     455             :         }
     456             : 
     457           0 :         for (i = 0; i < res->count; i++) {
     458             : 
     459             :             struct ldb_dn *orig_dn;
     460             : 
     461           0 :             msg = res->msgs[i];
     462             : 
     463             :             /* skip pre-created congtainers */
     464           0 :             if ((ldb_dn_compare(msg->dn, domain_dn) == 0) ||
     465           0 :                 (ldb_dn_compare(msg->dn, users_dn) == 0) ||
     466           0 :                 (ldb_dn_compare(msg->dn, groups_dn) == 0)) {
     467           0 :                 continue;
     468             :             }
     469             : 
     470             :             /* regenerate the DN against the new ldb as it may have different
     471             :              * casefolding rules (example: name changing from case insensitive
     472             :              * to case sensitive) */
     473           0 :             orig_dn = msg->dn;
     474           0 :             msg->dn = ldb_dn_new(msg, sysdb->ldb,
     475             :                                  ldb_dn_get_linearized(orig_dn));
     476           0 :             if (!msg->dn) {
     477           0 :                 ret = ENOMEM;
     478           0 :                 goto done;
     479             :             }
     480             : 
     481           0 :             ret = ldb_add(sysdb->ldb, msg);
     482           0 :             if (ret != LDB_SUCCESS) {
     483           0 :                 DEBUG(SSSDBG_FATAL_FAILURE, "WARNING: Could not add entry %s,"
     484             :                           " to new ldb file! (%d [%s])\n",
     485             :                           ldb_dn_get_linearized(msg->dn),
     486             :                           ret, ldb_errstring(sysdb->ldb));
     487             :             }
     488             : 
     489           0 :             ret = ldb_delete(ldb, orig_dn);
     490           0 :             if (ret != LDB_SUCCESS) {
     491           0 :                 DEBUG(SSSDBG_FATAL_FAILURE,
     492             :                       "WARNING: Could not remove entry %s,"
     493             :                           " from old ldb file! (%d [%s])\n",
     494             :                           ldb_dn_get_linearized(orig_dn),
     495             :                           ret, ldb_errstring(ldb));
     496             :             }
     497             :         }
     498             : 
     499             :         /* now remove the basic containers from local */
     500             :         /* these were optional so debug at level 9 in case
     501             :          * of failure just for tracing */
     502           0 :         ret = ldb_delete(ldb, groups_dn);
     503           0 :         if (ret != LDB_SUCCESS) {
     504           0 :             DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s,"
     505             :                       " from old ldb file! (%d [%s])\n",
     506             :                       ldb_dn_get_linearized(groups_dn),
     507             :                       ret, ldb_errstring(ldb));
     508             :         }
     509           0 :         ret = ldb_delete(ldb, users_dn);
     510           0 :         if (ret != LDB_SUCCESS) {
     511           0 :             DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s,"
     512             :                       " from old ldb file! (%d [%s])\n",
     513             :                       ldb_dn_get_linearized(users_dn),
     514             :                       ret, ldb_errstring(ldb));
     515             :         }
     516           0 :         ret = ldb_delete(ldb, domain_dn);
     517           0 :         if (ret != LDB_SUCCESS) {
     518           0 :             DEBUG(SSSDBG_TRACE_ALL, "WARNING: Could not remove entry %s,"
     519             :                       " from old ldb file! (%d [%s])\n",
     520             :                       ldb_dn_get_linearized(domain_dn),
     521             :                       ret, ldb_errstring(ldb));
     522             :         }
     523             : 
     524           0 :         ret = ldb_transaction_commit(sysdb->ldb);
     525           0 :         if (ret != LDB_SUCCESS) {
     526           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     527             :                   "Failed to commit ldb transaction! (%d)\n", ret);
     528           0 :             ret = EIO;
     529           0 :             goto done;
     530             :         }
     531           0 :         ctx_trans = false;
     532             : 
     533           0 :         talloc_zfree(domain_dn);
     534           0 :         talloc_zfree(groups_dn);
     535           0 :         talloc_zfree(users_dn);
     536           0 :         talloc_zfree(res);
     537             :     }
     538             : 
     539             :     /* conversion done, upgrade version number */
     540           0 :     msg = ldb_msg_new(tmp_ctx);
     541           0 :     if (!msg) {
     542           0 :         ret = ENOMEM;
     543           0 :         goto done;
     544             :     }
     545           0 :     msg->dn = ldb_dn_new(tmp_ctx, ldb, SYSDB_BASE);
     546           0 :     if (!msg->dn) {
     547           0 :         ret = ENOMEM;
     548           0 :         goto done;
     549             :     }
     550             : 
     551           0 :     ret = ldb_msg_add_empty(msg, "version", LDB_FLAG_MOD_REPLACE, NULL);
     552           0 :     if (ret != LDB_SUCCESS) {
     553           0 :         ret = ENOMEM;
     554           0 :         goto done;
     555             :     }
     556           0 :     ret = ldb_msg_add_string(msg, "version", SYSDB_VERSION_0_3);
     557           0 :     if (ret != LDB_SUCCESS) {
     558           0 :         ret = ENOMEM;
     559           0 :         goto done;
     560             :     }
     561             : 
     562           0 :     ret = ldb_modify(ldb, msg);
     563           0 :     if (ret != LDB_SUCCESS) {
     564           0 :         ret = sysdb_error_to_errno(ret);
     565           0 :         goto done;
     566             :     }
     567             : 
     568           0 :     ret = ldb_transaction_commit(ldb);
     569           0 :     if (ret != LDB_SUCCESS) {
     570           0 :         DEBUG(SSSDBG_CRIT_FAILURE,
     571             :               "Failed to commit ldb transaction! (%d)\n", ret);
     572           0 :         ret = EIO;
     573           0 :         goto exit;
     574             :     }
     575             : 
     576           0 :     ret = EOK;
     577             : 
     578             : done:
     579           0 :     if (ret != EOK) {
     580           0 :         if (ctx_trans) {
     581           0 :             ret = ldb_transaction_cancel(sysdb->ldb);
     582           0 :             if (ret != LDB_SUCCESS) {
     583           0 :                 DEBUG(SSSDBG_CRIT_FAILURE,
     584             :                       "Failed to cancel ldb transaction! (%d)\n", ret);
     585             :             }
     586             :         }
     587           0 :         ret = ldb_transaction_cancel(ldb);
     588           0 :         if (ret != LDB_SUCCESS) {
     589           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
     590             :                   "Failed to cancel ldb transaction! (%d)\n", ret);
     591             :         }
     592             :     }
     593             : 
     594             : exit:
     595           0 :     talloc_free(tmp_ctx);
     596           0 :     return ret;
     597             : }
     598             : 
     599           0 : int sysdb_upgrade_03(struct sysdb_ctx *sysdb, const char **ver)
     600             : {
     601             :     TALLOC_CTX *tmp_ctx;
     602             :     int ret;
     603             :     struct ldb_message *msg;
     604             :     struct upgrade_ctx *ctx;
     605             : 
     606           0 :     tmp_ctx = talloc_new(NULL);
     607           0 :     if (!tmp_ctx) {
     608           0 :         return ENOMEM;
     609             :     }
     610             : 
     611           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_4, &ctx);
     612           0 :     if (ret) {
     613           0 :         return ret;
     614             :     }
     615             : 
     616             :     /* Make this database case-sensitive */
     617           0 :     msg = ldb_msg_new(tmp_ctx);
     618           0 :     if (!msg) {
     619           0 :         ret = ENOMEM;
     620           0 :         goto done;
     621             :     }
     622           0 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES");
     623           0 :     if (!msg->dn) {
     624           0 :         ret = ENOMEM;
     625           0 :         goto done;
     626             :     }
     627             : 
     628           0 :     ret = ldb_msg_add_empty(msg, "name", LDB_FLAG_MOD_DELETE, NULL);
     629           0 :     if (ret != LDB_SUCCESS) {
     630           0 :         ret = ENOMEM;
     631           0 :         goto done;
     632             :     }
     633             : 
     634           0 :     ret = ldb_modify(sysdb->ldb, msg);
     635           0 :     if (ret != LDB_SUCCESS) {
     636           0 :         ret = sysdb_error_to_errno(ret);
     637           0 :         goto done;
     638             :     }
     639             : 
     640             :     /* conversion done, update version number */
     641           0 :     ret = update_version(ctx);
     642             : 
     643             : done:
     644           0 :     ret = finish_upgrade(ret, &ctx, ver);
     645           0 :     talloc_free(tmp_ctx);
     646           0 :     return ret;
     647             : }
     648             : 
     649           0 : int sysdb_upgrade_04(struct sysdb_ctx *sysdb, const char **ver)
     650             : {
     651             :     TALLOC_CTX *tmp_ctx;
     652             :     int ret;
     653             :     struct ldb_message *msg;
     654             :     struct upgrade_ctx *ctx;
     655             : 
     656           0 :     tmp_ctx = talloc_new(NULL);
     657           0 :     if (!tmp_ctx) {
     658           0 :         return ENOMEM;
     659             :     }
     660             : 
     661           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_5, &ctx);
     662           0 :     if (ret) {
     663           0 :         return ret;
     664             :     }
     665             : 
     666             :     /* Add new index */
     667           0 :     msg = ldb_msg_new(tmp_ctx);
     668           0 :     if (!msg) {
     669           0 :         ret = ENOMEM;
     670           0 :         goto done;
     671             :     }
     672           0 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
     673           0 :     if (!msg->dn) {
     674           0 :         ret = ENOMEM;
     675           0 :         goto done;
     676             :     }
     677             : 
     678           0 :     ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
     679           0 :     if (ret != LDB_SUCCESS) {
     680           0 :         ret = ENOMEM;
     681           0 :         goto done;
     682             :     }
     683           0 :     ret = ldb_msg_add_string(msg, "@IDXATTR", "originalDN");
     684           0 :     if (ret != LDB_SUCCESS) {
     685           0 :         ret = ENOMEM;
     686           0 :         goto done;
     687             :     }
     688             : 
     689           0 :     ret = ldb_modify(sysdb->ldb, msg);
     690           0 :     if (ret != LDB_SUCCESS) {
     691           0 :         ret = sysdb_error_to_errno(ret);
     692           0 :         goto done;
     693             :     }
     694             : 
     695             :     /* Rebuild memberuid and memberoif attributes */
     696           0 :     msg = ldb_msg_new(tmp_ctx);
     697           0 :     if (!msg) {
     698           0 :         ret = ENOMEM;
     699           0 :         goto done;
     700             :     }
     701           0 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@MEMBEROF-REBUILD");
     702           0 :     if (!msg->dn) {
     703           0 :         ret = ENOMEM;
     704           0 :         goto done;
     705             :     }
     706             : 
     707           0 :     ret = ldb_add(sysdb->ldb, msg);
     708           0 :     if (ret != LDB_SUCCESS) {
     709           0 :         ret = sysdb_error_to_errno(ret);
     710           0 :         goto done;
     711             :     }
     712             : 
     713             :     /* conversion done, update version number */
     714           0 :     ret = update_version(ctx);
     715             : 
     716             : done:
     717           0 :     ret = finish_upgrade(ret, &ctx, ver);
     718           0 :     talloc_free(tmp_ctx);
     719           0 :     return ret;
     720             : }
     721             : 
     722           0 : int sysdb_upgrade_05(struct sysdb_ctx *sysdb, const char **ver)
     723             : {
     724             :     TALLOC_CTX *tmp_ctx;
     725             :     int ret;
     726             :     struct ldb_message *msg;
     727             :     struct upgrade_ctx *ctx;
     728             : 
     729           0 :     tmp_ctx = talloc_new(NULL);
     730           0 :     if (!tmp_ctx) {
     731           0 :         return ENOMEM;
     732             :     }
     733             : 
     734           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_6, &ctx);
     735           0 :     if (ret) {
     736           0 :         return ret;
     737             :     }
     738             : 
     739             :     /* Add new indexes */
     740           0 :     msg = ldb_msg_new(tmp_ctx);
     741           0 :     if (!msg) {
     742           0 :         ret = ENOMEM;
     743           0 :         goto done;
     744             :     }
     745           0 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
     746           0 :     if (!msg->dn) {
     747           0 :         ret = ENOMEM;
     748           0 :         goto done;
     749             :     }
     750             : 
     751             :     /* Add Index for dataExpireTimestamp */
     752           0 :     ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
     753           0 :     if (ret != LDB_SUCCESS) {
     754           0 :         ret = ENOMEM;
     755           0 :         goto done;
     756             :     }
     757           0 :     ret = ldb_msg_add_string(msg, "@IDXATTR", "dataExpireTimestamp");
     758           0 :     if (ret != LDB_SUCCESS) {
     759           0 :         ret = ENOMEM;
     760           0 :         goto done;
     761             :     }
     762             : 
     763             :     /* Add index to speed up ONELEVEL searches */
     764           0 :     ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_ADD, NULL);
     765           0 :     if (ret != LDB_SUCCESS) {
     766           0 :         ret = ENOMEM;
     767           0 :         goto done;
     768             :     }
     769           0 :     ret = ldb_msg_add_string(msg, "@IDXONE", "1");
     770           0 :     if (ret != LDB_SUCCESS) {
     771           0 :         ret = ENOMEM;
     772           0 :         goto done;
     773             :     }
     774             : 
     775           0 :     ret = ldb_modify(sysdb->ldb, msg);
     776           0 :     if (ret != LDB_SUCCESS) {
     777           0 :         ret = sysdb_error_to_errno(ret);
     778           0 :         goto done;
     779             :     }
     780             : 
     781             :     /* conversion done, update version number */
     782           0 :     ret = update_version(ctx);
     783             : 
     784             : done:
     785           0 :     ret = finish_upgrade(ret, &ctx, ver);
     786           0 :     talloc_free(tmp_ctx);
     787           0 :     return ret;
     788             : }
     789             : 
     790           0 : int sysdb_upgrade_06(struct sysdb_ctx *sysdb, const char **ver)
     791             : {
     792             :     TALLOC_CTX *tmp_ctx;
     793             :     int ret;
     794             :     struct ldb_message *msg;
     795             :     struct upgrade_ctx *ctx;
     796             : 
     797           0 :     tmp_ctx = talloc_new(NULL);
     798           0 :     if (!tmp_ctx) {
     799           0 :         return ENOMEM;
     800             :     }
     801             : 
     802           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_7, &ctx);
     803           0 :     if (ret) {
     804           0 :         return ret;
     805             :     }
     806             : 
     807             :     /* Add new indexes */
     808           0 :     msg = ldb_msg_new(tmp_ctx);
     809           0 :     if (!msg) {
     810           0 :         ret = ENOMEM;
     811           0 :         goto done;
     812             :     }
     813           0 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES");
     814           0 :     if (!msg->dn) {
     815           0 :         ret = ENOMEM;
     816           0 :         goto done;
     817             :     }
     818             : 
     819             :     /* Case insensitive search for originalDN */
     820           0 :     ret = ldb_msg_add_empty(msg, SYSDB_ORIG_DN, LDB_FLAG_MOD_ADD, NULL);
     821           0 :     if (ret != LDB_SUCCESS) {
     822           0 :         ret = ENOMEM;
     823           0 :         goto done;
     824             :     }
     825           0 :     ret = ldb_msg_add_string(msg, SYSDB_ORIG_DN, "CASE_INSENSITIVE");
     826           0 :     if (ret != LDB_SUCCESS) {
     827           0 :         ret = ENOMEM;
     828           0 :         goto done;
     829             :     }
     830             : 
     831           0 :     ret = ldb_modify(sysdb->ldb, msg);
     832           0 :     if (ret != LDB_SUCCESS) {
     833           0 :         ret = sysdb_error_to_errno(ret);
     834           0 :         goto done;
     835             :     }
     836             : 
     837             :     /* conversion done, update version number */
     838           0 :     ret = update_version(ctx);
     839             : 
     840             : done:
     841           0 :     ret = finish_upgrade(ret, &ctx, ver);
     842           0 :     talloc_free(tmp_ctx);
     843           0 :     return ret;
     844             : }
     845             : 
     846           0 : int sysdb_upgrade_07(struct sysdb_ctx *sysdb, const char **ver)
     847             : {
     848             :     TALLOC_CTX *tmp_ctx;
     849             :     int ret;
     850             :     struct ldb_message *msg;
     851             :     struct upgrade_ctx *ctx;
     852             : 
     853           0 :     tmp_ctx = talloc_new(NULL);
     854           0 :     if (!tmp_ctx) {
     855           0 :         return ENOMEM;
     856             :     }
     857             : 
     858           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_8, &ctx);
     859           0 :     if (ret) {
     860           0 :         return ret;
     861             :     }
     862             : 
     863             :     /* Add new indexes */
     864           0 :     msg = ldb_msg_new(tmp_ctx);
     865           0 :     if (!msg) {
     866           0 :         ret = ENOMEM;
     867           0 :         goto done;
     868             :     }
     869           0 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
     870           0 :     if (!msg->dn) {
     871           0 :         ret = ENOMEM;
     872           0 :         goto done;
     873             :     }
     874             : 
     875             :     /* Add Index for nameAlias */
     876           0 :     ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
     877           0 :     if (ret != LDB_SUCCESS) {
     878           0 :         ret = ENOMEM;
     879           0 :         goto done;
     880             :     }
     881           0 :     ret = ldb_msg_add_string(msg, "@IDXATTR", "nameAlias");
     882           0 :     if (ret != LDB_SUCCESS) {
     883           0 :         ret = ENOMEM;
     884           0 :         goto done;
     885             :     }
     886             : 
     887           0 :     ret = ldb_modify(sysdb->ldb, msg);
     888           0 :     if (ret != LDB_SUCCESS) {
     889           0 :         ret = sysdb_error_to_errno(ret);
     890           0 :         goto done;
     891             :     }
     892             : 
     893             :     /* conversion done, update version number */
     894           0 :     ret = update_version(ctx);
     895             : 
     896             : done:
     897           0 :     ret = finish_upgrade(ret, &ctx, ver);
     898           0 :     talloc_free(tmp_ctx);
     899           0 :     return ret;
     900             : }
     901             : 
     902           0 : int sysdb_upgrade_08(struct sysdb_ctx *sysdb, const char **ver)
     903             : {
     904             :     TALLOC_CTX *tmp_ctx;
     905             :     int ret;
     906             :     struct ldb_message *msg;
     907             :     struct upgrade_ctx *ctx;
     908             : 
     909           0 :     tmp_ctx = talloc_new(NULL);
     910           0 :     if (!tmp_ctx) {
     911           0 :         return ENOMEM;
     912             :     }
     913             : 
     914           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_9, &ctx);
     915           0 :     if (ret) {
     916           0 :         return ret;
     917             :     }
     918             : 
     919             :     /* Add new indexes */
     920           0 :     msg = ldb_msg_new(tmp_ctx);
     921           0 :     if (!msg) {
     922           0 :         ret = ENOMEM;
     923           0 :         goto done;
     924             :     }
     925           0 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
     926           0 :     if (!msg->dn) {
     927           0 :         ret = ENOMEM;
     928           0 :         goto done;
     929             :     }
     930             : 
     931             :     /* Add Index for servicePort and serviceProtocol */
     932           0 :     ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
     933           0 :     if (ret != LDB_SUCCESS) {
     934           0 :         ret = ENOMEM;
     935           0 :         goto done;
     936             :     }
     937           0 :     ret = ldb_msg_add_string(msg, "@IDXATTR", "servicePort");
     938           0 :     if (ret != LDB_SUCCESS) {
     939           0 :         ret = ENOMEM;
     940           0 :         goto done;
     941             :     }
     942             : 
     943           0 :     ret = ldb_msg_add_string(msg, "@IDXATTR", "serviceProtocol");
     944           0 :     if (ret != LDB_SUCCESS) {
     945           0 :         ret = ENOMEM;
     946           0 :         goto done;
     947             :     }
     948             : 
     949           0 :     ret = ldb_modify(sysdb->ldb, msg);
     950           0 :     if (ret != LDB_SUCCESS) {
     951           0 :         ret = sysdb_error_to_errno(ret);
     952           0 :         goto done;
     953             :     }
     954             : 
     955             :     /* conversion done, update version number */
     956           0 :     ret = update_version(ctx);
     957             : 
     958             : done:
     959           0 :     ret = finish_upgrade(ret, &ctx, ver);
     960           0 :     talloc_free(tmp_ctx);
     961           0 :     return ret;
     962             : }
     963             : 
     964           0 : int sysdb_upgrade_09(struct sysdb_ctx *sysdb, const char **ver)
     965             : {
     966             :     TALLOC_CTX *tmp_ctx;
     967             :     int ret;
     968             :     struct ldb_message *msg;
     969             :     struct upgrade_ctx *ctx;
     970             : 
     971           0 :     tmp_ctx = talloc_new(NULL);
     972           0 :     if (!tmp_ctx) {
     973           0 :         return ENOMEM;
     974             :     }
     975             : 
     976           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_10, &ctx);
     977           0 :     if (ret) {
     978           0 :         return ret;
     979             :     }
     980             : 
     981             :     /* Add new indexes */
     982           0 :     msg = ldb_msg_new(tmp_ctx);
     983           0 :     if (!msg) {
     984           0 :         ret = ENOMEM;
     985           0 :         goto done;
     986             :     }
     987           0 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
     988           0 :     if (!msg->dn) {
     989           0 :         ret = ENOMEM;
     990           0 :         goto done;
     991             :     }
     992             : 
     993             :     /* Add Index for servicePort and serviceProtocol */
     994           0 :     ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
     995           0 :     if (ret != LDB_SUCCESS) {
     996           0 :         ret = ENOMEM;
     997           0 :         goto done;
     998             :     }
     999             : 
    1000           0 :     ret = ldb_msg_add_string(msg, "@IDXATTR", "sudoUser");
    1001           0 :     if (ret != LDB_SUCCESS) {
    1002           0 :         ret = ENOMEM;
    1003           0 :         goto done;
    1004             :     }
    1005             : 
    1006           0 :     ret = ldb_modify(sysdb->ldb, msg);
    1007           0 :     if (ret != LDB_SUCCESS) {
    1008           0 :         ret = sysdb_error_to_errno(ret);
    1009           0 :         goto done;
    1010             :     }
    1011             : 
    1012             :     /* conversion done, update version number */
    1013           0 :     ret = update_version(ctx);
    1014             : 
    1015             : done:
    1016           0 :     ret = finish_upgrade(ret, &ctx, ver);
    1017           0 :     talloc_free(tmp_ctx);
    1018           0 :     return ret;
    1019             : }
    1020             : 
    1021           0 : int sysdb_upgrade_10(struct sysdb_ctx *sysdb, struct sss_domain_info *domain,
    1022             :                      const char **ver)
    1023             : {
    1024             : 
    1025             :     TALLOC_CTX *tmp_ctx;
    1026             :     int ret;
    1027             :     struct ldb_result *res;
    1028             :     struct ldb_message *msg;
    1029             :     struct ldb_message *user;
    1030             :     struct ldb_message_element *memberof_el;
    1031             :     const char *name;
    1032             :     struct ldb_dn *basedn;
    1033           0 :     const char *filter = "(&(objectClass=user)(!(uidNumber=*))(memberOf=*))";
    1034           0 :     const char *attrs[] = { "name", "memberof", NULL };
    1035             :     struct upgrade_ctx *ctx;
    1036             :     int i, j;
    1037             : 
    1038           0 :     tmp_ctx = talloc_new(NULL);
    1039           0 :     if (tmp_ctx == NULL) {
    1040           0 :         return ENOMEM;
    1041             :     }
    1042             : 
    1043           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_11, &ctx);
    1044           0 :     if (ret) {
    1045           0 :         return ret;
    1046             :     }
    1047             : 
    1048           0 :     basedn = sysdb_user_base_dn(tmp_ctx, domain);
    1049           0 :     if (basedn == NULL) {
    1050           0 :         ret = EIO;
    1051           0 :         goto done;
    1052             :     }
    1053             : 
    1054           0 :     ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE,
    1055             :                      attrs, "%s", filter);
    1056           0 :     if (ret != LDB_SUCCESS) {
    1057           0 :         ret = EIO;
    1058           0 :         goto done;
    1059             :     }
    1060             : 
    1061           0 :     for (i = 0; i < res->count; i++) {
    1062           0 :         user = res->msgs[i];
    1063           0 :         memberof_el = ldb_msg_find_element(user, "memberof");
    1064           0 :         name = ldb_msg_find_attr_as_string(user, "name", NULL);
    1065           0 :         if (name == NULL) {
    1066           0 :             ret = EIO;
    1067           0 :             goto done;
    1068             :         }
    1069             : 
    1070           0 :         DEBUG(SSSDBG_TRACE_LIBS, "User [%s] is a member of %d groups\n",
    1071             :               name, memberof_el->num_values);
    1072             : 
    1073           0 :         for (j = 0; j < memberof_el->num_values; j++) {
    1074           0 :             msg = ldb_msg_new(tmp_ctx);
    1075           0 :             if (msg == NULL) {
    1076           0 :                 ret = ENOMEM;
    1077           0 :                 goto done;
    1078             :             }
    1079             : 
    1080           0 :             msg->dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &memberof_el->values[j]);
    1081           0 :             if (msg->dn == NULL) {
    1082           0 :                 ret = ENOMEM;
    1083           0 :                 goto done;
    1084             :             }
    1085             : 
    1086           0 :             if (!ldb_dn_validate(msg->dn)) {
    1087           0 :                 DEBUG(SSSDBG_MINOR_FAILURE, "DN validation failed during "
    1088             :                                              "upgrade: [%s]\n",
    1089             :                                              memberof_el->values[j].data);
    1090           0 :                 talloc_zfree(msg);
    1091           0 :                 continue;
    1092             :             }
    1093             : 
    1094           0 :             ret = ldb_msg_add_empty(msg, "ghost", LDB_FLAG_MOD_ADD, NULL);
    1095           0 :             if (ret != LDB_SUCCESS) {
    1096           0 :                 ret = ENOMEM;
    1097           0 :                 goto done;
    1098             :             }
    1099           0 :             ret = ldb_msg_add_string(msg, "ghost", name);
    1100           0 :             if (ret != LDB_SUCCESS) {
    1101           0 :                 ret = ENOMEM;
    1102           0 :                 goto done;
    1103             :             }
    1104             : 
    1105           0 :             DEBUG(SSSDBG_TRACE_FUNC, "Adding ghost [%s] to entry [%s]\n",
    1106             :                   name, ldb_dn_get_linearized(msg->dn));
    1107             : 
    1108           0 :             ret = sss_ldb_modify_permissive(sysdb->ldb, msg);
    1109           0 :             talloc_zfree(msg);
    1110           0 :             if (ret == LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS) {
    1111             :                 /* If we failed adding the ghost user(s) because the values already
    1112             :                  * exist, they were probably propagated from a parent that was
    1113             :                  * upgraded before us. Mark the group as expired so that it is
    1114             :                  * refreshed on next request.
    1115             :                  */
    1116           0 :                 msg = ldb_msg_new(tmp_ctx);
    1117           0 :                 if (msg == NULL) {
    1118           0 :                     ret = ENOMEM;
    1119           0 :                     goto done;
    1120             :                 }
    1121             : 
    1122           0 :                 msg->dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb, &memberof_el->values[j]);
    1123           0 :                 if (msg->dn == NULL) {
    1124           0 :                     ret = ENOMEM;
    1125           0 :                     goto done;
    1126             :                 }
    1127             : 
    1128           0 :                 ret = ldb_msg_add_empty(msg, SYSDB_CACHE_EXPIRE,
    1129             :                                         LDB_FLAG_MOD_REPLACE, NULL);
    1130           0 :                 if (ret != LDB_SUCCESS) {
    1131           0 :                     goto done;
    1132             :                 }
    1133             : 
    1134           0 :                 ret = ldb_msg_add_string(msg, SYSDB_CACHE_EXPIRE, "1");
    1135           0 :                 if (ret != LDB_SUCCESS) {
    1136           0 :                     goto done;
    1137             :                 }
    1138             : 
    1139           0 :                 ret = sss_ldb_modify_permissive(sysdb->ldb, msg);
    1140           0 :                 talloc_zfree(msg);
    1141           0 :                 if (ret != LDB_SUCCESS) {
    1142           0 :                     goto done;
    1143             :                 }
    1144           0 :             } else if (ret != LDB_SUCCESS) {
    1145           0 :                 ret = sysdb_error_to_errno(ret);
    1146           0 :                 goto done;
    1147             :             }
    1148             :         }
    1149             : 
    1150           0 :         DEBUG(SSSDBG_TRACE_FUNC, "Removing fake user [%s]\n",
    1151             :               ldb_dn_get_linearized(user->dn));
    1152             : 
    1153           0 :         ret = ldb_delete(sysdb->ldb, user->dn);
    1154           0 :         if (ret != LDB_SUCCESS) {
    1155           0 :             ret = sysdb_error_to_errno(ret);
    1156           0 :             goto done;
    1157             :         }
    1158             :     }
    1159             : 
    1160             :     /* conversion done, update version number */
    1161           0 :     ret = update_version(ctx);
    1162             : 
    1163             : done:
    1164           0 :     ret = finish_upgrade(ret, &ctx, ver);
    1165           0 :     talloc_free(tmp_ctx);
    1166           0 :     return ret;
    1167             : }
    1168             : 
    1169           0 : int sysdb_upgrade_11(struct sysdb_ctx *sysdb, struct sss_domain_info *domain,
    1170             :                      const char **ver)
    1171             : {
    1172             :     TALLOC_CTX *tmp_ctx;
    1173             :     errno_t ret;
    1174             :     struct ldb_result *res;
    1175             :     struct ldb_message *entry;
    1176             :     const char *key;
    1177             :     const char *value;
    1178             :     struct ldb_message_element *memberof_el;
    1179             :     struct ldb_dn *memberof_dn;
    1180             :     struct ldb_dn *basedn;
    1181             :     const struct ldb_val *val;
    1182           0 :     const char *attrs[] = { SYSDB_AUTOFS_ENTRY_KEY,
    1183             :                             SYSDB_AUTOFS_ENTRY_VALUE,
    1184             :                             SYSDB_MEMBEROF,
    1185             :                             NULL };
    1186             :     struct upgrade_ctx *ctx;
    1187             :     size_t i, j;
    1188             : 
    1189           0 :     tmp_ctx = talloc_new(NULL);
    1190           0 :     if (!tmp_ctx) {
    1191           0 :         return ENOMEM;
    1192             :     }
    1193             : 
    1194           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_12, &ctx);
    1195           0 :     if (ret) {
    1196           0 :         return ret;
    1197             :     }
    1198             : 
    1199           0 :     basedn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb, SYSDB_TMPL_CUSTOM_SUBTREE,
    1200             :                             AUTOFS_ENTRY_SUBDIR, domain->name);
    1201           0 :     if (basedn == NULL) {
    1202           0 :         ret = ENOMEM;
    1203           0 :         goto done;
    1204             :     }
    1205             : 
    1206           0 :     ret = ldb_search(sysdb->ldb, tmp_ctx, &res, basedn, LDB_SCOPE_SUBTREE,
    1207             :                      attrs, "(objectClass=%s)", SYSDB_AUTOFS_ENTRY_OC);
    1208           0 :     if (ret != LDB_SUCCESS) {
    1209           0 :         ret = EIO;
    1210           0 :         goto done;
    1211             :     }
    1212             : 
    1213           0 :     DEBUG(SSSDBG_TRACE_LIBS, "Found %d autofs entries\n", res->count);
    1214             : 
    1215           0 :     for (i = 0; i < res->count; i++) {
    1216           0 :         entry = res->msgs[i];
    1217           0 :         key = ldb_msg_find_attr_as_string(entry,
    1218             :                                           SYSDB_AUTOFS_ENTRY_KEY, NULL);
    1219           0 :         value = ldb_msg_find_attr_as_string(entry,
    1220             :                                             SYSDB_AUTOFS_ENTRY_VALUE, NULL);
    1221           0 :         memberof_el = ldb_msg_find_element(entry, SYSDB_MEMBEROF);
    1222             : 
    1223           0 :         if (key && value && memberof_el) {
    1224           0 :             for (j = 0; j < memberof_el->num_values; j++) {
    1225           0 :                 memberof_dn = ldb_dn_from_ldb_val(tmp_ctx, sysdb->ldb,
    1226           0 :                                                   &(memberof_el->values[j]));
    1227           0 :                 if (!memberof_dn) {
    1228           0 :                     DEBUG(SSSDBG_OP_FAILURE, "Cannot convert memberof into DN, skipping\n");
    1229           0 :                     continue;
    1230             :                 }
    1231             : 
    1232           0 :                 val = ldb_dn_get_rdn_val(memberof_dn);
    1233           0 :                 if (!val) {
    1234           0 :                     DEBUG(SSSDBG_OP_FAILURE, "Cannot get map name from map DN\n");
    1235           0 :                     continue;
    1236             :                 }
    1237             : 
    1238           0 :                 ret = sysdb_save_autofsentry(domain,
    1239           0 :                                              (const char *) val->data,
    1240             :                                              key, value, NULL);
    1241           0 :                 if (ret != EOK) {
    1242           0 :                     DEBUG(SSSDBG_OP_FAILURE,
    1243             :                           "Cannot save autofs entry [%s]-[%s] into map %s\n",
    1244             :                            key, value, val->data);
    1245           0 :                     continue;
    1246             :                 }
    1247             :             }
    1248             : 
    1249             :         }
    1250             : 
    1251             :         /* Delete the old entry if it was either processed or incomplete */
    1252           0 :         DEBUG(SSSDBG_TRACE_LIBS, "Deleting [%s]\n",
    1253             :               ldb_dn_get_linearized(entry->dn));
    1254             : 
    1255           0 :         ret = ldb_delete(sysdb->ldb, entry->dn);
    1256           0 :         if (ret != EOK) {
    1257           0 :             DEBUG(SSSDBG_OP_FAILURE, "Cannot delete old autofs entry %s\n",
    1258             :                   ldb_dn_get_linearized(entry->dn));
    1259           0 :             continue;
    1260             :         }
    1261             :     }
    1262             : 
    1263             :     /* conversion done, update version number */
    1264           0 :     ret = update_version(ctx);
    1265             : 
    1266             : done:
    1267           0 :     ret = finish_upgrade(ret, &ctx, ver);
    1268           0 :     talloc_free(tmp_ctx);
    1269           0 :     return ret;
    1270             : }
    1271             : 
    1272           0 : int sysdb_upgrade_12(struct sysdb_ctx *sysdb, const char **ver)
    1273             : {
    1274             :     TALLOC_CTX *tmp_ctx;
    1275             :     int ret;
    1276             :     struct ldb_message *msg;
    1277             :     struct upgrade_ctx *ctx;
    1278             : 
    1279           0 :     tmp_ctx = talloc_new(NULL);
    1280           0 :     if (!tmp_ctx) {
    1281           0 :         return ENOMEM;
    1282             :     }
    1283             : 
    1284           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_13, &ctx);
    1285           0 :     if (ret) {
    1286           0 :         return ret;
    1287             :     }
    1288             : 
    1289             :     /* add new indexes */
    1290           0 :     msg = ldb_msg_new(tmp_ctx);
    1291           0 :     if (!msg) {
    1292           0 :         ret = ENOMEM;
    1293           0 :         goto done;
    1294             :     }
    1295           0 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@INDEXLIST");
    1296           0 :     if (!msg->dn) {
    1297           0 :         ret = ENOMEM;
    1298           0 :         goto done;
    1299             :     }
    1300             : 
    1301             :     /* add index for sshKnownHostsExpire */
    1302           0 :     ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
    1303           0 :     if (ret != LDB_SUCCESS) {
    1304           0 :         ret = ENOMEM;
    1305           0 :         goto done;
    1306             :     }
    1307             : 
    1308           0 :     ret = ldb_msg_add_string(msg, "@IDXATTR", "sshKnownHostsExpire");
    1309           0 :     if (ret != LDB_SUCCESS) {
    1310           0 :         ret = ENOMEM;
    1311           0 :         goto done;
    1312             :     }
    1313             : 
    1314           0 :     ret = ldb_modify(sysdb->ldb, msg);
    1315           0 :     if (ret != LDB_SUCCESS) {
    1316           0 :         ret = sysdb_error_to_errno(ret);
    1317           0 :         goto done;
    1318             :     }
    1319             : 
    1320             :     /* conversion done, update version number */
    1321           0 :     ret = update_version(ctx);
    1322             : 
    1323             : done:
    1324           0 :     ret = finish_upgrade(ret, &ctx, ver);
    1325           0 :     talloc_free(tmp_ctx);
    1326           0 :     return ret;
    1327             : }
    1328             : 
    1329           0 : int sysdb_upgrade_13(struct sysdb_ctx *sysdb, const char **ver)
    1330             : {
    1331             :     struct upgrade_ctx *ctx;
    1332             :     struct ldb_result *dom_res;
    1333             :     struct ldb_result *res;
    1334             :     struct ldb_dn *basedn;
    1335           0 :     const char *attrs[] = { "cn", "name", NULL };
    1336             :     const char *tmp_str;
    1337             :     errno_t ret;
    1338             :     int i, j, l, n;
    1339             : 
    1340           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_14, &ctx);
    1341           0 :     if (ret) {
    1342           0 :         return ret;
    1343             :     }
    1344             : 
    1345           0 :     basedn = ldb_dn_new(ctx, sysdb->ldb, SYSDB_BASE);
    1346           0 :     if (!basedn) {
    1347           0 :         DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n");
    1348           0 :         ret = EIO;
    1349           0 :         goto done;
    1350             :     }
    1351             : 
    1352           0 :     ret = ldb_search(sysdb->ldb, ctx, &dom_res,
    1353             :                      basedn, LDB_SCOPE_ONELEVEL,
    1354             :                      attrs, "objectclass=%s", SYSDB_SUBDOMAIN_CLASS);
    1355           0 :     if (ret != LDB_SUCCESS) {
    1356           0 :         DEBUG(SSSDBG_OP_FAILURE, "Failed to search subdomains\n");
    1357           0 :         ret = EIO;
    1358           0 :         goto done;
    1359             :     }
    1360             : 
    1361           0 :     for (i = 0; i < dom_res->count; i++) {
    1362             : 
    1363           0 :         tmp_str = ldb_msg_find_attr_as_string(dom_res->msgs[i], "cn", NULL);
    1364           0 :         if (tmp_str == NULL) {
    1365           0 :             DEBUG(SSSDBG_MINOR_FAILURE,
    1366             :                   "The object [%s] doesn't have a name\n",
    1367             :                    ldb_dn_get_linearized(dom_res->msgs[i]->dn));
    1368           0 :             continue;
    1369             :         }
    1370             : 
    1371           0 :         basedn = ldb_dn_new_fmt(ctx, sysdb->ldb, SYSDB_DOM_BASE, tmp_str);
    1372           0 :         if (!basedn) {
    1373           0 :             DEBUG(SSSDBG_OP_FAILURE,
    1374             :                   "Failed to build base dn for subdomain %s\n", tmp_str);
    1375           0 :             continue;
    1376             :         }
    1377             : 
    1378           0 :         ret = ldb_search(sysdb->ldb, ctx, &res,
    1379             :                          basedn, LDB_SCOPE_SUBTREE, attrs, NULL);
    1380           0 :         if (ret != LDB_SUCCESS) {
    1381           0 :             DEBUG(SSSDBG_OP_FAILURE,
    1382             :                   "Failed to search subdomain %s\n", tmp_str);
    1383           0 :             talloc_free(basedn);
    1384           0 :             continue;
    1385             :         }
    1386             : 
    1387           0 :         l = ldb_dn_get_comp_num(basedn);
    1388           0 :         for (j = 0; j < res->count; j++) {
    1389           0 :             n = ldb_dn_get_comp_num(res->msgs[j]->dn);
    1390           0 :             if (n <= l + 1) {
    1391             :                 /* Do not remove subdomain containers, only their contents */
    1392           0 :                 continue;
    1393             :             }
    1394           0 :             ret = ldb_delete(sysdb->ldb, res->msgs[j]->dn);
    1395           0 :             if (ret) {
    1396           0 :                 DEBUG(SSSDBG_OP_FAILURE,
    1397             :                       "Failed to delete %s\n",
    1398             :                        ldb_dn_get_linearized(res->msgs[j]->dn));
    1399           0 :                 continue;
    1400             :             }
    1401             :         }
    1402             : 
    1403           0 :         talloc_free(basedn);
    1404           0 :         talloc_free(res);
    1405             :     }
    1406             : 
    1407           0 :     talloc_free(dom_res);
    1408             : 
    1409             :     /* conversion done, update version number */
    1410           0 :     ret = update_version(ctx);
    1411             : 
    1412             : done:
    1413           0 :     ret = finish_upgrade(ret, &ctx, ver);
    1414           0 :     return ret;
    1415             : }
    1416             : 
    1417           0 : int sysdb_upgrade_14(struct sysdb_ctx *sysdb, const char **ver)
    1418             : {
    1419             :     struct upgrade_ctx *ctx;
    1420             :     struct ldb_message *msg;
    1421             :     struct ldb_result *res;
    1422             :     struct ldb_dn *basedn;
    1423             :     struct ldb_dn *newdn;
    1424           0 :     const char *attrs[] = { SYSDB_NAME, NULL };
    1425             :     const char *tmp_str;
    1426             :     errno_t ret;
    1427             :     int i;
    1428             : 
    1429           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_15, &ctx);
    1430           0 :     if (ret) {
    1431           0 :         return ret;
    1432             :     }
    1433             : 
    1434           0 :     basedn = ldb_dn_new(ctx, sysdb->ldb, SYSDB_BASE);
    1435           0 :     if (!basedn) {
    1436           0 :         DEBUG(SSSDBG_OP_FAILURE, "Failed to build base dn\n");
    1437           0 :         ret = EIO;
    1438           0 :         goto done;
    1439             :     }
    1440             : 
    1441             :     /* create base ranges container */
    1442           0 :     msg = ldb_msg_new(ctx);
    1443           0 :     if (!msg) {
    1444           0 :         ret = ENOMEM;
    1445           0 :         goto done;
    1446             :     }
    1447           0 :     msg->dn = ldb_dn_new(msg, sysdb->ldb, SYSDB_TMPL_RANGE_BASE);
    1448           0 :     if (!msg->dn) {
    1449           0 :         ret = ENOMEM;
    1450           0 :         goto done;
    1451             :     }
    1452           0 :     ret = ldb_msg_add_string(msg, "cn", "ranges");
    1453           0 :     if (ret != LDB_SUCCESS) {
    1454           0 :         ret = EIO;
    1455           0 :         goto done;
    1456             :     }
    1457             :     /* do a synchronous add */
    1458           0 :     ret = ldb_add(sysdb->ldb, msg);
    1459           0 :     if (ret != LDB_SUCCESS) {
    1460           0 :         DEBUG(SSSDBG_FATAL_FAILURE,
    1461             :               "Failed to upgrade DB (%d, [%s])!\n",
    1462             :                ret, ldb_errstring(sysdb->ldb));
    1463           0 :         ret = EIO;
    1464           0 :         goto done;
    1465             :     }
    1466           0 :     talloc_zfree(msg);
    1467             : 
    1468           0 :     ret = ldb_search(sysdb->ldb, ctx, &res,
    1469             :                      basedn, LDB_SCOPE_SUBTREE, attrs,
    1470             :                      "objectclass=%s", SYSDB_ID_RANGE_CLASS);
    1471           0 :     if (ret != LDB_SUCCESS) {
    1472           0 :         DEBUG(SSSDBG_OP_FAILURE, "Failed to search range objects\n");
    1473           0 :         ret = EIO;
    1474           0 :         goto done;
    1475             :     }
    1476             : 
    1477             :     /* Failure to convert any range is not fatal. As long as there are no
    1478             :      * left-over objects we can fail to move them around, as they will be
    1479             :      * recreated on the next online access */
    1480           0 :     for (i = 0; i < res->count; i++) {
    1481           0 :         tmp_str = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_NAME, NULL);
    1482           0 :         if (tmp_str == NULL) {
    1483           0 :             DEBUG(SSSDBG_OP_FAILURE,
    1484             :                   "The object [%s] doesn't have a name\n",
    1485             :                    ldb_dn_get_linearized(res->msgs[i]->dn));
    1486           0 :             ret = ldb_delete(sysdb->ldb, res->msgs[i]->dn);
    1487           0 :             if (ret) {
    1488           0 :                 DEBUG(SSSDBG_OP_FAILURE,
    1489             :                       "Failed to delete %s\n",
    1490             :                        ldb_dn_get_linearized(res->msgs[i]->dn));
    1491           0 :                 ret = EIO;
    1492           0 :                 goto done;
    1493             :             }
    1494           0 :             continue;
    1495             :         }
    1496             : 
    1497           0 :         newdn = ldb_dn_new_fmt(ctx, sysdb->ldb, SYSDB_TMPL_RANGE, tmp_str);
    1498           0 :         if (!newdn) {
    1499           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
    1500             :                   "Failed to create new DN to move [%s]\n",
    1501             :                    ldb_dn_get_linearized(res->msgs[i]->dn));
    1502           0 :             ret = ENOMEM;
    1503           0 :             goto done;
    1504             :         }
    1505           0 :         ret = ldb_rename(sysdb->ldb, res->msgs[i]->dn, newdn);
    1506           0 :         if (ret != LDB_SUCCESS) {
    1507           0 :             DEBUG(SSSDBG_CRIT_FAILURE,
    1508             :                   "Failed to move [%s] to [%s]\n",
    1509             :                    ldb_dn_get_linearized(res->msgs[i]->dn),
    1510             :                    ldb_dn_get_linearized(newdn));
    1511           0 :             ret = ldb_delete(sysdb->ldb, res->msgs[i]->dn);
    1512           0 :             if (ret) {
    1513           0 :                 DEBUG(SSSDBG_OP_FAILURE,
    1514             :                       "Failed to delete %s\n",
    1515             :                        ldb_dn_get_linearized(res->msgs[i]->dn));
    1516           0 :                 ret = EIO;
    1517           0 :                 goto done;
    1518             :             }
    1519             :         }
    1520           0 :         talloc_zfree(newdn);
    1521             :     }
    1522             : 
    1523             :     /* conversion done, update version number */
    1524           0 :     ret = update_version(ctx);
    1525             : 
    1526             : done:
    1527           0 :     ret = finish_upgrade(ret, &ctx, ver);
    1528           0 :     return ret;
    1529             : }
    1530             : 
    1531           0 : int sysdb_upgrade_15(struct sysdb_ctx *sysdb, const char **ver)
    1532             : {
    1533             :     TALLOC_CTX *tmp_ctx;
    1534             :     int ret;
    1535             :     struct ldb_message *msg;
    1536             :     struct upgrade_ctx *ctx;
    1537             : 
    1538           0 :     tmp_ctx = talloc_new(NULL);
    1539           0 :     if (!tmp_ctx) {
    1540           0 :         return ENOMEM;
    1541             :     }
    1542             : 
    1543           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_16, &ctx);
    1544           0 :     if (ret) {
    1545           0 :         return ret;
    1546             :     }
    1547             : 
    1548             :     /* Add new indexes */
    1549           0 :     msg = ldb_msg_new(tmp_ctx);
    1550           0 :     if (!msg) {
    1551           0 :         ret = ENOMEM;
    1552           0 :         goto done;
    1553             :     }
    1554           0 :     msg->dn = ldb_dn_new(tmp_ctx, sysdb->ldb, "@ATTRIBUTES");
    1555           0 :     if (!msg->dn) {
    1556           0 :         ret = ENOMEM;
    1557           0 :         goto done;
    1558             :     }
    1559             : 
    1560             :     /* Case insensitive search for canonicalUserPrincipalName */
    1561           0 :     ret = ldb_msg_add_empty(msg, SYSDB_CANONICAL_UPN, LDB_FLAG_MOD_ADD, NULL);
    1562           0 :     if (ret != LDB_SUCCESS) {
    1563           0 :         ret = ENOMEM;
    1564           0 :         goto done;
    1565             :     }
    1566           0 :     ret = ldb_msg_add_string(msg, SYSDB_CANONICAL_UPN, "CASE_INSENSITIVE");
    1567           0 :     if (ret != LDB_SUCCESS) {
    1568           0 :         ret = ENOMEM;
    1569           0 :         goto done;
    1570             :     }
    1571             : 
    1572           0 :     ret = ldb_modify(sysdb->ldb, msg);
    1573           0 :     if (ret != LDB_SUCCESS) {
    1574           0 :         ret = sysdb_error_to_errno(ret);
    1575           0 :         goto done;
    1576             :     }
    1577             : 
    1578             :     /* conversion done, update version number */
    1579           0 :     ret = update_version(ctx);
    1580             : 
    1581             : done:
    1582           0 :     ret = finish_upgrade(ret, &ctx, ver);
    1583           0 :     talloc_free(tmp_ctx);
    1584           0 :     return ret;
    1585             : }
    1586             : 
    1587           0 : int sysdb_upgrade_16(struct sysdb_ctx *sysdb, const char **ver)
    1588             : {
    1589             :     struct ldb_message *msg;
    1590             :     struct upgrade_ctx *ctx;
    1591             :     errno_t ret;
    1592             : 
    1593           0 :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_17, &ctx);
    1594           0 :     if (ret) {
    1595           0 :         return ret;
    1596             :     }
    1597             : 
    1598           0 :     msg = ldb_msg_new(ctx);
    1599           0 :     if (msg == NULL) {
    1600           0 :         ret = ENOMEM;
    1601           0 :         goto done;
    1602             :     }
    1603             : 
    1604           0 :     msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST");
    1605           0 :     if (msg->dn == NULL) {
    1606           0 :         ret = ENOMEM;
    1607           0 :         goto done;
    1608             :     }
    1609             : 
    1610             :     /* add index for objectSIDString */
    1611           0 :     ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL);
    1612           0 :     if (ret != LDB_SUCCESS) {
    1613           0 :         ret = ENOMEM;
    1614           0 :         goto done;
    1615             :     }
    1616             : 
    1617           0 :     ret = ldb_msg_add_string(msg, "@IDXATTR", "objectSIDString");
    1618           0 :     if (ret != LDB_SUCCESS) {
    1619           0 :         ret = ENOMEM;
    1620           0 :         goto done;
    1621             :     }
    1622             : 
    1623           0 :     ret = ldb_modify(sysdb->ldb, msg);
    1624           0 :     if (ret != LDB_SUCCESS) {
    1625           0 :         ret = sysdb_error_to_errno(ret);
    1626           0 :         goto done;
    1627             :     }
    1628             : 
    1629             :     /* conversion done, update version number */
    1630           0 :     ret = update_version(ctx);
    1631             : 
    1632             : done:
    1633           0 :     ret = finish_upgrade(ret, &ctx, ver);
    1634           0 :     return ret;
    1635             : }
    1636             : 
    1637             : /*
    1638             :  * Example template for future upgrades.
    1639             :  * Copy and change version numbers as appropriate.
    1640             :  */
    1641             : #if 0
    1642             : 
    1643             : int sysdb_upgrade_13(struct sysdb_ctx *sysdb, const char **ver)
    1644             : {
    1645             :     struct upgrade_ctx *ctx;
    1646             :     errno_t ret;
    1647             : 
    1648             :     ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_14, &ctx);
    1649             :     if (ret) {
    1650             :         return ret;
    1651             :     }
    1652             : 
    1653             :     /* DO STUFF HERE (use ctx, as the local temporary memory context) */
    1654             : 
    1655             :     /* conversion done, update version number */
    1656             :     ret = update_version(ctx);
    1657             : 
    1658             : done:
    1659             :     ret = finish_upgrade(ret, &ctx, ver);
    1660             :     return ret;
    1661             : }
    1662             : #endif

Generated by: LCOV version 1.10