Introduce a libnet_conf context created by libnet_conf_open().
authorMichael Adam <obnox@samba.org>
Sun, 13 Jan 2008 00:40:05 +0000 (01:40 +0100)
committerMichael Adam <obnox@samba.org>
Sun, 13 Jan 2008 01:14:34 +0000 (02:14 +0100)
The libnet_conf_ctx stores the information necessary to interoperate
with the configuration. It is created by calling libnet_conf_open()
and destroyed by calling libnet_conf_close(). The context is passed
to all the libnet_conf functions. It currently stores the token to
access the registry. Later, it could store more data, e.g. the server
to connect to, credentials, and so on. For support of other backends
than registry or support of remote configuration, only the open
function will have to be changed.

In net_conf, the calls to the actual net_conf functions is wrapped
into a function that calls libnet_conf_open()/_close(). Thus an
individual variant of net_conf_runfunction2() and functable2 is
used to cope with functions being called by the wrapper with the
additional libnet_conf_ctx argument.

Michael
(This used to be commit c2a9346faa26e79af5948197a1b322e545f0ed09)

source3/lib/netapi/serverinfo.c
source3/libnet/libnet.h
source3/libnet/libnet_conf.c
source3/libnet/libnet_conf.h [new file with mode: 0644]
source3/libnet/libnet_join.c
source3/utils/net_conf.c

index 0e356e0ee7c07cfb2083aacc79f4e5dbb2fd4151..67680ba55afb9b5439ac7d759ec5b2782503925b 100644 (file)
@@ -149,6 +149,10 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx,
                                         uint8_t *buffer,
                                         uint32_t *parm_error)
 {
+       WERROR werr;
+       struct libnet_conf_ctx *conf_ctx;
+       TALLOC_CTX *mem_ctx;
+
        struct srvsvc_NetSrvInfo1005 *info1005;
 
        if (!buffer) {
@@ -167,8 +171,20 @@ static WERROR NetServerSetInfoLocal_1005(struct libnetapi_ctx *ctx,
                return WERR_NOT_SUPPORTED;
        }
 
-       return libnet_conf_set_global_parameter("server string",
+       mem_ctx = talloc_stackframe();
+       werr = libnet_conf_open(mem_ctx, &conf_ctx);
+       if (!W_ERROR_IS_OK(werr)) {
+               goto done;
+       }
+
+       werr = libnet_conf_set_global_parameter(conf_ctx,
+                                               "server string",
                                                info1005->comment);
+
+done:
+       libnet_conf_close(conf_ctx);
+       TALLOC_FREE(mem_ctx);
+       return werr;
 }
 
 static WERROR NetServerSetInfoLocal(struct libnetapi_ctx *ctx,
index fa24c3b40a84d03ee7fe4cde910d0129d60bf5dc..d6238ca98209c5277d68ef1aeda62fa4e15407e3 100644 (file)
@@ -21,6 +21,7 @@
 #define __LIBNET_H__
 
 #include "libnet/libnet_join.h"
+#include "libnet/libnet_conf.h"
 #include "libnet/libnet_proto.h"
 
 #endif
index 47b4800d80020bda1275bca088e54f922f732952..8e44e4f52531eb26a132fb6617f1701c8fe2c5f0 100644 (file)
 #include "includes.h"
 #include "libnet/libnet.h"
 
-/*
- * yuck - static variable to keep track of the registry initialization. 
- */
-static bool registry_initialized = false;
-
 /**********************************************************************
  *
  * Helper functions (mostly registry related)
@@ -59,20 +54,21 @@ static WERROR libnet_conf_add_string_to_array(TALLOC_CTX *mem_ctx,
        return WERR_OK;
 }
 
-static WERROR libnet_conf_reg_initialize(void)
+static WERROR libnet_conf_reg_initialize(struct libnet_conf_ctx *ctx)
 {
        WERROR werr = WERR_OK;
 
-       if (registry_initialized) {
-               goto done;
-       }
-
        if (!registry_init_regdb()) {
                werr = WERR_REG_IO_FAILURE;
                goto done;
        }
 
-       registry_initialized = true;
+       werr = ntstatus_to_werror(registry_create_admin_token(ctx,
+                                                             &(ctx->token)));
+       if (!W_ERROR_IS_OK(werr)) {
+               DEBUG(1, ("Error creating admin token\n"));
+               goto done;
+       }
 
 done:
        return werr;
@@ -82,40 +78,33 @@ done:
  * Open a registry key specified by "path"
  */
 static WERROR libnet_conf_reg_open_path(TALLOC_CTX *mem_ctx,
+                                       struct libnet_conf_ctx *ctx,
                                        const char *path,
                                        uint32 desired_access,
                                        struct registry_key **key)
 {
        WERROR werr = WERR_OK;
-       NT_USER_TOKEN *token = NULL;
-       TALLOC_CTX *tmp_ctx = NULL;
 
-       if (path == NULL) {
-               DEBUG(1, ("Error: NULL path string given\n"));
+       if (ctx == NULL) {
+               DEBUG(1, ("Error: configuration is not open!\n"));
                werr = WERR_INVALID_PARAM;
                goto done;
        }
 
-       tmp_ctx = talloc_new(mem_ctx);
-       if (tmp_ctx == NULL) {
-               werr = WERR_NOMEM;
-               goto done;
-       }
-
-       werr = libnet_conf_reg_initialize();
-       if (!W_ERROR_IS_OK(werr)) {
-               DEBUG(1, ("Error initializing registry: %s\n",
-                         dos_errstr(werr)));
+       if (ctx->token == NULL) {
+               DEBUG(1, ("Error: token missing from libnet_conf_ctx. "
+                         "was libnet_conf_open() called?\n"));
+               werr = WERR_INVALID_PARAM;
                goto done;
        }
 
-       werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
-       if (!W_ERROR_IS_OK(werr)) {
-               DEBUG(1, ("Error creating admin token\n"));
+       if (path == NULL) {
+               DEBUG(1, ("Error: NULL path string given\n"));
+               werr = WERR_INVALID_PARAM;
                goto done;
        }
 
-       werr = reg_open_path(mem_ctx, path, desired_access, token, key);
+       werr = reg_open_path(mem_ctx, path, desired_access, ctx->token, key);
 
        if (!W_ERROR_IS_OK(werr)) {
                DEBUG(1, ("Error opening registry path '%s': %s\n",
@@ -123,14 +112,14 @@ static WERROR libnet_conf_reg_open_path(TALLOC_CTX *mem_ctx,
        }
 
 done:
-       TALLOC_FREE(tmp_ctx);
        return werr;
 }
 
 /**
  * Open a subkey of KEY_SMBCONF (i.e a service)
  */
-static WERROR libnet_conf_reg_open_service_key(TALLOC_CTX *ctx,
+static WERROR libnet_conf_reg_open_service_key(TALLOC_CTX *mem_ctx,
+                                              struct libnet_conf_ctx *ctx,
                                               const char *servicename,
                                               uint32 desired_access,
                                               struct registry_key **key)
@@ -144,9 +133,10 @@ static WERROR libnet_conf_reg_open_service_key(TALLOC_CTX *ctx,
                goto done;
        }
 
-       path = talloc_asprintf(ctx, "%s\\%s", KEY_SMBCONF, servicename);
+       path = talloc_asprintf(mem_ctx, "%s\\%s", KEY_SMBCONF, servicename);
 
-       werr = libnet_conf_reg_open_path(ctx, path, desired_access, key);
+       werr = libnet_conf_reg_open_path(mem_ctx, ctx, path, desired_access,
+                                        key);
 
 done:
        TALLOC_FREE(path);
@@ -156,11 +146,13 @@ done:
 /**
  * open the base key KEY_SMBCONF
  */
-static WERROR libnet_conf_reg_open_base_key(TALLOC_CTX *ctx,
+static WERROR libnet_conf_reg_open_base_key(TALLOC_CTX *mem_ctx,
+                                           struct libnet_conf_ctx *ctx,
                                            uint32 desired_access,
                                            struct registry_key **key)
 {
-       return libnet_conf_reg_open_path(ctx, KEY_SMBCONF, desired_access, key);
+       return libnet_conf_reg_open_path(mem_ctx, ctx, KEY_SMBCONF,
+                                        desired_access, key);
 }
 
 /**
@@ -186,7 +178,8 @@ static bool libnet_conf_value_exists(struct registry_key *key,
 /**
  * create a subkey of KEY_SMBCONF
  */
-static WERROR libnet_conf_reg_create_service_key(TALLOC_CTX *ctx,
+static WERROR libnet_conf_reg_create_service_key(TALLOC_CTX *mem_ctx,
+                                                struct libnet_conf_ctx *ctx,
                                                 const char * subkeyname,
                                                 struct registry_key **newkey)
 {
@@ -198,18 +191,18 @@ static WERROR libnet_conf_reg_create_service_key(TALLOC_CTX *ctx,
        /* 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))) {
+       if (!(create_ctx = talloc_new(mem_ctx))) {
                werr = WERR_NOMEM;
                goto done;
        }
 
-       werr = libnet_conf_reg_open_base_key(create_ctx, REG_KEY_WRITE,
+       werr = libnet_conf_reg_open_base_key(create_ctx, ctx, REG_KEY_WRITE,
                                             &create_parent);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
        }
 
-       werr = reg_createkey(ctx, create_parent, subkeyname,
+       werr = reg_createkey(mem_ctx, create_parent, subkeyname,
                             REG_KEY_WRITE, newkey, &action);
        if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
                DEBUG(10, ("Key '%s' already exists.\n", subkeyname));
@@ -414,16 +407,72 @@ done:
        return werr;
 }
 
+static int libnet_conf_destroy_ctx(struct libnet_conf_ctx *ctx)
+{
+       return regdb_close();
+}
+
 /**********************************************************************
  *
  * The actual net conf api functions, that are exported.
  *
  **********************************************************************/
 
+/**
+ * Open the configuration.
+ *
+ * This should be the first function in a sequence of calls to libnet_conf
+ * functions:
+ *
+ * Upon success, this creates and returns the conf context
+ * that should be passed around in subsequent calls to the other
+ * libnet_conf functions.
+ *
+ * After the work with the configuration is completed, libnet_conf_close()
+ * should be called.
+ */
+WERROR libnet_conf_open(TALLOC_CTX *mem_ctx, struct libnet_conf_ctx **conf_ctx)
+{
+       WERROR werr = WERR_OK;
+       struct libnet_conf_ctx *ctx;
+
+       if (conf_ctx == NULL) {
+               return WERR_INVALID_PARAM;
+       }
+
+       ctx = TALLOC_ZERO_P(mem_ctx, struct libnet_conf_ctx);
+       if (ctx == NULL) {
+               return WERR_NOMEM;
+       }
+
+       werr = libnet_conf_reg_initialize(ctx);
+       if (!W_ERROR_IS_OK(werr)) {
+               goto fail;
+       }
+
+       talloc_set_destructor(ctx, libnet_conf_destroy_ctx);
+
+       *conf_ctx = ctx;
+       return werr;
+
+fail:
+       TALLOC_FREE(ctx);
+       return werr;
+}
+
+/**
+ * Close the configuration.
+ */
+void libnet_conf_close(struct libnet_conf_ctx *ctx)
+{
+       /* this also closes the registry (by destructor): */
+       TALLOC_FREE(ctx);
+}
+
 /**
  * Drop the whole configuration (restarting empty).
  */
-WERROR libnet_conf_drop(void)
+WERROR libnet_conf_drop(struct libnet_conf_ctx *ctx)
 {
        char *path, *p;
        WERROR werr = WERR_OK;
@@ -439,7 +488,7 @@ WERROR libnet_conf_drop(void)
        }
        p = strrchr(path, '\\');
        *p = '\0';
-       werr = libnet_conf_reg_open_path(mem_ctx, path, REG_KEY_WRITE,
+       werr = libnet_conf_reg_open_path(mem_ctx, ctx, path, REG_KEY_WRITE,
                                         &parent_key);
 
        if (!W_ERROR_IS_OK(werr)) {
@@ -469,7 +518,8 @@ done:
  *  param_names  : list of lists of parameter names for each share
  *  param_values : list of lists of parameter values for each share
  */
-WERROR libnet_conf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
+WERROR libnet_conf_get_config(TALLOC_CTX *mem_ctx,
+                             struct libnet_conf_ctx *ctx, uint32_t *num_shares,
                              char ***share_names, uint32_t **num_params,
                              char ****param_names, char ****param_values)
 {
@@ -496,7 +546,7 @@ WERROR libnet_conf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
                goto done;
        }
 
-       werr = libnet_conf_get_share_names(tmp_ctx, &tmp_num_shares,
+       werr = libnet_conf_get_share_names(tmp_ctx, ctx, &tmp_num_shares,
                                           &tmp_share_names);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
@@ -514,7 +564,8 @@ WERROR libnet_conf_get_config(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
        }
 
        for (count = 0; count < tmp_num_shares; count++) {
-               werr = libnet_conf_get_share(mem_ctx, tmp_share_names[count],
+               werr = libnet_conf_get_share(mem_ctx, ctx,
+                                            tmp_share_names[count],
                                             &tmp_num_params[count],
                                             &tmp_param_names[count],
                                             &tmp_param_values[count]);
@@ -543,11 +594,12 @@ done:
        return werr;
 }
 
-
 /**
  * get the list of share names defined in the configuration.
  */
-WERROR libnet_conf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
+WERROR libnet_conf_get_share_names(TALLOC_CTX *mem_ctx,
+                                  struct libnet_conf_ctx *ctx,
+                                  uint32_t *num_shares,
                                   char ***share_names)
 {
        uint32_t count;
@@ -570,7 +622,7 @@ WERROR libnet_conf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
        }
 
        /* make sure "global" is always listed first */
-       if (libnet_conf_share_exists(GLOBAL_NAME)) {
+       if (libnet_conf_share_exists(ctx, GLOBAL_NAME)) {
                werr = libnet_conf_add_string_to_array(tmp_ctx,
                                                       &tmp_share_names,
                                                       0, GLOBAL_NAME);
@@ -580,8 +632,8 @@ WERROR libnet_conf_get_share_names(TALLOC_CTX *mem_ctx, uint32_t *num_shares,
                added_count++;
        }
 
-       werr = libnet_conf_reg_open_base_key(tmp_ctx, SEC_RIGHTS_ENUM_SUBKEYS,
-                                            &key);
+       werr = libnet_conf_reg_open_base_key(tmp_ctx, ctx,
+                                            SEC_RIGHTS_ENUM_SUBKEYS, &key);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
        }
@@ -624,14 +676,15 @@ done:
 /**
  * check if a share/service of a given name exists
  */
-bool libnet_conf_share_exists(const char *servicename)
+bool libnet_conf_share_exists(struct libnet_conf_ctx *ctx,
+                             const char *servicename)
 {
        bool ret = false;
        WERROR werr = WERR_OK;
        TALLOC_CTX *mem_ctx = talloc_stackframe();
        struct registry_key *key = NULL;
 
-       werr = libnet_conf_reg_open_service_key(mem_ctx, servicename,
+       werr = libnet_conf_reg_open_service_key(mem_ctx, ctx, servicename,
                                                REG_KEY_READ, &key);
        if (W_ERROR_IS_OK(werr)) {
                ret = true;
@@ -644,18 +697,20 @@ bool libnet_conf_share_exists(const char *servicename)
 /**
  * Add a service if it does not already exist.
  */
-WERROR libnet_conf_create_share(const char *servicename)
+WERROR libnet_conf_create_share(struct libnet_conf_ctx *ctx,
+                               const char *servicename)
 {
        WERROR werr;
        TALLOC_CTX *mem_ctx = talloc_stackframe();
        struct registry_key *key = NULL;
 
-       if (libnet_conf_share_exists(servicename)) {
+       if (libnet_conf_share_exists(ctx, servicename)) {
                werr = WERR_ALREADY_EXISTS;
                goto done;
        }
 
-       werr = libnet_conf_reg_create_service_key(mem_ctx, servicename, &key);
+       werr = libnet_conf_reg_create_service_key(mem_ctx, ctx, servicename,
+                                                 &key);
 
 done:
        TALLOC_FREE(mem_ctx);
@@ -665,14 +720,14 @@ done:
 /**
  * get a definition of a share (service) from configuration.
  */
-WERROR libnet_conf_get_share(TALLOC_CTX *mem_ctx, const char *servicename,
-                            uint32_t *num_params, char ***param_names,
-                            char ***param_values)
+WERROR libnet_conf_get_share(TALLOC_CTX *mem_ctx, struct libnet_conf_ctx *ctx,
+                            const char *servicename, uint32_t *num_params,
+                            char ***param_names, char ***param_values)
 {
        WERROR werr = WERR_OK;
        struct registry_key *key = NULL;
 
-       werr = libnet_conf_reg_open_service_key(mem_ctx, servicename,
+       werr = libnet_conf_reg_open_service_key(mem_ctx, ctx, servicename,
                                                REG_KEY_READ, &key);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
@@ -689,13 +744,14 @@ done:
 /**
  * delete a service from configuration
  */
-WERROR libnet_conf_delete_share(const char *servicename)
+WERROR libnet_conf_delete_share(struct libnet_conf_ctx *ctx,
+                               const char *servicename)
 {
        WERROR werr = WERR_OK;
        struct registry_key *key = NULL;
-       TALLOC_CTX *ctx = talloc_stackframe();
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
 
-       werr = libnet_conf_reg_open_base_key(ctx, REG_KEY_WRITE, &key);
+       werr = libnet_conf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, &key);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
        }
@@ -703,14 +759,15 @@ WERROR libnet_conf_delete_share(const char *servicename)
        werr = reg_deletekey_recursive(key, key, servicename);
 
 done:
-       TALLOC_FREE(ctx);
+       TALLOC_FREE(mem_ctx);
        return werr;
 }
 
 /**
  * set a configuration parameter to the value provided.
  */
-WERROR libnet_conf_set_parameter(const char *service,
+WERROR libnet_conf_set_parameter(struct libnet_conf_ctx *ctx,
+                                const char *service,
                                 const char *param,
                                 const char *valstr)
 {
@@ -718,15 +775,15 @@ WERROR libnet_conf_set_parameter(const char *service,
        struct registry_key *key = NULL;
        TALLOC_CTX *mem_ctx = talloc_stackframe();
 
-       if (!libnet_conf_share_exists(service)) {
-               werr = libnet_conf_create_share(service);
+       if (!libnet_conf_share_exists(ctx, service)) {
+               werr = libnet_conf_create_share(ctx, service);
                if (!W_ERROR_IS_OK(werr)) {
                        goto done;
                }
        }
 
-       werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_WRITE,
-                                               &key);
+       werr = libnet_conf_reg_open_service_key(mem_ctx, ctx, service,
+                                               REG_KEY_WRITE, &key);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
        }
@@ -742,6 +799,7 @@ done:
  * get the value of a configuration parameter as a string
  */
 WERROR libnet_conf_get_parameter(TALLOC_CTX *mem_ctx,
+                                struct libnet_conf_ctx *ctx,
                                 const char *service,
                                 const char *param,
                                 char **valstr)
@@ -755,13 +813,13 @@ WERROR libnet_conf_get_parameter(TALLOC_CTX *mem_ctx,
                goto done;
        }
 
-       if (!libnet_conf_share_exists(service)) {
+       if (!libnet_conf_share_exists(ctx, service)) {
                werr = WERR_NO_SUCH_SERVICE;
                goto done;
        }
 
-       werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_READ,
-                                               &key);
+       werr = libnet_conf_reg_open_service_key(mem_ctx, ctx, service,
+                                               REG_KEY_READ, &key);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
        }
@@ -791,17 +849,19 @@ done:
 /**
  * delete a parameter from configuration
  */
-WERROR libnet_conf_delete_parameter(const char *service, const char *param)
+WERROR libnet_conf_delete_parameter(struct libnet_conf_ctx *ctx,
+                                   const char *service, const char *param)
 {
        struct registry_key *key = NULL;
        WERROR werr = WERR_OK;
        TALLOC_CTX *mem_ctx = talloc_stackframe();
 
-       if (!libnet_conf_share_exists(service)) {
+       if (!libnet_conf_share_exists(ctx, service)) {
                return WERR_NO_SUCH_SERVICE;
        }
 
-       werr = libnet_conf_reg_open_service_key(mem_ctx, service, REG_KEY_ALL,
+       werr = libnet_conf_reg_open_service_key(mem_ctx, ctx, service,
+                                               REG_KEY_ALL,
                                                &key);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
@@ -826,8 +886,9 @@ done:
  *
  **********************************************************************/
 
-WERROR libnet_conf_set_global_parameter(const char *param, const char *val)
+WERROR libnet_conf_set_global_parameter(struct libnet_conf_ctx *ctx,
+                                       const char *param, const char *val)
 {
-       return libnet_conf_set_parameter(GLOBAL_NAME, param, val);
+       return libnet_conf_set_parameter(ctx, GLOBAL_NAME, param, val);
 }
 
diff --git a/source3/libnet/libnet_conf.h b/source3/libnet/libnet_conf.h
new file mode 100644 (file)
index 0000000..b518c0e
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  libnet smbconf registry support
+ *  Copyright (C) Michael Adam 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 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIBNET_CONF_H__
+#define __LIBNET_CONF_H__
+
+struct libnet_conf_ctx {
+       NT_USER_TOKEN *token;
+};
+
+#endif
index 9b62286ecb14e730f26d7c3f450339a94875bbda..66b5461dc2252433873267bde93c48e5d250a9a3 100644 (file)
@@ -19,8 +19,7 @@
  */
 
 #include "includes.h"
-#include "libnet/libnet_join.h"
-#include "libnet/libnet_proto.h"
+#include "libnet/libnet.h"
 
 /****************************************************************
 ****************************************************************/
@@ -886,33 +885,48 @@ done:
 static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r)
 {
        WERROR werr;
+       struct libnet_conf_ctx *ctx;
+
+       werr = libnet_conf_open(r, &ctx);
+       if (!W_ERROR_IS_OK(werr)) {
+               goto done;
+       }
 
        if (!(r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE)) {
 
-               werr = libnet_conf_set_global_parameter("security", "user");
-               W_ERROR_NOT_OK_RETURN(werr);
+               werr = libnet_conf_set_global_parameter(ctx, "security", "user");
+               if (!W_ERROR_IS_OK(werr)) {
+                       goto done;
+               }
 
-               werr = libnet_conf_set_global_parameter("workgroup",
+               werr = libnet_conf_set_global_parameter(ctx, "workgroup",
                                                        r->in.domain_name);
-               return werr;
+               goto done;
        }
 
-       werr = libnet_conf_set_global_parameter("security", "domain");
-       W_ERROR_NOT_OK_RETURN(werr);
+       werr = libnet_conf_set_global_parameter(ctx, "security", "domain");
+       if (!W_ERROR_IS_OK(werr)) {
+               goto done;
+       }
 
-       werr = libnet_conf_set_global_parameter("workgroup",
+       werr = libnet_conf_set_global_parameter(ctx, "workgroup",
                                                r->out.netbios_domain_name);
-       W_ERROR_NOT_OK_RETURN(werr);
+       if (!W_ERROR_IS_OK(werr)) {
+               goto done;
+       }
 
        if (r->out.domain_is_ad) {
-               werr = libnet_conf_set_global_parameter("security", "ads");
-               W_ERROR_NOT_OK_RETURN(werr);
+               werr = libnet_conf_set_global_parameter(ctx, "security", "ads");
+               if (!W_ERROR_IS_OK(werr)) {
+                       goto done;
+               }
 
-               werr = libnet_conf_set_global_parameter("realm",
+               werr = libnet_conf_set_global_parameter(ctx, "realm",
                                                        r->out.dns_domain_name);
-               W_ERROR_NOT_OK_RETURN(werr);
        }
 
+done:
+       libnet_conf_close(ctx);
        return werr;
 }
 
@@ -922,15 +936,25 @@ static WERROR do_join_modify_vals_config(struct libnet_JoinCtx *r)
 static WERROR do_unjoin_modify_vals_config(struct libnet_UnjoinCtx *r)
 {
        WERROR werr = WERR_OK;
+       struct libnet_conf_ctx *ctx;
+
+       werr = libnet_conf_open(r, &ctx);
+       if (!W_ERROR_IS_OK(werr)) {
+               goto done;
+       }
 
        if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
 
-               werr = libnet_conf_set_global_parameter("security", "user");
-               W_ERROR_NOT_OK_RETURN(werr);
+               werr = libnet_conf_set_global_parameter(ctx, "security", "user");
+               if (!W_ERROR_IS_OK(werr)) {
+                       goto done;
+               }
        }
 
-       libnet_conf_delete_parameter(GLOBAL_NAME, "realm");
+       libnet_conf_delete_parameter(ctx, GLOBAL_NAME, "realm");
 
+done:
+       libnet_conf_close(ctx);
        return werr;
 }
 
index 38cdeacc11223f27ad9ad96ed50085392fccba6d..f212ed7b198b41c3a09299d16cfc622beb42d0c4 100644 (file)
@@ -188,6 +188,7 @@ static char *parm_valstr(TALLOC_CTX *ctx, struct parm_struct *parm,
 }
 
 static int import_process_service(TALLOC_CTX *ctx,
+                                 struct libnet_conf_ctx *conf_ctx,
                                  struct share_params *share)
 {
        int ret = -1;
@@ -210,8 +211,8 @@ static int import_process_service(TALLOC_CTX *ctx,
        if (opt_testmode) {
                d_printf("[%s]\n", servicename);
        } else {
-               if (libnet_conf_share_exists(servicename)) {
-                       werr = libnet_conf_delete_share(servicename);
+               if (libnet_conf_share_exists(conf_ctx, servicename)) {
+                       werr = libnet_conf_delete_share(conf_ctx, servicename);
                        if (!W_ERROR_IS_OK(werr)) {
                                goto done;
                        }
@@ -232,7 +233,8 @@ static int import_process_service(TALLOC_CTX *ctx,
                        if (opt_testmode) {
                                d_printf("\t%s = %s\n", parm->label, valstr);
                        } else {
-                               werr = libnet_conf_set_parameter(servicename,
+                               werr = libnet_conf_set_parameter(conf_ctx,
+                                                                servicename,
                                                                 parm->label,
                                                                 valstr);
                                if (!W_ERROR_IS_OK(werr)) {
@@ -275,7 +277,8 @@ static bool globals_exist(void)
  * the conf functions
  */
 
-static int net_conf_list(int argc, const char **argv)
+static int net_conf_list(struct libnet_conf_ctx *conf_ctx,
+                        int argc, const char **argv)
 {
        WERROR werr = WERR_OK;
        int ret = -1;
@@ -294,9 +297,8 @@ static int net_conf_list(int argc, const char **argv)
                goto done;
        }
 
-       werr = libnet_conf_get_config(ctx, &num_shares, &share_names,
-                                     &num_params, &param_names,
-                                     &param_values);
+       werr = libnet_conf_get_config(ctx, conf_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));
@@ -322,7 +324,8 @@ done:
        return ret;
 }
 
-static int net_conf_import(int argc, const char **argv)
+static int net_conf_import(struct libnet_conf_ctx *conf_ctx,
+                          int argc, const char **argv)
 {
        int ret = -1;
        const char *filename = NULL;
@@ -369,7 +372,7 @@ static int net_conf_import(int argc, const char **argv)
            strequal(servicename, GLOBAL_NAME))
        {
                service_found = true;
-               if (import_process_service(ctx, &global_share) != 0) {
+               if (import_process_service(ctx, conf_ctx, &global_share) != 0) {
                        goto done;
                }
        }
@@ -388,7 +391,7 @@ static int net_conf_import(int argc, const char **argv)
                    || strequal(servicename, lp_servicename(share->service)))
                {
                        service_found = true;
-                       if (import_process_service(ctx, share)!= 0) {
+                       if (import_process_service(ctx, conf_ctx, share)!= 0) {
                                goto done;
                        }
                }
@@ -408,7 +411,8 @@ done:
        return ret;
 }
 
-static int net_conf_listshares(int argc, const char **argv)
+static int net_conf_listshares(struct libnet_conf_ctx *conf_ctx,
+                              int argc, const char **argv)
 {
        WERROR werr = WERR_OK;
        int ret = -1;
@@ -423,7 +427,8 @@ static int net_conf_listshares(int argc, const char **argv)
                goto done;
        }
 
-       werr = libnet_conf_get_share_names(ctx, &num_shares, &share_names);
+       werr = libnet_conf_get_share_names(ctx, conf_ctx, &num_shares,
+                                          &share_names);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
        }
@@ -440,7 +445,8 @@ done:
        return ret;
 }
 
-static int net_conf_drop(int argc, const char **argv)
+static int net_conf_drop(struct libnet_conf_ctx *conf_ctx,
+                        int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr;
@@ -450,7 +456,7 @@ static int net_conf_drop(int argc, const char **argv)
                goto done;
        }
 
-       werr = libnet_conf_drop();
+       werr = libnet_conf_drop(conf_ctx);
        if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error deleting configuration: %s\n",
                          dos_errstr(werr));
@@ -463,7 +469,8 @@ done:
        return ret;
 }
 
-static int net_conf_showshare(int argc, const char **argv)
+static int net_conf_showshare(struct libnet_conf_ctx *conf_ctx,
+                             int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
@@ -483,7 +490,7 @@ static int net_conf_showshare(int argc, const char **argv)
 
        sharename = argv[0];
 
-       werr = libnet_conf_get_share(ctx, sharename, &num_params,
+       werr = libnet_conf_get_share(ctx, conf_ctx, sharename, &num_params,
                                     &param_names, &param_values);
        if (!W_ERROR_IS_OK(werr)) {
                d_printf("error getting share parameters: %s\n",
@@ -511,7 +518,8 @@ done:
  * 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)
+static int net_conf_addshare(struct libnet_conf_ctx *conf_ctx,
+                            int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
@@ -599,7 +607,7 @@ static int net_conf_addshare(int argc, const char **argv)
                goto done;
        }
 
-       if (libnet_conf_share_exists(sharename)) {
+       if (libnet_conf_share_exists(conf_ctx, sharename)) {
                d_fprintf(stderr, "ERROR: share %s already exists.\n",
                          sharename);
                goto done;
@@ -634,7 +642,7 @@ static int net_conf_addshare(int argc, const char **argv)
         * create the share
         */
 
-       werr = libnet_conf_create_share(sharename);
+       werr = libnet_conf_create_share(conf_ctx, sharename);
        if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error creating share %s: %s\n",
                          sharename, dos_errstr(werr));
@@ -645,7 +653,7 @@ static int net_conf_addshare(int argc, const char **argv)
         * fill the share with parameters
         */
 
-       werr = libnet_conf_set_parameter(sharename, "path", path);
+       werr = libnet_conf_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));
@@ -653,7 +661,8 @@ static int net_conf_addshare(int argc, const char **argv)
        }
 
        if (comment != NULL) {
-               werr = libnet_conf_set_parameter(sharename, "comment", comment);
+               werr = libnet_conf_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));
@@ -661,14 +670,16 @@ static int net_conf_addshare(int argc, const char **argv)
                }
        }
 
-       werr = libnet_conf_set_parameter(sharename, "guest ok", guest_ok);
+       werr = libnet_conf_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_conf_set_parameter(sharename, "writeable", writeable);
+       werr = libnet_conf_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));
@@ -682,7 +693,8 @@ done:
        return ret;
 }
 
-static int net_conf_delshare(int argc, const char **argv)
+static int net_conf_delshare(struct libnet_conf_ctx *conf_ctx,
+                            int argc, const char **argv)
 {
        int ret = -1;
        const char *sharename = NULL;
@@ -694,7 +706,7 @@ static int net_conf_delshare(int argc, const char **argv)
        }
        sharename = argv[0];
 
-       werr = libnet_conf_delete_share(sharename);
+       werr = libnet_conf_delete_share(conf_ctx, sharename);
        if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error deleting share %s: %s\n",
                          sharename, dos_errstr(werr));
@@ -706,7 +718,8 @@ done:
        return ret;
 }
 
-static int net_conf_setparm(int argc, const char **argv)
+static int net_conf_setparm(struct libnet_conf_ctx *conf_ctx,
+                           int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
@@ -722,8 +735,8 @@ static int net_conf_setparm(int argc, const char **argv)
        param = strdup_lower(argv[1]);
        value_str = argv[2];
 
-       if (!libnet_conf_share_exists(service)) {
-               werr = libnet_conf_create_share(service);
+       if (!libnet_conf_share_exists(conf_ctx, service)) {
+               werr = libnet_conf_create_share(conf_ctx, service);
                if (!W_ERROR_IS_OK(werr)) {
                        d_fprintf(stderr, "Error creating share '%s': %s\n",
                                  service, dos_errstr(werr));
@@ -731,7 +744,7 @@ static int net_conf_setparm(int argc, const char **argv)
                }
        }
 
-       werr = libnet_conf_set_parameter(service, param, value_str);
+       werr = libnet_conf_set_parameter(conf_ctx, service, param, value_str);
 
        if (!W_ERROR_IS_OK(werr)) {
                d_fprintf(stderr, "Error setting value '%s': %s\n",
@@ -747,7 +760,8 @@ done:
        return ret;
 }
 
-static int net_conf_getparm(int argc, const char **argv)
+static int net_conf_getparm(struct libnet_conf_ctx *conf_ctx,
+                           int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
@@ -765,7 +779,7 @@ static int net_conf_getparm(int argc, const char **argv)
        service = strdup_lower(argv[0]);
        param = strdup_lower(argv[1]);
 
-       werr = libnet_conf_get_parameter(ctx, service, param, &valstr);
+       werr = libnet_conf_get_parameter(ctx, conf_ctx, service, param, &valstr);
 
        if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
                d_fprintf(stderr,
@@ -793,7 +807,8 @@ done:
        return ret;
 }
 
-static int net_conf_delparm(int argc, const char **argv)
+static int net_conf_delparm(struct libnet_conf_ctx *conf_ctx,
+                           int argc, const char **argv)
 {
        int ret = -1;
        WERROR werr = WERR_OK;
@@ -807,7 +822,7 @@ static int net_conf_delparm(int argc, const char **argv)
        service = strdup_lower(argv[0]);
        param = strdup_lower(argv[1]);
 
-       werr = libnet_conf_delete_parameter(service, param);
+       werr = libnet_conf_delete_parameter(conf_ctx, service, param);
 
        if (W_ERROR_EQUAL(werr, WERR_NO_SUCH_SERVICE)) {
                d_fprintf(stderr,
@@ -833,6 +848,62 @@ done:
        return ret;
 }
 
+static int net_conf_wrap_function(int (*fn)(struct libnet_conf_ctx *,
+                                           int, const char **),
+                                 int argc, const char **argv)
+{
+       WERROR werr;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+       struct libnet_conf_ctx *conf_ctx;
+       int ret = -1;
+
+       werr = libnet_conf_open(mem_ctx, &conf_ctx);
+
+       if (!W_ERROR_IS_OK(werr)) {
+               return -1;
+       }
+
+       ret = fn(conf_ctx, argc, argv);
+
+       libnet_conf_close(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 libnet_conf_ctx *ctx, int argc, const char **argv);
+       const char *helptext;
+};
+
+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.
  */
@@ -840,7 +911,7 @@ 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,
@@ -864,7 +935,7 @@ int net_conf(int argc, const char **argv)
                {NULL, NULL, NULL}
        };
 
-       ret = net_run_function2(argc, argv, "net conf", func);
+       ret = net_conf_run_function(argc, argv, "net conf", func_table);
 
        return ret;
 }