Rename libnet_smbconf_getshare() to libnet_conf_get_share().
[ira/wip.git] / source3 / utils / net_conf.c
index febc8dc9e13cbb2777fc48465a68a9ed9b9fc420..7859e0e615e3bcc7f039cbaa8e1965c154a98d65 100644 (file)
@@ -1,34 +1,34 @@
-/* 
- *  Samba Unix/Linux SMB client library 
- *  Distributed SMB/CIFS Server Management Utility 
+/*
+ *  Samba Unix/Linux SMB client library
+ *  Distributed SMB/CIFS Server Management Utility
  *  Local configuration interface
- *  Copyright (C) Michael Adam 2007
+ *  Copyright (C) Michael Adam 2007-2008
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation; either version 3 of the License, or
  *  (at your option) any later version.
- *  
+ *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
- *  
+ *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
- * This is an interface to the configuration stored inside the 
- * samba registry. In the future there might be support for other 
+ * This is an interface to the configuration stored inside the
+ * samba registry. In the future there might be support for other
  * configuration backends as well.
  */
 
 #include "includes.h"
 #include "utils/net.h"
+#include "libnet/libnet.h"
 
-/* 
+/*
  * usage functions
  */
 
@@ -40,7 +40,8 @@ static int net_conf_list_usage(int argc, const char **argv)
 
 static int net_conf_import_usage(int argc, const char**argv)
 {
-       d_printf("USAGE: net conf import [--test|-T] <filename> [<servicename>]\n"
+       d_printf("USAGE: net conf import [--test|-T] <filename> "
+                "[<servicename>]\n"
                 "\t[--test|-T]    testmode - do not act, just print "
                                   "what would be done\n"
                 "\t<servicename>  only import service <servicename>, "
@@ -109,467 +110,133 @@ static int net_conf_delparm_usage(int argc, const char **argv)
  * Helper functions
  */
 
-static char *format_value(TALLOC_CTX *mem_ctx, struct registry_value *value)
+static char *parm_valstr(TALLOC_CTX *ctx, struct parm_struct *parm,
+                        struct share_params *share)
 {
-       char *result = NULL;
+       char *valstr = NULL;
+       int i = 0;
+       void *ptr = parm->ptr;
 
-       /* what if mem_ctx = NULL? */
+       if (parm->p_class == P_LOCAL && share->service >= 0) {
+               ptr = lp_local_ptr(share->service, ptr);
+       }
 
-       switch (value->type) {
-       case REG_DWORD:
-               result = talloc_asprintf(mem_ctx, "%d", value->v.dword);
+       switch (parm->type) {
+       case P_CHAR:
+               valstr = talloc_asprintf(ctx, "%c", *(char *)ptr);
                break;
-       case REG_SZ:
-       case REG_EXPAND_SZ:
-               result = talloc_asprintf(mem_ctx, "%s", value->v.sz.str);
+       case P_STRING:
+       case P_USTRING:
+               valstr = talloc_asprintf(ctx, "%s", *(char **)ptr);
+               break;
+       case P_BOOL:
+               valstr = talloc_asprintf(ctx, "%s", BOOLSTR(*(bool *)ptr));
+               break;
+       case P_BOOLREV:
+               valstr = talloc_asprintf(ctx, "%s", BOOLSTR(!*(bool *)ptr));
+               break;
+       case P_ENUM:
+               for (i = 0; parm->enum_list[i].name; i++) {
+                       if (*(int *)ptr == parm->enum_list[i].value)
+                       {
+                               valstr = talloc_asprintf(ctx, "%s",
+                                        parm->enum_list[i].name);
+                               break;
+                       }
+               }
+               break;
+       case P_OCTAL: {
+               char *o = octal_string(*(int *)ptr);
+               valstr = talloc_move(ctx, &o);
                break;
-       case REG_MULTI_SZ: {
-                uint32 j;
-                for (j = 0; j < value->v.multi_sz.num_strings; j++) {
-                        result = talloc_asprintf(mem_ctx, "\"%s\" ", 
-                                                value->v.multi_sz.strings[j]);
-                }
-                break;
-        }
-       case REG_BINARY:
-                result = talloc_asprintf(mem_ctx, "binary (%d bytes)",
-                                        (int)value->v.binary.length);
-                break;
-        default:
-                result = talloc_asprintf(mem_ctx, "<unprintable>");
-                break;
-        }
-       return result;
-}
-
-/*
- * add a value to a key. 
- */
-static WERROR reg_setvalue_internal(struct registry_key *key,
-                                   const char *valname,
-                                   const char *valtype,
-                                   const char *valstr)
-{
-       struct registry_value val;
-       WERROR werr = WERR_OK;
-
-       ZERO_STRUCT(val);
-
-       if (strequal(valtype, "dword")) {
-               val.type = REG_DWORD;
-               val.v.dword = strtoul(valstr, NULL, 10);
-       }
-       else if (strequal(valtype, "sz")) {
-               val.type = REG_SZ;
-               val.v.sz.str = CONST_DISCARD(char *, valstr);
-               val.v.sz.len = strlen(valstr) + 1;
-       }
-       else {
-               d_fprintf(stderr, "Only value types DWORD and SZ are"
-                         "currently implemented for setting values.\n");
-               werr = WERR_INVALID_PARAM;
-               goto done;
-       }
-
-       if (!lp_parameter_is_valid(valname)) {
-               d_fprintf(stderr, "Invalid parameter '%s' given.\n", valname);
-               werr = WERR_INVALID_PARAM;
-               goto done;
-       }
-
-       if (registry_smbconf_valname_forbidden(valname)) {
-               d_fprintf(stderr, "Parameter '%s' not allowed in registry.\n",
-                         valname);
-               werr = WERR_INVALID_PARAM;
-               goto done;
-       }
-
-       if (!strequal(strrchr_m(key->key->name, '\\')+1, GLOBAL_NAME) &&
-           lp_parameter_is_global(valname))
-       {
-               d_fprintf(stderr, "Global paramter '%s' not allowed in "
-                         "service definition ('%s').\n", valname,
-                         strrchr_m(key->key->name, '\\')+1);
-               werr = WERR_INVALID_PARAM;
-               goto done;
-       }
-
-       werr = reg_setvalue(key, valname, &val);
-       if (!W_ERROR_IS_OK(werr)) {
-               d_fprintf(stderr,
-                         "Error adding value '%s' to "
-                         "key '%s': %s\n",
-                         valname, key->key->name, dos_errstr(werr));
-       }
-
-done:
-       return werr;
-}
-
-/* 
- * Open a subkey of KEY_SMBCONF (i.e a service)
- * - variant without error output (q = quiet)-
- */
-static WERROR smbconf_open_path_q(TALLOC_CTX *ctx, const char *subkeyname,
-                                 uint32 desired_access, 
-                                 struct registry_key **key)
-{
-       WERROR werr = WERR_OK;
-       char *path = NULL;
-       NT_USER_TOKEN *token;
-
-       if (!(token = registry_create_admin_token(ctx))) {
-               DEBUG(1, ("Error creating admin token\n"));
-               goto done;
-       }
-
-       if (subkeyname == NULL) {
-               path = talloc_strdup(ctx, KEY_SMBCONF);
-       }
-       else {
-               path = talloc_asprintf(ctx, "%s\\%s", KEY_SMBCONF, subkeyname);
-       }
-
-       werr = reg_open_path(ctx, path, desired_access,
-                            token, key);
-
-done:
-       TALLOC_FREE(path);
-       return werr;
-}
-
-/* 
- * Open a subkey of KEY_SMBCONF (i.e a service)
- * - variant with error output -
- */
-static WERROR smbconf_open_path(TALLOC_CTX *ctx, const char *subkeyname,
-                               uint32 desired_access, 
-                               struct registry_key **key)
-{
-       WERROR werr = WERR_OK;
-
-       werr = smbconf_open_path_q(ctx, subkeyname, desired_access, key);
-       if (!W_ERROR_IS_OK(werr)) {
-               d_fprintf(stderr, "Error opening registry path '%s\\%s': %s\n",
-                         KEY_SMBCONF, 
-                         (subkeyname == NULL) ? "" : subkeyname, 
-                         dos_errstr(werr));
-       }
-
-       return werr;
-}
-
-/*
- * open the base key KEY_SMBCONF
- */
-static WERROR smbconf_open_basepath(TALLOC_CTX *ctx, uint32 desired_access,
-                                   struct registry_key **key)
-{
-       return smbconf_open_path(ctx, NULL, desired_access, key);
-}
-
-/*
- * delete a subkey of KEY_SMBCONF
- */
-static WERROR reg_delkey_internal(TALLOC_CTX *ctx, const char *keyname)
-{
-       WERROR werr = WERR_OK;
-       struct registry_key *key = NULL;
-
-       werr = smbconf_open_basepath(ctx, REG_KEY_WRITE, &key);
-       if (!W_ERROR_IS_OK(werr)) {
-               goto done;
-       }
-
-       werr = reg_deletekey_recursive(key, key, keyname);
-       if (!W_ERROR_IS_OK(werr)) {
-               d_fprintf(stderr, "Error deleting registry key %s\\%s: %s\n",
-                         KEY_SMBCONF, keyname, dos_errstr(werr));
-       }
-
-done:
-       TALLOC_FREE(key);
-       return werr;
-}
-
-/*
- * create a subkey of KEY_SMBCONF
- */
-static WERROR reg_createkey_internal(TALLOC_CTX *ctx,
-                                    const char * subkeyname,
-                                    struct registry_key **newkey)
-{
-       WERROR werr = WERR_OK;
-       struct registry_key *create_parent = NULL;
-       TALLOC_CTX *create_ctx;
-       enum winreg_CreateAction action = REG_ACTION_NONE;
-
-       /* create a new talloc ctx for creation. it will hold
-        * the intermediate parent key (SMBCONF) for creation
-        * and will be destroyed when leaving this function... */
-       if (!(create_ctx = talloc_new(ctx))) {
-               werr = WERR_NOMEM;
-               goto done;
-       }
-
-       werr = smbconf_open_basepath(create_ctx, REG_KEY_WRITE, &create_parent);
-       if (!W_ERROR_IS_OK(werr)) {
-               goto done;
-       }
-
-       werr = reg_createkey(ctx, create_parent, subkeyname, 
-                            REG_KEY_WRITE, newkey, &action);
-       if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
-               d_fprintf(stderr, "Key '%s' already exists.\n", subkeyname);
-               werr = WERR_ALREADY_EXISTS;
-       }
-       if (!W_ERROR_IS_OK(werr)) {
-               d_fprintf(stderr, "Error creating key %s: %s\n",
-                        subkeyname, dos_errstr(werr));
-       }
-
-done:
-       TALLOC_FREE(create_ctx);
-       return werr;
-}
-
-/*
- * check if a subkey of KEY_SMBCONF of a given name exists
- */
-static BOOL smbconf_key_exists(TALLOC_CTX *ctx, const char *subkeyname)
-{
-       BOOL ret = False;
-       WERROR werr = WERR_OK;
-       TALLOC_CTX *mem_ctx;
-       struct registry_key *key;
-
-       if (!(mem_ctx = talloc_new(ctx))) {
-               d_fprintf(stderr, "ERROR: Out of memory...!\n");
-               goto done;
-       }
-
-       werr = smbconf_open_path_q(mem_ctx, subkeyname, REG_KEY_READ, &key);
-       if (W_ERROR_IS_OK(werr)) {
-               ret = True;
-       }
-
-done:
-       TALLOC_FREE(mem_ctx);
-       return ret;
-}
-
-static BOOL smbconf_value_exists(TALLOC_CTX *ctx, struct registry_key *key,
-                                const char *param)
-{
-       BOOL ret = False;
-       WERROR werr = WERR_OK;
-       struct registry_value *value = NULL;
-
-       werr = reg_queryvalue(ctx, key, param, &value); 
-       if (W_ERROR_IS_OK(werr)) {
-               ret = True;
-       }
-
-       TALLOC_FREE(value);
-       return ret;
-}
-
-static WERROR list_values(TALLOC_CTX *ctx, struct registry_key *key)
-{
-       WERROR werr = WERR_OK;
-       uint32 idx = 0;
-       struct registry_value *valvalue = NULL;
-       char *valname = NULL;
-
-       for (idx = 0;
-            W_ERROR_IS_OK(werr = reg_enumvalue(ctx, key, idx, &valname,
-                                               &valvalue));
-            idx++)
-       {
-               d_printf("\t%s = %s\n", valname, format_value(ctx, valvalue));
-       }
-       if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
-                d_fprintf(stderr, "Error enumerating values: %s\n",
-                          dos_errstr(werr));
-               goto done;
-        }
-       werr = WERR_OK;
-
-done:
-       return werr; 
-}
-
-static WERROR drop_smbconf_internal(TALLOC_CTX *ctx)
-{
-       char *path, *p;
-       WERROR werr = WERR_OK;
-       NT_USER_TOKEN *token;
-       struct registry_key *parent_key = NULL;
-       struct registry_key *new_key = NULL;
-       TALLOC_CTX* tmp_ctx = NULL;
-       enum winreg_CreateAction action;
-
-       tmp_ctx = talloc_new(ctx);
-       if (tmp_ctx == NULL) {
-               werr = WERR_NOMEM;
-               goto done;
-       }
-
-       if (!(token = registry_create_admin_token(tmp_ctx))) {
-               /* what is the appropriate error code here? */
-               werr = WERR_CAN_NOT_COMPLETE; 
-               goto done;
-       }
-
-       path = talloc_strdup(tmp_ctx, KEY_SMBCONF);
-       if (path == NULL) {
-               d_fprintf(stderr, "ERROR: out of memory!\n");
-               werr = WERR_NOMEM;
-               goto done;
-       }
-       p = strrchr(path, '\\');
-       *p = '\0';
-       werr = reg_open_path(tmp_ctx, path, REG_KEY_WRITE, token, &parent_key);
-
-       if (!W_ERROR_IS_OK(werr)) {
-               goto done;
        }
-
-       werr = reg_deletekey_recursive(tmp_ctx, parent_key, p+1);
-
-       if (!W_ERROR_IS_OK(werr)) {
-               goto done;
+       case P_LIST:
+               valstr = talloc_strdup(ctx, "");
+               if ((char ***)ptr && *(char ***)ptr) {
+                       char **list = *(char ***)ptr;
+                       for (; *list; list++) {
+                               /* surround strings with whitespace
+                                * in double quotes */
+                               if (strchr_m(*list, ' '))
+                               {
+                                       valstr = talloc_asprintf_append(
+                                               valstr, "\"%s\"%s",
+                                               *list,
+                                                ((*(list+1))?", ":""));
+                               } else {
+                                       valstr = talloc_asprintf_append(
+                                               valstr, "%s%s", *list,
+                                                ((*(list+1))?", ":""));
+                               }
+                       }
+               }
+               break;
+       case P_INTEGER:
+               valstr = talloc_asprintf(ctx, "%d", *(int *)ptr);
+               break;
+       case P_SEP:
+               break;
+       default:
+               valstr = talloc_asprintf(ctx, "<type unimplemented>\n");
+               break;
        }
-       
-       werr = reg_createkey(tmp_ctx, parent_key, p+1, REG_KEY_WRITE, 
-                            &new_key, &action);
 
-done:
-       TALLOC_FREE(tmp_ctx);
-       return werr;
+       return valstr;
 }
 
-static int import_process_service(TALLOC_CTX *ctx, 
+static int import_process_service(TALLOC_CTX *ctx,
                                  struct share_params *share)
 {
        int ret = -1;
        struct parm_struct *parm;
        int pnum = 0;
        const char *servicename;
-       struct registry_key *key;
        WERROR werr;
-       const char *valtype = NULL;
        char *valstr = NULL;
+       TALLOC_CTX *tmp_ctx = NULL;
+
+       tmp_ctx = talloc_new(ctx);
+       if (tmp_ctx == NULL) {
+               werr = WERR_NOMEM;
+               goto done;
+       }
 
        servicename = (share->service == GLOBAL_SECTION_SNUM)?
                GLOBAL_NAME : lp_servicename(share->service);
 
        if (opt_testmode) {
                d_printf("[%s]\n", servicename);
-       }
-       else {
-               if (smbconf_key_exists(ctx, servicename)) {
-                       werr = reg_delkey_internal(ctx, servicename);
+       } else {
+               if (libnet_conf_share_exists(servicename)) {
+                       werr = libnet_smbconf_delshare(servicename);
                        if (!W_ERROR_IS_OK(werr)) {
                                goto done;
                        }
                }
-               werr = reg_createkey_internal(ctx, servicename, &key);
-               if (!W_ERROR_IS_OK(werr)) {
-                       goto done;
-               }
        }
 
        while ((parm = lp_next_parameter(share->service, &pnum, 0)))
        {
-               void *ptr = parm->ptr;
-               int i = 0;
-
-               if ((share->service < 0 && parm->p_class == P_LOCAL) 
+               if ((share->service < 0) && (parm->p_class == P_LOCAL)
                    && !(parm->flags & FLAG_GLOBAL))
+               {
                        continue;
-
-               if (parm->p_class == P_LOCAL && share->service >= 0) {
-                       ptr = lp_local_ptr(share->service, ptr);
                }
 
-               valtype = "sz";
-
-               switch (parm->type) {
-               case P_CHAR:
-                       valstr = talloc_asprintf(ctx, "%c", *(char *)ptr);
-                       break;
-               case P_STRING:
-               case P_USTRING:
-                       valstr = talloc_asprintf(ctx, "%s", *(char **)ptr);
-                       break;
-               case P_GSTRING:
-               case P_UGSTRING:
-                       valstr = talloc_asprintf(ctx, "%s", (char *)ptr);
-                       break;
-               case P_BOOL:
-                       valstr = talloc_asprintf(ctx, "%s", 
-                                               BOOLSTR(*(BOOL *)ptr));
-                       break;
-               case P_BOOLREV:
-                       valstr = talloc_asprintf(ctx, "%s", 
-                                               BOOLSTR(!*(BOOL *)ptr));
-                       break;
-               case P_ENUM:
-                       for (i = 0; parm->enum_list[i].name; i++) {
-                               if (*(int *)ptr == 
-                                   parm->enum_list[i].value) 
-                               {
-                                       valstr = talloc_asprintf(ctx, "%s",
-                                                parm->enum_list[i].name);
-                                       break;
-                               }
-                       }
-                       break;
-               case P_OCTAL:
-                       valstr = talloc_asprintf(ctx, "%s", octal_string(*(int *)ptr));
-                       break;
-               case P_LIST:
-                       valstr = talloc_strdup(ctx, "");
-                       if ((char ***)ptr && *(char ***)ptr) {
-                               char **list = *(char ***)ptr;
-                               for (; *list; list++) {
-                                       /* surround strings with whitespace 
-                                        * in double quotes */
-                                       if (strchr_m(*list, ' '))
-                                       {
-                                               valstr = talloc_asprintf_append(
-                                                       valstr, "\"%s\"%s", 
-                                                       *list, 
-                                                        ((*(list+1))?", ":""));
-                                       }
-                                       else {
-                                               valstr = talloc_asprintf_append(
-                                                       valstr, "%s%s", *list, 
-                                                        ((*(list+1))?", ":""));
-                                       }
-                               }
-                       }
-                       break;
-               case P_INTEGER:
-                       valtype = "dword";
-                       valstr = talloc_asprintf(ctx, "%d", *(int *)ptr);
-                       break;
-               case P_SEP:
-                       break;
-               default:
-                       valstr = talloc_asprintf(ctx, "<type unimplemented>\n");
-                       break;
-               }
+               valstr = parm_valstr(tmp_ctx, parm, share);
 
                if (parm->type != P_SEP) {
                        if (opt_testmode) {
                                d_printf("\t%s = %s\n", parm->label, valstr);
-                       }
-                       else {
-                               werr = reg_setvalue_internal(key, parm->label, 
-                                                            valtype, valstr);
+                       } else {
+                               werr = libnet_smbconf_setparm(servicename,
+                                                             parm->label,
+                                                             valstr);
                                if (!W_ERROR_IS_OK(werr)) {
+                                       d_fprintf(stderr,
+                                                 "Error setting parameter '%s'"
+                                                 ": %s\n", parm->label,
+                                                  dos_errstr(werr));
                                        goto done;
                                }
                        }
@@ -581,24 +248,41 @@ static int import_process_service(TALLOC_CTX *ctx,
        }
 
        ret = 0;
+
 done:
+       TALLOC_FREE(tmp_ctx);
        return ret;
 }
 
+/* return true iff there are nondefault globals */
+static bool globals_exist(void)
+{
+       int i = 0;
+       struct parm_struct *parm;
+
+       while ((parm = lp_next_parameter(GLOBAL_SECTION_SNUM, &i, 0)) != NULL) {
+               if (parm->type != P_SEP) {
+                       return true;
+               }
+       }
+       return false;
+}
 
 /*
- * the conf functions 
+ * the conf functions
  */
 
-int net_conf_list(int argc, const char **argv)
+static int net_conf_list(int argc, const char **argv)
 {
        WERROR werr = WERR_OK;
        int ret = -1;
        TALLOC_CTX *ctx;
-       struct registry_key *base_key = NULL;
-       struct registry_key *sub_key = NULL;
-       uint32 idx_key = 0;
-       char *subkey_name = NULL;
+       uint32_t num_shares;
+       char **share_names;
+       uint32_t *num_params;
+       char ***param_names;
+       char ***param_values;
+       uint32_t share_count, param_count;
 
        ctx = talloc_init("list");
 
@@ -607,54 +291,26 @@ int net_conf_list(int argc, const char **argv)
                goto done;
        }
 
-       werr = smbconf_open_basepath(ctx, REG_KEY_READ, &base_key);
+       werr = libnet_conf_get_config(ctx, &num_shares, &share_names,
+                                     &num_params, &param_names,
+                                     &param_values);
        if (!W_ERROR_IS_OK(werr)) {
+               d_fprintf(stderr, "Error getting config: %s\n",
+                         dos_errstr(werr));
                goto done;
        }
 
-       if (smbconf_key_exists(ctx, GLOBAL_NAME))  {
-               werr = reg_openkey(ctx, base_key, GLOBAL_NAME, 
-                                  REG_KEY_READ, &sub_key);
-               if (!W_ERROR_IS_OK(werr)) {
-                       d_fprintf(stderr, "Error opening subkey '%s' : %s\n",
-                                 subkey_name, dos_errstr(werr));
-                       goto done;
-               }
-               d_printf("[%s]\n", GLOBAL_NAME);
-               if (!W_ERROR_IS_OK(list_values(ctx, sub_key))) {
-                       goto done;
-               }
-               d_printf("\n");
-       }
-
-       for (idx_key = 0;
-            W_ERROR_IS_OK(werr = reg_enumkey(ctx, base_key, idx_key,
-                                             &subkey_name, NULL));
-            idx_key++) 
-       {
-               if (strequal(subkey_name, GLOBAL_NAME)) {
-                       continue;
-               }
-               d_printf("[%s]\n", subkey_name);
-
-               werr = reg_openkey(ctx, base_key, subkey_name, 
-                                  REG_KEY_READ, &sub_key);
-               if (!W_ERROR_IS_OK(werr)) {
-                       d_fprintf(stderr, 
-                                 "Error opening subkey '%s': %s\n",
-                                 subkey_name, dos_errstr(werr));
-                       goto done;
-               }
-               if (!W_ERROR_IS_OK(list_values(ctx, sub_key))) {
-                       goto done;
+       for (share_count = 0; share_count < num_shares; share_count++) {
+               d_printf("[%s]\n", share_names[share_count]);
+               for (param_count = 0; param_count < num_params[share_count];
+                    param_count++)
+               {
+                       d_printf("\t%s = %s\n",
+                                param_names[share_count][param_count],
+                                param_values[share_count][param_count]);
                }
                d_printf("\n");
        }
-       if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
-               d_fprintf(stderr, "Error enumerating subkeys: %s\n", 
-                         dos_errstr(werr));
-               goto done;
-       }
 
        ret = 0;
 
@@ -663,12 +319,12 @@ done:
        return ret;
 }
 
-int net_conf_import(int argc, const char **argv)
+static int net_conf_import(int argc, const char **argv)
 {
        int ret = -1;
        const char *filename = NULL;
        const char *servicename = NULL;
-       BOOL service_found = False;
+       bool service_found = false;
        TALLOC_CTX *ctx;
        struct share_iterator *shares;
        struct share_params *share;
@@ -691,22 +347,25 @@ int net_conf_import(int argc, const char **argv)
        DEBUG(3,("net_conf_import: reading configuration from file %s.\n",
                filename));
 
-       if (!lp_load(filename, 
-                    False,     /* global_only */
-                    True,      /* save_defaults */
-                    False,     /* add_ipc */
-                    True))     /* initialize_globals */
+       if (!lp_load(filename,
+                    false,     /* global_only */
+                    true,      /* save_defaults */
+                    false,     /* add_ipc */
+                    true))     /* initialize_globals */
        {
                d_fprintf(stderr, "Error parsing configuration file.\n");
                goto done;
        }
 
        if (opt_testmode) {
-               d_printf("\nTEST MODE - would import the following configuration:\n\n");
+               d_printf("\nTEST MODE - "
+                        "would import the following configuration:\n\n");
        }
 
-       if ((servicename == NULL) || strequal(servicename, GLOBAL_NAME)) {
-               service_found = True;
+       if (((servicename == NULL) && globals_exist()) ||
+           strequal(servicename, GLOBAL_NAME))
+       {
+               service_found = true;
                if (import_process_service(ctx, &global_share) != 0) {
                        goto done;
                }
@@ -722,37 +381,36 @@ int net_conf_import(int argc, const char **argv)
                goto done;
        }
        while ((share = next_share(shares)) != NULL) {
-               if ((servicename == NULL) 
-                   || strequal(servicename, lp_servicename(share->service))) 
+               if ((servicename == NULL)
+                   || strequal(servicename, lp_servicename(share->service)))
                {
-                       service_found = True;
+                       service_found = true;
                        if (import_process_service(ctx, share)!= 0) {
                                goto done;
                        }
                }
        }
-       
+
        if ((servicename != NULL) && !service_found) {
-               d_printf("Share %s not found in file %s\n", 
+               d_printf("Share %s not found in file %s\n",
                         servicename, filename);
                goto done;
 
        }
 
        ret = 0;
-       
+
 done:
        TALLOC_FREE(ctx);
        return ret;
 }
 
-int net_conf_listshares(int argc, const char **argv)
+static int net_conf_listshares(int argc, const char **argv)
 {
        WERROR werr = WERR_OK;
        int ret = -1;
-       struct registry_key *key;
-       uint32 idx = 0;
-       char *subkey_name = NULL;
+       uint32_t count, num_shares = 0;
+       char **share_names = NULL;
        TALLOC_CTX *ctx;
 
        ctx = talloc_init("listshares");
@@ -762,22 +420,14 @@ int net_conf_listshares(int argc, const char **argv)
                goto done;
        }
 
-       werr = smbconf_open_basepath(ctx, SEC_RIGHTS_ENUM_SUBKEYS, &key);
+       werr = libnet_conf_get_share_names(ctx, &num_shares, &share_names);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
        }
 
-       for (idx = 0;
-            W_ERROR_IS_OK(werr = reg_enumkey(ctx, key, idx,
-                                             &subkey_name, NULL));
-            idx++) 
+       for (count = 0; count < num_shares; count++)
        {
-               d_printf("%s\n", subkey_name);
-       }
-       if (! W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
-               d_fprintf(stderr, "Error enumerating subkeys: %s\n", 
-                         dos_errstr(werr));
-               goto done;
+               d_printf("%s\n", share_names[count]);
        }
 
        ret = 0;
@@ -787,7 +437,7 @@ done:
        return ret;
 }
 
-int net_conf_drop(int argc, const char **argv)
+static int net_conf_drop(int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr;
@@ -797,7 +447,7 @@ int net_conf_drop(int argc, const char **argv)
                goto done;
        }
 
-       werr = drop_smbconf_internal(NULL);
+       werr = libnet_conf_drop();
        if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error deleting configuration: %s\n",
                          dos_errstr(werr));
@@ -810,12 +460,16 @@ done:
        return ret;
 }
 
-int net_conf_showshare(int argc, const char **argv)
+static int net_conf_showshare(int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
-       struct registry_key *key = NULL;
+       const char *sharename = NULL;
        TALLOC_CTX *ctx;
+       uint32_t num_params;
+       uint32_t count;
+       char **param_names;
+       char **param_values;
 
        ctx = talloc_init("showshare");
 
@@ -824,15 +478,21 @@ int net_conf_showshare(int argc, const char **argv)
                goto done;
        }
 
-       werr = smbconf_open_path(ctx, argv[0], REG_KEY_READ, &key);
+       sharename = argv[0];
+
+       werr = libnet_conf_get_share(ctx, sharename, &num_params,
+                                    &param_names, &param_values);
        if (!W_ERROR_IS_OK(werr)) {
+               d_printf("error getting share parameters: %s\n",
+                        dos_errstr(werr));
                goto done;
        }
 
-       d_printf("[%s]\n", argv[0]);
+       d_printf("[%s]\n", sharename);
 
-       if (!W_ERROR_IS_OK(list_values(ctx, key))) {
-               goto done;
+       for (count = 0; count < num_params; count++) {
+               d_printf("\t%s = %s\n", param_names[count],
+                        param_values[count]);
        }
 
        ret = 0;
@@ -842,11 +502,16 @@ done:
        return ret;
 }
 
-int net_conf_addshare(int argc, const char **argv)
+/**
+ * Add a share, with a couple of standard parameters, partly optional.
+ *
+ * This is a high level utility function of the net conf utility,
+ * not a direct frontend to the libnet_conf API.
+ */
+static int net_conf_addshare(int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
-       struct registry_key *newkey = NULL;
        char *sharename = NULL;
        const char *path = NULL;
        const char *comment = NULL;
@@ -857,7 +522,7 @@ int net_conf_addshare(int argc, const char **argv)
        switch (argc) {
                case 0:
                case 1:
-               default: 
+               default:
                        net_conf_addshare_usage(argc, argv);
                        goto done;
                case 5:
@@ -876,7 +541,7 @@ int net_conf_addshare(int argc, const char **argv)
                                case 'N':
                                        guest_ok = "no";
                                        break;
-                               default: 
+                               default:
                                        net_conf_addshare_usage(argc, argv);
                                        goto done;
                        }
@@ -898,21 +563,20 @@ int net_conf_addshare(int argc, const char **argv)
                                        net_conf_addshare_usage(argc, argv);
                                        goto done;
                        }
-
                case 2:
                        path = argv[1];
                        sharename = strdup_lower(argv[0]);
                        break;
        }
 
-       /* 
-        * validate arguments 
+       /*
+        * validate arguments
         */
 
        /* validate share name */
 
-       if (!validate_net_name(sharename, INVALID_SHARENAME_CHARS, 
-                              strlen(sharename))) 
+       if (!validate_net_name(sharename, INVALID_SHARENAME_CHARS,
+                              strlen(sharename)))
        {
                d_fprintf(stderr, "ERROR: share name %s contains "
                         "invalid characters (any of %s)\n",
@@ -927,15 +591,21 @@ int net_conf_addshare(int argc, const char **argv)
        }
 
        if (strequal(sharename, GLOBAL_NAME)) {
-               d_fprintf(stderr, 
+               d_fprintf(stderr,
                          "ERROR: 'global' is not a valid share name.\n");
                goto done;
        }
 
+       if (libnet_conf_share_exists(sharename)) {
+               d_fprintf(stderr, "ERROR: share %s already exists.\n",
+                         sharename);
+               goto done;
+       }
+
        /* validate path */
 
        if (path[0] != '/') {
-               d_fprintf(stderr, 
+               d_fprintf(stderr,
                          "Error: path '%s' is not an absolute path.\n",
                          path);
                goto done;
@@ -945,7 +615,7 @@ int net_conf_addshare(int argc, const char **argv)
                d_fprintf(stderr,
                          "ERROR: cannot stat path '%s' to ensure "
                          "this is a directory.\n"
-                         "Error was '%s'.\n", 
+                         "Error was '%s'.\n",
                          path, strerror(errno));
                goto done;
        }
@@ -957,57 +627,78 @@ int net_conf_addshare(int argc, const char **argv)
                goto done;
        }
 
-       /* 
-        * create the share 
+       /*
+        * create the share
         */
 
-       werr = reg_createkey_internal(NULL, argv[0], &newkey);
+       werr = libnet_conf_create_share(sharename);
        if (!W_ERROR_IS_OK(werr)) {
+               d_fprintf(stderr, "Error creating share %s: %s\n",
+                         sharename, dos_errstr(werr));
                goto done;
        }
 
-       /* add config params as values */
+       /*
+        * fill the share with parameters
+        */
 
-       werr = reg_setvalue_internal(newkey, "path", "sz", path);
-       if (!W_ERROR_IS_OK(werr))
+       werr = libnet_smbconf_setparm(sharename, "path", path);
+       if (!W_ERROR_IS_OK(werr)) {
+               d_fprintf(stderr, "Error setting parameter %s: %s\n",
+                         "path", dos_errstr(werr));
                goto done;
+       }
 
        if (comment != NULL) {
-               werr = reg_setvalue_internal(newkey, "comment", "sz", comment);
-               if (!W_ERROR_IS_OK(werr))
+               werr = libnet_smbconf_setparm(sharename, "comment", comment);
+               if (!W_ERROR_IS_OK(werr)) {
+                       d_fprintf(stderr, "Error setting parameter %s: %s\n",
+                                 "comment", dos_errstr(werr));
                        goto done;
+               }
        }
 
-       werr = reg_setvalue_internal(newkey, "guest ok", "sz", guest_ok);
-       if (!W_ERROR_IS_OK(werr))
+       werr = libnet_smbconf_setparm(sharename, "guest ok", guest_ok);
+       if (!W_ERROR_IS_OK(werr)) {
+               d_fprintf(stderr, "Error setting parameter %s: %s\n",
+                         "'guest ok'", dos_errstr(werr));
                goto done;
-       
-       werr = reg_setvalue_internal(newkey, "writeable", "sz", writeable);
-       if (!W_ERROR_IS_OK(werr))
+       }
+
+       werr = libnet_smbconf_setparm(sharename, "writeable", writeable);
+       if (!W_ERROR_IS_OK(werr)) {
+               d_fprintf(stderr, "Error setting parameter %s: %s\n",
+                         "writeable", dos_errstr(werr));
                goto done;
+       }
 
        ret = 0;
 
 done:
-       TALLOC_FREE(newkey);
        SAFE_FREE(sharename);
        return ret;
 }
 
-int net_conf_delshare(int argc, const char **argv)
+static int net_conf_delshare(int argc, const char **argv)
 {
        int ret = -1;
        const char *sharename = NULL;
+       WERROR werr = WERR_OK;
 
        if (argc != 1) {
                net_conf_delshare_usage(argc, argv);
                goto done;
        }
        sharename = argv[0];
-       
-       if (W_ERROR_IS_OK(reg_delkey_internal(NULL, sharename))) {
-               ret = 0;
+
+       werr = libnet_smbconf_delshare(sharename);
+       if (!W_ERROR_IS_OK(werr)) {
+               d_fprintf(stderr, "Error deleting share %s: %s\n",
+                         sharename, dos_errstr(werr));
+               goto done;
        }
+
+       ret = 0;
 done:
        return ret;
 }
@@ -1016,13 +707,9 @@ static int net_conf_setparm(int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
-       struct registry_key *key = NULL;
        char *service = NULL;
        char *param = NULL;
        const char *value_str = NULL;
-       TALLOC_CTX *ctx;
-
-       ctx = talloc_init("setparm");
 
        if (argc != 3) {
                net_conf_setparm_usage(argc, argv);
@@ -1032,29 +719,19 @@ static int net_conf_setparm(int argc, const char **argv)
        param = strdup_lower(argv[1]);
        value_str = argv[2];
 
-       if (!smbconf_key_exists(ctx, service)) {
-               werr = reg_createkey_internal(ctx, service, &key);
-       }
-       else {
-               werr = smbconf_open_path(ctx, service, REG_KEY_READ, &key);
-       }
-       if (!W_ERROR_IS_OK(werr)) {
-               goto done;
-       }
+       werr = libnet_smbconf_setparm(service, param, value_str);
 
-       werr = reg_setvalue_internal(key, param, "sz", value_str);
        if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error setting value '%s': %s\n",
                          param, dos_errstr(werr));
                goto done;
        }
 
-
        ret = 0;
 
 done:
        SAFE_FREE(service);
-       TALLOC_FREE(ctx);
+       SAFE_FREE(param);
        return ret;
 }
 
@@ -1062,10 +739,9 @@ static int net_conf_getparm(int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
-       struct registry_key *key = NULL;
        char *service = NULL;
        char *param = NULL;
-       struct registry_value *value = NULL;
+       char *valstr = NULL;
        TALLOC_CTX *ctx;
 
        ctx = talloc_init("getparm");
@@ -1077,27 +753,26 @@ static int net_conf_getparm(int argc, const char **argv)
        service = strdup_lower(argv[0]);
        param = strdup_lower(argv[1]);
 
-       if (!smbconf_key_exists(ctx, service)) {
-               d_fprintf(stderr, 
-                         "ERROR: given service '%s' does not exist.\n",
+       werr = libnet_smbconf_getparm(ctx, service, param, &valstr);
+
+       if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
+               d_fprintf(stderr,
+                         "Error: given service '%s' does not exist.\n",
                          service);
                goto done;
-       }
-
-       werr = smbconf_open_path(ctx, service, REG_KEY_READ, &key);
-       if (!W_ERROR_IS_OK(werr)) {
+       } else if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
+               d_fprintf(stderr,
+                         "Error: given parameter '%s' is not set.\n",
+                         param);
                goto done;
-       }
-
-       werr = reg_queryvalue(ctx, key, param, &value);
-       if (!W_ERROR_IS_OK(werr)) {
-               d_fprintf(stderr, "Error querying value '%s': %s.\n",
+       } else if (!W_ERROR_IS_OK(werr)) {
+               d_fprintf(stderr, "Error getting value '%s': %s.\n",
                          param, dos_errstr(werr));
                goto done;
        }
-       
-       d_printf("%s\n", format_value(ctx, value));
-       
+
+       d_printf("%s\n", valstr);
+
        ret = 0;
 done:
        SAFE_FREE(service);
@@ -1110,12 +785,8 @@ static int net_conf_delparm(int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
-       struct registry_key *key = NULL;
        char *service = NULL;
        char *param = NULL;
-       TALLOC_CTX *ctx;
-
-       ctx = talloc_init("delparm");
 
        if (argc != 2) {
                net_conf_delparm_usage(argc, argv);
@@ -1124,26 +795,19 @@ static int net_conf_delparm(int argc, const char **argv)
        service = strdup_lower(argv[0]);
        param = strdup_lower(argv[1]);
 
-       if (!smbconf_key_exists(ctx, service)) {
-               d_fprintf(stderr, 
+       werr = libnet_smbconf_delparm(service, param);
+
+       if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
+               d_fprintf(stderr,
                          "Error: given service '%s' does not exist.\n",
                          service);
                goto done;
-       }
-
-       werr = smbconf_open_path(ctx, service, REG_KEY_READ, &key);
-       if (!W_ERROR_IS_OK(werr)) {
-               goto done;
-       }
-
-       if (!smbconf_value_exists(ctx, key, param)) {
-               d_fprintf(stderr, 
+       } else if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
+               d_fprintf(stderr,
                          "Error: given parameter '%s' is not set.\n",
                          param);
                goto done;
-       }
-       werr = reg_deletevalue(key, param);
-       if (!W_ERROR_IS_OK(werr)) {
+       } else if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error deleting value '%s': %s.\n",
                          param, dos_errstr(werr));
                goto done;
@@ -1152,6 +816,8 @@ static int net_conf_delparm(int argc, const char **argv)
        ret = 0;
 
 done:
+       SAFE_FREE(service);
+       SAFE_FREE(param);
        return ret;
 }
 
@@ -1163,25 +829,25 @@ int net_conf(int argc, const char **argv)
 {
        int ret = -1;
        struct functable2 func[] = {
-               {"list", net_conf_list, 
+               {"list", net_conf_list,
                 "Dump the complete configuration in smb.conf like format."},
                {"import", net_conf_import,
                 "Import configuration from file in smb.conf format."},
-               {"listshares", net_conf_listshares, 
+               {"listshares", net_conf_listshares,
                 "List the registry shares."},
                {"drop", net_conf_drop,
                 "Delete the complete configuration from registry."},
-               {"showshare", net_conf_showshare, 
+               {"showshare", net_conf_showshare,
                 "Show the definition of a registry share."},
-               {"addshare", net_conf_addshare, 
+               {"addshare", net_conf_addshare,
                 "Create a new registry share."},
-               {"delshare", net_conf_delshare, 
+               {"delshare", net_conf_delshare,
                 "Delete a registry share."},
-               {"setparm", net_conf_setparm, 
+               {"setparm", net_conf_setparm,
                 "Store a parameter."},
-               {"getparm", net_conf_getparm, 
+               {"getparm", net_conf_getparm,
                 "Retrieve the value of a parameter."},
-               {"delparm", net_conf_delparm, 
+               {"delparm", net_conf_delparm,
                 "Delete a parameter."},
                {NULL, NULL, NULL}
        };
@@ -1199,4 +865,3 @@ done:
        return ret;
 }
 
-/* END */