Extend a comment.
[samba.git] / source3 / param / loadparm.c
index 163f4179a6345a92fe53a2674d14f8d78b86764f..358fabfb2a416e21e8571445ea9eefc0958d0c4a 100644 (file)
@@ -55,7 +55,6 @@
 bool in_client = False;                /* Not in the client by default */
 bool bLoaded = False;
 
-extern pstring user_socket_options;
 extern enum protocol_types Protocol;
 extern userdom_struct current_user_info;
 
@@ -89,8 +88,6 @@ static bool include_registry_globals = False;
 #define USERSHARE_VALID 1
 #define USERSHARE_PENDING_DELETE 2
 
-bool use_getwd_cache = True;
-
 extern int extra_time_offset;
 
 static bool defaults_saved = False;
@@ -216,6 +213,7 @@ typedef struct {
        int pwordlevel;
        int unamelevel;
        int deadtime;
+       bool getwd_cache;
        int maxprotocol;
        int minprotocol;
        int security;
@@ -474,6 +472,7 @@ typedef struct {
        int iAioWriteSize;
        int iMap_readonly;
        int iDirectoryNameCacheSize;
+       int ismb_encrypt;
        param_opt_struct *param_opt;
 
        char dummy[3];          /* for alignment */
@@ -619,6 +618,7 @@ static service sDefault = {
 #else
        100,                    /* iDirectoryNameCacheSize */
 #endif
+       Auto,                   /* ismb_encrypt */
        NULL,                   /* Parametric options */
 
        ""                      /* dummy */
@@ -628,7 +628,7 @@ static service sDefault = {
 static service **ServicePtrs = NULL;
 static int iNumServices = 0;
 static int iServiceIndex = 0;
-static TDB_CONTEXT *ServiceHash;
+static struct db_context *ServiceHash;
 static int *invalid_services = NULL;
 static int num_invalid_services = 0;
 static bool bInGlobalSection = True;
@@ -1029,6 +1029,7 @@ static struct parm_struct parm_table[] = {
        {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED}, 
        {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, 
        {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, 
+       {"smb encrypt", P_ENUM, P_LOCAL, &sDefault.ismb_encrypt, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
        {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED}, 
        {"client ldap sasl wrapping", P_ENUM, P_GLOBAL, &Globals.client_ldap_sasl_wrapping, NULL, enum_ldap_sasl_wrapping, FLAG_ADVANCED},
        {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED}, 
@@ -1038,7 +1039,7 @@ static struct parm_struct parm_table[] = {
 
        {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
        {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED}, 
-       {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED}, 
+       {"getwd cache", P_BOOL, P_GLOBAL, &Globals.getwd_cache, NULL, NULL, FLAG_ADVANCED},
        {"keepalive", P_INTEGER, P_GLOBAL, &Globals.iKeepalive, NULL, NULL, FLAG_ADVANCED},
        {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
        {"directory name cache size", P_INTEGER, P_LOCAL, &sDefault.iDirectoryNameCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
@@ -1052,7 +1053,7 @@ static struct parm_struct parm_table[] = {
        {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED}, 
        {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
 
-       {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED}, 
+       {"socket options", P_STRING, P_GLOBAL, &Globals.szSocketOptions, NULL, NULL, FLAG_ADVANCED},
        {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
        {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
        {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
@@ -1421,7 +1422,7 @@ static void init_printer_values(service *pService)
 static void init_globals(bool first_time_only)
 {
        static bool done_init = False;
-       pstring s;
+       char *s = NULL;
 
         /* If requested to initialize only once and we've already done it... */
         if (first_time_only && done_init) {
@@ -1457,8 +1458,8 @@ static void init_globals(bool first_time_only)
 
        DEBUG(3, ("Initialising global parameters\n"));
 
-       string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
-       string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
+       string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
+       string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
 
        /* use the new 'hash2' method by default, with a prefix of 1 */
        string_set(&Globals.szManglingMethod, "hash2");
@@ -1484,28 +1485,34 @@ static void init_globals(bool first_time_only)
         * Allow the default PASSWD_CHAT to be overridden in local.h.
         */
        string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
-       
+
        set_global_myname(myhostname());
        string_set(&Globals.szNetbiosName,global_myname());
 
        set_global_myworkgroup(WORKGROUP);
        string_set(&Globals.szWorkgroup, lp_workgroup());
-       
+
        string_set(&Globals.szPasswdProgram, "");
-       string_set(&Globals.szPidDir, dyn_PIDDIR);
-       string_set(&Globals.szLockDir, dyn_LOCKDIR);
+       string_set(&Globals.szPidDir, get_dyn_PIDDIR());
+       string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
        string_set(&Globals.szSocketAddress, "0.0.0.0");
-       pstrcpy(s, "Samba ");
-       pstrcat(s, SAMBA_VERSION_STRING);
+
+       if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
+               smb_panic("init_globals: ENOMEM");
+       }
        string_set(&Globals.szServerString, s);
-       slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
-                DEFAULT_MINOR_VERSION);
+       SAFE_FREE(s);
+       if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
+                       DEFAULT_MINOR_VERSION) < 0) {
+               smb_panic("init_globals: ENOMEM");
+       }
        string_set(&Globals.szAnnounceVersion, s);
+       SAFE_FREE(s);
 #ifdef DEVELOPER
        string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
 #endif
 
-       pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
+       string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
 
        string_set(&Globals.szLogonDrive, "");
        /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
@@ -1530,6 +1537,7 @@ static void init_globals(bool first_time_only)
        Globals.pwordlevel = 0;
        Globals.unamelevel = 0;
        Globals.deadtime = 0;
+       Globals.getwd_cache = true;
        Globals.bLargeReadwrite = True;
        Globals.max_log_size = 5000;
        Globals.max_open_files = MAX_OPEN_FILES;
@@ -1694,11 +1702,13 @@ static void init_globals(bool first_time_only)
        Globals.bEnablePrivileges = True;
        Globals.bHostMSDfs        = True;
        Globals.bASUSupport       = False;
-       
+
        /* User defined shares. */
-       pstrcpy(s, dyn_LOCKDIR);
-       pstrcat(s, "/usershares");
+       if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
+               smb_panic("init_globals: ENOMEM");
+       }
        string_set(&Globals.szUsersharePath, s);
+       SAFE_FREE(s);
        string_set(&Globals.szUsershareTemplateShare, "");
        Globals.iUsershareMaxShares = 0;
        /* By default disallow sharing of directories not owned by the sharer. */
@@ -1722,7 +1732,8 @@ static void init_globals(bool first_time_only)
 
 static char *lp_string(const char *s)
 {
-       char *ret, *tmpstr;
+       char *ret;
+       TALLOC_CTX *ctx = talloc_tos();
 
        /* The follow debug is useful for tracking down memory problems
           especially if you have an inner loop that is calling a lp_*()
@@ -1733,19 +1744,20 @@ static char *lp_string(const char *s)
        DEBUG(10, ("lp_string(%s)\n", s));
 #endif
 
-       tmpstr = alloc_sub_basic(get_current_username(),
-                                current_user_info.domain, s);
-       if (trim_char(tmpstr, '\"', '\"')) {
-               if (strchr(tmpstr,'\"') != NULL) {
-                       SAFE_FREE(tmpstr);
-                       tmpstr = alloc_sub_basic(get_current_username(),
-                                                current_user_info.domain, s);
+       ret = talloc_sub_basic(ctx,
+                       get_current_username(),
+                       current_user_info.domain,
+                       s);
+       if (trim_char(ret, '\"', '\"')) {
+               if (strchr(ret,'\"') != NULL) {
+                       TALLOC_FREE(ret);
+                       ret = talloc_sub_basic(ctx,
+                                       get_current_username(),
+                                       current_user_info.domain,
+                                       s);
                }
        }
-       ret = talloc_strdup(talloc_tos(), tmpstr);
-       SAFE_FREE(tmpstr);
-                       
-       return (ret);
+       return ret;
 }
 
 /*
@@ -2014,6 +2026,7 @@ FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
+FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
@@ -2032,6 +2045,7 @@ FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
+FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
 
 FN_LOCAL_STRING(lp_preexec, szPreExec)
 FN_LOCAL_STRING(lp_postexec, szPostExec)
@@ -2162,6 +2176,7 @@ FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
+FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
 FN_LOCAL_CHAR(lp_magicchar, magic_char)
 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
@@ -2169,7 +2184,6 @@ FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
-FN_GLOBAL_INTEGER(lp_min_receive_file_size, &Globals.iminreceivefile);
 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
 
 /* local prototypes */
@@ -2505,9 +2519,11 @@ static void free_service_byindex(int idx)
        /* we have to cleanup the hash record */
 
        if (ServicePtrs[idx]->szService) {
-               char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
+               char *canon_name = canonicalize_servicename(
+                       ServicePtrs[idx]->szService );
                
-               tdb_delete_bystring(ServiceHash, canon_name );
+               dbwrap_delete_bystring(ServiceHash, canon_name );
+               TALLOC_FREE(canon_name);
        }
 
        free_service(ServicePtrs[idx]);
@@ -2607,17 +2623,18 @@ static int add_a_service(const service *pservice, const char *name)
 
 static char *canonicalize_servicename(const char *src)
 {
-       static fstring canon; /* is fstring large enough? */
+       char *result;
 
        if ( !src ) {
                DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
                return NULL;
        }
 
-       fstrcpy( canon, src );
-       strlower_m( canon );
+       result = talloc_strdup(talloc_tos(), src);
+       SMB_ASSERT(result != NULL);
 
-       return canon;
+       strlower_m(result);
+       return result;
 }
 
 /***************************************************************************
@@ -2629,9 +2646,8 @@ static bool hash_a_service(const char *name, int idx)
        char *canon_name;
 
        if ( !ServiceHash ) {
-               DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
-               ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL, 
-                                        (O_RDWR|O_CREAT), 0600);
+               DEBUG(10,("hash_a_service: creating servicehash\n"));
+               ServiceHash = db_open_rbt(NULL);
                if ( !ServiceHash ) {
                        DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
                        return False;
@@ -2641,24 +2657,26 @@ static bool hash_a_service(const char *name, int idx)
        DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
                idx, name));
 
-       if ( !(canon_name = canonicalize_servicename( name )) )
-               return False;
+       canon_name = canonicalize_servicename( name );
 
-        tdb_store_int32(ServiceHash, canon_name, idx);
+       dbwrap_store_bystring(ServiceHash, canon_name,
+                             make_tdb_data((uint8 *)&idx, sizeof(idx)),
+                             TDB_REPLACE);
+
+       TALLOC_FREE(canon_name);
 
        return True;
 }
 
 /***************************************************************************
- Add a new home service, with the specified home directory, defaults coming 
+ Add a new home service, with the specified home directory, defaults coming
  from service ifrom.
 ***************************************************************************/
 
-bool lp_add_home(const char *pszHomename, int iDefaultService, 
+bool lp_add_home(const char *pszHomename, int iDefaultService,
                 const char *user, const char *pszHomedir)
 {
        int i;
-       pstring newHomedir;
 
        i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
 
@@ -2667,15 +2685,16 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
 
        if (!(*(ServicePtrs[iDefaultService]->szPath))
            || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
-               pstrcpy(newHomedir, pszHomedir);
-               string_set(&ServicePtrs[i]->szPath, newHomedir);
-       } 
+               string_set(&ServicePtrs[i]->szPath, pszHomedir);
+       }
 
        if (!(*(ServicePtrs[i]->comment))) {
-               pstring comment;
-               slprintf(comment, sizeof(comment) - 1,
-                        "Home directory of %s", user);
+               char *comment = NULL;
+               if (asprintf(&comment, "Home directory of %s", user) < 0) {
+                       return false;
+               }
                string_set(&ServicePtrs[i]->comment, comment);
+               SAFE_FREE(comment);
        }
 
        /* set the browseable flag from the global default */
@@ -2686,7 +2705,7 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
 
        DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
               user, ServicePtrs[i]->szPath ));
-       
+
        return (True);
 }
 
@@ -2709,14 +2728,16 @@ int lp_add_service(const char *pszService, int iDefaultService)
 
 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
 {
-       pstring comment;
+       char *comment = NULL;
        int i = add_a_service(&sDefault, ipc_name);
 
        if (i < 0)
                return (False);
 
-       slprintf(comment, sizeof(comment) - 1,
-                "IPC Service (%s)", Globals.szServerString);
+       if (asprintf(&comment, "IPC Service (%s)",
+                               Globals.szServerString) < 0) {
+               return (False);
+       }
 
        string_set(&ServicePtrs[i]->szPath, tmpdir());
        string_set(&ServicePtrs[i]->szUsername, "");
@@ -2732,6 +2753,7 @@ static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
 
        DEBUG(3, ("adding IPC service\n"));
 
+       SAFE_FREE(comment);
        return (True);
 }
 
@@ -2988,8 +3010,8 @@ static void show_parameter(int parmIndex)
        bool hadSyn;
        bool inverse;
        const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
-               "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
-               "P_UGSTRING", "P_ENUM", "P_SEP"};
+               "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
+               "P_ENUM", "P_SEP"};
        unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
                FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
                FLAG_HIDE, FLAG_DOS_STRING};
@@ -3165,20 +3187,25 @@ static int getservicebyname(const char *pszServiceName, service * pserviceDest)
 {
        int iService = -1;
        char *canon_name;
+       TDB_DATA data;
 
-       if (ServiceHash != NULL) {
-               if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
-                       return -1;
+       if (ServiceHash == NULL) {
+               return -1;
+       }
 
-               iService = tdb_fetch_int32(ServiceHash, canon_name );
+       canon_name = canonicalize_servicename(pszServiceName);
 
-               if (LP_SNUM_OK(iService)) {
-                       if (pserviceDest != NULL) {
-                               copy_service(pserviceDest, ServicePtrs[iService], NULL);
-                       }
-               } else {
-                       iService = -1;
-               }
+       data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
+
+       if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
+               iService = *(int *)data.dptr;
+       }
+
+       TALLOC_FREE(canon_name);
+
+       if ((iService != -1) && (LP_SNUM_OK(iService))
+           && (pserviceDest != NULL)) {
+               copy_service(pserviceDest, ServicePtrs[iService], NULL);
        }
 
        return (iService);
@@ -3341,12 +3368,12 @@ static struct tdb_wrap *lp_regdb_open(void)
        uint32 vers_id;
 
        become_root();
-       reg_tdb = tdb_wrap_open(NULL, lock_path("registry.tdb"), 0, 
+       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",
-                        lock_path("registry.tdb"), strerror(errno)));
+                        state_path("registry.tdb"), strerror(errno)));
                goto done;
        }
        else {
@@ -3357,7 +3384,7 @@ static struct tdb_wrap *lp_regdb_open(void)
        if (vers_id != REGVER_V1) {
                DEBUG(10, ("lp_regdb_open: INFO: registry tdb %s has wrong "
                          "INFO/version (got %d, expected %d)\n",
-                         lock_path("registry.tdb"), vers_id, REGVER_V1));
+                         state_path("registry.tdb"), vers_id, REGVER_V1));
                /* this is apparently not implemented in the tdb */
        }
 
@@ -3392,7 +3419,6 @@ static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
        uint32 size;
        uint32 num_values = 0;
        uint8 *data_p;
-       pstring valname;
        char * valstr;
        struct registry_value *value = NULL;
 
@@ -3409,7 +3435,7 @@ static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
        /* 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, 
+       keystr = talloc_asprintf(reg_tdb,"%s/%s/%s", REG_VALUE_PREFIX,
                                 KEY_SMBCONF, GLOBAL_NAME);
        normalize_dbkey(keystr);
 
@@ -3432,6 +3458,7 @@ static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
 
        /* unpack the values */
        for (i=0; i < num_values; i++) {
+               fstring valname;
                type = REG_NONE;
                size = 0;
                data_p = NULL;
@@ -3448,9 +3475,9 @@ static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
                DEBUG(10, ("process_registry_globals: got value '%s'\n",
                           valname));
                if (size && data_p) {
-                       err = registry_pull_value(reg_tdb, 
+                       err = registry_pull_value(reg_tdb,
                                                  &value,
-                                                 type,
+                                                 (enum winreg_Type)type,
                                                  data_p,
                                                  size,
                                                  size);
@@ -3460,7 +3487,7 @@ static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
                        }
                        switch(type) {
                        case REG_DWORD:
-                               valstr = talloc_asprintf(reg_tdb, "%d", 
+                               valstr = talloc_asprintf(reg_tdb, "%d",
                                                         value->v.dword);
                                pfunc(valname, valstr);
                                break;
@@ -3487,7 +3514,9 @@ done:
 /*
  * 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 *))
 {
@@ -3607,6 +3636,11 @@ static void add_to_file_list(const char *fname, const char *subfname)
        }
 }
 
+bool lp_include_registry_globals(void)
+{
+       return include_registry_globals;
+}
+
 /*******************************************************************
  Check if a config file has changed date.
 ********************************************************************/
@@ -3625,19 +3659,20 @@ bool lp_file_list_changed(void)
                        DEBUGADD(6, ("regdb seqnum changed: old = %d, new = %d\n",
                                    regdb_last_seqnum, tdb_get_seqnum(reg_tdb->tdb)));
                        TALLOC_FREE(reg_tdb);
-                       return True;
+                       return true;
                }
        }
 
        while (f) {
-               pstring n2;
+               char *n2 = NULL;
                time_t mod_time;
 
-               pstrcpy(n2, f->name);
-               standard_sub_basic( get_current_username(),
+               n2 = alloc_sub_basic(get_current_username(),
                                    current_user_info.domain,
-                                   n2, sizeof(n2) );
-
+                                   f->name);
+               if (!n2) {
+                       return false;
+               }
                DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
                             f->name, n2, ctime(&f->modtime)));
 
@@ -3649,9 +3684,12 @@ bool lp_file_list_changed(void)
                                  ctime(&mod_time)));
                        f->modtime = mod_time;
                        SAFE_FREE(f->subfname);
-                       f->subfname = SMB_STRDUP(n2);
-                       return (True);
+                       f->subfname = n2; /* Passing ownership of
+                                            return from alloc_sub_basic
+                                            above. */
+                       return true;
                }
+               SAFE_FREE(n2);
                f = f->next;
        }
        return (False);
@@ -3666,16 +3704,14 @@ bool lp_file_list_changed(void)
 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
 {
        bool ret;
-       pstring netbios_name;
-
-       pstrcpy(netbios_name, pszParmValue);
-
-       standard_sub_basic(get_current_username(), current_user_info.domain,
-                          netbios_name, sizeof(netbios_name));
+       char *netbios_name = alloc_sub_basic(get_current_username(),
+                                       current_user_info.domain,
+                                       pszParmValue);
 
        ret = set_global_myname(netbios_name);
+       SAFE_FREE(netbios_name);
        string_set(&Globals.szNetbiosName,global_myname());
-       
+
        DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
               global_myname()));
 
@@ -3726,33 +3762,36 @@ static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **pt
 
 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
 {
-       pstring fname;
-       pstrcpy(fname, pszParmValue);
+       char *fname;
 
-       if (strequal(fname, INCLUDE_REGISTRY_NAME)) {
+       if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
                if (bInGlobalSection) {
                        return process_registry_globals(do_parameter);
                }
                else {
                        DEBUG(1, ("\"include = registry\" only effective "
                                  "in %s section\n", GLOBAL_NAME));
-                       return False;
+                       return false;
                }
        }
 
-       standard_sub_basic(get_current_username(), current_user_info.domain,
-                          fname,sizeof(fname));
+       fname = alloc_sub_basic(get_current_username(),
+                               current_user_info.domain,
+                               pszParmValue);
 
        add_to_file_list(pszParmValue, fname);
 
        string_set(ptr, fname);
 
-       if (file_exist(fname, NULL))
-               return (pm_process(fname, do_section, do_parameter));
+       if (file_exist(fname, NULL)) {
+               bool ret = pm_process(fname, do_section, do_parameter);
+               SAFE_FREE(fname);
+               return ret;
+       }
 
        DEBUG(2, ("Can't find include file %s\n", fname));
-
-       return (False);
+       SAFE_FREE(fname);
+       return false;
 }
 
 /***************************************************************************
@@ -3880,11 +3919,8 @@ static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
 
 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
 {
-       pstring pszParmValue;
-
-       pstrcpy(pszParmValue, pszParmValueIn);
        string_set(ptr, pszParmValueIn);
-       return debug_parse_levels( pszParmValue );
+       return debug_parse_levels(pszParmValueIn);
 }
 
 /***************************************************************************
@@ -4019,7 +4055,7 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
        int parmnum, i, slen;
        void *parm_ptr = NULL;  /* where we are going to store the result */
        void *def_ptr = NULL;
-       pstring param_key;
+       char *param_key = NULL;
        char *sep;
        param_opt_struct *paramo, *data;
        bool not_added;
@@ -4028,14 +4064,23 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
 
        if (parmnum < 0) {
                if ((sep=strchr(pszParmName, ':')) != NULL) {
+                       TALLOC_CTX *frame = talloc_stackframe();
+
                        *sep = '\0';
-                       ZERO_STRUCT(param_key);
-                       pstr_sprintf(param_key, "%s:", pszParmName);
+                       param_key = talloc_asprintf(frame, "%s:", pszParmName);
+                       if (!param_key) {
+                               TALLOC_FREE(frame);
+                               return false;
+                       }
                        slen = strlen(param_key);
-                       pstrcat(param_key, sep+1);
+                       param_key = talloc_asprintf_append(param_key, sep+1);
+                       if (!param_key) {
+                               TALLOC_FREE(frame);
+                               return false;
+                       }
                        trim_char(param_key+slen, ' ', ' ');
                        not_added = True;
-                       data = (snum < 0) ? Globals.param_opt : 
+                       data = (snum < 0) ? Globals.param_opt :
                                ServicePtrs[snum]->param_opt;
                        /* Traverse destination */
                        while (data) {
@@ -4062,6 +4107,7 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                        }
 
                        *sep = ':';
+                       TALLOC_FREE(frame);
                        return (True);
                }
                DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
@@ -4147,15 +4193,6 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                        strupper_m(*(char **)parm_ptr);
                        break;
 
-               case P_GSTRING:
-                       pstrcpy((char *)parm_ptr, pszParmValue);
-                       break;
-
-               case P_UGSTRING:
-                       pstrcpy((char *)parm_ptr, pszParmValue);
-                       strupper_m((char *)parm_ptr);
-                       break;
-
                case P_ENUM:
                        lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
                        break;
@@ -4216,14 +4253,16 @@ static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
                        fprintf(f, "%c", *(char *)ptr);
                        break;
 
-               case P_OCTAL:
-                       fprintf(f, "%s", octal_string(*(int *)ptr));
+               case P_OCTAL: {
+                       char *o = octal_string(*(int *)ptr);
+                       fprintf(f, "%s", o);
+                       TALLOC_FREE(o);
                        break;
+               }
 
                case P_LIST:
                        if ((char ***)ptr && *(char ***)ptr) {
                                char **list = *(char ***)ptr;
-                               
                                for (; *list; list++) {
                                        /* surround strings with whitespace in double quotes */
                                        if ( strchr_m( *list, ' ' ) )
@@ -4234,13 +4273,6 @@ static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
                        }
                        break;
 
-               case P_GSTRING:
-               case P_UGSTRING:
-                       if ((char *)ptr) {
-                               fprintf(f, "%s", (char *)ptr);
-                       }
-                       break;
-
                case P_STRING:
                case P_USTRING:
                        if (*(char **)ptr) {
@@ -4270,20 +4302,10 @@ static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
 
                case P_CHAR:
                        return (*((char *)ptr1) == *((char *)ptr2));
-               
+
                case P_LIST:
                        return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
 
-               case P_GSTRING:
-               case P_UGSTRING:
-               {
-                       char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
-                       if (p1 && !*p1)
-                               p1 = NULL;
-                       if (p2 && !*p2)
-                               p2 = NULL;
-                       return (p1 == p2 || strequal(p1, p2));
-               }
                case P_STRING:
                case P_USTRING:
                {
@@ -4377,10 +4399,6 @@ static bool is_default(int i)
                case P_USTRING:
                        return strequal(parm_table[i].def.svalue,
                                        *(char **)parm_table[i].ptr);
-               case P_GSTRING:
-               case P_UGSTRING:
-                       return strequal(parm_table[i].def.svalue,
-                                       (char *)parm_table[i].ptr);
                case P_BOOL:
                case P_BOOLREV:
                        return parm_table[i].def.bvalue ==
@@ -4690,13 +4708,17 @@ static void lp_add_auto_services(char *str)
        homes = lp_servicenumber(HOMES_NAME);
 
        for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
-               char *home = get_user_home_dir(p);
+               char *home;
 
                if (lp_servicenumber(p) >= 0)
                        continue;
 
+               home = get_user_home_dir(talloc_tos(), p);
+
                if (home && homes >= 0)
                        lp_add_home(p, homes, p, home);
+
+               TALLOC_FREE(home);
        }
        SAFE_FREE(s);
 }
@@ -4787,14 +4809,6 @@ static void lp_save_defaults(void)
                                        parm_table[i].def.svalue = NULL;
                                }
                                break;
-                       case P_GSTRING:
-                       case P_UGSTRING:
-                               if (parm_table[i].ptr) {
-                                       parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
-                               } else {
-                                       parm_table[i].def.svalue = NULL;
-                               }
-                               break;
                        case P_BOOL:
                        case P_BOOLREV:
                                parm_table[i].def.bvalue =
@@ -4956,14 +4970,14 @@ static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
  Parse the contents of a usershare file.
 ***************************************************************************/
 
-enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, 
+enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
                        SMB_STRUCT_STAT *psbuf,
                        const char *servicename,
                        int snum,
                        char **lines,
                        int numlines,
-                       pstring sharepath,
-                       pstring comment,
+                       char **pp_sharepath,
+                       char **pp_comment,
                        SEC_DESC **ppsd,
                        bool *pallow_guest)
 {
@@ -4972,6 +4986,11 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
        int us_vers;
        SMB_STRUCT_DIR *dp;
        SMB_STRUCT_STAT sbuf;
+       char *sharepath = NULL;
+       char *comment = NULL;
+
+       *pp_sharepath = NULL;
+       *pp_comment = NULL;
 
        *pallow_guest = False;
 
@@ -4994,14 +5013,20 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
                return USERSHARE_MALFORMED_PATH;
        }
 
-       pstrcpy(sharepath, &lines[1][5]);
+       sharepath = talloc_strdup(ctx, &lines[1][5]);
+       if (!sharepath) {
+               return USERSHARE_POSIX_ERR;
+       }
        trim_string(sharepath, " ", " ");
 
        if (strncmp(lines[2], "comment=", 8) != 0) {
                return USERSHARE_MALFORMED_COMMENT_DEF;
        }
 
-       pstrcpy(comment, &lines[2][8]);
+       comment = talloc_strdup(ctx, &lines[2][8]);
+       if (!comment) {
+               return USERSHARE_POSIX_ERR;
+       }
        trim_string(comment, " ", " ");
        trim_char(comment, '"', '"');
 
@@ -5024,6 +5049,8 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
 
        if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
                /* Path didn't change, no checks needed. */
+               *pp_sharepath = sharepath;
+               *pp_comment = comment;
                return USERSHARE_OK;
        }
 
@@ -5108,6 +5135,8 @@ enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
                }
        }
 
+       *pp_sharepath = sharepath;
+       *pp_comment = comment;
        return USERSHARE_OK;
 }
 
@@ -5124,9 +5153,9 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
 {
        SMB_STRUCT_STAT sbuf;
        SMB_STRUCT_STAT lsbuf;
-       pstring fname;
-       pstring sharepath;
-       pstring comment;
+       char *fname = NULL;
+       char *sharepath = NULL;
+       char *comment = NULL;
        fstring service_name;
        char **lines = NULL;
        int numlines = 0;
@@ -5146,9 +5175,8 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
 
        fstrcpy(service_name, file_name);
 
-       pstrcpy(fname, dir_name);
-       pstrcat(fname, "/");
-       pstrcat(fname, file_name);
+       if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
+       }
 
        /* Minimize the race condition by doing an lstat before we
           open and fstat. Ensure this isn't a symlink link. */
@@ -5156,24 +5184,36 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        if (sys_lstat(fname, &lsbuf) != 0) {
                DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
                        fname, strerror(errno) ));
+               SAFE_FREE(fname);
                return -1;
        }
 
        /* This must be a regular file, not a symlink, directory or
           other strange filetype. */
        if (!check_usershare_stat(fname, &lsbuf)) {
+               SAFE_FREE(fname);
                return -1;
        }
 
-       /* See if there is already a servicenum for this name. */
-       /* tdb_fetch_int32 returns -1 if not found. */
-       iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
+       {
+               char *canon_name = canonicalize_servicename(service_name);
+               TDB_DATA data = dbwrap_fetch_bystring(
+                       ServiceHash, canon_name, canon_name);
+
+               iService = -1;
+
+               if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
+                       iService = *(int *)data.dptr;
+               }
+               TALLOC_FREE(canon_name);
+       }
 
        if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
                /* Nothing changed - Mark valid and return. */
                DEBUG(10,("process_usershare_file: service %s not changed.\n",
                        service_name ));
                ServicePtrs[iService]->usershare = USERSHARE_VALID;
+               SAFE_FREE(fname);
                return iService;
        }
 
@@ -5187,6 +5227,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        if (fd == -1) {
                DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
                        fname, strerror(errno) ));
+               SAFE_FREE(fname);
                return -1;
        }
 
@@ -5195,6 +5236,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
                close(fd);
                DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
                        fname, strerror(errno) ));
+               SAFE_FREE(fname);
                return -1;
        }
 
@@ -5203,12 +5245,14 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
                close(fd);
                DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
                        "Symlink spoofing going on ?\n", fname ));
+               SAFE_FREE(fname);
                return -1;
        }
 
        /* This must be a regular file, not a symlink, directory or
           other strange filetype. */
        if (!check_usershare_stat(fname, &sbuf)) {
+               SAFE_FREE(fname);
                return -1;
        }
 
@@ -5218,9 +5262,12 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        if (lines == NULL) {
                DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
                        fname, (unsigned int)sbuf.st_uid ));
+               SAFE_FREE(fname);
                return -1;
        }
 
+       SAFE_FREE(fname);
+
        /* Should we allow printers to be shared... ? */
        ctx = talloc_init("usershare_sd_xctx");
        if (!ctx) {
@@ -5229,8 +5276,8 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        }
 
        if (parse_usershare_file(ctx, &sbuf, service_name,
-                       iService, lines, numlines, sharepath,
-                       comment, &psd, &guest_ok) != USERSHARE_OK) {
+                       iService, lines, numlines, &sharepath,
+                       &comment, &psd, &guest_ok) != USERSHARE_OK) {
                talloc_destroy(ctx);
                file_lines_free(lines);
                return -1;
@@ -5266,8 +5313,6 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
                return -1;
        }
 
-       talloc_destroy(ctx);
-
        /* If from a template it may be marked invalid. */
        ServicePtrs[iService]->valid = True;
 
@@ -5284,6 +5329,8 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        string_set(&ServicePtrs[iService]->szPath, sharepath);
        string_set(&ServicePtrs[iService]->comment, comment);
 
+       talloc_destroy(ctx);
+
        return iService;
 }
 
@@ -5295,22 +5342,27 @@ static bool usershare_exists(int iService, time_t *last_mod)
 {
        SMB_STRUCT_STAT lsbuf;
        const char *usersharepath = Globals.szUsersharePath;
-       pstring fname;
+       char *fname;
 
-       pstrcpy(fname, usersharepath);
-       pstrcat(fname, "/");
-       pstrcat(fname, ServicePtrs[iService]->szService);
+       if (asprintf(&fname, "%s/%s",
+                               usersharepath,
+                               ServicePtrs[iService]->szService) < 0) {
+               return false;
+       }
 
        if (sys_lstat(fname, &lsbuf) != 0) {
-               return False;
+               SAFE_FREE(fname);
+               return false;
        }
 
        if (!S_ISREG(lsbuf.st_mode)) {
-               return False;
+               SAFE_FREE(fname);
+               return false;
        }
 
+       SAFE_FREE(fname);
        *last_mod = lsbuf.st_mtime;
-       return True;
+       return true;
 }
 
 /***************************************************************************
@@ -5597,21 +5649,23 @@ bool lp_load(const char *pszFname,
             bool add_ipc,
              bool initialize_globals)
 {
-       pstring n2;
+       char *n2 = NULL;
        bool bRetval;
        param_opt_struct *data, *pdata;
 
-       pstrcpy(n2, pszFname);
-       
-       standard_sub_basic( get_current_username(), current_user_info.domain,
-                           n2,sizeof(n2) );
+       n2 = alloc_sub_basic(get_current_username(),
+                               current_user_info.domain,
+                               pszFname);
+       if (!n2) {
+               smb_panic("lp_load: out of memory");
+       }
 
        add_to_file_list(pszFname, n2);
 
        bRetval = False;
 
        DEBUG(3, ("lp_load: refreshing parameters\n"));
-       
+
        bInGlobalSection = True;
        bGlobalOnly = global_only;
 
@@ -5635,16 +5689,19 @@ bool lp_load(const char *pszFname,
                }
                Globals.param_opt = NULL;
        }
-       
+
        /* We get sections first, so have to start 'behind' to make up */
        iServiceIndex = -1;
        bRetval = pm_process(n2, do_section, do_parameter);
+       SAFE_FREE(n2);
 
        /* finish up the last section */
        DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
-       if (bRetval)
-               if (iServiceIndex >= 0)
+       if (bRetval) {
+               if (iServiceIndex >= 0) {
                        bRetval = service_ok(iServiceIndex);
+               }
+       }
 
        lp_add_auto_services(lp_auto_services());
 
@@ -5652,8 +5709,9 @@ bool lp_load(const char *pszFname,
                /* When 'restrict anonymous = 2' guest connections to ipc$
                   are denied */
                lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
-               if ( lp_enable_asu_support() )
-                       lp_add_ipc("ADMIN$", False);
+               if ( lp_enable_asu_support() ) {
+                       lp_add_ipc("ADMIN$", false);
+               }
        }
 
        set_server_role();
@@ -6094,7 +6152,7 @@ const char *lp_printername(int snum)
 void lp_set_logfile(const char *name)
 {
        string_set(&Globals.szLogFile, name);
-       pstrcpy(debugf, name);
+       debug_set_logfile(name);
 }
 
 /*******************************************************************
@@ -6166,7 +6224,9 @@ bool lp_use_sendfile(int snum)
        if (Protocol < PROTOCOL_NT1) {
                return False;
        }
-       return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
+       return (_lp_use_sendfile(snum) &&
+                       (get_remote_arch() != RA_WIN95) &&
+                       !srv_is_signing_active());
 }
 
 /*******************************************************************
@@ -6242,3 +6302,11 @@ void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
        posix_default_lock_was_set = True;
        posix_cifsx_locktype = val;
 }
+
+int lp_min_receive_file_size(void)
+{
+       if (Globals.iminreceivefile < 0) {
+               return 0;
+       }
+       return MIN(Globals.iminreceivefile, BUFFER_SIZE);
+}