summaryrefslogtreecommitdiff
path: root/source3/libnet
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libnet')
-rw-r--r--source3/libnet/libnet.h1
-rw-r--r--source3/libnet/libnet_conf.c279
-rw-r--r--source3/libnet/libnet_conf.h27
-rw-r--r--source3/libnet/libnet_join.c368
-rw-r--r--source3/libnet/libnet_join.h1
5 files changed, 485 insertions, 191 deletions
diff --git a/source3/libnet/libnet.h b/source3/libnet/libnet.h
index fa24c3b40a..d6238ca982 100644
--- a/source3/libnet/libnet.h
+++ b/source3/libnet/libnet.h
@@ -21,6 +21,7 @@
#define __LIBNET_H__
#include "libnet/libnet_join.h"
+#include "libnet/libnet_conf.h"
#include "libnet/libnet_proto.h"
#endif
diff --git a/source3/libnet/libnet_conf.c b/source3/libnet/libnet_conf.c
index d0ef6eb0e6..d20e10b141 100644
--- a/source3/libnet/libnet_conf.c
+++ b/source3/libnet/libnet_conf.c
@@ -21,11 +21,6 @@
#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,6 +407,11 @@ 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.
@@ -421,9 +419,60 @@ done:
**********************************************************************/
/**
+ * 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,13 +775,13 @@ 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)) {
+ 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_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;
}
@@ -737,9 +794,33 @@ done:
}
/**
+ * Set a global parameter
+ * (i.e. a parameter in the [global] service).
+ *
+ * This also creates [global] when it does not exist.
+ */
+WERROR libnet_conf_set_global_parameter(struct libnet_conf_ctx *ctx,
+ const char *param, const char *val)
+{
+ WERROR werr;
+
+ if (!libnet_conf_share_exists(ctx, GLOBAL_NAME)) {
+ werr = libnet_conf_create_share(ctx, GLOBAL_NAME);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+ }
+ werr = libnet_conf_set_parameter(ctx, GLOBAL_NAME, param, val);
+
+done:
+ return werr;
+}
+
+/**
* 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)
@@ -753,13 +834,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;
}
@@ -787,19 +868,46 @@ done:
}
/**
+ * Get the value of a global parameter.
+ *
+ * Create [global] if it does not exist.
+ */
+WERROR libnet_conf_get_global_parameter(TALLOC_CTX *mem_ctx,
+ struct libnet_conf_ctx *ctx,
+ const char *param,
+ char **valstr)
+{
+ WERROR werr;
+
+ if (!libnet_conf_share_exists(ctx, GLOBAL_NAME)) {
+ werr = libnet_conf_create_share(ctx, GLOBAL_NAME);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+ }
+ werr = libnet_conf_get_parameter(mem_ctx, ctx, GLOBAL_NAME, param,
+ valstr);
+
+done:
+ return werr;
+}
+
+/**
* 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;
@@ -817,15 +925,24 @@ done:
return werr;
}
-
-/**********************************************************************
- *
- * Convenience functions that are also exported.
+/**
+ * Delete a global parameter.
*
- **********************************************************************/
-
-WERROR libnet_conf_set_global_parameter(const char *param, const char *val)
+ * Create [global] if it does not exist.
+ */
+WERROR libnet_conf_delete_global_parameter(struct libnet_conf_ctx *ctx,
+ const char *param)
{
- return libnet_conf_set_parameter(GLOBAL_NAME, param, val);
-}
+ WERROR werr;
+
+ if (!libnet_conf_share_exists(ctx, GLOBAL_NAME)) {
+ werr = libnet_conf_create_share(ctx, GLOBAL_NAME);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+ }
+ werr = libnet_conf_delete_parameter(ctx, GLOBAL_NAME, param);
+done:
+ return werr;
+}
diff --git a/source3/libnet/libnet_conf.h b/source3/libnet/libnet_conf.h
new file mode 100644
index 0000000000..b518c0e3b0
--- /dev/null
+++ b/source3/libnet/libnet_conf.h
@@ -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
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 1df85ebb61..c60f4c9803 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -19,8 +19,7 @@
*/
#include "includes.h"
-#include "libnet/libnet_join.h"
-#include "libnet/libnet_proto.h"
+#include "libnet/libnet.h"
/****************************************************************
****************************************************************/
@@ -30,14 +29,14 @@ static void libnet_join_set_error_string(TALLOC_CTX *mem_ctx,
const char *format, ...)
{
va_list args;
- char *tmp = NULL;
+
+ if (r->out.error_string) {
+ return;
+ }
va_start(args, format);
- tmp = talloc_vasprintf(mem_ctx, format, args);
+ r->out.error_string = talloc_vasprintf(mem_ctx, format, args);
va_end(args);
-
- TALLOC_FREE(r->out.error_string);
- r->out.error_string = tmp;
}
/****************************************************************
@@ -48,17 +47,17 @@ static void libnet_unjoin_set_error_string(TALLOC_CTX *mem_ctx,
const char *format, ...)
{
va_list args;
- char *tmp = NULL;
+
+ if (r->out.error_string) {
+ return;
+ }
va_start(args, format);
- tmp = talloc_vasprintf(mem_ctx, format, args);
+ r->out.error_string = talloc_vasprintf(mem_ctx, format, args);
va_end(args);
-
- TALLOC_FREE(r->out.error_string);
- r->out.error_string = tmp;
}
-#ifdef HAVE_LDAP
+#ifdef WITH_ADS
/****************************************************************
****************************************************************/
@@ -108,10 +107,6 @@ static ADS_STATUS libnet_join_connect_ads(TALLOC_CTX *mem_ctx,
{
ADS_STATUS status;
- if (r->in.ads) {
- ads_destroy(&r->in.ads);
- }
-
status = libnet_connect_ads(r->in.domain_name,
r->in.domain_name,
r->in.dc_name,
@@ -135,10 +130,6 @@ static ADS_STATUS libnet_unjoin_connect_ads(TALLOC_CTX *mem_ctx,
{
ADS_STATUS status;
- if (r->in.ads) {
- ads_destroy(&r->in.ads);
- }
-
status = libnet_connect_ads(r->in.domain_name,
r->in.domain_name,
r->in.dc_name,
@@ -426,8 +417,6 @@ static ADS_STATUS libnet_join_set_os_attributes(TALLOC_CTX *mem_ctx,
return ads_gen_mod(r->in.ads, r->out.dn, mods);
}
-#endif /* HAVE_LDAP */
-
/****************************************************************
****************************************************************/
@@ -437,16 +426,14 @@ static bool libnet_join_create_keytab(TALLOC_CTX *mem_ctx,
if (!lp_use_kerberos_keytab()) {
return true;
}
-#ifdef HAVE_KRB5
+
if (!ads_keytab_create_default(r->in.ads)) {
return false;
}
-#endif /* HAVE_KRB5 */
+
return true;
}
-#ifdef HAVE_KRB5
-
/****************************************************************
****************************************************************/
@@ -461,7 +448,8 @@ static bool libnet_join_derive_salting_principal(TALLOC_CTX *mem_ctx,
status = ads_domain_func_level(r->in.ads, &domain_func);
if (!ADS_ERR_OK(status)) {
libnet_join_set_error_string(mem_ctx, r,
- "Failed to determine domain functional level!");
+ "failed to determine domain functional level: %s",
+ ads_errstr(status));
return false;
}
@@ -495,7 +483,51 @@ static bool libnet_join_derive_salting_principal(TALLOC_CTX *mem_ctx,
return kerberos_secrets_store_des_salt(salt);
}
-#endif /* HAVE_KRB5 */
+/****************************************************************
+****************************************************************/
+
+static ADS_STATUS libnet_join_post_processing_ads(TALLOC_CTX *mem_ctx,
+ struct libnet_JoinCtx *r)
+{
+ ADS_STATUS status;
+
+ status = libnet_join_set_machine_spn(mem_ctx, r);
+ if (!ADS_ERR_OK(status)) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "failed to set machine spn: %s",
+ ads_errstr(status));
+ return status;
+ }
+
+ status = libnet_join_set_os_attributes(mem_ctx, r);
+ if (!ADS_ERR_OK(status)) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "failed to set machine os attributes: %s",
+ ads_errstr(status));
+ return status;
+ }
+
+ status = libnet_join_set_machine_upn(mem_ctx, r);
+ if (!ADS_ERR_OK(status)) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "failed to set machine upn: %s",
+ ads_errstr(status));
+ return status;
+ }
+
+ if (!libnet_join_derive_salting_principal(mem_ctx, r)) {
+ return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+ }
+
+ if (!libnet_join_create_keytab(mem_ctx, r)) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "failed to create kerberos keytab");
+ return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+ }
+
+ return ADS_SUCCESS;
+}
+#endif /* WITH_ADS */
/****************************************************************
****************************************************************/
@@ -630,7 +662,8 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
0xe005000b, &user_pol,
&user_rid);
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
- if (!(r->in.join_flags & WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED)) {
+ if (!(r->in.join_flags &
+ WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED)) {
goto done;
}
}
@@ -678,14 +711,13 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx,
memcpy(&pwbuf[516], md5buffer, sizeof(md5buffer));
acb_info |= ACB_PWNOEXP;
-#if 0
- if ( dom_type == ND_TYPE_AD ) {
+ if (r->out.domain_is_ad) {
#if !defined(ENCTYPE_ARCFOUR_HMAC)
acb_info |= ACB_USE_DES_KEY_ONLY;
#endif
;;
}
-#endif
+
ZERO_STRUCT(ctr);
ZERO_STRUCT(p25);
@@ -845,33 +877,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",
- r->out.dns_domain_name);
- W_ERROR_NOT_OK_RETURN(werr);
+ werr = libnet_conf_set_global_parameter(ctx, "realm",
+ r->out.dns_domain_name);
}
+done:
+ libnet_conf_close(ctx);
return werr;
}
@@ -881,15 +928,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_global_parameter(ctx, "realm");
+done:
+ libnet_conf_close(ctx);
return werr;
}
@@ -948,6 +1005,58 @@ static WERROR do_UnjoinConfig(struct libnet_UnjoinCtx *r)
/****************************************************************
****************************************************************/
+static WERROR libnet_join_pre_processing(TALLOC_CTX *mem_ctx,
+ struct libnet_JoinCtx *r)
+{
+
+ if (!r->in.domain_name) {
+ return WERR_INVALID_PARAM;
+ }
+
+ if (r->in.modify_config && !lp_include_registry_globals()) {
+ return WERR_NOT_SUPPORTED;
+ }
+
+ if (IS_DC) {
+ return WERR_SETUP_DOMAIN_CONTROLLER;
+ }
+
+ if (!secrets_init()) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "Unable to open secrets database");
+ return WERR_CAN_NOT_COMPLETE;
+ }
+
+ return WERR_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
+static WERROR libnet_join_post_processing(TALLOC_CTX *mem_ctx,
+ struct libnet_JoinCtx *r)
+{
+ WERROR werr;
+
+ if (!W_ERROR_IS_OK(r->out.result)) {
+ return r->out.result;
+ }
+
+ werr = do_JoinConfig(r);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
+ saf_store(r->in.domain_name, r->in.dc_name);
+ }
+
+ return WERR_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
static int libnet_destroy_JoinCtx(struct libnet_JoinCtx *r)
{
if (r->in.ads) {
@@ -1022,28 +1131,59 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
struct libnet_JoinCtx *r)
{
NTSTATUS status;
-#ifdef HAVE_LDAP
+#ifdef WITH_ADS
ADS_STATUS ads_status;
+#endif /* WITH_ADS */
+
+ if (!r->in.dc_name) {
+ struct DS_DOMAIN_CONTROLLER_INFO *info;
+ status = dsgetdcname(mem_ctx,
+ NULL,
+ r->in.domain_name,
+ NULL,
+ NULL,
+ DS_DIRECTORY_SERVICE_REQUIRED |
+ DS_WRITABLE_REQUIRED |
+ DS_RETURN_DNS_NAME,
+ &info);
+ if (!NT_STATUS_IS_OK(status)) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "failed to find DC: %s",
+ nt_errstr(status));
+ return WERR_DOMAIN_CONTROLLER_NOT_FOUND;
+ }
+ r->in.dc_name = talloc_strdup(mem_ctx,
+ info->domain_controller_name);
+ W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
+ }
+
+#ifdef WITH_ADS
if (r->in.account_ou) {
+
ads_status = libnet_join_connect_ads(mem_ctx, r);
if (!ADS_ERR_OK(ads_status)) {
- return WERR_GENERAL_FAILURE;
+ return WERR_DEFAULT_JOIN_REQUIRED;
}
+
ads_status = libnet_join_precreate_machine_acct(mem_ctx, r);
if (!ADS_ERR_OK(ads_status)) {
libnet_join_set_error_string(mem_ctx, r,
"failed to precreate account in ou %s: %s",
r->in.account_ou,
ads_errstr(ads_status));
- return WERR_GENERAL_FAILURE;
+ return WERR_DEFAULT_JOIN_REQUIRED;
}
r->in.join_flags &= ~WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE;
}
-#endif /* HAVE_LDAP */
+#endif /* WITH_ADS */
+
status = libnet_join_joindomain_rpc(mem_ctx, r);
if (!NT_STATUS_IS_OK(status)) {
+ libnet_join_set_error_string(mem_ctx, r,
+ "failed to join domain over rpc: %s",
+ nt_errstr(status));
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
return WERR_SETUP_ALREADY_JOINED;
}
@@ -1054,43 +1194,14 @@ static WERROR libnet_DomainJoin(TALLOC_CTX *mem_ctx,
return WERR_SETUP_NOT_JOINED;
}
-#ifdef HAVE_LDAP
- ads_status = libnet_join_set_machine_spn(mem_ctx, r);
- if (!ADS_ERR_OK(ads_status)) {
- libnet_join_set_error_string(mem_ctx, r,
- "failed to set machine spn: %s",
- ads_errstr(ads_status));
- return WERR_GENERAL_FAILURE;
- }
-
- ads_status = libnet_join_set_os_attributes(mem_ctx, r);
- if (!ADS_ERR_OK(ads_status)) {
- libnet_join_set_error_string(mem_ctx, r,
- "failed to set machine os attributes: %s",
- ads_errstr(ads_status));
- return WERR_GENERAL_FAILURE;
- }
-
- ads_status = libnet_join_set_machine_upn(mem_ctx, r);
- if (!ADS_ERR_OK(ads_status)) {
- libnet_join_set_error_string(mem_ctx, r,
- "failed to set machine upn: %s",
- ads_errstr(ads_status));
- return WERR_GENERAL_FAILURE;
- }
-
-#ifdef HAVE_KRB5
- if (!libnet_join_derive_salting_principal(mem_ctx, r)) {
- return WERR_GENERAL_FAILURE;
- }
-#endif /* HAVE_KRB5 */
-
-#endif /* HAVE_LDAP */
- if (!libnet_join_create_keytab(mem_ctx, r)) {
- libnet_join_set_error_string(mem_ctx, r,
- "failed to create kerberos keytab");
- return WERR_GENERAL_FAILURE;
+#ifdef WITH_ADS
+ if (r->out.domain_is_ad) {
+ ads_status = libnet_join_post_processing_ads(mem_ctx, r);
+ if (!ADS_ERR_OK(ads_status)) {
+ return WERR_GENERAL_FAILURE;
+ }
}
+#endif /* WITH_ADS */
return WERR_OK;
}
@@ -1103,30 +1214,23 @@ WERROR libnet_Join(TALLOC_CTX *mem_ctx,
{
WERROR werr;
- if (!r->in.domain_name) {
- return WERR_INVALID_PARAM;
- }
-
- if (r->in.modify_config && !lp_include_registry_globals()) {
- return WERR_NOT_SUPPORTED;
- }
-
- if (IS_DC) {
- return WERR_SETUP_DOMAIN_CONTROLLER;
+ werr = libnet_join_pre_processing(mem_ctx, r);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
}
if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
werr = libnet_DomainJoin(mem_ctx, r);
if (!W_ERROR_IS_OK(werr)) {
- return werr;
+ goto done;
}
}
- werr = do_JoinConfig(r);
+ werr = libnet_join_post_processing(mem_ctx, r);
if (!W_ERROR_IS_OK(werr)) {
- return werr;
+ goto done;
}
-
+ done:
return werr;
}
@@ -1138,6 +1242,29 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
+ if (!r->in.dc_name) {
+ struct DS_DOMAIN_CONTROLLER_INFO *info;
+ status = dsgetdcname(mem_ctx,
+ NULL,
+ r->in.domain_name,
+ NULL,
+ NULL,
+ DS_DIRECTORY_SERVICE_REQUIRED |
+ DS_WRITABLE_REQUIRED |
+ DS_RETURN_DNS_NAME,
+ &info);
+ if (!NT_STATUS_IS_OK(status)) {
+ libnet_unjoin_set_error_string(mem_ctx, r,
+ "failed to find DC: %s",
+ nt_errstr(status));
+ return WERR_DOMAIN_CONTROLLER_NOT_FOUND;
+ }
+
+ r->in.dc_name = talloc_strdup(mem_ctx,
+ info->domain_controller_name);
+ W_ERROR_HAVE_NO_MEMORY(r->in.dc_name);
+ }
+
status = libnet_join_unjoindomain_rpc(mem_ctx, r);
if (!NT_STATUS_IS_OK(status)) {
libnet_unjoin_set_error_string(mem_ctx, r,
@@ -1149,7 +1276,7 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx,
return ntstatus_to_werror(status);
}
-#ifdef HAVE_LDAP
+#ifdef WITH_ADS
if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_ACCOUNT_DELETE) {
ADS_STATUS ads_status;
libnet_unjoin_connect_ads(mem_ctx, r);
@@ -1160,7 +1287,8 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx,
ads_errstr(ads_status));
}
}
-#endif /* HAVE_LDAP */
+#endif /* WITH_ADS */
+
libnet_join_unjoindomain_remove_secrets(mem_ctx, r);
return WERR_OK;
@@ -1169,27 +1297,47 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx,
/****************************************************************
****************************************************************/
+static WERROR libnet_unjoin_pre_processing(TALLOC_CTX *mem_ctx,
+ struct libnet_UnjoinCtx *r)
+{
+ if (r->in.modify_config && !lp_include_registry_globals()) {
+ return WERR_NOT_SUPPORTED;
+ }
+
+ if (!secrets_init()) {
+ libnet_unjoin_set_error_string(mem_ctx, r,
+ "Unable to open secrets database");
+ return WERR_CAN_NOT_COMPLETE;
+ }
+
+ return WERR_OK;
+}
+
+/****************************************************************
+****************************************************************/
+
WERROR libnet_Unjoin(TALLOC_CTX *mem_ctx,
struct libnet_UnjoinCtx *r)
{
WERROR werr;
- if (r->in.modify_config && !lp_include_registry_globals()) {
- return WERR_NOT_SUPPORTED;
+ werr = libnet_unjoin_pre_processing(mem_ctx, r);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
}
if (r->in.unjoin_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
werr = libnet_DomainUnjoin(mem_ctx, r);
if (!W_ERROR_IS_OK(werr)) {
- do_UnjoinConfig(r);
- return werr;
+ goto done;
}
}
werr = do_UnjoinConfig(r);
if (!W_ERROR_IS_OK(werr)) {
- return werr;
+ goto done;
}
+ done:
return werr;
}
diff --git a/source3/libnet/libnet_join.h b/source3/libnet/libnet_join.h
index 95b965717e..c47e8d934c 100644
--- a/source3/libnet/libnet_join.h
+++ b/source3/libnet/libnet_join.h
@@ -36,6 +36,7 @@ struct libnet_JoinCtx {
const char *upn;
bool modify_config;
struct ads_struct *ads;
+ bool debug;
} in;
struct {