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
+ 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,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
#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)
BOOL bWinbindUseDefaultDomain;
BOOL bWinbindTrustedDomainsOnly;
BOOL bWinbindNestedGroups;
+ int winbind_expand_groups;
BOOL bWinbindRefreshTickets;
BOOL bWinbindOfflineLogon;
BOOL bWinbindNormalizeNames;
+ BOOL bWinbindRpcOnly;
char **szIdmapDomains;
char **szIdmapBackend; /* deprecated */
char *szIdmapAllocBackend;
int iAclCompat;
char *szCupsServer;
char *szIPrintServer;
+ char *ctdbdSocket;
+ BOOL clustering;
int ldap_passwd_sync;
int ldap_replication_sleep;
int ldap_timeout; /* This is initialised in init_globals */
int client_signing;
int server_signing;
int iUsershareMaxShares;
- int iIdmapExpireTime;
- int iIdmapNegativeTime;
+ int iIdmapCacheTime;
+ int iIdmapNegativeCacheTime;
BOOL bResetOnZeroVC;
int iKeepalive;
{"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
{"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
+ {"ctdbd socket", P_STRING, P_GLOBAL, &Globals.ctdbdSocket, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
+ {"clustering", P_BOOL, P_GLOBAL, &Globals.clustering, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
{N_("Printing Options"), P_SEP, P_SEPARATOR},
{"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED},
{"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED },
{"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED},
- {"idmap expire time", P_INTEGER, P_GLOBAL, &Globals.iIdmapExpireTime, NULL, NULL, FLAG_ADVANCED},
- {"idmap negative time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeTime, NULL, NULL, FLAG_ADVANCED},
+ {"idmap cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapCacheTime, NULL, NULL, FLAG_ADVANCED},
+ {"idmap negative cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeCacheTime, NULL, NULL, FLAG_ADVANCED},
{"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED },
{"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE },
{"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED },
{"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
{"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
{"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
+ {"winbind expand groups", P_INTEGER, P_GLOBAL, &Globals.winbind_expand_groups, NULL, NULL, FLAG_ADVANCED},
{"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
{"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
{"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
{"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
+ {"winbind rpc only", P_BOOL, P_GLOBAL, &Globals.bWinbindRpcOnly, NULL, NULL, FLAG_ADVANCED},
{NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
string_set(&Globals.szCupsServer, "");
string_set(&Globals.szIPrintServer, "");
+ string_set(&Globals.ctdbdSocket, "");
+ Globals.clustering = False;
+
Globals.winbind_cache_time = 300; /* 5 minutes */
Globals.bWinbindEnumUsers = False;
Globals.bWinbindEnumGroups = False;
Globals.bWinbindUseDefaultDomain = False;
Globals.bWinbindTrustedDomainsOnly = False;
Globals.bWinbindNestedGroups = True;
+ Globals.winbind_expand_groups = 1;
+ Globals.szWinbindNssInfo = str_list_make("template", NULL);
Globals.bWinbindRefreshTickets = False;
Globals.bWinbindOfflineLogon = False;
- Globals.iIdmapExpireTime = 900; /* 15 minutes by default */
- Globals.iIdmapNegativeTime = 120; /* 2 minutes by default */
+ Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
+ Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
Globals.bPassdbExpandExplicit = False;
}
if (lp_talloc == NULL) {
- smb_panic("Could not create temporary talloc context\n");
+ smb_panic("Could not create temporary talloc context");
}
return lp_talloc;
FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
+FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
+FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
-FN_GLOBAL_INTEGER(lp_idmap_expire_time, &Globals.iIdmapExpireTime)
-FN_GLOBAL_INTEGER(lp_idmap_negative_time, &Globals.iIdmapNegativeTime)
+FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
+FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
+FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
+FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering);
FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
return (-1);
}
- return atoi(s);
+ return (int)strtol(s, NULL, 0);
}
/*******************************************************************
return (0);
}
- return strtoul(s, NULL, 10);
+ return strtoul(s, NULL, 0);
}
/*******************************************************************
}
/***************************************************************************
- Convert a string to uppercase and remove whitespaces.
+ Canonicalize by converting to lowercase.
***************************************************************************/
static char *canonicalize_servicename(const char *src)
return (True);
}
+
+/***************************************************************************
+ Check whether the given parameter name is valid.
+ Parametric options (names containing a colon) are considered valid.
+***************************************************************************/
+
+BOOL lp_parameter_is_valid(const char *pszParmName)
+{
+ return ((map_parameter(pszParmName) != -1) ||
+ (strchr(pszParmName, ':') != NULL));
+}
+
+/***************************************************************************
+ Check whether the given name is the name of a global parameter.
+ Returns True for strings belonging to parameters of class
+ P_GLOBAL, False for all other strings, also for parametric options
+ and strings not belonging to any option.
+***************************************************************************/
+
+BOOL lp_parameter_is_global(const char *pszParmName)
+{
+ int num = map_parameter(pszParmName);
+
+ if (num >= 0) {
+ return (parm_table[num].p_class == P_GLOBAL);
+ }
+
+ return False;
+}
+
/***************************************************************************
Map a parameter's string representation to something we can use.
Returns False if the parameter string is not recognised, else TRUE.
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(1, ("lp_regdb_open: failed to open %s: %s\n",
+ lock_path("registry.tdb"), strerror(errno)));
+ goto done;
+ }
+ 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 */
+ }
+
+done:
+ 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", REG_VALUE_PREFIX,
+ KEY_SMBCONF, GLOBAL_NAME);
+ normalize_dbkey(keystr);
+
+ DEBUG(10, ("process_registry_globals: 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_globals: 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);
+ if (registry_smbconf_valname_forbidden(valname)) {
+ DEBUG(10, ("process_registry_globals: Ignoring "
+ "parameter '%s' in registry.\n", valname));
+ continue;
+ }
+ DEBUG(10, ("process_registry_globals: 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;
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;
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));
parm_ptr =
((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
&sDefault);
- }
- if (snum >= 0) {
if (!ServicePtrs[snum]->copymap)
init_copymap(ServicePtrs[snum]);
}
/***************************************************************************
- Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
+ Return info about the next parameter in a service.
+ snum==GLOBAL_SECTION_SNUM gives the globals.
Return NULL when out of parameters.
***************************************************************************/
&& (parm_table[*i].ptr ==
parm_table[(*i) - 1].ptr))
continue;
+
+ if (is_default(*i) && !allparameters)
+ continue;
return &parm_table[(*i)++];
}
A useful volume label function.
********************************************************************/
-char *volume_label(int snum)
+const char *volume_label(int snum)
{
- char *ret = lp_volume(snum);
- if (!*ret)
- return lp_servicename(snum);
- return (ret);
+ char *ret;
+ const char *label = lp_volume(snum);
+ if (!*label) {
+ label = lp_servicename(snum);
+ }
+
+ /* This returns a 33 byte guarenteed null terminated string. */
+ ret = talloc_strndup(main_loop_talloc_get(), label, 32);
+ if (!ret) {
+ return "";
+ }
+ return ret;
}
-
/*******************************************************************
Set the server type we will announce as via nmbd.
********************************************************************/