diff options
-rw-r--r-- | source3/Makefile.in | 11 | ||||
-rw-r--r-- | source3/include/includes.h | 1 | ||||
-rw-r--r-- | source3/include/reg_db.h | 31 | ||||
-rw-r--r-- | source3/param/loadparm.c | 265 | ||||
-rw-r--r-- | source3/registry/reg_db.c | 9 |
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 */ |