param: use a single special handler for idmap parameters
[mat/samba.git] / source3 / param / loadparm.c
index bae73394efb2236c478d646c75c69ca954c976f4..d5f7bacf1b05f6f512513e5c1cd09791f2997f20 100644 (file)
 #include <cups/http.h>
 #endif
 
-#ifdef CLUSTER_SUPPORT
-#include "ctdb_private.h"
-#endif
-
 bool bLoaded = false;
 
 extern userdom_struct current_user_info;
@@ -108,33 +104,7 @@ static int config_backend = CONFIG_BACKEND_FILE;
 
 static bool defaults_saved = false;
 
-#define LOADPARM_EXTRA_GLOBALS \
-       struct parmlist_entry *param_opt;                               \
-       char *realm_original;                                           \
-       char *loglevel;                                                 \
-       int iminreceivefile;                                            \
-       char *szPrintcapname;                                           \
-       int CupsEncrypt;                                                \
-       int  iPreferredMaster;                                          \
-       char *szLdapMachineSuffix;                                      \
-       char *szLdapUserSuffix;                                         \
-       char *szLdapIdmapSuffix;                                        \
-       char *szLdapGroupSuffix;                                        \
-       char *szStateDir;                                               \
-       char *szCacheDir;                                               \
-       char *szUsershareTemplateShare;                                 \
-       char *szIdmapUID;                                               \
-       char *szIdmapGID;                                               \
-       char *szIdmapBackend;                                           \
-       int winbindMaxDomainConnections;                                \
-       int ismb2_max_credits;                                          \
-       char *tls_keyfile;                                              \
-       char *tls_certfile;                                             \
-       char *tls_cafile;                                               \
-       char *tls_crlfile;                                              \
-       char *tls_dhpfile;
-
-#include "param/param_global.h"
+#include "lib/param/param_global.h"
 
 static struct loadparm_global Globals;
 
@@ -155,40 +125,40 @@ static struct loadparm_service sDefault =
        .szInclude = NULL,
        .preexec = NULL,
        .postexec = NULL,
-       .rootpreexec = NULL,
-       .rootpostexec = NULL,
+       .root_preexec = NULL,
+       .root_postexec = NULL,
        .cups_options = NULL,
-       .printcommand = NULL,
-       .lpqcommand = NULL,
-       .lprmcommand = NULL,
-       .lppausecommand = NULL,
-       .lpresumecommand = NULL,
-       .queuepausecommand = NULL,
-       .queueresumecommand = NULL,
+       .print_command = NULL,
+       .lpq_command = NULL,
+       .lprm_command = NULL,
+       .lppause_command = NULL,
+       .lpresume_command = NULL,
+       .queuepause_command = NULL,
+       .queueresume_command = NULL,
        ._printername = NULL,
        .printjob_username = NULL,
        .dont_descend = NULL,
        .hosts_allow = NULL,
        .hosts_deny = NULL,
-       .magicscript = NULL,
-       .magicoutput = NULL,
+       .magic_script = NULL,
+       .magic_output = NULL,
        .veto_files = NULL,
        .hide_files = NULL,
        .veto_oplock_files = NULL,
        .comment = NULL,
        .force_user = NULL,
        .force_group = NULL,
-       .readlist = NULL,
-       .writelist = NULL,
+       .read_list = NULL,
+       .write_list = NULL,
        .volume = NULL,
        .fstype = NULL,
        .vfs_objects = NULL,
        .msdfs_proxy = NULL,
        .aio_write_behind = NULL,
        .dfree_command = NULL,
-       .minprintspace = 0,
+       .min_print_space = 0,
        .iMaxPrintJobs = 1000,
-       .max_reported_jobs = 0,
+       .max_reported_print_jobs = 0,
        .write_cache_size = 0,
        .create_mask = 0744,
        .force_create_mode = 0,
@@ -202,7 +172,7 @@ static struct loadparm_service sDefault =
        .block_size = 1024,
        .dfree_cache_time = 0,
        .preexec_close = false,
-       .rootpreexec_close = false,
+       .root_preexec_close = false,
        .case_sensitive = Auto,
        .preserve_case = true,
        .short_preserve_case = true,
@@ -230,11 +200,11 @@ static struct loadparm_service sDefault =
        .oplocks = true,
        .kernel_oplocks = false,
        .level2_oplocks = true,
-       .onlyuser = false,
+       .only_user = false,
        .mangled_names = true,
        .bWidelinks = false,
        .follow_symlinks = true,
-       .syncalways = false,
+       .sync_always = false,
        .strict_allocate = false,
        .strict_sync = false,
        .mangling_char = '~',
@@ -247,7 +217,7 @@ static struct loadparm_service sDefault =
        .dos_filetime_resolution = false,
        .fake_directory_create_times = false,
        .blocking_locks = true,
-       .inherit_perms = false,
+       .inherit_permissions = false,
        .inherit_acls = false,
        .inherit_owner = false,
        .msdfs_root = false,
@@ -286,32 +256,12 @@ static int iServiceIndex = 0;
 static struct db_context *ServiceHash;
 static bool bInGlobalSection = true;
 static bool bGlobalOnly = false;
+static struct file_lists *file_lists = NULL;
 
 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
 
-/* prototypes for the special type handlers */
-static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
-static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
-static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
-static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
-static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr );
-static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr);
-
-/* these are parameter handlers which are not needed in the
- * source3 code
- */
-
-#define handle_logfile NULL
-
 static void set_allowed_client_auth(void);
 
-static void add_to_file_list(const char *fname, const char *subfname);
 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
 static void free_param_opts(struct parmlist_entry **popts);
 
@@ -320,31 +270,6 @@ static void free_param_opts(struct parmlist_entry **popts);
 /* this is used to prevent lots of mallocs of size 1 */
 static const char null_string[] = "";
 
-/**
- Set a string value, allocing the space for the string
-**/
-
-static bool string_init(char **dest,const char *src)
-{
-       size_t l;
-
-       if (!src)
-               src = "";
-
-       l = strlen(src);
-
-       if (l == 0) {
-               *dest = discard_const_p(char, null_string);
-       } else {
-               (*dest) = SMB_STRDUP(src);
-               if ((*dest) == NULL) {
-                       DEBUG(0,("Out of memory in string_init\n"));
-                       return false;
-               }
-       }
-       return(true);
-}
-
 /**
  Free a string value.
 **/
@@ -355,7 +280,7 @@ static void string_free(char **s)
                return;
        if (*s == null_string)
                *s = NULL;
-       SAFE_FREE(*s);
+       TALLOC_FREE(*s);
 }
 
 /**
@@ -363,17 +288,32 @@ static void string_free(char **s)
  for the string
 **/
 
-static bool string_set(char **dest,const char *src)
+static bool string_set(TALLOC_CTX *mem_ctx, char **dest,const char *src)
 {
        string_free(dest);
-       return(string_init(dest,src));
+
+       if (!src) {
+               src = "";
+       }
+
+       (*dest) = talloc_strdup(mem_ctx, src);
+       if ((*dest) == NULL) {
+               DEBUG(0,("Out of memory in string_init\n"));
+               return false;
+       }
+
+       return true;
+}
+
+bool lp_string_set(char **dest, const char *src) {
+       return string_set(Globals.ctx, dest, src);
 }
 
 /***************************************************************************
  Initialise the sDefault parameter structure for the printer values.
 ***************************************************************************/
 
-static void init_printer_values(struct loadparm_service *pService)
+void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pService)
 {
        /* choose defaults depending on the type of printing */
        switch (pService->printing) {
@@ -381,52 +321,52 @@ static void init_printer_values(struct loadparm_service *pService)
                case PRINT_AIX:
                case PRINT_LPRNT:
                case PRINT_LPROS2:
-                       string_set(&pService->lpqcommand, "lpq -P'%p'");
-                       string_set(&pService->lprmcommand, "lprm -P'%p' %j");
-                       string_set(&pService->printcommand, "lpr -r -P'%p' %s");
+                       lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
+                       lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
+                       lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
                        break;
 
                case PRINT_LPRNG:
                case PRINT_PLP:
-                       string_set(&pService->lpqcommand, "lpq -P'%p'");
-                       string_set(&pService->lprmcommand, "lprm -P'%p' %j");
-                       string_set(&pService->printcommand, "lpr -r -P'%p' %s");
-                       string_set(&pService->queuepausecommand, "lpc stop '%p'");
-                       string_set(&pService->queueresumecommand, "lpc start '%p'");
-                       string_set(&pService->lppausecommand, "lpc hold '%p' %j");
-                       string_set(&pService->lpresumecommand, "lpc release '%p' %j");
+                       lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
+                       lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
+                       lpcfg_string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
+                       lpcfg_string_set(ctx, &pService->queuepause_command, "lpc stop '%p'");
+                       lpcfg_string_set(ctx, &pService->queueresume_command, "lpc start '%p'");
+                       lpcfg_string_set(ctx, &pService->lppause_command, "lpc hold '%p' %j");
+                       lpcfg_string_set(ctx, &pService->lpresume_command, "lpc release '%p' %j");
                        break;
 
                case PRINT_CUPS:
                case PRINT_IPRINT:
                        /* set the lpq command to contain the destination printer
                           name only.  This is used by cups_queue_get() */
-                       string_set(&pService->lpqcommand, "%p");
-                       string_set(&pService->lprmcommand, "");
-                       string_set(&pService->printcommand, "");
-                       string_set(&pService->lppausecommand, "");
-                       string_set(&pService->lpresumecommand, "");
-                       string_set(&pService->queuepausecommand, "");
-                       string_set(&pService->queueresumecommand, "");
+                       lpcfg_string_set(ctx, &pService->lpq_command, "%p");
+                       lpcfg_string_set(ctx, &pService->lprm_command, "");
+                       lpcfg_string_set(ctx, &pService->print_command, "");
+                       lpcfg_string_set(ctx, &pService->lppause_command, "");
+                       lpcfg_string_set(ctx, &pService->lpresume_command, "");
+                       lpcfg_string_set(ctx, &pService->queuepause_command, "");
+                       lpcfg_string_set(ctx, &pService->queueresume_command, "");
                        break;
 
                case PRINT_SYSV:
                case PRINT_HPUX:
-                       string_set(&pService->lpqcommand, "lpstat -o%p");
-                       string_set(&pService->lprmcommand, "cancel %p-%j");
-                       string_set(&pService->printcommand, "lp -c -d%p %s; rm %s");
-                       string_set(&pService->queuepausecommand, "disable %p");
-                       string_set(&pService->queueresumecommand, "enable %p");
+                       lpcfg_string_set(ctx, &pService->lpq_command, "lpstat -o%p");
+                       lpcfg_string_set(ctx, &pService->lprm_command, "cancel %p-%j");
+                       lpcfg_string_set(ctx, &pService->print_command, "lp -c -d%p %s; rm %s");
+                       lpcfg_string_set(ctx, &pService->queuepause_command, "disable %p");
+                       lpcfg_string_set(ctx, &pService->queueresume_command, "enable %p");
 #ifndef HPUX
-                       string_set(&pService->lppausecommand, "lp -i %p-%j -H hold");
-                       string_set(&pService->lpresumecommand, "lp -i %p-%j -H resume");
+                       lpcfg_string_set(ctx, &pService->lppause_command, "lp -i %p-%j -H hold");
+                       lpcfg_string_set(ctx, &pService->lpresume_command, "lp -i %p-%j -H resume");
 #endif /* HPUX */
                        break;
 
                case PRINT_QNX:
-                       string_set(&pService->lpqcommand, "lpq -P%p");
-                       string_set(&pService->lprmcommand, "lprm -P%p %j");
-                       string_set(&pService->printcommand, "lp -r -P%p %s");
+                       lpcfg_string_set(ctx, &pService->lpq_command, "lpq -P%p");
+                       lpcfg_string_set(ctx, &pService->lprm_command, "lprm -P%p %j");
+                       lpcfg_string_set(ctx, &pService->print_command, "lp -r -P%p %s");
                        break;
 
 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
@@ -434,7 +374,7 @@ static void init_printer_values(struct loadparm_service *pService)
        case PRINT_TEST:
        case PRINT_VLP: {
                const char *tdbfile;
-               TALLOC_CTX *tmp_ctx = talloc_stackframe();
+               TALLOC_CTX *tmp_ctx = talloc_new(ctx);
                char *tmp;
 
                tdbfile = talloc_asprintf(
@@ -447,37 +387,37 @@ static void init_printer_values(struct loadparm_service *pService)
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
                                      tdbfile);
-               string_set(&pService->printcommand,
+               lpcfg_string_set(ctx, &pService->print_command,
                           tmp ? tmp : "vlp print %p %s");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s lpq %%p",
                                      tdbfile);
-               string_set(&pService->lpqcommand,
+               lpcfg_string_set(ctx, &pService->lpq_command,
                           tmp ? tmp : "vlp lpq %p");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s lprm %%p %%j",
                                      tdbfile);
-               string_set(&pService->lprmcommand,
+               lpcfg_string_set(ctx, &pService->lprm_command,
                           tmp ? tmp : "vlp lprm %p %j");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s lppause %%p %%j",
                                      tdbfile);
-               string_set(&pService->lppausecommand,
+               lpcfg_string_set(ctx, &pService->lppause_command,
                           tmp ? tmp : "vlp lppause %p %j");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s lpresume %%p %%j",
                                      tdbfile);
-               string_set(&pService->lpresumecommand,
+               lpcfg_string_set(ctx, &pService->lpresume_command,
                           tmp ? tmp : "vlp lpresume %p %j");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s queuepause %%p",
                                      tdbfile);
-               string_set(&pService->queuepausecommand,
+               lpcfg_string_set(ctx, &pService->queuepause_command,
                           tmp ? tmp : "vlp queuepause %p");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
                                      tdbfile);
-               string_set(&pService->queueresumecommand,
+               lpcfg_string_set(ctx, &pService->queueresume_command,
                           tmp ? tmp : "vlp queueresume %p");
                TALLOC_FREE(tmp_ctx);
 
@@ -722,81 +662,82 @@ static void init_globals(bool reinit_globals)
         * table once the defaults are set */
        ZERO_STRUCT(Globals);
 
-       Globals.ctx = talloc_new(NULL);
+       Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
 
        for (i = 0; parm_table[i].label; i++) {
                if ((parm_table[i].type == P_STRING ||
                     parm_table[i].type == P_USTRING))
                {
-                       string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
+                       string_set(Globals.ctx, (char **)lp_parm_ptr(NULL, &parm_table[i]), "");
                }
        }
 
 
-       string_set(&sDefault.fstype, FSTYPE_STRING);
-       string_set(&sDefault.printjob_username, "%U");
+       string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
+       string_set(Globals.ctx, &sDefault.printjob_username, "%U");
 
-       init_printer_values(&sDefault);
+       init_printer_values(Globals.ctx, &sDefault);
 
        sDefault.ntvfs_handler = (const char **)str_list_make_v3(NULL, "unixuid default", NULL);
 
        DEBUG(3, ("Initialising global parameters\n"));
 
        /* Must manually force to upper case here, as this does not go via the handler */
-       string_set(&Globals.netbios_name, myhostname_upper());
+       string_set(Globals.ctx, &Globals.netbios_name, myhostname_upper());
 
-       string_set(&Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
-       string_set(&Globals.private_dir, get_dyn_PRIVATE_DIR());
+       string_set(Globals.ctx, &Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
+       string_set(Globals.ctx, &Globals.private_dir, get_dyn_PRIVATE_DIR());
 
        /* use the new 'hash2' method by default, with a prefix of 1 */
-       string_set(&Globals.mangling_method, "hash2");
+       string_set(Globals.ctx, &Globals.mangling_method, "hash2");
        Globals.mangle_prefix = 1;
 
-       string_set(&Globals.guest_account, GUEST_ACCOUNT);
+       string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
 
        /* using UTF8 by default allows us to support all chars */
-       string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
+       string_set(Globals.ctx, &Globals.unix_charset, DEFAULT_UNIX_CHARSET);
 
        /* Use codepage 850 as a default for the dos character set */
-       string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
+       string_set(Globals.ctx, &Globals.dos_charset, DEFAULT_DOS_CHARSET);
 
        /*
         * Allow the default PASSWD_CHAT to be overridden in local.h.
         */
-       string_set(&Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
+       string_set(Globals.ctx, &Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
 
-       string_set(&Globals.workgroup, DEFAULT_WORKGROUP);
+       string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
 
-       string_set(&Globals.passwd_program, "");
-       string_set(&Globals.lock_directory, get_dyn_LOCKDIR());
-       string_set(&Globals.szStateDir, get_dyn_STATEDIR());
-       string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
-       string_set(&Globals.pid_directory, get_dyn_PIDDIR());
-       string_set(&Globals.nbt_client_socket_address, "0.0.0.0");
+       string_set(Globals.ctx, &Globals.passwd_program, "");
+       string_set(Globals.ctx, &Globals.lock_directory, get_dyn_LOCKDIR());
+       string_set(Globals.ctx, &Globals.state_directory, get_dyn_STATEDIR());
+       string_set(Globals.ctx, &Globals.cache_directory, get_dyn_CACHEDIR());
+       string_set(Globals.ctx, &Globals.pid_directory, get_dyn_PIDDIR());
+       string_set(Globals.ctx, &Globals.nbt_client_socket_address, "0.0.0.0");
        /*
         * By default support explicit binding to broadcast
         * addresses.
         */
        Globals.nmbd_bind_explicit_broadcast = true;
 
-       if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
+       s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
+       if (s == NULL) {
                smb_panic("init_globals: ENOMEM");
        }
-       string_set(&Globals.server_string, s);
-       SAFE_FREE(s);
+       string_set(Globals.ctx, &Globals.server_string, s);
+       TALLOC_FREE(s);
 #ifdef DEVELOPER
-       string_set(&Globals.panic_action, "/bin/sleep 999999999");
+       string_set(Globals.ctx, &Globals.panic_action, "/bin/sleep 999999999");
 #endif
 
-       string_set(&Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
+       string_set(Globals.ctx, &Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
 
-       string_set(&Globals.logon_drive, "");
+       string_set(Globals.ctx, &Globals.logon_drive, "");
        /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
-       string_set(&Globals.logon_home, "\\\\%N\\%U");
-       string_set(&Globals.logon_path, "\\\\%N\\%U\\profile");
+       string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
+       string_set(Globals.ctx, &Globals.logon_path, "\\\\%N\\%U\\profile");
 
        Globals.name_resolve_order = (const char **)str_list_make_v3(NULL, "lmhosts wins host bcast", NULL);
-       string_set(&Globals.password_server, "*");
+       string_set(Globals.ctx, &Globals.password_server, "*");
 
        Globals.algorithmic_rid_base = BASE_RID;
 
@@ -809,34 +750,35 @@ static void init_globals(bool reinit_globals)
        /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
        /* Discovered by 2 days of pain by Don McCall @ HP :-). */
        Globals.max_xmit = 0x4104;
-       Globals.maxmux = 50;    /* This is *needed* for profile support. */
-       Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
+       Globals.max_mux = 50;   /* This is *needed* for profile support. */
+       Globals.lpq_cache_time = 30;    /* changed to handle large print servers better -- jerry */
        Globals._disable_spoolss = false;
        Globals.max_smbd_processes = 0;/* no limit specified */
-       Globals.usernamelevel = 0;
+       Globals.username_level = 0;
        Globals.deadtime = 0;
        Globals.getwd_cache = true;
        Globals.large_readwrite = true;
        Globals.max_log_size = 5000;
        Globals.max_open_files = max_open_files();
-       Globals.srv_maxprotocol = PROTOCOL_SMB3_00;
-       Globals.srv_minprotocol = PROTOCOL_LANMAN1;
-       Globals.cli_maxprotocol = PROTOCOL_NT1;
-       Globals.cli_minprotocol = PROTOCOL_CORE;
+       Globals.server_max_protocol = PROTOCOL_SMB3_00;
+       Globals.server_min_protocol = PROTOCOL_LANMAN1;
+       Globals.client_max_protocol = PROTOCOL_NT1;
+       Globals.client_min_protocol = PROTOCOL_CORE;
        Globals._security = SEC_AUTO;
-       Globals.encrypted_passwords = true;
+       Globals.encrypt_passwords = true;
        Globals.client_schannel = Auto;
        Globals.winbind_sealed_pipes = true;
        Globals.require_strong_key = true;
        Globals.server_schannel = Auto;
-       Globals.bReadRaw = true;
-       Globals.bWriteRaw = true;
+       Globals.read_raw = true;
+       Globals.write_raw = true;
        Globals.null_passwords = false;
+       Globals.old_password_allowed_period = 60;
        Globals.obey_pam_restrictions = false;
        Globals.syslog = 1;
        Globals.syslog_only = false;
        Globals.timestamp_logs = true;
-       string_set(&Globals.loglevel, "0");
+       string_set(Globals.ctx, &Globals.log_level, "0");
        Globals.debug_prefix_timestamp = false;
        Globals.debug_hires_timestamp = true;
        Globals.debug_pid = false;
@@ -850,11 +792,11 @@ static void init_globals(bool reinit_globals)
        Globals.lm_announce = Auto;     /* = Auto: send only if LM clients found */
        Globals.lm_interval = 60;
 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
-       Globals.nis_home_map = false;
+       Globals.nis_homedir = false;
 #ifdef WITH_NISPLUS_HOME
-       string_set(&Globals.nis_home_map_name, "auto_home.org_dir");
+       string_set(Globals.ctx, &Globals.homedir_map, "auto_home.org_dir");
 #else
-       string_set(&Globals.nis_home_map_name, "auto.home");
+       string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
 #endif
 #endif
        Globals.time_server = false;
@@ -895,14 +837,14 @@ static void init_globals(bool reinit_globals)
           a large number of sites (tridge) */
        Globals.hostname_lookups = false;
 
-       string_set(&Globals.passdb_backend, "tdbsam");
-       string_set(&Globals.ldap_suffix, "");
-       string_set(&Globals.szLdapMachineSuffix, "");
-       string_set(&Globals.szLdapUserSuffix, "");
-       string_set(&Globals.szLdapGroupSuffix, "");
-       string_set(&Globals.szLdapIdmapSuffix, "");
+       string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
+       string_set(Globals.ctx, &Globals.ldap_suffix, "");
+       string_set(Globals.ctx, &Globals.szLdapMachineSuffix, "");
+       string_set(Globals.ctx, &Globals.szLdapUserSuffix, "");
+       string_set(Globals.ctx, &Globals.szLdapGroupSuffix, "");
+       string_set(Globals.ctx, &Globals.szLdapIdmapSuffix, "");
 
-       string_set(&Globals.ldap_admin_dn, "");
+       string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
        Globals.ldap_ssl = LDAP_SSL_START_TLS;
        Globals.ldap_ssl_ads = false;
        Globals.ldap_deref = -1;
@@ -935,7 +877,7 @@ static void init_globals(bool reinit_globals)
 
 */
 
-       Globals.ms_add_printer_wizard = true;
+       Globals.show_add_printer_wizard = true;
        Globals.os_level = 20;
        Globals.local_master = true;
        Globals._domain_master = Auto;  /* depending on _domain_logons */
@@ -950,21 +892,17 @@ static void init_globals(bool reinit_globals)
        Globals.wins_dns_proxy = true;
 
        Globals.allow_trusted_domains = true;
-       string_set(&Globals.szIdmapBackend, "tdb");
+       string_set(Globals.ctx, &Globals.szIdmapBackend, "tdb");
 
-       string_set(&Globals.template_shell, "/bin/false");
-       string_set(&Globals.template_homedir, "/home/%D/%U");
-       string_set(&Globals.winbind_separator, "\\");
-       string_set(&Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
+       string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
+       string_set(Globals.ctx, &Globals.template_homedir, "/home/%D/%U");
+       string_set(Globals.ctx, &Globals.winbind_separator, "\\");
+       string_set(Globals.ctx, &Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
 
-       string_set(&Globals.cups_server, "");
-       string_set(&Globals.iprint_server, "");
+       string_set(Globals.ctx, &Globals.cups_server, "");
+       string_set(Globals.ctx, &Globals.iprint_server, "");
 
-#ifdef CLUSTER_SUPPORT
-       string_set(&Globals.ctdbd_socket, CTDB_PATH);
-#else
-       string_set(&Globals.ctdbd_socket, "");
-#endif
+       string_set(Globals.ctx, &Globals._ctdbd_socket, "");
 
        Globals.cluster_addresses = NULL;
        Globals.clustering = false;
@@ -1005,12 +943,13 @@ static void init_globals(bool reinit_globals)
        Globals.enable_asu_support       = false;
 
        /* User defined shares. */
-       if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
+       s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
+       if (s == NULL) {
                smb_panic("init_globals: ENOMEM");
        }
-       string_set(&Globals.usershare_path, s);
-       SAFE_FREE(s);
-       string_set(&Globals.szUsershareTemplateShare, "");
+       string_set(Globals.ctx, &Globals.usershare_path, s);
+       TALLOC_FREE(s);
+       string_set(Globals.ctx, &Globals.usershare_template_share, "");
        Globals.usershare_max_shares = 0;
        /* By default disallow sharing of directories not owned by the sharer. */
        Globals.usershare_owner_only = true;
@@ -1032,7 +971,7 @@ static void init_globals(bool reinit_globals)
        Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
        Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
 
-       string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
+       string_set(Globals.ctx, &Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
 
        Globals.server_services = (const char **)str_list_make_v3(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbind ntp_signd kcc dnsupdate dns", NULL);
 
@@ -1040,37 +979,40 @@ static void init_globals(bool reinit_globals)
 
        Globals.tls_enabled = true;
 
-       string_set(&Globals.tls_keyfile, "tls/key.pem");
-       string_set(&Globals.tls_certfile, "tls/cert.pem");
-       string_set(&Globals.tls_cafile, "tls/ca.pem");
+       string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
+       string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
+       string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
 
-       string_set(&Globals.share_backend, "classic");
+       string_set(Globals.ctx, &Globals.share_backend, "classic");
 
        Globals.iPreferredMaster = Auto;
 
        Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
 
-       string_set(&Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
+       string_set(Globals.ctx, &Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
 
-       string_set(&Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
+       string_set(Globals.ctx, &Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
 
-       if (asprintf(&s, "%s/samba_kcc", get_dyn_SCRIPTSBINDIR()) < 0) {
+       s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
+       if (s == NULL) {
                smb_panic("init_globals: ENOMEM");
        }
        Globals.samba_kcc_command = (const char **)str_list_make_v3(NULL, s, NULL);
-       SAFE_FREE(s);
+       TALLOC_FREE(s);
 
-       if (asprintf(&s, "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
+       s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
+       if (s == NULL) {
                smb_panic("init_globals: ENOMEM");
        }
        Globals.dns_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
-       SAFE_FREE(s);
+       TALLOC_FREE(s);
 
-       if (asprintf(&s, "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
+       s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
+       if (s == NULL) {
                smb_panic("init_globals: ENOMEM");
        }
        Globals.spn_update_command = (const char **)str_list_make_v3(NULL, s, NULL);
-       SAFE_FREE(s);
+       TALLOC_FREE(s);
 
        Globals.nsupdate_command = (const char **)str_list_make_v3(NULL, "/usr/bin/nsupdate -g", NULL);
 
@@ -1098,7 +1040,7 @@ static void init_globals(bool reinit_globals)
  callers without affecting the source string.
 ********************************************************************/
 
-static char *lp_string(TALLOC_CTX *ctx, const char *s)
+char *lp_string(TALLOC_CTX *ctx, const char *s)
 {
        char *ret;
 
@@ -1166,31 +1108,6 @@ char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK
 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
  char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
 
-
-static FN_GLOBAL_BOOL(_readraw, bReadRaw)
-static FN_GLOBAL_BOOL(_writeraw, bWriteRaw)
-
-/* If lp_statedir() and lp_cachedir() are explicitely set during the
- * build process or in smb.conf, we use that value.  Otherwise they
- * default to the value of lp_lock_directory(). */
-const char *lp_statedir(void) {
-       if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
-           (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
-               return(*(char **)(&Globals.szStateDir) ?
-                      *(char **)(&Globals.szStateDir) : "");
-       else
-               return(*(char **)(&Globals.lock_directory) ?
-                      *(char **)(&Globals.lock_directory) : "");
-}
-const char *lp_cachedir(void) {
-       if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
-           (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
-               return(*(char **)(&Globals.szCacheDir) ?
-                      *(char **)(&Globals.szCacheDir) : "");
-       else
-               return(*(char **)(&Globals.lock_directory) ?
-                      *(char **)(&Globals.lock_directory) : "");
-}
 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
                  winbindMaxDomainConnections)
 
@@ -1233,26 +1150,21 @@ int lp_cups_encrypt(void)
 
 /* These functions remain in source3/param for now */
 
-FN_GLOBAL_STRING(configfile, szConfigFile)
-
 #include "lib/param/param_functions.c"
 
 FN_LOCAL_STRING(servicename, szService)
 FN_LOCAL_CONST_STRING(const_servicename, szService)
 
+/* These functions cannot be auto-generated */
+FN_LOCAL_BOOL(autoloaded, autoloaded)
+
 /* local prototypes */
 
 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
 static const char *get_boolean(bool bool_value);
-static int getservicebyname(const char *pszServiceName,
-                           struct loadparm_service *pserviceDest);
-static void copy_service(struct loadparm_service *pserviceDest,
-                        struct loadparm_service *pserviceSource,
-                        struct bitmap *pcopymapDest);
 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
                         void *userdata);
 static bool do_section(const char *pszSectionName, void *userdata);
-static void init_copymap(struct loadparm_service *pservice);
 static bool hash_a_service(const char *name, int number);
 static void free_service_byindex(int iService);
 static void show_parameter(int parmIndex);
@@ -1269,6 +1181,7 @@ static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service
        bool global_section = false;
        char* param_key;
         struct parmlist_entry *data;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
 
        if (service == NULL) {
                data = Globals.param_opt;
@@ -1277,14 +1190,16 @@ static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service
                data = service->param_opt;
        }
 
-       if (asprintf(&param_key, "%s:%s", type, option) == -1) {
+       param_key = talloc_asprintf(mem_ctx, "%s:%s", type, option);
+       if (param_key == NULL) {
                DEBUG(0,("asprintf failed!\n"));
+               TALLOC_FREE(mem_ctx);
                return NULL;
        }
 
        while (data) {
                if (strwicmp(data->key, param_key) == 0) {
-                       string_free(&param_key);
+                       TALLOC_FREE(mem_ctx);
                        return data;
                }
                data = data->next;
@@ -1296,14 +1211,14 @@ static struct parmlist_entry *get_parametrics_by_service(struct loadparm_service
                data = Globals.param_opt;
                while (data) {
                        if (strwicmp(data->key, param_key) == 0) {
-                               string_free(&param_key);
+                               TALLOC_FREE(mem_ctx);
                                return data;
                        }
                        data = data->next;
                }
        }
 
-       string_free(&param_key);
+       TALLOC_FREE(mem_ctx);
 
        return NULL;
 }
@@ -1329,54 +1244,6 @@ static struct parmlist_entry *get_parametrics(int snum, const char *type,
 #define MISSING_PARAMETER(name) \
     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
 
-/*******************************************************************
-convenience routine to return int parameters.
-********************************************************************/
-static int lp_int(const char *s)
-{
-
-       if (!s || !*s) {
-               MISSING_PARAMETER(lp_int);
-               return (-1);
-       }
-
-       return (int)strtol(s, NULL, 0);
-}
-
-/*******************************************************************
-convenience routine to return unsigned long parameters.
-********************************************************************/
-static unsigned long lp_ulong(const char *s)
-{
-
-       if (!s || !*s) {
-               MISSING_PARAMETER(lp_ulong);
-               return (0);
-       }
-
-       return strtoul(s, NULL, 0);
-}
-
-/*******************************************************************
-convenience routine to return boolean parameters.
-********************************************************************/
-static bool lp_bool(const char *s)
-{
-       bool ret = false;
-
-       if (!s || !*s) {
-               MISSING_PARAMETER(lp_bool);
-               return false;
-       }
-
-       if (!set_boolean(s, &ret)) {
-               DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
-               return false;
-       }
-
-       return ret;
-}
-
 /*******************************************************************
 convenience routine to return enum parameters.
 ********************************************************************/
@@ -1429,12 +1296,14 @@ const char *lp_parm_const_string(int snum, const char *type, const char *option,
        return data->value;
 }
 
-const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, const char *option)
+const char *lp_parm_const_string_service(struct loadparm_service *service,
+                                        const char *type, const char *option,
+                                        const char *def)
 {
        struct parmlist_entry *data = get_parametrics_by_service(service, type, option);
 
        if (data == NULL||data->value==NULL)
-               return NULL;
+               return def;
 
        return data->value;
 }
@@ -1510,18 +1379,6 @@ int lp_parm_enum(int snum, const char *type, const char *option,
        return def;
 }
 
-
-/***************************************************************************
- Initialise a service to the defaults.
-***************************************************************************/
-
-static void init_service(struct loadparm_service *pservice)
-{
-       memset((char *)pservice, '\0', sizeof(struct loadparm_service));
-       copy_service(pservice, &sDefault, NULL);
-}
-
-
 /**
  * free a param_opts structure.
  * param_opts handling should be moved to talloc;
@@ -1541,7 +1398,7 @@ static void free_param_opts(struct parmlist_entry **popts)
                string_free(&opt->value);
                TALLOC_FREE(opt->list);
                next_opt = opt->next;
-               SAFE_FREE(opt);
+               TALLOC_FREE(opt);
                opt = next_opt;
        }
        *popts = NULL;
@@ -1606,12 +1463,9 @@ static void free_service_byindex(int idx)
 static int add_a_service(const struct loadparm_service *pservice, const char *name)
 {
        int i;
-       struct loadparm_service tservice;
        int num_to_alloc = iNumServices + 1;
        struct loadparm_service **tsp = NULL;
 
-       tservice = *pservice;
-
        /* it might already exist */
        if (name) {
                i = getservicebyname(name, NULL);
@@ -1622,13 +1476,13 @@ static int add_a_service(const struct loadparm_service *pservice, const char *na
 
        /* if not, then create one */
        i = iNumServices;
-       tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct loadparm_service *, num_to_alloc);
+       tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
        if (tsp == NULL) {
                DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
                return (-1);
        }
        ServicePtrs = tsp;
-       ServicePtrs[iNumServices] = talloc(NULL, struct loadparm_service);
+       ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service);
        if (!ServicePtrs[iNumServices]) {
                DEBUG(0,("add_a_service: out of memory!\n"));
                return (-1);
@@ -1637,10 +1491,9 @@ static int add_a_service(const struct loadparm_service *pservice, const char *na
 
        ServicePtrs[i]->valid = true;
 
-       init_service(ServicePtrs[i]);
-       copy_service(ServicePtrs[i], &tservice, NULL);
+       copy_service(ServicePtrs[i], pservice, NULL);
        if (name)
-               string_set(&ServicePtrs[i]->szService, name);
+               string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name);
 
        DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
                i, ServicePtrs[i]->szService));
@@ -1729,16 +1582,16 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
        if (!(*(ServicePtrs[iDefaultService]->path))
            || strequal(ServicePtrs[iDefaultService]->path,
                        lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
-               string_set(&ServicePtrs[i]->path, pszHomedir);
+               string_set(ServicePtrs[i], &ServicePtrs[i]->path, pszHomedir);
        }
 
        if (!(*(ServicePtrs[i]->comment))) {
-               char *comment = NULL;
-               if (asprintf(&comment, "Home directory of %s", user) < 0) {
+               char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
+               if (comment == NULL) {
                        return false;
                }
-               string_set(&ServicePtrs[i]->comment, comment);
-               SAFE_FREE(comment);
+               string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
+               TALLOC_FREE(comment);
        }
 
        /* set the browseable flag from the global default */
@@ -1779,15 +1632,16 @@ static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
        if (i < 0)
                return false;
 
-       if (asprintf(&comment, "IPC Service (%s)",
-                               Globals.server_string) < 0) {
+       comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
+                                 Globals.server_string);
+       if (comment == NULL) {
                return false;
        }
 
-       string_set(&ServicePtrs[i]->path, tmpdir());
-       string_set(&ServicePtrs[i]->username, "");
-       string_set(&ServicePtrs[i]->comment, comment);
-       string_set(&ServicePtrs[i]->fstype, "IPC");
+       string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
+       string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
+       string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
+       string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
        ServicePtrs[i]->max_connections = 0;
        ServicePtrs[i]->bAvailable = true;
        ServicePtrs[i]->read_only = true;
@@ -1799,7 +1653,7 @@ static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
 
        DEBUG(3, ("adding IPC service\n"));
 
-       SAFE_FREE(comment);
+       TALLOC_FREE(comment);
        return true;
 }
 
@@ -1821,8 +1675,8 @@ bool lp_add_printer(const char *pszPrintername, int iDefaultService)
        /* entry (if/when the 'available' keyword is implemented!).    */
 
        /* the printer name is set to the service name. */
-       string_set(&ServicePtrs[i]->_printername, pszPrintername);
-       string_set(&ServicePtrs[i]->comment, comment);
+       string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, pszPrintername);
+       string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
 
        /* set the browseable flag from the gloabl default */
        ServicePtrs[i]->browseable = sDefault.browseable;
@@ -2106,15 +1960,6 @@ void show_parameter_list(void)
        }
 }
 
-/***************************************************************************
- Check if a given string correctly represents a boolean value.
-***************************************************************************/
-
-bool lp_string_is_valid_boolean(const char *parm_value)
-{
-       return set_boolean(parm_value, NULL);
-}
-
 /***************************************************************************
  Get the standard string representation of a boolean value ("yes" or "no")
 ***************************************************************************/
@@ -2167,7 +2012,7 @@ bool lp_canonicalize_boolean(const char *str, const char**canon_str)
 Find a service by name. Otherwise works like get_service.
 ***************************************************************************/
 
-static int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
+int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
 {
        int iService = -1;
        char *canon_name;
@@ -2223,124 +2068,6 @@ struct loadparm_service *lp_default_loadparm_service()
        return &sDefault;
 }
 
-
-/***************************************************************************
- Copy a service structure to another.
- If pcopymapDest is NULL then copy all fields
-***************************************************************************/
-
-/**
- * Add a parametric option to a parmlist_entry,
- * replacing old value, if already present.
- */
-static void set_param_opt(struct parmlist_entry **opt_list,
-                         const char *opt_name,
-                         const char *opt_value,
-                         unsigned priority)
-{
-       struct parmlist_entry *new_opt, *opt;
-       bool not_added;
-
-       opt = *opt_list;
-       not_added = true;
-
-       /* Traverse destination */
-       while (opt) {
-               /* If we already have same option, override it */
-               if (strwicmp(opt->key, opt_name) == 0) {
-                       if ((opt->priority & FLAG_CMDLINE) &&
-                           !(priority & FLAG_CMDLINE)) {
-                               /* it's been marked as not to be
-                                  overridden */
-                               return;
-                       }
-                       string_free(&opt->value);
-                       TALLOC_FREE(opt->list);
-                       opt->value = SMB_STRDUP(opt_value);
-                       opt->priority = priority;
-                       not_added = false;
-                       break;
-               }
-               opt = opt->next;
-       }
-       if (not_added) {
-           new_opt = SMB_XMALLOC_P(struct parmlist_entry);
-           new_opt->key = SMB_STRDUP(opt_name);
-           new_opt->value = SMB_STRDUP(opt_value);
-           new_opt->list = NULL;
-           new_opt->priority = priority;
-           DLIST_ADD(*opt_list, new_opt);
-       }
-}
-
-static void copy_service(struct loadparm_service *pserviceDest, struct loadparm_service *pserviceSource,
-                        struct bitmap *pcopymapDest)
-{
-       int i;
-       bool bcopyall = (pcopymapDest == NULL);
-       struct parmlist_entry *data;
-
-       for (i = 0; parm_table[i].label; i++)
-               if (parm_table[i].p_class == P_LOCAL &&
-                   (bcopyall || bitmap_query(pcopymapDest,i))) {
-                       void *src_ptr = lp_parm_ptr(pserviceSource, &parm_table[i]);
-                       void *dest_ptr = lp_parm_ptr(pserviceDest, &parm_table[i]);
-
-                       switch (parm_table[i].type) {
-                               case P_BOOL:
-                               case P_BOOLREV:
-                                       *(bool *)dest_ptr = *(bool *)src_ptr;
-                                       break;
-
-                               case P_INTEGER:
-                               case P_ENUM:
-                               case P_OCTAL:
-                               case P_BYTES:
-                                       *(int *)dest_ptr = *(int *)src_ptr;
-                                       break;
-
-                               case P_CHAR:
-                                       *(char *)dest_ptr = *(char *)src_ptr;
-                                       break;
-
-                               case P_STRING:
-                                       string_set((char **)dest_ptr,
-                                                  *(char **)src_ptr);
-                                       break;
-
-                               case P_USTRING:
-                               {
-                                       char *upper_string = strupper_talloc(talloc_tos(), 
-                                                                            *(char **)src_ptr);
-                                       string_set((char **)dest_ptr,
-                                                  upper_string);
-                                       TALLOC_FREE(upper_string);
-                                       break;
-                               }
-                               case P_LIST:
-                                       TALLOC_FREE(*((char ***)dest_ptr));
-                                       *((char ***)dest_ptr) = str_list_copy(NULL, 
-                                                     *(const char ***)src_ptr);
-                                       break;
-                               default:
-                                       break;
-                       }
-               }
-
-       if (bcopyall) {
-               init_copymap(pserviceDest);
-               if (pserviceSource->copymap)
-                       bitmap_copy(pserviceDest->copymap,
-                                   pserviceSource->copymap);
-       }
-
-       data = pserviceSource->param_opt;
-       while (data) {
-               set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->priority);
-               data = data->next;
-       }
-}
-
 /***************************************************************************
 Check a service for consistency. Return false if the service is in any way
 incomplete or faulty, else true.
@@ -2482,7 +2209,7 @@ static bool process_registry_globals(void)
 {
        bool ret;
 
-       add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
+       add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
 
        ret = do_parameter("registry shares", "yes", NULL);
        if (!ret) {
@@ -2564,54 +2291,6 @@ done:
 
 static uint8_t include_depth;
 
-static struct file_lists {
-       struct file_lists *next;
-       char *name;
-       char *subfname;
-       time_t modtime;
-} *file_lists = NULL;
-
-/*******************************************************************
- Keep a linked list of all config files so we know when one has changed 
- it's date and needs to be reloaded.
-********************************************************************/
-
-static void add_to_file_list(const char *fname, const char *subfname)
-{
-       struct file_lists *f = file_lists;
-
-       while (f) {
-               if (f->name && !strcmp(f->name, fname))
-                       break;
-               f = f->next;
-       }
-
-       if (!f) {
-               f = SMB_MALLOC_P(struct file_lists);
-               if (!f)
-                       return;
-               f->next = file_lists;
-               f->name = SMB_STRDUP(fname);
-               if (!f->name) {
-                       SAFE_FREE(f);
-                       return;
-               }
-               f->subfname = SMB_STRDUP(subfname);
-               if (!f->subfname) {
-                       SAFE_FREE(f->name);
-                       SAFE_FREE(f);
-                       return;
-               }
-               file_lists = f;
-               f->modtime = file_modtime(subfname);
-       } else {
-               time_t t = file_modtime(subfname);
-               if (t)
-                       f->modtime = t;
-       }
-       return;
-}
-
 /**
  * Free the file lists
  */
@@ -2623,9 +2302,7 @@ static void free_file_list(void)
        f = file_lists;
        while( f ) {
                next = f->next;
-               SAFE_FREE( f->name );
-               SAFE_FREE( f->subfname );
-               SAFE_FREE( f );
+               TALLOC_FREE( f );
                f = next;
        }
        file_lists = NULL;
@@ -2696,8 +2373,11 @@ bool lp_file_list_changed(void)
                                         ("file %s modified: %s\n", n2,
                                          ctime(&mod_time)));
                                f->modtime = mod_time;
-                               SAFE_FREE(f->subfname);
-                               f->subfname = SMB_STRDUP(n2);
+                               TALLOC_FREE(f->subfname);
+                               f->subfname = talloc_strdup(f, n2);
+                               if (f->subfname == NULL) {
+                                       smb_panic("talloc_strdup failed");
+                               }
                                TALLOC_FREE(n2);
                                return true;
                        }
@@ -2723,80 +2403,12 @@ static void init_iconv(void)
                                                      true, global_iconv_handle);
 }
 
-static bool handle_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       if (strcmp(*ptr, pszParmValue) != 0) {
-               string_set(ptr, pszParmValue);
-               init_iconv();
-       }
-       return true;
-}
-
-static bool handle_dos_charset(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       bool is_utf8 = false;
-       size_t len = strlen(pszParmValue);
-
-       if (len == 4 || len == 5) {
-               /* Don't use StrCaseCmp here as we don't want to
-                  initialize iconv. */
-               if ((toupper_m(pszParmValue[0]) == 'U') &&
-                   (toupper_m(pszParmValue[1]) == 'T') &&
-                   (toupper_m(pszParmValue[2]) == 'F')) {
-                       if (len == 4) {
-                               if (pszParmValue[3] == '8') {
-                                       is_utf8 = true;
-                               }
-                       } else {
-                               if (pszParmValue[3] == '-' &&
-                                   pszParmValue[4] == '8') {
-                                       is_utf8 = true;
-                               }
-                       }
-               }
-       }
-
-       if (strcmp(*ptr, pszParmValue) != 0) {
-               if (is_utf8) {
-                       DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
-                               "be UTF8, using (default value) %s instead.\n",
-                               DEFAULT_DOS_CHARSET));
-                       pszParmValue = DEFAULT_DOS_CHARSET;
-               }
-               string_set(ptr, pszParmValue);
-               init_iconv();
-       }
-       return true;
-}
-
-static bool handle_realm(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       bool ret = true;
-       TALLOC_CTX *frame = talloc_stackframe();
-       char *realm = strupper_talloc(frame, pszParmValue);
-       char *dnsdomain = strlower_talloc(realm, pszParmValue);
-
-       ret &= string_set(&Globals.realm_original, pszParmValue);
-       ret &= string_set(&Globals.realm, realm);
-       ret &= string_set(&Globals.dnsdomain, dnsdomain);
-       TALLOC_FREE(frame);
-
-       return ret;
-}
-
-static bool handle_netbios_aliases(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       TALLOC_FREE(Globals.netbios_aliases);
-       Globals.netbios_aliases = (const char **)str_list_make_v3(NULL, pszParmValue, NULL);
-       return set_netbios_aliases(Globals.netbios_aliases);
-}
-
 /***************************************************************************
  Handle the include operation.
 ***************************************************************************/
 static bool bAllowIncludeRegistry = true;
 
-static bool handle_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
+bool lp_include(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
 {
        char *fname;
 
@@ -2827,9 +2439,13 @@ static bool handle_include(struct loadparm_context *unused, int snum, const char
                                 current_user_info.domain,
                                 pszParmValue);
 
-       add_to_file_list(pszParmValue, fname);
+       add_to_file_list(NULL, &file_lists, pszParmValue, fname);
 
-       string_set(ptr, fname);
+       if (snum < 0) {
+               string_set(Globals.ctx, ptr, fname);
+       } else {
+               string_set(ServicePtrs[snum], ptr, fname);
+       }
 
        if (file_exist(fname)) {
                bool ret;
@@ -2845,74 +2461,6 @@ static bool handle_include(struct loadparm_context *unused, int snum, const char
        return true;
 }
 
-/***************************************************************************
- Handle the interpretation of the copy parameter.
-***************************************************************************/
-
-static bool handle_copy(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       bool bRetval;
-       int iTemp;
-       struct loadparm_service serviceTemp;
-
-       string_set(ptr, pszParmValue);
-
-       init_service(&serviceTemp);
-
-       bRetval = false;
-
-       DEBUG(3, ("Copying service from service %s\n", pszParmValue));
-
-       if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
-               if (iTemp == iServiceIndex) {
-                       DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
-               } else {
-                       copy_service(ServicePtrs[iServiceIndex],
-                                    &serviceTemp,
-                                    ServicePtrs[iServiceIndex]->copymap);
-                       bRetval = true;
-               }
-       } else {
-               DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
-               bRetval = false;
-       }
-
-       free_service(&serviceTemp);
-       return (bRetval);
-}
-
-static bool handle_ldap_debug_level(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       Globals.ldap_debug_level = lp_int(pszParmValue);
-       init_ldap_debugging();
-       return true;
-}
-
-/*
- * idmap related parameters
- */
-
-static bool handle_idmap_backend(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
-
-       return true;
-}
-
-static bool handle_idmap_uid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       lp_do_parameter(snum, "idmap config * : range", pszParmValue);
-
-       return true;
-}
-
-static bool handle_idmap_gid(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       lp_do_parameter(snum, "idmap config * : range", pszParmValue);
-
-       return true;
-}
-
 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
 {
        char *config_option = NULL;
@@ -2990,16 +2538,6 @@ const char *lp_idmap_default_backend(void)
        return lp_idmap_backend("*");
 }
 
-/***************************************************************************
- Handle the DEBUG level list.
-***************************************************************************/
-
-static bool handle_debug_list(struct loadparm_context *unused, int snum, const char *pszParmValueIn, char **ptr )
-{
-       string_set(ptr, pszParmValueIn);
-       return debug_parse_levels(pszParmValueIn);
-}
-
 /***************************************************************************
  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
 ***************************************************************************/
@@ -3050,69 +2588,6 @@ const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
        return lp_string(ctx, Globals.ldap_suffix);
 }
 
-/****************************************************************************
- set the value for a P_ENUM
- ***************************************************************************/
-
-static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
-                              int *ptr )
-{
-       int i;
-
-       for (i = 0; parm->enum_list[i].name; i++) {
-               if ( strequal(pszParmValue, parm->enum_list[i].name)) {
-                       *ptr = parm->enum_list[i].value;
-                       return;
-               }
-       }
-       DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
-                 pszParmValue, parm->label));
-}
-
-/***************************************************************************
-***************************************************************************/
-
-static bool handle_printing(struct loadparm_context *unused, int snum, const char *pszParmValue, char **ptr)
-{
-       static int parm_num = -1;
-       struct loadparm_service *s;
-
-       if ( parm_num == -1 )
-               parm_num = lpcfg_map_parameter( "printing" );
-
-       lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
-
-       if ( snum < 0 )
-               s = &sDefault;
-       else
-               s = ServicePtrs[snum];
-
-       init_printer_values( s );
-
-       return true;
-}
-
-
-/***************************************************************************
- Initialise a copymap.
-***************************************************************************/
-
-static void init_copymap(struct loadparm_service *pservice)
-{
-       int i;
-
-       TALLOC_FREE(pservice->copymap);
-
-       pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
-       if (!pservice->copymap)
-               DEBUG(0,
-                     ("Couldn't allocate copymap!! (size %d)\n",
-                      (int)NUMPARAMETERS));
-       else
-               for (i = 0; i < NUMPARAMETERS; i++)
-                       bitmap_set(pservice->copymap, i);
-}
-
 /**
   return the parameter pointer for a parameter
 */
@@ -3148,6 +2623,7 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
        int parmnum, i;
        void *parm_ptr = NULL;  /* where we are going to store the result */
        struct parmlist_entry **opt_list;
+       TALLOC_CTX *mem_ctx;
 
        parmnum = lpcfg_map_parameter(pszParmName);
 
@@ -3162,9 +2638,13 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                 * We've got a parametric option
                 */
 
-               opt_list = (snum < 0)
-                       ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
-               set_param_opt(opt_list, pszParmName, pszParmValue, 0);
+               if (snum < 0) {
+                       opt_list = &Globals.param_opt;
+                       set_param_opt(NULL, opt_list, pszParmName, pszParmValue, 0);
+               } else {
+                       opt_list = &ServicePtrs[snum]->param_opt;
+                       set_param_opt(ServicePtrs[snum], opt_list, pszParmName, pszParmValue, 0);
+               }
 
                return true;
        }
@@ -3205,12 +2685,23 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                                bitmap_clear(ServicePtrs[snum]->copymap, i);
                        }
                }
+               mem_ctx = ServicePtrs[snum];
+       } else {
+               mem_ctx = Globals.ctx;
        }
 
        /* if it is a special case then go ahead */
        if (parm_table[parmnum].special) {
-               return parm_table[parmnum].special(NULL, snum, pszParmValue,
-                                                  (char **)parm_ptr);
+               bool ok;
+               struct loadparm_context *lp_ctx = loadparm_init_s3(talloc_tos(),
+                                                                  loadparm_s3_helpers());
+               lp_ctx->sDefault = &sDefault;
+               lp_ctx->services = ServicePtrs;
+               ok = parm_table[parmnum].special(lp_ctx, snum, pszParmValue,
+                                                 (char **)parm_ptr);
+               TALLOC_FREE(lp_ctx);
+
+               return ok;
        }
 
        /* now switch on the type of variable it is */
@@ -3262,19 +2753,21 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                        break;
 
                case P_STRING:
-                       string_set((char **)parm_ptr, pszParmValue);
+                       string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
                        break;
 
                case P_USTRING:
                {
                        char *upper_string = strupper_talloc(talloc_tos(), 
                                                             pszParmValue);
-                       string_set((char **)parm_ptr, upper_string);
+                       string_set(mem_ctx, (char **)parm_ptr, upper_string);
                        TALLOC_FREE(upper_string);
                        break;
                }
                case P_ENUM:
-                       lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
+                       if (!lp_set_enum_parm(&parm_table[parmnum], pszParmValue, (int*)parm_ptr)) {
+                               return false;
+                       }
                        break;
                case P_SEP:
                        break;
@@ -3321,7 +2814,7 @@ static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmVa
 
        /* it might be parametric */
        if (strchr(pszParmName, ':') != NULL) {
-               set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
+               set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
                if (store_values) {
                        store_lp_set_cmdline(pszParmName, pszParmValue);
                }
@@ -3353,37 +2846,6 @@ static bool do_parameter(const char *pszParmName, const char *pszParmValue,
                                pszParmName, pszParmValue));
 }
 
-/*
-  set a option from the commandline in 'a=b' format. Use to support --option
-*/
-bool lp_set_option(const char *option)
-{
-       char *p, *s;
-       bool ret;
-
-       s = talloc_strdup(NULL, option);
-       if (!s) {
-               return false;
-       }
-
-       p = strchr(s, '=');
-       if (!p) {
-               talloc_free(s);
-               return false;
-       }
-
-       *p = 0;
-
-       /* skip white spaces after the = sign */
-       do {
-               p++;
-       } while (*p == ' ');
-
-       ret = lp_set_cmdline(s, p);
-       talloc_free(s);
-       return ret;
-}
-
 /***************************************************************************
  Initialize any local variables in the sDefault table, after parsing a
  [globals] section.
@@ -3485,7 +2947,7 @@ static bool is_default(int i)
        switch (parm_table[i].type) {
                case P_LIST:
                case P_CMDLIST:
-                       return str_list_equal((const char **)parm_table[i].def.lvalue, 
+                       return str_list_equal((const char * const *)parm_table[i].def.lvalue,
                                              *(const char ***)lp_parm_ptr(NULL, 
                                                                           &parm_table[i]));
                case P_STRING:
@@ -3700,9 +3162,11 @@ static void lp_add_auto_services(char *str)
        if (!str)
                return;
 
-       s = SMB_STRDUP(str);
-       if (!s)
+       s = talloc_strdup(talloc_tos(), str);
+       if (!s) {
+               smb_panic("talloc_strdup failed");
                return;
+       }
 
        homes = lp_servicenumber(HOMES_NAME);
 
@@ -3720,7 +3184,7 @@ static void lp_add_auto_services(char *str)
 
                TALLOC_FREE(home);
        }
-       SAFE_FREE(s);
+       TALLOC_FREE(s);
 }
 
 /***************************************************************************
@@ -3736,7 +3200,7 @@ void lp_add_one_printer(const char *name, const char *comment,
        if (lp_servicenumber(name) < 0) {
                lp_add_printer(name, printers);
                if ((i = lp_servicenumber(name)) >= 0) {
-                       string_set(&ServicePtrs[i]->comment, comment);
+                       string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
                        ServicePtrs[i]->autoloaded = true;
                }
        }
@@ -3815,7 +3279,10 @@ static void lp_save_defaults(void)
                                break;
                        case P_STRING:
                        case P_USTRING:
-                               parm_table[i].def.svalue = SMB_STRDUP(*(char **)lp_parm_ptr(NULL, &parm_table[i]));
+                               parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
+                               if (parm_table[i].def.svalue == NULL) {
+                                       smb_panic("talloc_strdup failed");
+                               }
                                break;
                        case P_BOOL:
                        case P_BOOLREV:
@@ -4279,8 +3746,8 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
 
        /* And note when it was loaded. */
        ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
-       string_set(&ServicePtrs[iService]->path, sharepath);
-       string_set(&ServicePtrs[iService]->comment, comment);
+       string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
+       string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
 
        ret = iService;
 
@@ -4305,23 +3772,25 @@ static bool usershare_exists(int iService, struct timespec *last_mod)
        const char *usersharepath = Globals.usershare_path;
        char *fname;
 
-       if (asprintf(&fname, "%s/%s",
+       fname = talloc_asprintf(talloc_tos(),
+                               "%s/%s",
                                usersharepath,
-                               ServicePtrs[iService]->szService) < 0) {
+                               ServicePtrs[iService]->szService);
+       if (fname == NULL) {
                return false;
        }
 
        if (sys_lstat(fname, &lsbuf, false) != 0) {
-               SAFE_FREE(fname);
+               TALLOC_FREE(fname);
                return false;
        }
 
        if (!S_ISREG(lsbuf.st_ex_mode)) {
-               SAFE_FREE(fname);
+               TALLOC_FREE(fname);
                return false;
        }
 
-       SAFE_FREE(fname);
+       TALLOC_FREE(fname);
        *last_mod = lsbuf.st_ex_mtime;
        return true;
 }
@@ -4370,13 +3839,13 @@ int load_usershare_service(const char *servicename)
        }
 
        /* Ensure the template share exists if it's set. */
-       if (Globals.szUsershareTemplateShare[0]) {
+       if (Globals.usershare_template_share[0]) {
                /* We can't use lp_servicenumber here as we are recommending that
                   template shares have -valid=false set. */
                for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
                        if (ServicePtrs[snum_template]->szService &&
                                        strequal(ServicePtrs[snum_template]->szService,
-                                               Globals.szUsershareTemplateShare)) {
+                                               Globals.usershare_template_share)) {
                                break;
                        }
                }
@@ -4384,7 +3853,7 @@ int load_usershare_service(const char *servicename)
                if (snum_template == -1) {
                        DEBUG(0,("load_usershare_service: usershare template share %s "
                                "does not exist.\n",
-                               Globals.szUsershareTemplateShare ));
+                               Globals.usershare_template_share ));
                        return -1;
                }
        }
@@ -4443,13 +3912,13 @@ int load_usershare_shares(struct smbd_server_connection *sconn,
        }
 
        /* Ensure the template share exists if it's set. */
-       if (Globals.szUsershareTemplateShare[0]) {
+       if (Globals.usershare_template_share[0]) {
                /* We can't use lp_servicenumber here as we are recommending that
                   template shares have -valid=false set. */
                for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
                        if (ServicePtrs[snum_template]->szService &&
                                        strequal(ServicePtrs[snum_template]->szService,
-                                               Globals.szUsershareTemplateShare)) {
+                                               Globals.usershare_template_share)) {
                                break;
                        }
                }
@@ -4457,7 +3926,7 @@ int load_usershare_shares(struct smbd_server_connection *sconn,
                if (snum_template == -1) {
                        DEBUG(0,("load_usershare_shares: usershare template share %s "
                                "does not exist.\n",
-                               Globals.szUsershareTemplateShare ));
+                               Globals.usershare_template_share ));
                        return ret;
                }
        }
@@ -4578,7 +4047,7 @@ void gfree_loadparm(void)
                }
        }
 
-       SAFE_FREE( ServicePtrs );
+       TALLOC_FREE( ServicePtrs );
        iNumServices = 0;
 
        /* Now release all resources allocated to global
@@ -4656,7 +4125,7 @@ static bool lp_load_ex(const char *pszFname,
                        smb_panic("lp_load_ex: out of memory");
                }
 
-               add_to_file_list(pszFname, n2);
+               add_to_file_list(NULL, &file_lists, pszFname, n2);
 
                bRetval = pm_process(n2, do_section, do_parameter, NULL);
                TALLOC_FREE(n2);
@@ -5067,22 +4536,6 @@ void lp_remove_service(int snum)
        ServicePtrs[snum]->valid = false;
 }
 
-/*******************************************************************
- Copy a service.
-********************************************************************/
-
-void lp_copy_service(int snum, const char *new_name)
-{
-       do_section(new_name, NULL);
-       if (snum >= 0) {
-               snum = lp_servicenumber(new_name);
-               if (snum >= 0) {
-                       char *name = lp_servicename(talloc_tos(), snum);
-                       lp_do_parameter(snum, "copy", name);
-               }
-       }
-}
-
 const char *lp_printername(TALLOC_CTX *ctx, int snum)
 {
        const char *ret = lp__printername(ctx, snum);
@@ -5100,7 +4553,7 @@ const char *lp_printername(TALLOC_CTX *ctx, int snum)
 
 void lp_set_logfile(const char *name)
 {
-       string_set(&Globals.logfile, name);
+       string_set(Globals.ctx, &Globals.logfile, name);
        debug_set_logfile(name);
 }
 
@@ -5200,7 +4653,7 @@ void set_store_dos_attributes(int snum, bool val)
 
 void lp_set_mangling_method(const char *new_method)
 {
-       string_set(&Globals.mangling_method, new_method);
+       string_set(Globals.ctx, &Globals.mangling_method, new_method);
 }
 
 /*******************************************************************
@@ -5254,7 +4707,7 @@ int lp_min_receive_file_size(void)
        if (Globals.iminreceivefile < 0) {
                return 0;
        }
-       return MIN(Globals.iminreceivefile, BUFFER_SIZE);
+       return Globals.iminreceivefile;
 }
 
 /*******************************************************************
@@ -5299,22 +4752,6 @@ bool lp_widelinks(int snum)
        return lp_widelinks_internal(snum);
 }
 
-bool lp_writeraw(void)
-{
-       if (lp_async_smb_echo_handler()) {
-               return false;
-       }
-       return lp__writeraw();
-}
-
-bool lp_readraw(void)
-{
-       if (lp_async_smb_echo_handler()) {
-               return false;
-       }
-       return lp__readraw();
-}
-
 int lp_server_role(void)
 {
        return lp_find_server_role(lp__server_role(),
@@ -5328,3 +4765,8 @@ int lp_security(void)
        return lp_find_security(lp__server_role(),
                                lp__security());
 }
+
+struct loadparm_global * get_globals(void)
+{
+       return &Globals;
+}