net conf: use the new smbconf_init() dispatcher instead of explicit backend init.
[ira/wip.git] / source3 / utils / net_conf.c
index f45042b2f8b17ac6d57075d02867944d3d4c2dd6..88cc15e0eb7a82b9d4d94cbb734bf2bdc35c8908 100644 (file)
@@ -2,7 +2,7 @@
  *  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
  */
 
 /*
- * 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.
+ * This is an interface to Samba's configuration as made available
+ * by the libsmbconf interface (source/lib/smbconf/smbconf.c).
+ *
+ * This currently supports local interaction with the configuration
+ * stored in the registry. But other backends and remote access via
+ * rpc might get implemented in the future.
  */
 
 #include "includes.h"
 #include "utils/net.h"
-#include "libnet/libnet.h"
 
-/*
+/**********************************************************************
+ *
  * usage functions
- */
+ *
+ **********************************************************************/
 
 static int net_conf_list_usage(int argc, const char **argv)
 {
@@ -43,9 +47,9 @@ static int net_conf_import_usage(int argc, const char**argv)
        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"
+                       "what would be done\n"
                 "\t<servicename>  only import service <servicename>, "
-                                  "ignore the rest\n");
+                       "ignore the rest\n");
        return -1;
 }
 
@@ -105,364 +109,169 @@ static int net_conf_delparm_usage(int argc, const char **argv)
        return -1;
 }
 
-
-/*
- * Helper functions
- */
-
-static char *format_value(TALLOC_CTX *mem_ctx, struct registry_value *value)
+static int net_conf_getincludes_usage(int argc, const char **argv)
 {
-       char *result = NULL;
-
-       /* what if mem_ctx = NULL? */
-
-       switch (value->type) {
-       case REG_DWORD:
-               result = talloc_asprintf(mem_ctx, "%d", value->v.dword);
-               break;
-       case REG_SZ:
-       case REG_EXPAND_SZ:
-               result = talloc_asprintf(mem_ctx, "%s", value->v.sz.str);
-               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;
+       d_printf("USAGE: net conf getincludes <section>\n");
+       return -1;
 }
 
-static WERROR list_values(TALLOC_CTX *ctx, struct registry_key *key)
+static int net_conf_setincludes_usage(int argc, const char **argv)
 {
-       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;
+       d_printf("USAGE: net conf setincludes <section> [<filename>]*\n");
+       return -1;
 }
 
-static WERROR drop_smbconf_internal(TALLOC_CTX *ctx)
+static int net_conf_delincludes_usage(int argc, const char **argv)
 {
-       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;
+       d_printf("USAGE: net conf delincludes <section>\n");
+       return -1;
+}
 
-       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;
-       }
+/**********************************************************************
+ *
+ * Helper functions
+ *
+ **********************************************************************/
 
-       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);
+/**
+ * This functions process a service previously loaded with libsmbconf.
+ */
+static WERROR import_process_service(struct smbconf_ctx *conf_ctx,
+                                    const char *servicename,
+                                    const uint32_t num_params,
+                                    const char **param_names,
+                                    const char **param_values)
+{
+       uint32_t idx;
+       WERROR werr = WERR_OK;
+       uint32_t num_includes = 0;
+       char **includes = NULL;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
 
-       if (!W_ERROR_IS_OK(werr)) {
+       if (opt_testmode) {
+               d_printf("[%s]\n", servicename);
+               for (idx = 0; idx < num_params; idx ++) {
+                       d_printf("\t%s = %s\n", param_names[idx],
+                                param_values[idx]);
+               }
+               d_printf("\n");
                goto done;
        }
 
-       werr = reg_deletekey_recursive(tmp_ctx, parent_key, p+1);
-
+       if (smbconf_share_exists(conf_ctx, servicename)) {
+               werr = smbconf_delete_share(conf_ctx, servicename);
+               if (!W_ERROR_IS_OK(werr)) {
+                       goto done;
+               }
+       }
+       werr = smbconf_create_share(conf_ctx, servicename);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
        }
 
-       werr = reg_createkey(tmp_ctx, parent_key, p+1, REG_KEY_WRITE,
-                            &new_key, &action);
-
-done:
-       TALLOC_FREE(tmp_ctx);
-       return werr;
-}
-
-static char *parm_valstr(TALLOC_CTX *ctx, struct parm_struct *parm,
-                        struct share_params *share)
-{
-       char *valstr = NULL;
-       int i = 0;
-       void *ptr = parm->ptr;
-
-       if (parm->p_class == P_LOCAL && share->service >= 0) {
-               ptr = lp_local_ptr(share->service, ptr);
-       }
-
-       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_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 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))?", ":""));
-                               }
+       for (idx = 0; idx < num_params; idx ++) {
+               if (strequal(param_names[idx], "include")) {
+                       includes = TALLOC_REALLOC_ARRAY(mem_ctx,
+                                                       includes,
+                                                       char *,
+                                                       num_includes+1);
+                       if (includes == NULL) {
+                               werr = WERR_NOMEM;
+                               goto done;
                        }
-               }
-               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;
-       }
-
-       return valstr;
-}
-
-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;
-       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 (libnet_smbconf_key_exists(servicename)) {
-                       werr = reg_delkey_internal(tmp_ctx, servicename);
-                       if (!W_ERROR_IS_OK(werr)) {
+                       includes[num_includes] = talloc_strdup(includes,
+                                                       param_values[idx]);
+                       if (includes[num_includes] == NULL) {
+                               werr = WERR_NOMEM;
                                goto done;
                        }
-               }
-               werr = libnet_smbconf_reg_createkey_internal(tmp_ctx, servicename, &key);
-               if (!W_ERROR_IS_OK(werr)) {
-                       goto done;
-               }
-       }
-
-       while ((parm = lp_next_parameter(share->service, &pnum, 0)))
-       {
-               if ((share->service < 0 && parm->p_class == P_LOCAL)
-                   && !(parm->flags & FLAG_GLOBAL))
-                       continue;
-
-               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 = libnet_smbconf_reg_setvalue_internal(key,
-                                                       parm->label, valstr);
-                               if (!W_ERROR_IS_OK(werr)) {
-                                       goto done;
-                               }
+                       num_includes++;
+               } else {
+                       werr = smbconf_set_parameter(conf_ctx,
+                                                    servicename,
+                                                    param_names[idx],
+                                                    param_values[idx]);
+                       if (!W_ERROR_IS_OK(werr)) {
+                               goto done;
                        }
                }
        }
 
-       if (opt_testmode) {
-               d_printf("\n");
-       }
-
-       ret = 0;
+       werr = smbconf_set_includes(conf_ctx, servicename, num_includes,
+                                   (const char **)includes);
 
 done:
-       TALLOC_FREE(tmp_ctx);
-       return ret;
+       TALLOC_FREE(mem_ctx);
+       return werr;
 }
 
-/* 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 main conf functions
+ *
+ **********************************************************************/
 
-int net_conf_list(int argc, const char **argv)
+static int net_conf_list(struct smbconf_ctx *conf_ctx,
+                        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;
+       TALLOC_CTX *mem_ctx;
+       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");
+       mem_ctx = talloc_stackframe();
 
        if (argc != 0) {
                net_conf_list_usage(argc, argv);
                goto done;
        }
 
-       werr = libnet_smbconf_open_basepath(ctx, REG_KEY_READ, &base_key);
+       werr = smbconf_get_config(conf_ctx, mem_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 (libnet_smbconf_key_exists(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;
 
 done:
-       TALLOC_FREE(ctx);
+       TALLOC_FREE(mem_ctx);
        return ret;
 }
 
-int net_conf_import(int argc, const char **argv)
+static int net_conf_import(struct smbconf_ctx *conf_ctx,
+                          int argc, const char **argv)
 {
        int ret = -1;
        const char *filename = NULL;
        const char *servicename = NULL;
-       bool service_found = False;
-       TALLOC_CTX *ctx;
-       struct share_iterator *shares;
-       struct share_params *share;
-       struct share_params global_share = { GLOBAL_SECTION_SNUM };
+       char *conf_source = NULL;
+       TALLOC_CTX *mem_ctx;
+       struct smbconf_ctx *txt_ctx;
+       WERROR werr;
 
-       ctx = talloc_init("net_conf_import");
+       mem_ctx = talloc_stackframe();
 
        switch (argc) {
                case 0:
@@ -470,7 +279,11 @@ int net_conf_import(int argc, const char **argv)
                        net_conf_import_usage(argc, argv);
                        goto done;
                case 2:
-                       servicename = argv[1];
+                       servicename = talloc_strdup_lower(mem_ctx, argv[1]);
+                       if (servicename == NULL) {
+                               d_printf("error: out of memory!\n");
+                               goto done;
+                       }
                case 1:
                        filename = argv[0];
                        break;
@@ -479,13 +292,16 @@ 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 */
-       {
-               d_fprintf(stderr, "Error parsing configuration file.\n");
+       conf_source = talloc_asprintf(mem_ctx, "file:%s", filename);
+       if (conf_source == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
+
+       werr = smbconf_init(mem_ctx, &txt_ctx, conf_source);
+       if (!W_ERROR_IS_OK(werr)) {
+               d_printf("error loading file '%s': %s\n", filename,
+                        dos_errstr(werr));
                goto done;
        }
 
@@ -494,91 +310,100 @@ int net_conf_import(int argc, const char **argv)
                         "would import the following configuration:\n\n");
        }
 
-       if (((servicename == NULL) && globals_exist()) ||
-           strequal(servicename, GLOBAL_NAME))
-       {
-               service_found = True;
-               if (import_process_service(ctx, &global_share) != 0) {
+       if (servicename != NULL) {
+               char **param_names, **param_values;
+               uint32_t num_params;
+
+               werr = smbconf_get_share(txt_ctx, mem_ctx,
+                                        servicename,
+                                        &num_params,
+                                        &param_names,
+                                        &param_values);
+               if (!W_ERROR_IS_OK(werr)) {
                        goto done;
                }
-       }
-
-       if (service_found && (servicename != NULL)) {
-               ret = 0;
-               goto done;
-       }
-
-       if (!(shares = share_list_all(ctx))) {
-               d_fprintf(stderr, "Could not list shares...\n");
-               goto done;
-       }
-       while ((share = next_share(shares)) != NULL) {
-               if ((servicename == NULL)
-                   || strequal(servicename, lp_servicename(share->service)))
-               {
-                       service_found = True;
-                       if (import_process_service(ctx, share)!= 0) {
+               werr = import_process_service(conf_ctx,
+                                             servicename,
+                                             num_params,
+                                             (const char **)param_names,
+                                             (const char **)param_values);
+               if (!W_ERROR_IS_OK(werr)) {
+                       goto done;
+               }
+       } else {
+               char **share_names, ***param_names, ***param_values;
+               uint32_t num_shares, *num_params, sidx;
+
+               werr = smbconf_get_config(txt_ctx, mem_ctx,
+                                         &num_shares,
+                                         &share_names,
+                                         &num_params,
+                                         &param_names,
+                                         &param_values);
+               if (!W_ERROR_IS_OK(werr)) {
+                       goto done;
+               }
+               if (!opt_testmode) {
+                       werr = smbconf_drop(conf_ctx);
+                       if (!W_ERROR_IS_OK(werr)) {
+                               goto done;
+                       }
+               }
+               for (sidx = 0; sidx < num_shares; sidx++) {
+                       werr = import_process_service(conf_ctx,
+                                       share_names[sidx],
+                                       num_params[sidx],
+                                       (const char **)param_names[sidx],
+                                       (const char **)param_values[sidx]);
+                       if (!W_ERROR_IS_OK(werr)) {
                                goto done;
                        }
                }
-       }
-
-       if ((servicename != NULL) && !service_found) {
-               d_printf("Share %s not found in file %s\n",
-                        servicename, filename);
-               goto done;
-
        }
 
        ret = 0;
 
 done:
-       TALLOC_FREE(ctx);
+       TALLOC_FREE(mem_ctx);
        return ret;
 }
 
-int net_conf_listshares(int argc, const char **argv)
+static int net_conf_listshares(struct smbconf_ctx *conf_ctx,
+                              int argc, const char **argv)
 {
        WERROR werr = WERR_OK;
        int ret = -1;
-       struct registry_key *key;
-       uint32 idx = 0;
-       char *subkey_name = NULL;
-       TALLOC_CTX *ctx;
+       uint32_t count, num_shares = 0;
+       char **share_names = NULL;
+       TALLOC_CTX *mem_ctx;
 
-       ctx = talloc_init("listshares");
+       mem_ctx = talloc_stackframe();
 
        if (argc != 0) {
                net_conf_listshares_usage(argc, argv);
                goto done;
        }
 
-       werr = libnet_smbconf_open_basepath(ctx, SEC_RIGHTS_ENUM_SUBKEYS, &key);
+       werr = smbconf_get_share_names(conf_ctx, mem_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;
 
 done:
-       TALLOC_FREE(ctx);
+       TALLOC_FREE(mem_ctx);
        return ret;
 }
 
-int net_conf_drop(int argc, const char **argv)
+static int net_conf_drop(struct smbconf_ctx *conf_ctx,
+                        int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr;
@@ -588,7 +413,7 @@ int net_conf_drop(int argc, const char **argv)
                goto done;
        }
 
-       werr = drop_smbconf_internal(NULL);
+       werr = smbconf_drop(conf_ctx);
        if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error deleting configuration: %s\n",
                          dos_errstr(werr));
@@ -601,49 +426,71 @@ done:
        return ret;
 }
 
-int net_conf_showshare(int argc, const char **argv)
+static int net_conf_showshare(struct smbconf_ctx *conf_ctx,
+                             int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
-       struct registry_key *key = NULL;
-       TALLOC_CTX *ctx;
+       const char *sharename = NULL;
+       TALLOC_CTX *mem_ctx;
+       uint32_t num_params;
+       uint32_t count;
+       char **param_names;
+       char **param_values;
 
-       ctx = talloc_init("showshare");
+       mem_ctx = talloc_stackframe();
 
        if (argc != 1) {
                net_conf_showshare_usage(argc, argv);
                goto done;
        }
 
-       werr = libnet_smbconf_open_path(ctx, argv[0], REG_KEY_READ, &key);
+       sharename = talloc_strdup_lower(mem_ctx, argv[0]);
+       if (sharename == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
+
+       werr = smbconf_get_share(conf_ctx, mem_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;
 
 done:
-       TALLOC_FREE(ctx);
+       TALLOC_FREE(mem_ctx);
        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 smbconf API.
+ */
+static int net_conf_addshare(struct smbconf_ctx *conf_ctx,
+                            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;
        const char *guest_ok = "no";
        const char *writeable = "no";
        SMB_STRUCT_STAT sbuf;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
 
        switch (argc) {
                case 0:
@@ -689,10 +536,14 @@ 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]);
+                       sharename = talloc_strdup_lower(mem_ctx, argv[0]);
+                       if (sharename == NULL) {
+                               d_printf("error: out of memory!\n");
+                               goto done;
+                       }
+
                        break;
        }
 
@@ -723,6 +574,12 @@ int net_conf_addshare(int argc, const char **argv)
                goto done;
        }
 
+       if (smbconf_share_exists(conf_ctx, sharename)) {
+               d_fprintf(stderr, "ERROR: share %s already exists.\n",
+                         sharename);
+               goto done;
+       }
+
        /* validate path */
 
        if (path[0] != '/') {
@@ -752,80 +609,123 @@ int net_conf_addshare(int argc, const char **argv)
         * create the share
         */
 
-       werr = libnet_smbconf_reg_createkey_internal(NULL, argv[0], &newkey);
+       werr = smbconf_create_share(conf_ctx, 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 = libnet_smbconf_reg_setvalue_internal(newkey, "path", path);
-       if (!W_ERROR_IS_OK(werr))
+       werr = smbconf_set_parameter(conf_ctx, 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 = libnet_smbconf_reg_setvalue_internal(newkey, "comment",
-                                                           comment);
-               if (!W_ERROR_IS_OK(werr))
+               werr = smbconf_set_parameter(conf_ctx, 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 = libnet_smbconf_reg_setvalue_internal(newkey, "guest ok",
-                                                   guest_ok);
-       if (!W_ERROR_IS_OK(werr))
+       werr = smbconf_set_parameter(conf_ctx, 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 = libnet_smbconf_reg_setvalue_internal(newkey, "writeable",
-                                                   writeable);
-       if (!W_ERROR_IS_OK(werr))
+       werr = smbconf_set_parameter(conf_ctx, 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);
+       TALLOC_FREE(mem_ctx);
        return ret;
 }
 
-int net_conf_delshare(int argc, const char **argv)
+static int net_conf_delshare(struct smbconf_ctx *conf_ctx,
+                            int argc, const char **argv)
 {
        int ret = -1;
        const char *sharename = NULL;
+       WERROR werr = WERR_OK;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
 
        if (argc != 1) {
                net_conf_delshare_usage(argc, argv);
                goto done;
        }
-       sharename = argv[0];
+       sharename = talloc_strdup_lower(mem_ctx, argv[0]);
+       if (sharename == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
 
-       if (W_ERROR_IS_OK(reg_delkey_internal(NULL, sharename))) {
-               ret = 0;
+       werr = smbconf_delete_share(conf_ctx, 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:
+       TALLOC_FREE(mem_ctx);
        return ret;
 }
 
-static int net_conf_setparm(int argc, const char **argv)
+static int net_conf_setparm(struct smbconf_ctx *conf_ctx,
+                           int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
        char *service = NULL;
        char *param = NULL;
        const char *value_str = NULL;
-       TALLOC_CTX *ctx;
-
-       ctx = talloc_init("setparm");
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
 
        if (argc != 3) {
                net_conf_setparm_usage(argc, argv);
                goto done;
        }
-       service = strdup_lower(argv[0]);
-       param = strdup_lower(argv[1]);
+       service = talloc_strdup_lower(mem_ctx, argv[0]);
+       if (service == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
+       param = talloc_strdup_lower(mem_ctx, argv[1]);
+       if (param == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
        value_str = argv[2];
 
-       werr = libnet_smbconf_setparm(ctx, service, param, value_str);
+       if (!smbconf_share_exists(conf_ctx, service)) {
+               werr = smbconf_create_share(conf_ctx, service);
+               if (!W_ERROR_IS_OK(werr)) {
+                       d_fprintf(stderr, "Error creating share '%s': %s\n",
+                                 service, dos_errstr(werr));
+                       goto done;
+               }
+       }
+
+       werr = smbconf_set_parameter(conf_ctx, service, param, value_str);
 
        if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error setting value '%s': %s\n",
@@ -836,30 +736,38 @@ static int net_conf_setparm(int argc, const char **argv)
        ret = 0;
 
 done:
-       SAFE_FREE(service);
-       TALLOC_FREE(ctx);
+       TALLOC_FREE(mem_ctx);
        return ret;
 }
 
-static int net_conf_getparm(int argc, const char **argv)
+static int net_conf_getparm(struct smbconf_ctx *conf_ctx,
+                           int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
        char *service = NULL;
        char *param = NULL;
-       struct registry_value *value = NULL;
-       TALLOC_CTX *ctx;
+       char *valstr = NULL;
+       TALLOC_CTX *mem_ctx;
 
-       ctx = talloc_init("getparm");
+       mem_ctx = talloc_stackframe();
 
        if (argc != 2) {
                net_conf_getparm_usage(argc, argv);
                goto done;
        }
-       service = strdup_lower(argv[0]);
-       param = strdup_lower(argv[1]);
+       service = talloc_strdup_lower(mem_ctx, argv[0]);
+       if (service == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
+       param = talloc_strdup_lower(mem_ctx, argv[1]);
+       if (param == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
 
-       werr = libnet_smbconf_getparm(ctx, service, param, &value);
+       werr = smbconf_get_parameter(conf_ctx, mem_ctx, service, param, &valstr);
 
        if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
                d_fprintf(stderr,
@@ -877,34 +785,39 @@ static int net_conf_getparm(int argc, const char **argv)
                goto done;
        }
 
-       d_printf("%s\n", format_value(ctx, value));
+       d_printf("%s\n", valstr);
 
        ret = 0;
 done:
-       SAFE_FREE(service);
-       SAFE_FREE(param);
-       TALLOC_FREE(ctx);
+       TALLOC_FREE(mem_ctx);
        return ret;
 }
 
-static int net_conf_delparm(int argc, const char **argv)
+static int net_conf_delparm(struct smbconf_ctx *conf_ctx,
+                           int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
        char *service = NULL;
        char *param = NULL;
-       TALLOC_CTX *ctx;
-
-       ctx = talloc_init("delparm");
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
 
        if (argc != 2) {
                net_conf_delparm_usage(argc, argv);
                goto done;
        }
-       service = strdup_lower(argv[0]);
-       param = strdup_lower(argv[1]);
+       service = talloc_strdup_lower(mem_ctx, argv[0]);
+       if (service == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
+       param = talloc_strdup_lower(mem_ctx, argv[1]);
+       if (param == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
 
-       werr = libnet_smbconf_delparm(ctx, service, param);
+       werr = smbconf_delete_parameter(conf_ctx, service, param);
 
        if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
                d_fprintf(stderr,
@@ -925,9 +838,195 @@ static int net_conf_delparm(int argc, const char **argv)
        ret = 0;
 
 done:
+       TALLOC_FREE(mem_ctx);
+       return ret;
+}
+
+static int net_conf_getincludes(struct smbconf_ctx *conf_ctx,
+                               int argc, const char **argv)
+{
+       WERROR werr;
+       uint32_t num_includes;
+       uint32_t count;
+       char *service;
+       char **includes = NULL;
+       int ret = -1;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+       if (argc != 1) {
+               net_conf_getincludes_usage(argc, argv);
+               goto done;
+       }
+
+       service = talloc_strdup_lower(mem_ctx, argv[0]);
+       if (service == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
+
+       werr = smbconf_get_includes(conf_ctx, mem_ctx, service,
+                                   &num_includes, &includes);
+       if (!W_ERROR_IS_OK(werr)) {
+               d_printf("error getting includes: %s\n", dos_errstr(werr));
+               goto done;
+       }
+
+       for (count = 0; count < num_includes; count++) {
+               d_printf("include = %s\n", includes[count]);
+       }
+
+       ret = 0;
+
+done:
+       TALLOC_FREE(mem_ctx);
+       return ret;
+}
+
+static int net_conf_setincludes(struct smbconf_ctx *conf_ctx,
+                               int argc, const char **argv)
+{
+       WERROR werr;
+       char *service;
+       uint32_t num_includes;
+       const char **includes;
+       int ret = -1;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+       if (argc < 1) {
+               net_conf_setincludes_usage(argc, argv);
+               goto done;
+       }
+
+       service = talloc_strdup_lower(mem_ctx, argv[0]);
+       if (service == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
+
+       num_includes = argc - 1;
+       if (num_includes == 0) {
+               includes = NULL;
+       } else {
+               includes = argv + 1;
+       }
+
+       werr = smbconf_set_includes(conf_ctx, service, num_includes, includes);
+       if (!W_ERROR_IS_OK(werr)) {
+               d_printf("error setting includes: %s\n", dos_errstr(werr));
+               goto done;
+       }
+
+       ret = 0;
+
+done:
+       TALLOC_FREE(mem_ctx);
+       return ret;
+}
+
+static int net_conf_delincludes(struct smbconf_ctx *conf_ctx,
+                               int argc, const char **argv)
+{
+       WERROR werr;
+       char *service;
+       int ret = -1;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+
+       if (argc != 1) {
+               net_conf_delincludes_usage(argc, argv);
+               goto done;
+       }
+
+       service = talloc_strdup_lower(mem_ctx, argv[0]);
+       if (service == NULL) {
+               d_printf("error: out of memory!\n");
+               goto done;
+       }
+
+       werr = smbconf_delete_includes(conf_ctx, service);
+       if (!W_ERROR_IS_OK(werr)) {
+               d_printf("error deleting includes: %s\n", dos_errstr(werr));
+               goto done;
+       }
+
+       ret = 0;
+
+done:
+       TALLOC_FREE(mem_ctx);
+       return ret;
+}
+
+
+/**********************************************************************
+ *
+ * Wrapper and net_conf_run_function mechanism.
+ *
+ **********************************************************************/
+
+/**
+ * Wrapper function to call the main conf functions.
+ * The wrapper calls handles opening and closing of the
+ * configuration.
+ */
+static int net_conf_wrap_function(int (*fn)(struct smbconf_ctx *,
+                                           int, const char **),
+                                 int argc, const char **argv)
+{
+       WERROR werr;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+       struct smbconf_ctx *conf_ctx;
+       int ret = -1;
+
+       werr = smbconf_init(mem_ctx, &conf_ctx, "registry:");
+
+       if (!W_ERROR_IS_OK(werr)) {
+               return -1;
+       }
+
+       ret = fn(conf_ctx, argc, argv);
+
+       smbconf_shutdown(conf_ctx);
+
        return ret;
 }
 
+/*
+ * We need a functable struct of our own, because the
+ * functions are called through a wrapper that handles
+ * the opening and closing of the configuration, and so on.
+ */
+struct conf_functable {
+       const char *funcname;
+       int (*fn)(struct smbconf_ctx *ctx, int argc, const char **argv);
+       const char *helptext;
+};
+
+/**
+ * This imitates net_run_function2 but calls the main functions
+ * through the wrapper net_conf_wrap_function().
+ */
+static int net_conf_run_function(int argc, const char **argv,
+                                const char *whoami,
+                                struct conf_functable *table)
+{
+       int i;
+
+       if (argc != 0) {
+               for (i=0; table[i].funcname; i++) {
+                       if (StrCaseCmp(argv[0], table[i].funcname) == 0)
+                               return net_conf_wrap_function(table[i].fn,
+                                                             argc-1,
+                                                             argv+1);
+               }
+       }
+
+       for (i=0; table[i].funcname; i++) {
+               d_printf("%s %-15s %s\n", whoami, table[i].funcname,
+                        table[i].helptext);
+       }
+
+       return -1;
+}
+
 /*
  * Entry-point for all the CONF functions.
  */
@@ -935,40 +1034,38 @@ done:
 int net_conf(int argc, const char **argv)
 {
        int ret = -1;
-       struct functable2 func[] = {
+       struct conf_functable func_table[] = {
                {"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,
-                "List the registry shares."},
+                "List the share names."},
                {"drop", net_conf_drop,
-                "Delete the complete configuration from registry."},
+                "Delete the complete configuration."},
                {"showshare", net_conf_showshare,
-                "Show the definition of a registry share."},
+                "Show the definition of a share."},
                {"addshare", net_conf_addshare,
-                "Create a new registry share."},
+                "Create a new share."},
                {"delshare", net_conf_delshare,
-                "Delete a registry share."},
+                "Delete a share."},
                {"setparm", net_conf_setparm,
                 "Store a parameter."},
                {"getparm", net_conf_getparm,
                 "Retrieve the value of a parameter."},
                {"delparm", net_conf_delparm,
                 "Delete a parameter."},
+               {"getincludes", net_conf_getincludes,
+                "Show the includes of a share definition."},
+               {"setincludes", net_conf_setincludes,
+                "Set includes for a share."},
+               {"delincludes", net_conf_delincludes,
+                "Delete includes from a share definition."},
                {NULL, NULL, NULL}
        };
 
-       if (!registry_init_regdb()) {
-               d_fprintf(stderr, "Error initializing the registry!\n");
-               goto done;
-       }
-
-       ret = net_run_function2(argc, argv, "net conf", func);
+       ret = net_conf_run_function(argc, argv, "net conf", func_table);
 
-       regdb_close();
-
-done:
        return ret;
 }