LCOV - code coverage report
Current view: top level - source3/utils - net_registry.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 337 833 40.5 %
Date: 2024-04-21 15:09:00 Functions: 23 40 57.5 %

          Line data    Source code
       1             : /*
       2             :  * Samba Unix/Linux SMB client library
       3             :  * Distributed SMB/CIFS Server Management Utility
       4             :  * Local registry interface
       5             :  *
       6             :  * Copyright (C) Michael Adam 2008
       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 "includes.h"
      23             : #include "registry.h"
      24             : #include "registry/reg_api.h"
      25             : #include "registry/reg_util_token.h"
      26             : #include "registry/reg_init_basic.h"
      27             : #include "utils/net.h"
      28             : #include "utils/net_registry_util.h"
      29             : #include "include/g_lock.h"
      30             : #include "registry/reg_backend_db.h"
      31             : #include "registry/reg_import.h"
      32             : #include "registry/reg_format.h"
      33             : #include "registry/reg_api_util.h"
      34             : #include <assert.h>
      35             : #include "../libcli/security/display_sec.h"
      36             : #include "../libcli/security/sddl.h"
      37             : #include "../libcli/registry/util_reg.h"
      38             : #include "passdb/machine_sid.h"
      39             : #include "net_registry_check.h"
      40             : #include "lib/util/util_tdb.h"
      41             : #include "lib/util/smb_strtox.h"
      42             : 
      43             : /*
      44             :  *
      45             :  * Helper functions
      46             :  *
      47             :  */
      48             : 
      49             : /**
      50             :  * split given path into hive and remaining path and open the hive key
      51             :  */
      52         350 : static WERROR open_hive(TALLOC_CTX *ctx, const char *path,
      53             :                         uint32_t desired_access,
      54             :                         struct registry_key **hive,
      55             :                         char **subkeyname)
      56             : {
      57           0 :         WERROR werr;
      58         350 :         struct security_token *token = NULL;
      59         350 :         char *hivename = NULL;
      60         350 :         char *tmp_subkeyname = NULL;
      61         350 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
      62             : 
      63         350 :         if ((hive == NULL) || (subkeyname == NULL)) {
      64           0 :                 werr = WERR_INVALID_PARAMETER;
      65           0 :                 goto done;
      66             :         }
      67             : 
      68         350 :         werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
      69         350 :         if (!W_ERROR_IS_OK(werr)) {
      70           0 :                 goto done;
      71             :         }
      72         350 :         *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
      73         350 :         if (*subkeyname == NULL) {
      74           0 :                 werr = WERR_NOT_ENOUGH_MEMORY;
      75           0 :                 goto done;
      76             :         }
      77             : 
      78         350 :         werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
      79         350 :         if (!W_ERROR_IS_OK(werr)) {
      80           0 :                 goto done;
      81             :         }
      82             : 
      83         350 :         werr = reg_openhive(ctx, hivename, desired_access, token, hive);
      84         350 :         if (!W_ERROR_IS_OK(werr)) {
      85           2 :                 goto done;
      86             :         }
      87             : 
      88         348 :         werr = WERR_OK;
      89             : 
      90         350 : done:
      91         350 :         TALLOC_FREE(tmp_ctx);
      92         350 :         return werr;
      93             : }
      94             : 
      95          34 : static WERROR open_key(TALLOC_CTX *ctx, const char *path,
      96             :                        uint32_t desired_access,
      97             :                        struct registry_key **key)
      98             : {
      99           0 :         WERROR werr;
     100          34 :         char *subkey_name = NULL;
     101          34 :         struct registry_key *hive = NULL;
     102          34 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     103             : 
     104          34 :         if ((path == NULL) || (key == NULL)) {
     105           0 :                 return WERR_INVALID_PARAMETER;
     106             :         }
     107             : 
     108          34 :         werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name);
     109          34 :         if (!W_ERROR_IS_OK(werr)) {
     110           0 :                 d_fprintf(stderr, _("open_hive failed: %s\n"),
     111             :                           win_errstr(werr));
     112           0 :                 goto done;
     113             :         }
     114             : 
     115          34 :         werr = reg_openkey(ctx, hive, subkey_name, desired_access, key);
     116          34 :         if (!W_ERROR_IS_OK(werr)) {
     117           0 :                 d_fprintf(stderr, _("reg_openkey failed: %s\n"),
     118             :                           win_errstr(werr));
     119           0 :                 goto done;
     120             :         }
     121             : 
     122          34 :         werr = WERR_OK;
     123             : 
     124          34 : done:
     125          34 :         TALLOC_FREE(tmp_ctx);
     126          34 :         return werr;
     127             : }
     128             : 
     129          52 : static WERROR registry_enumkey(struct registry_key *parent, const char *keyname,
     130             :                                bool recursive)
     131             : {
     132           0 :         WERROR werr;
     133          52 :         TALLOC_CTX *ctx = talloc_stackframe();
     134           0 :         char *subkey_name;
     135           0 :         NTTIME modtime;
     136           0 :         uint32_t count;
     137          52 :         char *valname = NULL;
     138          52 :         struct registry_value *valvalue = NULL;
     139          52 :         struct registry_key *key = NULL;
     140             : 
     141          52 :         werr = reg_openkey(ctx, parent, keyname, REG_KEY_READ, &key);
     142          52 :         if (!W_ERROR_IS_OK(werr)) {
     143           8 :                 goto done;
     144             :         }
     145             : 
     146          44 :         if (recursive) {
     147           0 :                 printf("[%s]\n\n", key->key->name);
     148             :         } else {
     149          44 :                 for (count = 0;
     150         114 :                      werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
     151         114 :                      W_ERROR_IS_OK(werr);
     152          70 :                      count++)
     153             :                 {
     154          70 :                         print_registry_key(subkey_name, &modtime);
     155             :                 }
     156          44 :                 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
     157           0 :                         goto done;
     158             :                 }
     159             :         }
     160             : 
     161          44 :         for (count = 0;
     162          48 :              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
     163          48 :              W_ERROR_IS_OK(werr);
     164           4 :              count++)
     165             :         {
     166           4 :                 print_registry_value_with_name(valname, valvalue);
     167             :         }
     168          44 :         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
     169           0 :                 goto done;
     170             :         }
     171             : 
     172          44 :         if (!recursive) {
     173          44 :                 werr = WERR_OK;
     174          44 :                 goto done;
     175             :         }
     176             : 
     177           0 :         for (count = 0;
     178           0 :              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
     179           0 :              W_ERROR_IS_OK(werr);
     180           0 :              count++)
     181             :         {
     182           0 :                 werr = registry_enumkey(key, subkey_name, recursive);
     183           0 :                 if (!W_ERROR_IS_OK(werr)) {
     184           0 :                         goto done;
     185             :                 }
     186             :         }
     187           0 :         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
     188           0 :                 goto done;
     189             :         }
     190             : 
     191           0 :         werr = WERR_OK;
     192             : 
     193          52 : done:
     194          52 :         TALLOC_FREE(ctx);
     195          52 :         return werr;
     196             : }
     197             : 
     198             : 
     199             : 
     200             : /*
     201             :  *
     202             :  * the main "net registry" function implementations
     203             :  *
     204             :  */
     205          56 : static int net_registry_enumerate(struct net_context *c, int argc,
     206             :                                   const char **argv)
     207             : {
     208           0 :         WERROR werr;
     209          56 :         struct registry_key *key = NULL;
     210          56 :         char *name = NULL;
     211          56 :         TALLOC_CTX *ctx = talloc_stackframe();
     212          56 :         int ret = -1;
     213             : 
     214          56 :         if (argc != 1 || c->display_usage) {
     215           2 :                 d_printf("%s\n%s",
     216             :                          _("Usage:"),
     217             :                          _("net registry enumerate <path>\n"));
     218           2 :                 d_printf("%s\n%s",
     219             :                          _("Example:"),
     220             :                          _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
     221           2 :                 goto done;
     222             :         }
     223             : 
     224          54 :         werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
     225          54 :         if (!W_ERROR_IS_OK(werr)) {
     226           2 :                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
     227           2 :                 goto done;
     228             :         }
     229             : 
     230          52 :         werr = registry_enumkey(key, name, c->opt_reboot);
     231          52 :         if (W_ERROR_IS_OK(werr)) {
     232          44 :                 ret = 0;
     233             :         }
     234           8 : done:
     235          56 :         TALLOC_FREE(ctx);
     236          56 :         return ret;
     237             : }
     238             : 
     239           0 : static int net_registry_enumerate_recursive(struct net_context *c, int argc,
     240             :                                             const char **argv)
     241             : {
     242           0 :         WERROR werr;
     243           0 :         struct registry_key *key = NULL;
     244           0 :         char *name = NULL;
     245           0 :         TALLOC_CTX *ctx = talloc_stackframe();
     246           0 :         int ret = -1;
     247             : 
     248           0 :         if (argc != 1 || c->display_usage) {
     249           0 :                 d_printf("%s\n%s",
     250             :                          _("Usage:"),
     251             :                          _("net registry enumerate <path>\n"));
     252           0 :                 d_printf("%s\n%s",
     253             :                          _("Example:"),
     254             :                          _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
     255           0 :                 goto done;
     256             :         }
     257             : 
     258           0 :         werr = open_hive(ctx, argv[0], REG_KEY_READ, &key, &name);
     259           0 :         if (!W_ERROR_IS_OK(werr)) {
     260           0 :                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
     261           0 :                 goto done;
     262             :         }
     263             : 
     264           0 :         werr = registry_enumkey(key, name, true);
     265           0 :         if (W_ERROR_IS_OK(werr)) {
     266           0 :                 ret = 0;
     267             :         }
     268           0 : done:
     269           0 :         TALLOC_FREE(ctx);
     270           0 :         return ret;
     271             : }
     272             : 
     273             : 
     274          20 : static int net_registry_createkey(struct net_context *c, int argc,
     275             :                                   const char **argv)
     276             : {
     277           0 :         WERROR werr;
     278           0 :         enum winreg_CreateAction action;
     279          20 :         char *subkeyname = NULL;
     280          20 :         struct registry_key *hivekey = NULL;
     281          20 :         struct registry_key *subkey = NULL;
     282          20 :         TALLOC_CTX *ctx = talloc_stackframe();
     283          20 :         int ret = -1;
     284             : 
     285          20 :         if (argc != 1 || c->display_usage) {
     286           0 :                 d_printf("%s\n%s",
     287             :                          _("Usage:"),
     288             :                          _("net registry createkey <path>\n"));
     289           0 :                 d_printf("%s\n%s",
     290             :                          _("Example:"),
     291             :                          _("net registry createkey "
     292             :                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
     293           0 :                 goto done;
     294             :         }
     295          20 :         if (strlen(argv[0]) == 0) {
     296           0 :                 d_fprintf(stderr, _("error: zero length key name given\n"));
     297           0 :                 goto done;
     298             :         }
     299             : 
     300          20 :         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
     301          20 :         if (!W_ERROR_IS_OK(werr)) {
     302           0 :                 d_fprintf(stderr, _("open_hive failed: %s\n"),
     303             :                           win_errstr(werr));
     304           0 :                 goto done;
     305             :         }
     306             : 
     307          20 :         werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
     308             :                              &subkey, &action);
     309          20 :         if (!W_ERROR_IS_OK(werr)) {
     310           0 :                 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
     311             :                           win_errstr(werr));
     312           0 :                 goto done;
     313             :         }
     314          20 :         switch (action) {
     315           0 :                 case REG_ACTION_NONE:
     316           0 :                         d_printf(_("createkey did nothing -- huh?\n"));
     317           0 :                         break;
     318          10 :                 case REG_CREATED_NEW_KEY:
     319          10 :                         d_printf(_("createkey created %s\n"), argv[0]);
     320          10 :                         break;
     321          10 :                 case REG_OPENED_EXISTING_KEY:
     322          10 :                         d_printf(_("createkey opened existing %s\n"), argv[0]);
     323          10 :                         break;
     324             :         }
     325             : 
     326          20 :         ret = 0;
     327             : 
     328          20 : done:
     329          20 :         TALLOC_FREE(ctx);
     330          20 :         return ret;
     331             : }
     332             : 
     333          18 : static int net_registry_deletekey_internal(struct net_context *c, int argc,
     334             :                                            const char **argv,
     335             :                                            bool recursive)
     336             : {
     337           0 :         WERROR werr;
     338          18 :         char *subkeyname = NULL;
     339          18 :         struct registry_key *hivekey = NULL;
     340          18 :         TALLOC_CTX *ctx = talloc_stackframe();
     341          18 :         int ret = -1;
     342             : 
     343          18 :         if (argc != 1 || c->display_usage) {
     344           0 :                 d_printf("%s\n%s",
     345             :                          _("Usage:"),
     346             :                          _("net registry deletekey <path>\n"));
     347           0 :                 d_printf("%s\n%s",
     348             :                          _("Example:"),
     349             :                          _("net registry deletekey "
     350             :                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
     351           0 :                 goto done;
     352             :         }
     353          18 :         if (strlen(argv[0]) == 0) {
     354           0 :                 d_fprintf(stderr, _("error: zero length key name given\n"));
     355           0 :                 goto done;
     356             :         }
     357             : 
     358          18 :         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
     359          18 :         if (!W_ERROR_IS_OK(werr)) {
     360           0 :                 d_fprintf(stderr, "open_hive %s: %s\n", _("failed"),
     361             :                           win_errstr(werr));
     362           0 :                 goto done;
     363             :         }
     364             : 
     365          18 :         if (recursive) {
     366           0 :                 werr = reg_deletekey_recursive(hivekey, subkeyname);
     367             :         } else {
     368          18 :                 werr = reg_deletekey(hivekey, subkeyname);
     369             :         }
     370          18 :         if (!W_ERROR_IS_OK(werr) &&
     371           4 :             !(c->opt_force && W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)))
     372             :         {
     373           4 :                 d_fprintf(stderr, "reg_deletekey %s: %s\n", _("failed"),
     374             :                           win_errstr(werr));
     375           4 :                 goto done;
     376             :         }
     377             : 
     378          14 :         ret = 0;
     379             : 
     380          18 : done:
     381          18 :         TALLOC_FREE(ctx);
     382          18 :         return ret;
     383             : }
     384             : 
     385          18 : static int net_registry_deletekey(struct net_context *c, int argc,
     386             :                                   const char **argv)
     387             : {
     388          18 :         return net_registry_deletekey_internal(c, argc, argv, false);
     389             : }
     390             : 
     391           0 : static int net_registry_deletekey_recursive(struct net_context *c, int argc,
     392             :                                             const char **argv)
     393             : {
     394           0 :         return net_registry_deletekey_internal(c, argc, argv, true);
     395             : }
     396             : 
     397           6 : static int net_registry_getvalue_internal(struct net_context *c, int argc,
     398             :                                           const char **argv, bool raw)
     399             : {
     400           0 :         WERROR werr;
     401           6 :         int ret = -1;
     402           6 :         struct registry_key *key = NULL;
     403           6 :         struct registry_value *value = NULL;
     404           6 :         TALLOC_CTX *ctx = talloc_stackframe();
     405             : 
     406           6 :         if (argc != 2 || c->display_usage) {
     407           0 :                 d_fprintf(stderr, "%s\n%s",
     408             :                           _("Usage:"),
     409             :                           _("net registry getvalue <key> <valuename>\n"));
     410           0 :                 goto done;
     411             :         }
     412             : 
     413           6 :         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
     414           6 :         if (!W_ERROR_IS_OK(werr)) {
     415           0 :                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
     416           0 :                 goto done;
     417             :         }
     418             : 
     419           6 :         werr = reg_queryvalue(ctx, key, argv[1], &value);
     420           6 :         if (!W_ERROR_IS_OK(werr)) {
     421           0 :                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
     422             :                           win_errstr(werr));
     423           0 :                 goto done;
     424             :         }
     425             : 
     426           6 :         print_registry_value(value, raw);
     427             : 
     428           6 :         ret = 0;
     429             : 
     430           6 : done:
     431           6 :         TALLOC_FREE(ctx);
     432           6 :         return ret;
     433             : }
     434             : 
     435           0 : static int net_registry_getvalue(struct net_context *c, int argc,
     436             :                                  const char **argv)
     437             : {
     438           0 :         return net_registry_getvalue_internal(c, argc, argv, false);
     439             : }
     440             : 
     441           6 : static int net_registry_getvalueraw(struct net_context *c, int argc,
     442             :                                     const char **argv)
     443             : {
     444           6 :         return net_registry_getvalue_internal(c, argc, argv, true);
     445             : }
     446             : 
     447           0 : static int net_registry_getvaluesraw(struct net_context *c, int argc,
     448             :                                      const char **argv)
     449             : {
     450           0 :         WERROR werr;
     451           0 :         int ret = -1;
     452           0 :         struct registry_key *key = NULL;
     453           0 :         TALLOC_CTX *ctx = talloc_stackframe();
     454           0 :         uint32_t idx;
     455             : 
     456           0 :         if (argc != 1 || c->display_usage) {
     457           0 :                 d_fprintf(stderr, "usage: net rpc registry getvaluesraw "
     458             :                           "<key>\n");
     459           0 :                 goto done;
     460             :         }
     461             : 
     462           0 :         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
     463           0 :         if (!W_ERROR_IS_OK(werr)) {
     464           0 :                 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
     465           0 :                 goto done;
     466             :         }
     467             : 
     468           0 :         idx = 0;
     469           0 :         while (true) {
     470           0 :                 struct registry_value *val;
     471             : 
     472           0 :                 werr = reg_enumvalue(talloc_tos(), key, idx, NULL, &val);
     473             : 
     474           0 :                 if (W_ERROR_EQUAL(werr, WERR_NO_MORE_ITEMS)) {
     475           0 :                         ret = 0;
     476           0 :                         break;
     477             :                 }
     478           0 :                 if (!W_ERROR_IS_OK(werr)) {
     479           0 :                         break;
     480             :                 }
     481           0 :                 print_registry_value(val, true);
     482           0 :                 TALLOC_FREE(val);
     483           0 :                 idx += 1;
     484             :         }
     485           0 : done:
     486           0 :         TALLOC_FREE(ctx);
     487           0 :         return ret;
     488             : }
     489             : 
     490           8 : static int net_registry_setvalue(struct net_context *c, int argc,
     491             :                                  const char **argv)
     492             : {
     493           0 :         WERROR werr;
     494           0 :         struct registry_value value;
     495           8 :         struct registry_key *key = NULL;
     496           8 :         int ret = -1;
     497           8 :         TALLOC_CTX *ctx = talloc_stackframe();
     498             : 
     499           8 :         if (argc < 4 || c->display_usage) {
     500           0 :                 d_fprintf(stderr, "%s\n%s",
     501             :                           _("Usage:"),
     502             :                           _("net registry setvalue <key> <valuename> "
     503             :                             "<type> [<val>]+\n"));
     504           0 :                 goto done;
     505             :         }
     506             : 
     507           8 :         if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
     508           0 :                 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
     509           0 :                 goto done;
     510             :         }
     511             : 
     512           8 :         if (strequal(argv[2], "dword")) {
     513           2 :                 int error = 0;
     514           0 :                 uint32_t v;
     515             : 
     516           2 :                 v = smb_strtoul(argv[3], NULL, 10, &error, SMB_STR_STANDARD);
     517           2 :                 if (error != 0) {
     518           0 :                         goto done;
     519             :                 }
     520             : 
     521           2 :                 value.type = REG_DWORD;
     522           2 :                 value.data = data_blob_talloc(ctx, NULL, 4);
     523           2 :                 SIVAL(value.data.data, 0, v);
     524           6 :         } else if (strequal(argv[2], "sz")) {
     525           6 :                 value.type = REG_SZ;
     526           6 :                 if (!push_reg_sz(ctx, &value.data, argv[3])) {
     527           0 :                         goto done;
     528             :                 }
     529           0 :         } else if (strequal(argv[2], "multi_sz")) {
     530           0 :                 const char **array;
     531           0 :                 int count = argc - 3;
     532           0 :                 int i;
     533           0 :                 value.type = REG_MULTI_SZ;
     534           0 :                 array = talloc_zero_array(ctx, const char *, count + 1);
     535           0 :                 if (array == NULL) {
     536           0 :                         goto done;
     537             :                 }
     538           0 :                 for (i=0; i < count; i++) {
     539           0 :                         array[i] = talloc_strdup(array, argv[count+i]);
     540           0 :                         if (array[i] == NULL) {
     541           0 :                                 goto done;
     542             :                         }
     543             :                 }
     544           0 :                 if (!push_reg_multi_sz(ctx, &value.data, array)) {
     545           0 :                         goto done;
     546             :                 }
     547             :         } else {
     548           0 :                 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
     549           0 :                 goto done;
     550             :         }
     551             : 
     552           8 :         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
     553           8 :         if (!W_ERROR_IS_OK(werr)) {
     554           0 :                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
     555           0 :                 goto done;
     556             :         }
     557             : 
     558           8 :         werr = reg_setvalue(key, argv[1], &value);
     559           8 :         if (!W_ERROR_IS_OK(werr)) {
     560           0 :                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
     561             :                           win_errstr(werr));
     562           0 :                 goto done;
     563             :         }
     564             : 
     565           8 :         ret = 0;
     566             : 
     567           8 : done:
     568           8 :         TALLOC_FREE(ctx);
     569           8 :         return ret;
     570             : }
     571             : 
     572           0 : static int net_registry_increment(struct net_context *c, int argc,
     573             :                                   const char **argv)
     574             : {
     575           0 :         TDB_DATA lock_key = string_term_tdb_data("registry_increment_lock");
     576           0 :         struct g_lock_ctx *ctx = NULL;
     577           0 :         const char *keyname = NULL;
     578           0 :         struct registry_key *key = NULL;
     579           0 :         const char *valuename = NULL;
     580           0 :         struct registry_value *value = NULL;
     581           0 :         uint32_t v;
     582           0 :         uint32_t increment;
     583           0 :         uint32_t newvalue;
     584           0 :         NTSTATUS status;
     585           0 :         WERROR werr;
     586           0 :         int ret = -1;
     587             : 
     588           0 :         if (argc < 2 || c->display_usage) {
     589           0 :                 d_fprintf(stderr, "%s\n%s",
     590             :                           _("Usage:"),
     591             :                           _("net registry increment <key> <valuename> "
     592             :                             "[<increment>]\n"));
     593           0 :                 goto done;
     594             :         }
     595             : 
     596           0 :         keyname = argv[0];
     597           0 :         valuename = argv[1];
     598             : 
     599           0 :         increment = 1;
     600           0 :         if (argc == 3) {
     601           0 :                 int error = 0;
     602             : 
     603           0 :                 increment = smb_strtoul(
     604           0 :                         argv[2], NULL, 10, &error, SMB_STR_STANDARD);
     605           0 :                 if (error != 0) {
     606           0 :                         goto done;
     607             :                 }
     608             :         }
     609             : 
     610           0 :         ctx = g_lock_ctx_init(c, c->msg_ctx);
     611           0 :         if (ctx == NULL) {
     612           0 :                 d_fprintf(stderr, _("g_lock_ctx_init failed\n"));
     613           0 :                 goto done;
     614             :         }
     615             : 
     616           0 :         status = g_lock_lock(ctx,
     617             :                              lock_key,
     618             :                              G_LOCK_WRITE,
     619             :                              tevent_timeval_set(600, 0),
     620             :                              NULL,
     621             :                              NULL);
     622           0 :         if (!NT_STATUS_IS_OK(status)) {
     623           0 :                 d_fprintf(stderr, _("g_lock_lock failed: %s\n"),
     624             :                           nt_errstr(status));
     625           0 :                 goto done;
     626             :         }
     627             : 
     628           0 :         werr = open_key(c, keyname, REG_KEY_READ|REG_KEY_WRITE, &key);
     629           0 :         if (!W_ERROR_IS_OK(werr)) {
     630           0 :                 d_fprintf(stderr, _("open_key failed: %s\n"),
     631             :                           win_errstr(werr));
     632           0 :                 goto done;
     633             :         }
     634             : 
     635           0 :         werr = reg_queryvalue(key, key, valuename, &value);
     636           0 :         if (!W_ERROR_IS_OK(werr)) {
     637           0 :                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
     638             :                           win_errstr(werr));
     639           0 :                 goto done;
     640             :         }
     641             : 
     642           0 :         if (value->type != REG_DWORD) {
     643           0 :                 d_fprintf(stderr, _("value not a DWORD: %s\n"),
     644           0 :                           str_regtype(value->type));
     645           0 :                 goto done;
     646             :         }
     647             : 
     648           0 :         if (value->data.length < 4) {
     649           0 :                 d_fprintf(stderr, _("value too short for regular DWORD\n"));
     650           0 :                 goto done;
     651             :         }
     652             : 
     653           0 :         v = IVAL(value->data.data, 0);
     654           0 :         v += increment;
     655           0 :         newvalue = v;
     656             : 
     657           0 :         SIVAL(value->data.data, 0, v);
     658             : 
     659           0 :         werr = reg_setvalue(key, valuename, value);
     660           0 :         if (!W_ERROR_IS_OK(werr)) {
     661           0 :                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
     662             :                           win_errstr(werr));
     663           0 :                 goto done;
     664             :         }
     665             : 
     666           0 :         if (!W_ERROR_IS_OK(werr)) {
     667           0 :                 d_fprintf(stderr, _("increment failed: %s\n"),
     668             :                           win_errstr(werr));
     669           0 :                 goto done;
     670             :         }
     671             : 
     672           0 :         g_lock_unlock(ctx, lock_key);
     673             : 
     674           0 :         d_printf(_("%"PRIu32"\n"), newvalue);
     675             : 
     676           0 :         ret = 0;
     677             : 
     678           0 : done:
     679           0 :         TALLOC_FREE(value);
     680           0 :         TALLOC_FREE(key);
     681           0 :         TALLOC_FREE(ctx);
     682           0 :         return ret;
     683             : }
     684             : 
     685           8 : static int net_registry_deletevalue(struct net_context *c, int argc,
     686             :                                     const char **argv)
     687             : {
     688           0 :         WERROR werr;
     689           8 :         struct registry_key *key = NULL;
     690           8 :         TALLOC_CTX *ctx = talloc_stackframe();
     691           8 :         int ret = -1;
     692             : 
     693           8 :         if (argc != 2 || c->display_usage) {
     694           0 :                 d_fprintf(stderr, "%s\n%s",
     695             :                           _("Usage:"),
     696             :                           _("net registry deletevalue <key> <valuename>\n"));
     697           0 :                 goto done;
     698             :         }
     699             : 
     700           8 :         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
     701           8 :         if (!W_ERROR_IS_OK(werr)) {
     702           0 :                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
     703           0 :                 goto done;
     704             :         }
     705             : 
     706           8 :         werr = reg_deletevalue(key, argv[1]);
     707           8 :         if (!W_ERROR_IS_OK(werr)) {
     708           4 :                 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
     709             :                           win_errstr(werr));
     710           4 :                 goto done;
     711             :         }
     712             : 
     713           4 :         ret = 0;
     714             : 
     715           8 : done:
     716           8 :         TALLOC_FREE(ctx);
     717           8 :         return ret;
     718             : }
     719             : 
     720           2 : static WERROR net_registry_getsd_internal(struct net_context *c,
     721             :                                           TALLOC_CTX *mem_ctx,
     722             :                                           const char *keyname,
     723             :                                           struct security_descriptor **sd)
     724             : {
     725           0 :         WERROR werr;
     726           2 :         struct registry_key *key = NULL;
     727           2 :         TALLOC_CTX *ctx = talloc_stackframe();
     728           2 :         uint32_t access_mask = REG_KEY_READ |
     729             :                                SEC_FLAG_MAXIMUM_ALLOWED |
     730             :                                SEC_FLAG_SYSTEM_SECURITY;
     731             : 
     732             :         /*
     733             :          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
     734             :          * is denied with these perms right now...
     735             :          */
     736           2 :         access_mask = REG_KEY_READ;
     737             : 
     738           2 :         if (sd == NULL) {
     739           0 :                 d_fprintf(stderr, _("internal error: invalid argument\n"));
     740           0 :                 werr = WERR_INVALID_PARAMETER;
     741           0 :                 goto done;
     742             :         }
     743             : 
     744           2 :         if (strlen(keyname) == 0) {
     745           0 :                 d_fprintf(stderr, _("error: zero length key name given\n"));
     746           0 :                 werr = WERR_INVALID_PARAMETER;
     747           0 :                 goto done;
     748             :         }
     749             : 
     750           2 :         werr = open_key(ctx, keyname, access_mask, &key);
     751           2 :         if (!W_ERROR_IS_OK(werr)) {
     752           0 :                 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
     753             :                           win_errstr(werr));
     754           0 :                 goto done;
     755             :         }
     756             : 
     757           2 :         werr = reg_getkeysecurity(mem_ctx, key, sd);
     758           2 :         if (!W_ERROR_IS_OK(werr)) {
     759           0 :                 d_fprintf(stderr, "%s%s\n", _("reg_getkeysecurity failed: "),
     760             :                           win_errstr(werr));
     761           0 :                 goto done;
     762             :         }
     763             : 
     764           2 :         werr = WERR_OK;
     765             : 
     766           2 : done:
     767           2 :         TALLOC_FREE(ctx);
     768           2 :         return werr;
     769             : }
     770             : 
     771           2 : static int net_registry_getsd(struct net_context *c, int argc,
     772             :                               const char **argv)
     773             : {
     774           0 :         WERROR werr;
     775           2 :         int ret = -1;
     776           2 :         struct security_descriptor *secdesc = NULL;
     777           2 :         TALLOC_CTX *ctx = talloc_stackframe();
     778             : 
     779           2 :         if (argc != 1 || c->display_usage) {
     780           0 :                 d_printf("%s\n%s",
     781             :                          _("Usage:"),
     782             :                          _("net registry getsd <path>\n"));
     783           0 :                 d_printf("%s\n%s",
     784             :                          _("Example:"),
     785             :                          _("net registry getsd 'HKLM\\Software\\Samba'\n"));
     786           0 :                 goto done;
     787             :         }
     788             : 
     789           2 :         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
     790           2 :         if (!W_ERROR_IS_OK(werr)) {
     791           0 :                 goto done;
     792             :         }
     793             : 
     794           2 :         display_sec_desc(secdesc);
     795             : 
     796           2 :         ret = 0;
     797             : 
     798           2 : done:
     799           2 :         TALLOC_FREE(ctx);
     800           2 :         return ret;
     801             : }
     802             : 
     803           0 : static int net_registry_getsd_sddl(struct net_context *c,
     804             :                                    int argc, const char **argv)
     805             : {
     806           0 :         WERROR werr;
     807           0 :         int ret = -1;
     808           0 :         struct security_descriptor *secdesc = NULL;
     809           0 :         TALLOC_CTX *ctx = talloc_stackframe();
     810             : 
     811           0 :         if (argc != 1 || c->display_usage) {
     812           0 :                 d_printf("%s\n%s",
     813             :                          _("Usage:"),
     814             :                          _("net registry getsd_sddl <path>\n"));
     815           0 :                 d_printf("%s\n%s",
     816             :                          _("Example:"),
     817             :                          _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
     818           0 :                 goto done;
     819             :         }
     820             : 
     821           0 :         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
     822           0 :         if (!W_ERROR_IS_OK(werr)) {
     823           0 :                 goto done;
     824             :         }
     825             : 
     826           0 :         d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
     827             : 
     828           0 :         ret = 0;
     829             : 
     830           0 : done:
     831           0 :         TALLOC_FREE(ctx);
     832           0 :         return ret;
     833             : }
     834             : 
     835           0 : static WERROR net_registry_setsd_internal(struct net_context *c,
     836             :                                           TALLOC_CTX *mem_ctx,
     837             :                                           const char *keyname,
     838             :                                           struct security_descriptor *sd)
     839             : {
     840           0 :         WERROR werr;
     841           0 :         struct registry_key *key = NULL;
     842           0 :         TALLOC_CTX *ctx = talloc_stackframe();
     843           0 :         uint32_t access_mask = REG_KEY_WRITE |
     844             :                                SEC_FLAG_MAXIMUM_ALLOWED |
     845             :                                SEC_FLAG_SYSTEM_SECURITY;
     846             : 
     847             :         /*
     848             :          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
     849             :          * is denied with these perms right now...
     850             :          */
     851           0 :         access_mask = REG_KEY_WRITE;
     852             : 
     853           0 :         if (strlen(keyname) == 0) {
     854           0 :                 d_fprintf(stderr, _("error: zero length key name given\n"));
     855           0 :                 werr = WERR_INVALID_PARAMETER;
     856           0 :                 goto done;
     857             :         }
     858             : 
     859           0 :         werr = open_key(ctx, keyname, access_mask, &key);
     860           0 :         if (!W_ERROR_IS_OK(werr)) {
     861           0 :                 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
     862             :                           win_errstr(werr));
     863           0 :                 goto done;
     864             :         }
     865             : 
     866           0 :         werr = reg_setkeysecurity(key, sd);
     867           0 :         if (!W_ERROR_IS_OK(werr)) {
     868           0 :                 d_fprintf(stderr, "%s%s\n", _("reg_setkeysecurity failed: "),
     869             :                           win_errstr(werr));
     870           0 :                 goto done;
     871             :         }
     872             : 
     873           0 :         werr = WERR_OK;
     874             : 
     875           0 : done:
     876           0 :         TALLOC_FREE(ctx);
     877           0 :         return werr;
     878             : }
     879             : 
     880           0 : static int net_registry_setsd_sddl(struct net_context *c,
     881             :                                    int argc, const char **argv)
     882             : {
     883           0 :         WERROR werr;
     884           0 :         int ret = -1;
     885           0 :         struct security_descriptor *secdesc = NULL;
     886           0 :         TALLOC_CTX *ctx = talloc_stackframe();
     887             : 
     888           0 :         if (argc != 2 || c->display_usage) {
     889           0 :                 d_printf("%s\n%s",
     890             :                          _("Usage:"),
     891             :                          _("net registry setsd_sddl <path> <security_descriptor>\n"));
     892           0 :                 d_printf("%s\n%s",
     893             :                          _("Example:"),
     894             :                          _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
     895           0 :                 goto done;
     896             :         }
     897             : 
     898           0 :         secdesc = sddl_decode(ctx, argv[1], get_global_sam_sid());
     899           0 :         if (secdesc == NULL) {
     900           0 :                 goto done;
     901             :         }
     902             : 
     903           0 :         werr = net_registry_setsd_internal(c, ctx, argv[0], secdesc);
     904           0 :         if (!W_ERROR_IS_OK(werr)) {
     905           0 :                 goto done;
     906             :         }
     907             : 
     908           0 :         ret = 0;
     909             : 
     910           0 : done:
     911           0 :         TALLOC_FREE(ctx);
     912           0 :         return ret;
     913             : }
     914             : 
     915             : /******************************************************************************/
     916             : /**
     917             :  * @defgroup net_registry net registry
     918             :  */
     919             : 
     920             : /**
     921             :  * @defgroup net_registry_import Import
     922             :  * @ingroup net_registry
     923             :  * @{
     924             :  */
     925             : 
     926             : struct import_ctx {
     927             :         TALLOC_CTX *mem_ctx;
     928             : };
     929             : 
     930             : 
     931         224 : static WERROR import_create_key(struct import_ctx *ctx,
     932             :                                 struct registry_key *parent,
     933             :                                 const char *name, void **pkey, bool *existing)
     934             : {
     935           0 :         WERROR werr;
     936         224 :         TALLOC_CTX *mem_ctx = talloc_new(ctx->mem_ctx);
     937             : 
     938         224 :         struct registry_key *key = NULL;
     939           0 :         enum winreg_CreateAction action;
     940             : 
     941         224 :         if (parent == NULL) {
     942         224 :                 char *subkeyname = NULL;
     943         224 :                 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
     944             :                          &parent, &subkeyname);
     945         224 :                 if (!W_ERROR_IS_OK(werr)) {
     946           0 :                         d_fprintf(stderr, _("open_hive failed: %s\n"),
     947             :                                   win_errstr(werr));
     948           0 :                         goto done;
     949             :                 }
     950         224 :                 name = subkeyname;
     951             :         }
     952             : 
     953         224 :         action = REG_ACTION_NONE;
     954         224 :         werr = reg_createkey(mem_ctx, parent, name, REG_KEY_WRITE,
     955             :                              &key, &action);
     956         224 :         if (!W_ERROR_IS_OK(werr)) {
     957           0 :                 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
     958             :                           win_errstr(werr));
     959           0 :                 goto done;
     960             :         }
     961             : 
     962         224 :         if (action == REG_ACTION_NONE) {
     963           0 :                 d_fprintf(stderr, _("createkey did nothing -- huh?\n"));
     964           0 :                 werr = WERR_CREATE_FAILED;
     965           0 :                 goto done;
     966             :         }
     967             : 
     968         224 :         if (existing != NULL) {
     969         224 :                 *existing = (action == REG_OPENED_EXISTING_KEY);
     970             :         }
     971             : 
     972         224 :         if (pkey!=NULL) {
     973         224 :                 *pkey = talloc_steal(ctx->mem_ctx, key);
     974             :         }
     975             : 
     976           0 : done:
     977         224 :         talloc_free(mem_ctx);
     978         224 :         return werr;
     979             : }
     980             : 
     981         222 : static WERROR import_close_key(struct import_ctx *ctx,
     982             :                                struct registry_key *key)
     983             : {
     984         222 :         return WERR_OK;
     985             : }
     986             : 
     987           0 : static WERROR import_delete_key(struct import_ctx *ctx,
     988             :                                 struct registry_key *parent, const char *name)
     989             : {
     990           0 :         WERROR werr;
     991           0 :         TALLOC_CTX *mem_ctx = talloc_new(talloc_tos());
     992             : 
     993           0 :         if (parent == NULL) {
     994           0 :                 char *subkeyname = NULL;
     995           0 :                 werr = open_hive(mem_ctx, name, REG_KEY_WRITE,
     996             :                          &parent, &subkeyname);
     997           0 :                 if (!W_ERROR_IS_OK(werr)) {
     998           0 :                         d_fprintf(stderr, _("open_hive failed: %s\n"),
     999             :                                   win_errstr(werr));
    1000           0 :                         goto done;
    1001             :                 }
    1002           0 :                 name = subkeyname;
    1003             :         }
    1004             : 
    1005           0 :         werr = reg_deletekey_recursive(parent, name);
    1006           0 :         if (!W_ERROR_IS_OK(werr)) {
    1007           0 :                 d_fprintf(stderr, "reg_deletekey_recursive %s: %s\n",
    1008             :                           _("failed"), win_errstr(werr));
    1009           0 :                 goto done;
    1010             :         }
    1011             : 
    1012           0 : done:
    1013           0 :         talloc_free(mem_ctx);
    1014           0 :         return werr;
    1015             : }
    1016             : 
    1017        1086 : static WERROR import_create_val (struct import_ctx *ctx,
    1018             :                                  struct registry_key *parent, const char *name,
    1019             :                                  const struct registry_value *value)
    1020             : {
    1021           0 :         WERROR werr;
    1022             : 
    1023        1086 :         if (parent == NULL) {
    1024           0 :                 return WERR_INVALID_PARAMETER;
    1025             :         }
    1026             : 
    1027        1086 :         werr = reg_setvalue(parent, name, value);
    1028        1086 :         if (!W_ERROR_IS_OK(werr)) {
    1029           0 :                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
    1030             :                           win_errstr(werr));
    1031             :         }
    1032        1086 :         return werr;
    1033             : }
    1034             : 
    1035           0 : static WERROR import_delete_val (struct import_ctx *ctx,
    1036             :                                  struct registry_key *parent, const char *name)
    1037             : {
    1038           0 :         WERROR werr;
    1039             : 
    1040           0 :         if (parent == NULL) {
    1041           0 :                 return WERR_INVALID_PARAMETER;
    1042             :         }
    1043             : 
    1044           0 :         werr = reg_deletevalue(parent, name);
    1045           0 :         if (!W_ERROR_IS_OK(werr)) {
    1046           0 :                 d_fprintf(stderr, _("reg_deletevalue failed: %s\n"),
    1047             :                           win_errstr(werr));
    1048             :         }
    1049             : 
    1050           0 :         return werr;
    1051             : }
    1052             : 
    1053             : struct precheck_ctx {
    1054             :         TALLOC_CTX *mem_ctx;
    1055             :         bool failed;
    1056             : };
    1057             : 
    1058           0 : static WERROR precheck_create_key(struct precheck_ctx *ctx,
    1059             :                                   struct registry_key *parent,
    1060             :                                   const char *name, void **pkey, bool *existing)
    1061             : {
    1062           0 :         WERROR werr;
    1063           0 :         TALLOC_CTX *frame = talloc_stackframe();
    1064           0 :         struct registry_key *key = NULL;
    1065             : 
    1066           0 :         if (parent == NULL) {
    1067           0 :                 char *subkeyname = NULL;
    1068           0 :                 werr = open_hive(frame, name, REG_KEY_READ,
    1069             :                                  &parent, &subkeyname);
    1070           0 :                 if (!W_ERROR_IS_OK(werr)) {
    1071           0 :                         d_printf("Precheck: open_hive of [%s] failed: %s\n",
    1072             :                                  name, win_errstr(werr));
    1073           0 :                         goto done;
    1074             :                 }
    1075           0 :                 name = subkeyname;
    1076             :         }
    1077             : 
    1078           0 :         werr = reg_openkey(frame, parent, name, 0, &key);
    1079           0 :         if (!W_ERROR_IS_OK(werr)) {
    1080           0 :                 d_printf("Precheck: openkey [%s] failed: %s\n",
    1081             :                          name, win_errstr(werr));
    1082           0 :                 goto done;
    1083             :         }
    1084             : 
    1085           0 :         if (existing != NULL) {
    1086           0 :                 *existing = true;
    1087             :         }
    1088             : 
    1089           0 :         if (pkey != NULL) {
    1090           0 :                 *pkey = talloc_steal(ctx->mem_ctx, key);
    1091             :         }
    1092             : 
    1093           0 : done:
    1094           0 :         talloc_free(frame);
    1095           0 :         ctx->failed = !W_ERROR_IS_OK(werr);
    1096           0 :         return werr;
    1097             : }
    1098             : 
    1099           0 : static WERROR precheck_close_key(struct precheck_ctx *ctx,
    1100             :                                  struct registry_key *key)
    1101             : {
    1102           0 :         talloc_free(key);
    1103           0 :         return WERR_OK;
    1104             : }
    1105             : 
    1106           0 : static WERROR precheck_delete_key(struct precheck_ctx *ctx,
    1107             :                                   struct registry_key *parent, const char *name)
    1108             : {
    1109           0 :         WERROR werr;
    1110           0 :         TALLOC_CTX *frame = talloc_stackframe();
    1111           0 :         struct registry_key *key;
    1112             : 
    1113           0 :         if (parent == NULL) {
    1114           0 :                 char *subkeyname = NULL;
    1115           0 :                 werr = open_hive(frame, name, REG_KEY_READ,
    1116             :                                  &parent, &subkeyname);
    1117           0 :                 if (!W_ERROR_IS_OK(werr)) {
    1118           0 :                         d_printf("Precheck: open_hive of [%s] failed: %s\n",
    1119             :                                  name, win_errstr(werr));
    1120           0 :                         goto done;
    1121             :                 }
    1122           0 :                 name = subkeyname;
    1123             :         }
    1124             : 
    1125           0 :         werr = reg_openkey(ctx->mem_ctx, parent, name, 0, &key);
    1126           0 :         if (W_ERROR_IS_OK(werr)) {
    1127           0 :                 d_printf("Precheck: key [%s\\%s] should not exist\n",
    1128           0 :                          parent->key->name, name);
    1129           0 :                 werr = WERR_FILE_EXISTS;
    1130           0 :         } else if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
    1131           0 :                 werr = WERR_OK;
    1132             :         } else {
    1133           0 :                 d_printf("Precheck: openkey [%s\\%s] failed: %s\n",
    1134           0 :                          parent->key->name, name, win_errstr(werr));
    1135             :         }
    1136             : 
    1137           0 : done:
    1138           0 :         talloc_free(frame);
    1139           0 :         ctx->failed = !W_ERROR_IS_OK(werr);
    1140           0 :         return werr;
    1141             : }
    1142             : 
    1143           0 : static int registry_value_cmp(
    1144             :         const struct registry_value* v1, const struct registry_value* v2)
    1145             : {
    1146           0 :         if (v1->type == v2->type) {
    1147           0 :                 return data_blob_cmp(&v1->data, &v2->data);
    1148             :         }
    1149           0 :         return NUMERIC_CMP(v1->type, v2->type);
    1150             : }
    1151             : 
    1152           0 : static WERROR precheck_create_val(struct precheck_ctx *ctx,
    1153             :                                   struct registry_key *parent,
    1154             :                                   const char *name,
    1155             :                                   const struct registry_value *value)
    1156             : {
    1157           0 :         TALLOC_CTX *frame = talloc_stackframe();
    1158           0 :         struct registry_value *old;
    1159           0 :         WERROR werr;
    1160             : 
    1161           0 :         SMB_ASSERT(parent);
    1162             : 
    1163           0 :         werr = reg_queryvalue(frame, parent, name, &old);
    1164           0 :         if (!W_ERROR_IS_OK(werr)) {
    1165           0 :                 d_printf("Precheck: queryvalue \"%s\" of [%s] failed: %s\n",
    1166           0 :                          name, parent->key->name, win_errstr(werr));
    1167           0 :                 goto done;
    1168             :         }
    1169           0 :         if (registry_value_cmp(value, old) != 0) {
    1170           0 :                 d_printf("Precheck: unexpected value \"%s\" of key [%s]\n",
    1171           0 :                          name, parent->key->name);
    1172           0 :                 ctx->failed = true;
    1173             :         }
    1174           0 : done:
    1175           0 :         talloc_free(frame);
    1176           0 :         return werr;
    1177             : }
    1178             : 
    1179           0 : static WERROR precheck_delete_val(struct precheck_ctx *ctx,
    1180             :                                   struct registry_key *parent,
    1181             :                                   const char *name)
    1182             : {
    1183           0 :         TALLOC_CTX *frame = talloc_stackframe();
    1184           0 :         struct registry_value *old;
    1185           0 :         WERROR werr;
    1186             : 
    1187           0 :         SMB_ASSERT(parent);
    1188             : 
    1189           0 :         werr = reg_queryvalue(frame, parent, name, &old);
    1190           0 :         if (W_ERROR_IS_OK(werr)) {
    1191           0 :                 d_printf("Precheck: value \"%s\" of key [%s] should not exist\n",
    1192           0 :                          name, parent->key->name);
    1193           0 :                 werr = WERR_FILE_EXISTS;
    1194           0 :         } else if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
    1195           0 :                 werr = WERR_OK;
    1196             :         } else {
    1197           0 :                 printf("Precheck: queryvalue \"%s\" of key [%s] failed: %s\n",
    1198           0 :                        name, parent->key->name, win_errstr(werr));
    1199             :         }
    1200             : 
    1201           0 :         talloc_free(frame);
    1202           0 :         ctx->failed = !W_ERROR_IS_OK(werr);
    1203           0 :         return werr;
    1204             : }
    1205             : 
    1206           2 : static bool import_precheck(const char *fname, const char *parse_options)
    1207             : {
    1208           2 :         TALLOC_CTX *mem_ctx = talloc_tos();
    1209           2 :         struct precheck_ctx precheck_ctx = {
    1210             :                 .mem_ctx = mem_ctx,
    1211             :                 .failed = false,
    1212             :         };
    1213           2 :         struct reg_import_callback precheck_callback = {
    1214             :                 .openkey     = NULL,
    1215             :                 .closekey    = (reg_import_callback_closekey_t)&precheck_close_key,
    1216             :                 .createkey   = (reg_import_callback_createkey_t)&precheck_create_key,
    1217             :                 .deletekey   = (reg_import_callback_deletekey_t)&precheck_delete_key,
    1218             :                 .deleteval   = (reg_import_callback_deleteval_t)&precheck_delete_val,
    1219             :                 .setval      = {
    1220             :                         .registry_value = (reg_import_callback_setval_registry_value_t)
    1221             :                                           &precheck_create_val,
    1222             :                 },
    1223             :                 .setval_type = REGISTRY_VALUE,
    1224             :                 .data        = &precheck_ctx
    1225             :         };
    1226           0 :         struct reg_parse_callback *parse_callback;
    1227           0 :         int ret;
    1228             : 
    1229           2 :         if (!fname) {
    1230           2 :                 return true;
    1231             :         }
    1232             : 
    1233           0 :         parse_callback = reg_import_adapter(mem_ctx, precheck_callback);
    1234           0 :         if (parse_callback == NULL) {
    1235           0 :                 d_printf("talloc failed\n");
    1236           0 :                 return false;
    1237             :         }
    1238             : 
    1239           0 :         ret = reg_parse_file(fname, parse_callback, parse_options);
    1240             : 
    1241           0 :         if (ret < 0 || precheck_ctx.failed) {
    1242           0 :                 d_printf("Precheck failed\n");
    1243           0 :                 return false;
    1244             :         }
    1245           0 :         return true;
    1246             : }
    1247             : 
    1248           2 : static int import_with_precheck_action(const char *import_fname,
    1249             :                                        const char *precheck_fname,
    1250             :                                        const char *parse_options)
    1251             : {
    1252           2 :         TALLOC_CTX *frame = talloc_stackframe();
    1253           2 :         struct import_ctx import_ctx = {
    1254             :                 .mem_ctx = frame,
    1255             :         };
    1256           2 :         struct reg_import_callback import_callback = {
    1257             :                 .openkey     = NULL,
    1258             :                 .closekey    = (reg_import_callback_closekey_t)&import_close_key,
    1259             :                 .createkey   = (reg_import_callback_createkey_t)&import_create_key,
    1260             :                 .deletekey   = (reg_import_callback_deletekey_t)&import_delete_key,
    1261             :                 .deleteval   = (reg_import_callback_deleteval_t)&import_delete_val,
    1262             :                 .setval      = {
    1263             :                         .registry_value = (reg_import_callback_setval_registry_value_t)
    1264             :                                           &import_create_val,
    1265             :                 },
    1266             :                 .setval_type = REGISTRY_VALUE,
    1267             :                 .data        = &import_ctx
    1268             :         };
    1269           0 :         struct reg_parse_callback *parse_callback;
    1270           2 :         int ret = -1;
    1271           0 :         bool precheck_ok;
    1272             : 
    1273           2 :         precheck_ok = import_precheck(precheck_fname, parse_options);
    1274           2 :         if (!precheck_ok) {
    1275           0 :                 goto done;
    1276             :         }
    1277             : 
    1278           2 :         parse_callback = reg_import_adapter(frame, import_callback);
    1279           2 :         if (parse_callback == NULL) {
    1280           0 :                 d_printf("talloc failed\n");
    1281           0 :                 goto done;
    1282             :         }
    1283             : 
    1284           2 :         ret = reg_parse_file(import_fname, parse_callback, parse_options);
    1285             : 
    1286           2 : done:
    1287           2 :         talloc_free(frame);
    1288           2 :         return ret;
    1289             : }
    1290             : 
    1291           2 : static int net_registry_import(struct net_context *c, int argc,
    1292             :                                const char **argv)
    1293             : {
    1294           2 :         const char *parse_options =  (argc > 1) ? argv[1] : NULL;
    1295           2 :         int ret = -1;
    1296           0 :         WERROR werr;
    1297             : 
    1298           2 :         if (argc < 1 || argc > 2 || c->display_usage) {
    1299           0 :                 d_printf("%s\n%s",
    1300             :                          _("Usage:"),
    1301             :                          _("net registry import <reg> [options]\n"));
    1302           0 :                 d_printf("%s\n%s",
    1303             :                          _("Example:"),
    1304             :                          _("net registry import file.reg enc=CP1252\n"));
    1305           0 :                 return -1;
    1306             :         }
    1307             : 
    1308           2 :         werr = regdb_open();
    1309           2 :         if (!W_ERROR_IS_OK(werr)) {
    1310           0 :                 d_printf("Failed to open regdb: %s\n", win_errstr(werr));
    1311           0 :                 return -1;
    1312             :         }
    1313             : 
    1314           2 :         werr = regdb_transaction_start();
    1315           2 :         if (!W_ERROR_IS_OK(werr)) {
    1316           0 :                 d_printf("Failed to start transaction on regdb: %s\n",
    1317             :                          win_errstr(werr));
    1318           0 :                 goto done;
    1319             :         }
    1320             : 
    1321           2 :         ret = import_with_precheck_action(argv[0], c->opt_precheck,
    1322             :                                           parse_options);
    1323             : 
    1324           2 :         if (ret < 0) {
    1325           0 :                 d_printf("Transaction canceled!\n");
    1326           0 :                 regdb_transaction_cancel();
    1327           0 :                 goto done;
    1328             :         }
    1329             : 
    1330           2 :         SMB_ASSERT(ret == 0);
    1331             : 
    1332           2 :         if (c->opt_testmode) {
    1333           0 :                 d_printf("Testmode: not committing changes.\n");
    1334           0 :                 regdb_transaction_cancel();
    1335           0 :                 goto done;
    1336             :         }
    1337             : 
    1338           2 :         werr = regdb_transaction_commit();
    1339           2 :         if (!W_ERROR_IS_OK(werr)) {
    1340           0 :                 d_printf("Failed to commit transaction on regdb: %s\n",
    1341             :                          win_errstr(werr));
    1342           0 :                 ret = -1;
    1343             :         }
    1344             : 
    1345           2 : done:
    1346           2 :         regdb_close();
    1347           2 :         return ret;
    1348             : }
    1349             : /**@}*/
    1350             : 
    1351             : /******************************************************************************/
    1352             : 
    1353             : /**
    1354             :  * @defgroup net_registry_export Export
    1355             :  * @ingroup net_registry
    1356             :  * @{
    1357             :  */
    1358             : 
    1359         724 : static int registry_export(TALLOC_CTX *ctx, /*const*/ struct registry_key *key,
    1360             :                            struct reg_format *f)
    1361             : {
    1362         724 :         int ret=-1;
    1363           0 :         WERROR werr;
    1364           0 :         uint32_t count;
    1365             : 
    1366         724 :         struct registry_value *valvalue = NULL;
    1367         724 :         char *valname = NULL;
    1368             : 
    1369         724 :         char *subkey_name = NULL;
    1370         724 :         NTTIME modtime = 0;
    1371             : 
    1372         724 :         reg_format_registry_key(f, key, false);
    1373             : 
    1374             :         /* print values */
    1375         724 :         for (count = 0;
    1376        2920 :              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
    1377        2920 :                      W_ERROR_IS_OK(werr);
    1378        2196 :              count++)
    1379             :         {
    1380        2196 :                 reg_format_registry_value(f, valname, valvalue);
    1381             :         }
    1382         724 :         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
    1383           0 :                 d_fprintf(stderr, _("reg_enumvalue failed: %s\n"),
    1384             :                           win_errstr(werr));
    1385           0 :                 goto done;
    1386             :         }
    1387             : 
    1388             :         /* recurse on subkeys */
    1389         724 :         for (count = 0;
    1390        1438 :              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
    1391        1438 :                      W_ERROR_IS_OK(werr);
    1392         714 :              count++)
    1393             :         {
    1394         714 :                 struct registry_key *subkey = NULL;
    1395             : 
    1396         714 :                 werr = reg_openkey(ctx, key, subkey_name, REG_KEY_READ,
    1397             :                                    &subkey);
    1398         714 :                 if (!W_ERROR_IS_OK(werr)) {
    1399           0 :                         d_fprintf(stderr, _("reg_openkey failed: %s\n"),
    1400             :                                   win_errstr(werr));
    1401           0 :                         goto done;
    1402             :                 }
    1403             : 
    1404         714 :                 registry_export(ctx, subkey, f);
    1405         714 :                 TALLOC_FREE(subkey);
    1406             :         }
    1407         724 :         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
    1408           0 :                 d_fprintf(stderr, _("reg_enumkey failed: %s\n"),
    1409             :                           win_errstr(werr));
    1410           0 :                 goto done;
    1411             :         }
    1412         724 :         ret = 0;
    1413         724 : done:
    1414         724 :         return ret;
    1415             : }
    1416             : 
    1417          10 : static int net_registry_export(struct net_context *c, int argc,
    1418             :                                const char **argv)
    1419             : {
    1420          10 :         int ret=-1;
    1421           0 :         WERROR werr;
    1422          10 :         struct registry_key *key = NULL;
    1423          10 :         TALLOC_CTX *ctx = talloc_stackframe();
    1424          10 :         struct reg_format *f=NULL;
    1425             : 
    1426          10 :         if (argc < 2 || argc > 3 || c->display_usage) {
    1427           0 :                 d_printf("%s\n%s",
    1428             :                          _("Usage:"),
    1429             :                          _("net registry export <path> <file> [opt]\n"));
    1430           0 :                 d_printf("%s\n%s",
    1431             :                          _("Example:"),
    1432             :                          _("net registry export 'HKLM\\Software\\Samba' "
    1433             :                            "samba.reg regedit5\n"));
    1434           0 :                 goto done;
    1435             :         }
    1436             : 
    1437          10 :         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
    1438          10 :         if (!W_ERROR_IS_OK(werr)) {
    1439           0 :                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
    1440           0 :                 goto done;
    1441             :         }
    1442             : 
    1443          10 :         f = reg_format_file(ctx, argv[1], (argc > 2) ? argv[2] : NULL);
    1444          10 :         if (f == NULL) {
    1445           0 :                 d_fprintf(stderr, _("open file failed: %s\n"), strerror(errno));
    1446           0 :                 goto done;
    1447             :         }
    1448             : 
    1449          10 :         ret = registry_export(ctx, key, f);
    1450             : 
    1451          10 : done:
    1452          10 :         TALLOC_FREE(ctx);
    1453          10 :         return ret;
    1454             : }
    1455             : /**@}*/
    1456             : 
    1457             : /******************************************************************************/
    1458             : /**
    1459             :  * @defgroup net_registry_convert Convert
    1460             :  * @ingroup net_registry
    1461             :  * @{
    1462             :  */
    1463             : 
    1464           0 : static int net_registry_convert(struct net_context *c, int argc,
    1465             :                                const char **argv)
    1466             : {
    1467           0 :         int ret;
    1468           0 :         TALLOC_CTX *mem_ctx;
    1469           0 :         const char *in_opt  = NULL;
    1470           0 :         const char *out_opt = NULL;
    1471             : 
    1472           0 :         if (argc < 2 || argc > 4|| c->display_usage) {
    1473           0 :                 d_printf("%s\n%s",
    1474             :                          _("Usage:"),
    1475             :                          _("net registry convert <in> <out> [in_opt] [out_opt]\n"
    1476             :                            "net registry convert <in> <out> [out_opt]\n"));
    1477           0 :                 d_printf("%s\n%s",
    1478             :                          _("Example:"),
    1479             :                          _("net registry convert in.reg out.reg regedit4,enc=CP1252\n"));
    1480           0 :                 return -1;
    1481             :         }
    1482             : 
    1483           0 :         mem_ctx = talloc_stackframe();
    1484             : 
    1485           0 :         switch (argc ) {
    1486           0 :         case 2:
    1487           0 :                 break;
    1488           0 :         case 3:
    1489           0 :                 out_opt = argv[2];
    1490           0 :                 break;
    1491           0 :         case 4:
    1492           0 :                 out_opt = argv[3];
    1493           0 :                 in_opt  = argv[2];
    1494           0 :                 break;
    1495           0 :         default:
    1496           0 :                 assert(false);
    1497             :         }
    1498             : 
    1499             : 
    1500           0 :         ret = reg_parse_file(argv[0], (struct reg_parse_callback*)
    1501           0 :                              reg_format_file(mem_ctx, argv[1], out_opt),
    1502             :                              in_opt);
    1503             : 
    1504           0 :         talloc_free(mem_ctx);
    1505             : 
    1506           0 :         return ret;
    1507             : }
    1508             : /**@}*/
    1509             : 
    1510          28 : static int net_registry_check(struct net_context *c, int argc,
    1511             :                               const char **argv)
    1512             : {
    1513           0 :         char *dbfile;
    1514           0 :         struct check_options opts;
    1515           0 :         int ret;
    1516             : 
    1517          28 :         if (argc > 1|| c->display_usage) {
    1518           0 :                 d_printf("%s\n%s",
    1519             :                          _("Usage:"),
    1520             :                          _("net registry check  [-vraTfl] [-o <ODB>] [--wipe] [<TDB>]\n"
    1521             :                            "  Check a registry database.\n"
    1522             :                            "    -v|--verbose\t be verbose\n"
    1523             :                            "    -r|--repair\t\t interactive repair mode\n"
    1524             :                            "    -a|--auto\t\t noninteractive repair mode\n"
    1525             :                            "    -T|--test\t\t dry run\n"
    1526             :                            "    -f|--force\t\t force\n"
    1527             :                            "    -l|--lock\t\t lock <TDB> while doing the check\n"
    1528             :                            "    -o|--output=<ODB>\t output database\n"
    1529             :                            "    --reg-version=n\t assume database format version {n|1,2,3}\n"
    1530             :                            "    --wipe\t\t create a new database from scratch\n"
    1531             :                            "    --db=<TDB>\t\t registry database to open\n"));
    1532           0 :                 return c->display_usage ? 0 : -1;
    1533             :         }
    1534             : 
    1535          28 :         if (c->opt_db != NULL) {
    1536           0 :                 dbfile = talloc_strdup(talloc_tos(), c->opt_db);
    1537          28 :         } else if (argc > 0) {
    1538          20 :                 dbfile = talloc_strdup(talloc_tos(), argv[0]);
    1539             :         } else {
    1540           8 :                 dbfile = state_path(talloc_tos(), "registry.tdb");
    1541             :         }
    1542          28 :         if (dbfile == NULL) {
    1543           0 :                 return -1;
    1544             :         }
    1545             : 
    1546          28 :         opts = (struct check_options) {
    1547          28 :                 .lock = c->opt_lock || c->opt_long_list_entries,
    1548          28 :                 .test = c->opt_testmode,
    1549          28 :                 .automatic = c->opt_auto,
    1550          28 :                 .verbose = c->opt_verbose,
    1551          28 :                 .force = c->opt_force,
    1552          28 :                 .repair = c->opt_repair || c->opt_reboot,
    1553          28 :                 .version = c->opt_reg_version,
    1554          28 :                 .output  = c->opt_output,
    1555          28 :                 .wipe = c->opt_wipe,
    1556          28 :                 .implicit_db = (c->opt_db == NULL) && (argc == 0),
    1557             :         };
    1558             : 
    1559          28 :         ret = net_registry_check_db(dbfile, &opts);
    1560          28 :         talloc_free(dbfile);
    1561          28 :         return ret;
    1562             : }
    1563             : 
    1564             : 
    1565             : /******************************************************************************/
    1566             : 
    1567         158 : int net_registry(struct net_context *c, int argc, const char **argv)
    1568             : {
    1569         158 :         int ret = -1;
    1570             : 
    1571         158 :         struct functable func[] = {
    1572             :                 {
    1573             :                         "enumerate",
    1574             :                         net_registry_enumerate,
    1575             :                         NET_TRANSPORT_LOCAL,
    1576             :                         N_("Enumerate registry keys and values"),
    1577             :                         N_("net registry enumerate\n"
    1578             :                            "    Enumerate registry keys and values")
    1579             :                 },
    1580             :                 {
    1581             :                         "enumerate_recursive",
    1582             :                         net_registry_enumerate_recursive,
    1583             :                         NET_TRANSPORT_LOCAL,
    1584             :                         N_("Enumerate registry keys and values"),
    1585             :                         N_("net registry enumerate_recursive\n"
    1586             :                            "    Enumerate registry keys and values")
    1587             :                 },
    1588             :                 {
    1589             :                         "createkey",
    1590             :                         net_registry_createkey,
    1591             :                         NET_TRANSPORT_LOCAL,
    1592             :                         N_("Create a new registry key"),
    1593             :                         N_("net registry createkey\n"
    1594             :                            "    Create a new registry key")
    1595             :                 },
    1596             :                 {
    1597             :                         "deletekey",
    1598             :                         net_registry_deletekey,
    1599             :                         NET_TRANSPORT_LOCAL,
    1600             :                         N_("Delete a registry key"),
    1601             :                         N_("net registry deletekey\n"
    1602             :                            "    Delete a registry key")
    1603             :                 },
    1604             :                 {
    1605             :                         "deletekey_recursive",
    1606             :                         net_registry_deletekey_recursive,
    1607             :                         NET_TRANSPORT_LOCAL,
    1608             :                         N_("Delete a registry key with subkeys"),
    1609             :                         N_("net registry deletekey_recursive\n"
    1610             :                            "    Delete a registry key with subkeys")
    1611             :                 },
    1612             :                 {
    1613             :                         "getvalue",
    1614             :                         net_registry_getvalue,
    1615             :                         NET_TRANSPORT_LOCAL,
    1616             :                         N_("Print a registry value"),
    1617             :                         N_("net registry getvalue\n"
    1618             :                            "    Print a registry value")
    1619             :                 },
    1620             :                 {
    1621             :                         "getvalueraw",
    1622             :                         net_registry_getvalueraw,
    1623             :                         NET_TRANSPORT_LOCAL,
    1624             :                         N_("Print a registry value (raw format)"),
    1625             :                         N_("net registry getvalueraw\n"
    1626             :                            "    Print a registry value (raw format)")
    1627             :                 },
    1628             :                 {
    1629             :                         "getvaluesraw",
    1630             :                         net_registry_getvaluesraw,
    1631             :                         NET_TRANSPORT_LOCAL,
    1632             :                         "Print all values of a key in raw format",
    1633             :                         "net registry getvaluesraw <key>\n"
    1634             :                         "    Print a registry value (raw format)"
    1635             :                 },
    1636             :                 {
    1637             :                         "setvalue",
    1638             :                         net_registry_setvalue,
    1639             :                         NET_TRANSPORT_LOCAL,
    1640             :                         N_("Set a new registry value"),
    1641             :                         N_("net registry setvalue\n"
    1642             :                            "    Set a new registry value")
    1643             :                 },
    1644             :                 {
    1645             :                         "increment",
    1646             :                         net_registry_increment,
    1647             :                         NET_TRANSPORT_LOCAL,
    1648             :                         N_("Increment a DWORD registry value under a lock"),
    1649             :                         N_("net registry increment\n"
    1650             :                            "    Increment a DWORD registry value under a lock")
    1651             :                 },
    1652             :                 {
    1653             :                         "deletevalue",
    1654             :                         net_registry_deletevalue,
    1655             :                         NET_TRANSPORT_LOCAL,
    1656             :                         N_("Delete a registry value"),
    1657             :                         N_("net registry deletevalue\n"
    1658             :                            "    Delete a registry value")
    1659             :                 },
    1660             :                 {
    1661             :                         "getsd",
    1662             :                         net_registry_getsd,
    1663             :                         NET_TRANSPORT_LOCAL,
    1664             :                         N_("Get security descriptor"),
    1665             :                         N_("net registry getsd\n"
    1666             :                            "    Get security descriptor")
    1667             :                 },
    1668             :                 {
    1669             :                         "getsd_sddl",
    1670             :                         net_registry_getsd_sddl,
    1671             :                         NET_TRANSPORT_LOCAL,
    1672             :                         N_("Get security descriptor in sddl format"),
    1673             :                         N_("net registry getsd_sddl\n"
    1674             :                            "    Get security descriptor in sddl format")
    1675             :                 },
    1676             :                 {
    1677             :                         "setsd_sddl",
    1678             :                         net_registry_setsd_sddl,
    1679             :                         NET_TRANSPORT_LOCAL,
    1680             :                         N_("Set security descriptor from sddl format string"),
    1681             :                         N_("net registry setsd_sddl\n"
    1682             :                            "    Set security descriptor from sddl format string")
    1683             :                 },
    1684             :                 {
    1685             :                         "import",
    1686             :                         net_registry_import,
    1687             :                         NET_TRANSPORT_LOCAL,
    1688             :                         N_("Import .reg file"),
    1689             :                         N_("net registry import\n"
    1690             :                            "    Import .reg file")
    1691             :                 },
    1692             :                 {
    1693             :                         "export",
    1694             :                         net_registry_export,
    1695             :                         NET_TRANSPORT_LOCAL,
    1696             :                         N_("Export .reg file"),
    1697             :                         N_("net registry export\n"
    1698             :                            "    Export .reg file")
    1699             :                 },
    1700             :                 {
    1701             :                         "convert",
    1702             :                         net_registry_convert,
    1703             :                         NET_TRANSPORT_LOCAL,
    1704             :                         N_("Convert .reg file"),
    1705             :                         N_("net registry convert\n"
    1706             :                            "    Convert .reg file")
    1707             :                 },
    1708             :                 {
    1709             :                         "check",
    1710             :                         net_registry_check,
    1711             :                         NET_TRANSPORT_LOCAL,
    1712             :                         N_("Check a registry database"),
    1713             :                         N_("net registry check\n"
    1714             :                            "    Check a registry database")
    1715             :                 },
    1716             :         { NULL, NULL, 0, NULL, NULL }
    1717             :         };
    1718             : 
    1719         158 :         if (!c->display_usage
    1720         158 :             && argc > 0
    1721         158 :             && (strcasecmp_m(argv[0], "convert") != 0)
    1722         158 :             && (strcasecmp_m(argv[0], "check") != 0))
    1723             :         {
    1724         130 :                 if (!W_ERROR_IS_OK(registry_init_basic())) {
    1725           0 :                         return -1;
    1726             :                 }
    1727             :         }
    1728             : 
    1729         158 :         ret = net_run_function(c, argc, argv, "net registry", func);
    1730             : 
    1731         158 :         return ret;
    1732             : }

Generated by: LCOV version 1.14