*/
#include "includes.h"
+#include "libnet/libnet.h"
bool in_client = False; /* Not in the client by default */
bool bLoaded = False;
#define HOMES_NAME "homes"
#endif
-static int regdb_last_seqnum = 0;
+static uint64_t conf_last_seqnum = 0;
+static struct libnet_conf_ctx *conf_ctx = NULL;
#define CONFIG_BACKEND_FILE 0
#define CONFIG_BACKEND_REGISTRY 1
int ldap_ssl;
char *szLdapSuffix;
char *szLdapAdminDn;
+ int ldap_debug_level;
+ int ldap_debug_threshold;
int iAclCompat;
char *szCupsServer;
char *szIPrintServer;
bool bRead_only;
bool bNo_set_dir;
bool bGuest_only;
+ bool bAdministrative_share;
bool bGuest_ok;
bool bPrint_ok;
bool bMap_system;
True, /* bRead_only */
True, /* bNo_set_dir */
False, /* bGuest_only */
+ False, /* bAdministrative_share */
False, /* bGuest_ok */
False, /* bPrint_ok */
False, /* bMap_system */
static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
+static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
static void set_server_role(void);
static void set_default_server_announce_type(void);
{"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
{"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
+ {"administrative share", P_BOOL, P_LOCAL, &sDefault.bAdministrative_share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
{"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
{"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
{"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
{"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
+ {"ldap debug level", P_INTEGER, P_GLOBAL, &Globals.ldap_debug_level, handle_ldap_debug_level, NULL, FLAG_ADVANCED},
+ {"ldap debug threshold", P_INTEGER, P_GLOBAL, &Globals.ldap_debug_threshold, NULL, NULL, FLAG_ADVANCED},
+
+
{N_("EventLog Options"), P_SEP, P_SEPARATOR},
{"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
Globals.ldap_page_size = LDAP_PAGE_SIZE;
+ Globals.ldap_debug_level = 0;
+ Globals.ldap_debug_threshold = 10;
+
/* This is what we tell the afs client. in reality we set the token
* to never expire, though, when this runs out the afs client will
* forget the token. Set to 0 to get NEVERDATE.*/
Globals.bWinbindTrustedDomainsOnly = False;
Globals.bWinbindNestedGroups = True;
Globals.winbind_expand_groups = 1;
- Globals.szWinbindNssInfo = str_list_make("template", NULL);
+ Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL);
Globals.bWinbindRefreshTickets = False;
Globals.bWinbindOfflineLogon = False;
FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
+FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
+FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
+FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
data = ServicePtrs[snum]->param_opt;
}
- asprintf(¶m_key, "%s:%s", type, option);
- if (!param_key) {
+ if (asprintf(¶m_key, "%s:%s", type, option) == -1) {
DEBUG(0,("asprintf failed!\n"));
return NULL;
}
return (const char **)def;
if (data->list==NULL) {
- data->list = str_list_make(data->value, NULL);
+ data->list = str_list_make(NULL, data->value, NULL);
}
return (const char **)data->list;
PTR_DIFF(parm_table[i].ptr, &sDefault)));
else if (parm_table[i].type == P_LIST &&
parm_table[i].p_class == P_LOCAL)
- str_list_free((char ***)
- (((char *)pservice) +
- PTR_DIFF(parm_table[i].ptr, &sDefault)));
+ TALLOC_FREE(*((char ***)
+ (((char *)pservice) +
+ PTR_DIFF(parm_table[i].ptr,
+ &sDefault))));
}
data = pservice->param_opt;
DEBUG(5,("[%s = %s]\n", data->key, data->value));
string_free(&data->key);
string_free(&data->value);
- str_list_free(&data->list);
+ TALLOC_FREE(data->list);
pdata = data->next;
SAFE_FREE(data);
data = pdata;
while (data) {
string_free(&data->key);
string_free(&data->value);
- str_list_free(&data->list);
+ TALLOC_FREE(data->list);
pdata = data->next;
SAFE_FREE(data);
data = pdata;
ServicePtrs[i]->bAvailable = True;
ServicePtrs[i]->bRead_only = True;
ServicePtrs[i]->bGuest_only = False;
+ ServicePtrs[i]->bAdministrative_share = True;
ServicePtrs[i]->bGuest_ok = guest_ok;
ServicePtrs[i]->bPrint_ok = False;
ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
strupper_m(*(char **)dest_ptr);
break;
case P_LIST:
- str_list_free((char ***)dest_ptr);
- str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
+ TALLOC_FREE(*((char ***)dest_ptr));
+ str_list_copy(NULL, (char ***)dest_ptr,
+ *(const char ***)src_ptr);
break;
default:
break;
/* If we already have same option, override it */
if (strcmp(pdata->key, data->key) == 0) {
string_free(&pdata->value);
- str_list_free(&data->list);
+ TALLOC_FREE(data->list);
pdata->value = SMB_STRDUP(data->value);
not_added = False;
break;
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, state_path("registry.tdb"), 0,
- REG_TDB_FLAGS, O_RDWR, 0600);
- unbecome_root();
- if (!reg_tdb) {
- DEBUG(1, ("lp_regdb_open: failed to open %s: %s\n",
- state_path("registry.tdb"), strerror(errno)));
- goto done;
- }
- else {
- DEBUG(10, ("lp_regdb_open: reg tdb opened.\n"));
- }
-
- 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",
- state_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;
- char * valstr;
- struct registry_value *value = NULL;
-
- 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++) {
- fstring valname;
- 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,
- (enum winreg_Type)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;
- }
+ WERROR werr;
+ char **param_names;
+ char **param_values;
+ uint32_t num_params;
+ uint32_t count;
+ TALLOC_CTX *mem_ctx = talloc_stackframe();
+ bool ret = false;
+
+ if (conf_ctx == NULL) {
+ /* first time */
+ werr = libnet_conf_open(NULL, &conf_ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
}
}
- 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...
- *
- * We are *not* currently doing it like this due to the large
- * linker dependecies of the registry code (see above).
- */
-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 = NULL;
-
- ctx = talloc_init("process_registry_globals");
- if (!ctx) {
- smb_panic("Failed to create talloc context!");
- }
-
- if (!registry_init_regdb()) {
- DEBUG(1, ("Error initializing the registry.\n"));
- goto done;
- }
-
- werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
+ werr = libnet_conf_get_share(mem_ctx, conf_ctx, GLOBAL_NAME,
+ &num_params, ¶m_names, ¶m_values);
if (!W_ERROR_IS_OK(werr)) {
- DEBUG(1, ("Error creating admin token: %s\n",dos_errstr(werr)));
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;
+ for (count = 0; count < num_params; count++) {
+ ret = pfunc(param_names[count], param_values[count]);
+ if (ret != true) {
+ goto done;
}
- TALLOC_FREE(value);
- TALLOC_FREE(valstr);
}
ret = pfunc("registry shares", "yes");
-
- regdb_last_seqnum = regdb_get_seqnum();
+ conf_last_seqnum = libnet_conf_get_seqnum(conf_ctx, NULL, NULL);
done:
- talloc_destroy(ctx);
+ TALLOC_FREE(mem_ctx);
return ret;
}
-#endif /* if 0 */
static struct file_lists {
struct file_lists *next;
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 (lp_config_backend() == CONFIG_BACKEND_REGISTRY) {
- 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);
+ uint64_t conf_cur_seqnum;
+ if (conf_ctx == NULL) {
+ WERROR werr;
+ werr = libnet_conf_open(NULL, &conf_ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(0, ("error opening configuration: %s\n",
+ dos_errstr(werr)));
+ return false;
+ }
+ }
+ conf_cur_seqnum = libnet_conf_get_seqnum(conf_ctx, NULL, NULL);
+ if (conf_last_seqnum != conf_cur_seqnum) {
+ DEBUGADD(6, ("regdb seqnum changed: old = %llu, "
+ "new = %llu\n",
+ (unsigned long long)conf_last_seqnum,
+ (unsigned long long)conf_cur_seqnum));
return true;
} else {
/*
static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
{
- str_list_free(&Globals.szNetbiosAliases);
- Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
+ TALLOC_FREE(Globals.szNetbiosAliases);
+ Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL);
return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
}
return (bRetval);
}
+static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
+{
+ Globals.ldap_debug_level = lp_int(pszParmValue);
+ init_ldap_debugging();
+ return true;
+}
+
/***************************************************************************
Handle idmap/non unix account uid and gid allocation parameters. The format of these
parameters is:
/* If we already have same option, override it */
if (strcmp(data->key, param_key) == 0) {
string_free(&data->value);
- str_list_free(&data->list);
+ TALLOC_FREE(data->list);
data->value = SMB_STRDUP(pszParmValue);
not_added = False;
break;
break;
case P_LIST:
- str_list_free((char ***)parm_ptr);
- *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
+ TALLOC_FREE(*((char ***)parm_ptr));
+ *(char ***)parm_ptr = str_list_make(
+ NULL, pszParmValue, NULL);
break;
case P_STRING:
char *s;
char *p;
int homes;
+ char *saveptr;
if (!str)
return;
homes = lp_servicenumber(HOMES_NAME);
- for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
+ for (p = strtok_r(s, LIST_SEP, &saveptr); p;
+ p = strtok_r(NULL, LIST_SEP, &saveptr)) {
char *home;
if (lp_servicenumber(p) >= 0)
continue;
switch (parm_table[i].type) {
case P_LIST:
- str_list_copy(&(parm_table[i].def.lvalue),
- *(const char ***)parm_table[i].ptr);
+ str_list_copy(
+ NULL, &(parm_table[i].def.lvalue),
+ *(const char ***)parm_table[i].ptr);
break;
case P_STRING:
case P_USTRING:
string_free( (char**)parm_table[i].ptr );
}
else if (parm_table[i].type == P_LIST) {
- str_list_free( (char***)parm_table[i].ptr );
+ TALLOC_FREE( *((char***)parm_table[i].ptr) );
}
}
}
while (data) {
string_free(&data->key);
string_free(&data->value);
- str_list_free(&data->list);
+ TALLOC_FREE(data->list);
pdata = data->next;
SAFE_FREE(data);
data = pdata;
*/
config_backend = CONFIG_BACKEND_REGISTRY;
/* start over */
+ init_globals(false);
return lp_load(pszFname, global_only, save_defaults,
add_ipc, initialize_globals);
}