summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in11
-rw-r--r--source3/include/includes.h1
-rw-r--r--source3/include/reg_db.h31
-rw-r--r--source3/param/loadparm.c265
-rw-r--r--source3/registry/reg_db.c9
5 files changed, 305 insertions, 12 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 6c3026d154..707bae3910 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -308,7 +308,9 @@ READLINE_OBJ = lib/readline.o
# Be sure to include them into your application
POPT_LIB_OBJ = lib/popt_common.o
-PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o lib/sharesec.o
+PARAM_WITHOUT_REG_OBJ = dynconfig.o param/loadparm.o param/params.o lib/sharesec.o
+PARAM_REG_ADD_OBJ = $(UTIL_REG_API_OBJ)
+PARAM_OBJ = $(PARAM_WITHOUT_REG_OBJ) $(PARAM_REG_ADD_OBJ)
KRBCLIENT_OBJ = libads/kerberos.o libads/ads_status.o
@@ -528,7 +530,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
smbd/dmapi.o lib/launchd.o smbd/sockinit.o \
$(MANGLE_OBJ) @VFS_STATIC@
-SMBD_OBJ_BASE = $(PARAM_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
+SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \
$(RPC_SERVER_OBJ) $(RPC_PARSE_OBJ) $(SECRETS_OBJ) \
$(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \
$(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \
@@ -672,11 +674,10 @@ TOOL_OBJ = client/smbctool.o client/clitar.o $(PARAM_OBJ) $(LIBSMB_OBJ) \
UTIL_REG_OBJ = lib/util_reg.o
UTIL_REG_API_OBJ = lib/util_reg_api.o
UTIL_REG_SMBCONF_OBJ = lib/util_reg_smbconf.o
-UTIL_REG_ALL_OBJ = $(UTIL_REG_OBJ) $(UTIL_REG_API_OBJ) $(UTIL_REG_SMBCONF_OBJ)
# objects to be used when not all of the registry code should be
# loaded but only the portion needed by reg_api, typically for
-# using smbconf (registry)
+# using smbconf (registry) - full access
REG_API_OBJ = registry/reg_api.o \
registry/reg_frontend_hilvl.o \
registry/reg_smbconf.o \
@@ -703,7 +704,7 @@ NET_OBJ1 = utils/net.o utils/net_ads.o utils/net_domain.o utils/net_help.o \
$(PASSWD_UTIL_OBJ) utils/net_dns.o utils/net_ads_gpo.o \
utils/net_conf.o
-NET_OBJ = $(NET_OBJ1) $(PARAM_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
+NET_OBJ = $(NET_OBJ1) $(PARAM_WITHOUT_REG_OBJ) $(SECRETS_OBJ) $(LIBSMB_OBJ) \
$(RPC_PARSE_OBJ) $(PASSDB_OBJ) $(GROUPDB_OBJ) \
$(KRBCLIENT_OBJ) $(LIB_NONSMBD_OBJ) $(LIBADDNS_OBJ0) \
$(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \
diff --git a/source3/include/includes.h b/source3/include/includes.h
index 20a693d64b..3994d3b3c9 100644
--- a/source3/include/includes.h
+++ b/source3/include/includes.h
@@ -681,6 +681,7 @@ typedef int BOOL;
#include "rpc_lsa.h"
#include "rpc_netlogon.h"
#include "reg_objects.h"
+#include "reg_db.h"
#include "rpc_samr.h"
#include "rpc_spoolss.h"
#include "rpc_eventlog.h"
diff --git a/source3/include/reg_db.h b/source3/include/reg_db.h
new file mode 100644
index 0000000000..474b095b68
--- /dev/null
+++ b/source3/include/reg_db.h
@@ -0,0 +1,31 @@
+/*
+ Parameters for Samba's Internal Registry Database
+
+ Copyright (C) Michael Adam 2007
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _REG_DB_H
+#define _REG_DB_H
+
+#define REG_TDB_FLAGS TDB_SEQNUM
+
+#define REGVER_V1 1 /* first db version with write support */
+
+#define VALUE_PREFIX "SAMBA_REGVAL"
+#define SECDESC_PREFIX "SAMBA_SECDESC"
+
+#endif /* _REG_DB_H */
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 27357868da..86b82174a9 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -72,6 +72,17 @@ extern userdom_struct current_user_info;
#define HOMES_NAME "homes"
#endif
+/* the special value for the include parameter
+ * to be interpreted not as a file name but to
+ * trigger loading of the global smb.conf options
+ * from registry. */
+#ifndef INCLUDE_REGISTRY_NAME
+#define INCLUDE_REGISTRY_NAME "registry"
+#endif
+
+static int regdb_last_seqnum = 0;
+static BOOL include_registry_globals = False;
+
/* some helpful bits */
#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
@@ -3037,6 +3048,237 @@ BOOL service_ok(int iService)
return (bRetval);
}
+/*
+ * lp_regdb_open - regdb helper function
+ *
+ * this should be considered an interim solution that becomes
+ * superfluous once the registry code has been rewritten
+ * do allow use of the tdb portion of the registry alone.
+ *
+ * in the meanwhile this provides a lean access
+ * to the registry globals.
+ */
+
+static struct tdb_wrap *lp_regdb_open(void)
+{
+ struct tdb_wrap *reg_tdb = NULL;
+ const char *vstring = "INFO/version";
+ uint32 vers_id;
+
+ become_root();
+ reg_tdb = tdb_wrap_open(NULL, lock_path("registry.tdb"), 0,
+ REG_TDB_FLAGS, O_RDWR, 0600);
+ if (!reg_tdb) {
+ DEBUG(0, ("lp_regdb_open: failed to open %s: %s\n",
+ lock_path("registry.tdb"), strerror(errno)));
+ }
+ else {
+ DEBUG(10, ("lp_regdb_open: reg tdb opened.\n"));
+ }
+ unbecome_root();
+
+ vers_id = tdb_fetch_int32(reg_tdb->tdb, vstring);
+ if (vers_id != REGVER_V1) {
+ DEBUG(10, ("lp_regdb_open: INFO: registry tdb %s has wrong "
+ "INFO/version (got %d, expected %d)\n",
+ lock_path("registry.tdb"), vers_id, REGVER_V1));
+ /* this is apparently not implemented in the tdb */
+ }
+
+ return reg_tdb;
+}
+
+/*
+ * process_registry_globals
+ *
+ * this is the interim version of process_registry globals
+ *
+ * until we can do it as we would like using the api and only
+ * using the tdb portion of the registry (see below),
+ * this just provides the needed functionality of regdb_fetch_values
+ * and regdb_unpack_values, circumventing any fancy stuff, to
+ * give us access to the registry globals.
+ */
+static BOOL process_registry_globals(BOOL (*pfunc)(const char *, const char *))
+{
+ BOOL ret = False;
+ struct tdb_wrap *reg_tdb = NULL;
+ WERROR err;
+ char *keystr;
+ TDB_DATA data;
+ /* vars for the tdb unpack loop */
+ int len = 0;
+ int i;
+ int buflen;
+ uint8 *buf;
+ uint32 type;
+ uint32 size;
+ uint32 num_values = 0;
+ uint8 *data_p;
+ pstring valname;
+ char * valstr;
+ struct registry_value *value = NULL;
+
+ include_registry_globals = True;
+
+ ZERO_STRUCT(data);
+
+ reg_tdb = lp_regdb_open();
+ if (!reg_tdb) {
+ DEBUG(1, ("Error opening the registry!\n"));
+ goto done;
+ }
+
+ /* reg_tdb is from now on used as talloc ctx.
+ * freeing it closes the tdb (if refcount is 0) */
+
+ keystr = talloc_asprintf(reg_tdb,"%s/%s/%s", VALUE_PREFIX,
+ KEY_SMBCONF, GLOBAL_NAME);
+ normalize_dbkey(keystr);
+
+ DEBUG(10, ("process_registry_shares: fetching key '%s'\n",
+ keystr));
+
+ data = tdb_fetch_bystring(reg_tdb->tdb, keystr);
+ if (!data.dptr) {
+ ret = True;
+ goto done;
+ }
+
+ buf = data.dptr;
+ buflen = data.dsize;
+
+ /* unpack number of values */
+ len = tdb_unpack(buf, buflen, "d", &num_values);
+ DEBUG(10, ("process_registry_shares: got %d values from tdb\n",
+ num_values));
+
+ /* unpack the values */
+ for (i=0; i < num_values; i++) {
+ type = REG_NONE;
+ size = 0;
+ data_p = NULL;
+ len += tdb_unpack(buf+len, buflen-len, "fdB",
+ valname,
+ &type,
+ &size,
+ &data_p);
+ DEBUG(10, ("process_registry_shares: got value '%s'\n",
+ valname));
+ if (size && data_p) {
+ err = registry_pull_value(reg_tdb,
+ &value,
+ type,
+ data_p,
+ size,
+ size);
+ SAFE_FREE(data_p);
+ if (!W_ERROR_IS_OK(err)) {
+ goto done;
+ }
+ switch(type) {
+ case REG_DWORD:
+ valstr = talloc_asprintf(reg_tdb, "%d",
+ value->v.dword);
+ pfunc(valname, valstr);
+ break;
+ case REG_SZ:
+ pfunc(valname, value->v.sz.str);
+ break;
+ default:
+ /* ignore other types */
+ break;
+ }
+ }
+ }
+
+ ret = pfunc("registry shares", "yes");
+ regdb_last_seqnum = tdb_get_seqnum(reg_tdb->tdb);
+
+done:
+ TALLOC_FREE(reg_tdb);
+ SAFE_FREE(data.dptr);
+ return ret;
+}
+
+#if 0
+/*
+ * this is process_registry_globals as it _should_ be (roughly)
+ * using the reg_api functions...
+ *
+ */
+static BOOL process_registry_globals(BOOL (*pfunc)(const char *, const char *))
+{
+ BOOL ret = False;
+ TALLOC_CTX *ctx = NULL;
+ char *regpath = NULL;
+ WERROR werr = WERR_OK;
+ struct registry_key *key = NULL;
+ struct registry_value *value = NULL;
+ char *valname = NULL;
+ char *valstr = NULL;
+ uint32 idx = 0;
+ NT_USER_TOKEN *token;
+
+ ctx = talloc_init("process_registry_globals");
+ if (!ctx) {
+ smb_panic("Failed to create talloc context!");
+ }
+
+ include_registry_globals = True;
+
+ if (!registry_init_regdb()) {
+ DEBUG(1, ("Error initializing the registry.\n"));
+ goto done;
+ }
+
+ if (!(token = registry_create_admin_token(ctx))) {
+ DEBUG(1, ("Error creating admin token\n"));
+ goto done;
+ }
+
+ regpath = talloc_asprintf(ctx,"%s\\%s", KEY_SMBCONF, GLOBAL_NAME);
+ werr = reg_open_path(ctx, regpath, REG_KEY_READ, token, &key);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, ("Registry smbconf global section does not exist.\n"));
+ DEBUGADD(1, ("Error opening registry path '%s\\%s: %s\n",
+ KEY_SMBCONF, GLOBAL_NAME, dos_errstr(werr)));
+ goto done;
+ }
+
+ for (idx = 0;
+ W_ERROR_IS_OK(werr = reg_enumvalue(ctx, key, idx, &valname,
+ &value));
+ idx++)
+ {
+ DEBUG(5, ("got global registry parameter '%s'\n", valname));
+ switch(value->type) {
+ case REG_DWORD:
+ valstr = talloc_asprintf(ctx, "%d", value->v.dword);
+ pfunc(valname, valstr);
+ TALLOC_FREE(valstr);
+ break;
+ case REG_SZ:
+ pfunc(valname, value->v.sz.str);
+ break;
+ default:
+ /* ignore other types */
+ break;
+ }
+ TALLOC_FREE(value);
+ TALLOC_FREE(valstr);
+ }
+
+ ret = pfunc("registry shares", "yes");
+
+ regdb_last_seqnum = regdb_get_seqnum();
+
+done:
+ talloc_destroy(ctx);
+ return ret;
+}
+#endif /* if 0 */
+
static struct file_lists {
struct file_lists *next;
char *name;
@@ -3090,9 +3332,21 @@ static void add_to_file_list(const char *fname, const char *subfname)
BOOL lp_file_list_changed(void)
{
struct file_lists *f = file_lists;
+ struct tdb_wrap *reg_tdb = NULL;
DEBUG(6, ("lp_file_list_changed()\n"));
+ if (include_registry_globals) {
+ reg_tdb = lp_regdb_open();
+ if (reg_tdb && (regdb_last_seqnum != tdb_get_seqnum(reg_tdb->tdb)))
+ {
+ DEBUGADD(6, ("regdb seqnum changed: old = %d, new = %d\n",
+ regdb_last_seqnum, tdb_get_seqnum(reg_tdb->tdb)));
+ TALLOC_FREE(reg_tdb);
+ return True;
+ }
+ }
+
while (f) {
pstring n2;
time_t mod_time;
@@ -3193,6 +3447,17 @@ static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
pstring fname;
pstrcpy(fname, pszParmValue);
+ if (strequal(fname, INCLUDE_REGISTRY_NAME)) {
+ if (bInGlobalSection) {
+ return process_registry_globals(do_parameter);
+ }
+ else {
+ DEBUG(1, ("\"include = registry\" only effective "
+ "in %s section\n", GLOBAL_NAME));
+ return False;
+ }
+ }
+
standard_sub_basic(get_current_username(), current_user_info.domain,
fname,sizeof(fname));
diff --git a/source3/registry/reg_db.c b/source3/registry/reg_db.c
index cea089a9db..a8e5ea665a 100644
--- a/source3/registry/reg_db.c
+++ b/source3/registry/reg_db.c
@@ -28,11 +28,6 @@
static struct tdb_wrap *tdb_reg = NULL;
static int tdb_refcount;
-#define VALUE_PREFIX "SAMBA_REGVAL"
-#define SECDESC_PREFIX "SAMBA_SECDESC"
-
-#define REG_TDB_FLAGS TDB_SEQNUM
-
/* List the deepest path into the registry. All part components will be created.*/
/* If you want to have a part of the path controlled by the tdb and part by
@@ -85,8 +80,6 @@ static struct builtin_regkey_value builtin_registry_values[] = {
{ NULL, NULL, 0, { NULL } }
};
-#define REGVER_V1 1 /* first db version with write support */
-
/***********************************************************************
Open the registry data in the tdb
***********************************************************************/
@@ -256,6 +249,8 @@ BOOL regdb_init( void )
if ( vers_id != REGVER_V1 ) {
/* any upgrade code here if needed */
+ DEBUG(10, ("regdb_init: got INFO/version = %d != %d\n",
+ vers_id, REGVER_V1));
}
/* always setup the necessary keys and values */