smbdotconf: mark "ldap user suffix" with constant="1"
[bbaumbach/samba-autobuild/.git] / source3 / param / loadparm.c
index 703460e4c474cf8463330bdf301504532f7edf3e..0249c7f2b747ed9b281849ceb94ae5b09e312f3a 100644 (file)
@@ -53,6 +53,7 @@
  *
  */
 
+#define LOADPARM_SUBSTITUTION_INTERNALS 1
 #include "includes.h"
 #include "system/filesys.h"
 #include "util_tdb.h"
@@ -160,7 +161,6 @@ static const struct loadparm_service _sDefault =
        .min_print_space = 0,
        .max_print_jobs = 1000,
        .max_reported_print_jobs = 0,
-       .write_cache_size = 0,
        .create_mask = 0744,
        .force_create_mode = 0,
        .directory_mask = 0755,
@@ -201,7 +201,7 @@ static const struct loadparm_service _sDefault =
        .oplocks = true,
        .kernel_oplocks = false,
        .level2_oplocks = true,
-       .mangled_names = MANGLED_NAMES_YES,
+       .mangled_names = MANGLED_NAMES_ILLEGAL,
        .wide_links = false,
        .follow_symlinks = true,
        .sync_always = false,
@@ -236,7 +236,6 @@ static const struct loadparm_service _sDefault =
        .acl_map_full_control = true,
        .acl_group_control = false,
        .acl_allow_execute_always = false,
-       .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
        .aio_read_size = 1,
        .aio_write_size = 1,
        .map_readonly = MAP_READONLY_NO,
@@ -248,6 +247,7 @@ static const struct loadparm_service _sDefault =
        .param_opt = NULL,
        .smbd_search_ask_sharemode = true,
        .smbd_getinfo_ask_sharemode = true,
+       .spotlight_backend = SPOTLIGHT_BACKEND_NOINDEX,
        .dummy = ""
 };
 
@@ -545,7 +545,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        init_printer_values(lp_ctx, Globals.ctx, &sDefault);
 
-       sDefault.ntvfs_handler = str_list_make_v3_const(NULL, "unixuid default", NULL);
+       sDefault.ntvfs_handler = str_list_make_v3_const(Globals.ctx, "unixuid default", NULL);
 
        DEBUG(3, ("Initialising global parameters\n"));
 
@@ -641,15 +641,15 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
        Globals._disable_spoolss = false;
        Globals.max_smbd_processes = 0;/* no limit specified */
        Globals.username_level = 0;
-       Globals.deadtime = 0;
+       Globals.deadtime = 10080;
        Globals.getwd_cache = true;
        Globals.large_readwrite = true;
        Globals.max_log_size = 5000;
        Globals.max_open_files = max_open_files();
        Globals.server_max_protocol = PROTOCOL_SMB3_11;
-       Globals.server_min_protocol = PROTOCOL_LANMAN1;
+       Globals.server_min_protocol = PROTOCOL_SMB2_02;
        Globals._client_max_protocol = PROTOCOL_DEFAULT;
-       Globals.client_min_protocol = PROTOCOL_CORE;
+       Globals.client_min_protocol = PROTOCOL_SMB2_02;
        Globals._client_ipc_max_protocol = PROTOCOL_DEFAULT;
        Globals._client_ipc_min_protocol = PROTOCOL_DEFAULT;
        Globals._security = SEC_AUTO;
@@ -934,8 +934,6 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
        Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
 
-       Globals.rndc_command = str_list_make_v3_const(NULL, "/usr/sbin/rndc", NULL);
-
        Globals.cldap_port = 389;
 
        Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
@@ -994,7 +992,11 @@ static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
  callers without affecting the source string.
 ********************************************************************/
 
-char *lp_string(TALLOC_CTX *ctx, const char *s)
+static char *loadparm_s3_global_substitution_fn(
+                       TALLOC_CTX *mem_ctx,
+                       const struct loadparm_substitution *lp_sub,
+                       const char *s,
+                       void *private_data)
 {
        char *ret;
 
@@ -1010,14 +1012,14 @@ char *lp_string(TALLOC_CTX *ctx, const char *s)
                return NULL;
        }
 
-       ret = talloc_sub_basic(ctx,
+       ret = talloc_sub_basic(mem_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,
+                       ret = talloc_sub_basic(mem_ctx,
                                        get_current_username(),
                                        current_user_info.domain,
                                        s);
@@ -1026,6 +1028,20 @@ char *lp_string(TALLOC_CTX *ctx, const char *s)
        return ret;
 }
 
+static const struct loadparm_substitution s3_global_substitution = {
+       .substituted_string_fn = loadparm_s3_global_substitution_fn,
+};
+
+const struct loadparm_substitution *loadparm_s3_global_substitution(void)
+{
+       return &s3_global_substitution;
+}
+
+char *lp_string(TALLOC_CTX *ctx, const char *s)
+{
+       return lpcfg_substituted_string(ctx, &s3_global_substitution, s);
+}
+
 /*
    In this section all the functions that are used to access the
    parameters from the rest of the program are defined
@@ -1033,6 +1049,9 @@ char *lp_string(TALLOC_CTX *ctx, const char *s)
 
 #define FN_GLOBAL_STRING(fn_name,ptr) \
 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
+#define FN_GLOBAL_SUBSTITUTED_STRING(fn_name,ptr) \
+char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub) \
+ {return lpcfg_substituted_string(ctx, lp_sub, *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : "");}
 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
  const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
 #define FN_GLOBAL_LIST(fn_name,ptr) \
@@ -1046,6 +1065,9 @@ char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globa
 
 #define FN_LOCAL_STRING(fn_name,val) \
 char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
+#define FN_LOCAL_SUBSTITUTED_STRING(fn_name,val) \
+char *lp_ ## fn_name(TALLOC_CTX *ctx, const struct loadparm_substitution *lp_sub, int i) \
+ {return lpcfg_substituted_string((ctx), lp_sub, (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
 #define FN_LOCAL_CONST_STRING(fn_name,val) \
  const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
 #define FN_LOCAL_LIST(fn_name,val) \
@@ -1216,19 +1238,26 @@ static int lp_enum(const char *s,const struct enum_list *_enum)
 
 /* Return parametric option from a given service. Type is a part of option before ':' */
 /* Parametric option has following syntax: 'Type: option = value' */
-char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
+char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx,
+                                const struct loadparm_substitution *lp_sub,
+                                int snum,
+                                const char *type,
+                                const char *option,
+                                const char *def)
 {
        struct parmlist_entry *data = get_parametrics(snum, type, option);
 
+       SMB_ASSERT(lp_sub != NULL);
+
        if (data == NULL||data->value==NULL) {
                if (def) {
-                       return lp_string(ctx, def);
+                       return lpcfg_substituted_string(mem_ctx, lp_sub, def);
                } else {
                        return NULL;
                }
        }
 
-       return lp_string(ctx, data->value);
+       return lpcfg_substituted_string(mem_ctx, lp_sub, data->value);
 }
 
 /* Return parametric option from a given service. Type is a part of option before ':' */
@@ -1528,6 +1557,8 @@ static bool hash_a_service(const char *name, int idx)
 bool lp_add_home(const char *pszHomename, int iDefaultService,
                 const char *user, const char *pszHomedir)
 {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        int i;
        char *global_path;
 
@@ -1541,7 +1572,7 @@ bool lp_add_home(const char *pszHomename, int iDefaultService,
        if (i < 0)
                return false;
 
-       global_path = lp_path(talloc_tos(), GLOBAL_SECTION_SNUM);
+       global_path = lp_path(talloc_tos(), lp_sub, GLOBAL_SECTION_SNUM);
        if (!(*(ServicePtrs[iDefaultService]->path))
            || strequal(ServicePtrs[iDefaultService]->path, global_path)) {
                lpcfg_string_set(ServicePtrs[i], &ServicePtrs[i]->path,
@@ -2565,7 +2596,7 @@ const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
        if (Globals._ldap_machine_suffix[0])
                return append_ldap_suffix(ctx, Globals._ldap_machine_suffix);
 
-       return lp_string(ctx, Globals.ldap_suffix);
+       return talloc_strdup(ctx, Globals.ldap_suffix);
 }
 
 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
@@ -2573,7 +2604,7 @@ const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
        if (Globals._ldap_user_suffix[0])
                return append_ldap_suffix(ctx, Globals._ldap_user_suffix);
 
-       return lp_string(ctx, Globals.ldap_suffix);
+       return talloc_strdup(ctx, Globals.ldap_suffix);
 }
 
 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
@@ -2581,7 +2612,7 @@ const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
        if (Globals._ldap_group_suffix[0])
                return append_ldap_suffix(ctx, Globals._ldap_group_suffix);
 
-       return lp_string(ctx, Globals.ldap_suffix);
+       return talloc_strdup(ctx, Globals.ldap_suffix);
 }
 
 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
@@ -2589,7 +2620,7 @@ const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
        if (Globals._ldap_idmap_suffix[0])
                return append_ldap_suffix(ctx, Globals._ldap_idmap_suffix);
 
-       return lp_string(ctx, Globals.ldap_suffix);
+       return talloc_strdup(ctx, Globals.ldap_suffix);
 }
 
 /**
@@ -2767,7 +2798,6 @@ bool lp_do_section(const char *pszSectionName, void *userdata)
        bool bRetval;
        bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
                         (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
-       bRetval = false;
 
        /* if we were in a global section then do the local inits */
        if (bInGlobalSection && !isglobal)
@@ -2871,7 +2901,7 @@ bool lp_snum_ok(int iService)
  Auto-load some home services.
 ***************************************************************************/
 
-static void lp_add_auto_services(char *str)
+static void lp_add_auto_services(const char *str)
 {
        char *s;
        char *p;
@@ -3333,6 +3363,7 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        char *canon_name = NULL;
        bool added_service = false;
        int ret = -1;
+       NTSTATUS status;
 
        /* Ensure share name doesn't contain invalid characters. */
        if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
@@ -3369,7 +3400,6 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
 
        {
                TDB_DATA data;
-               NTSTATUS status;
 
                status = dbwrap_fetch_bystring(ServiceHash, canon_name,
                                               canon_name, &data);
@@ -3466,7 +3496,8 @@ static int process_usershare_file(const char *dir_name, const char *file_name, i
        }
 
        /* Write the ACL of the new/modified share. */
-       if (!set_share_security(canon_name, psd)) {
+       status = set_share_security(canon_name, psd);
+       if (!NT_STATUS_IS_OK(status)) {
                 DEBUG(0, ("process_usershare_file: Failed to set share "
                        "security for user share %s\n",
                        canon_name ));
@@ -3864,8 +3895,7 @@ static bool lp_load_ex(const char *pszFname,
        bool bRetval;
        TALLOC_CTX *frame = talloc_stackframe();
        struct loadparm_context *lp_ctx;
-
-       bRetval = false;
+       int max_protocol, min_protocol;
 
        DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
 
@@ -3959,7 +3989,9 @@ static bool lp_load_ex(const char *pszFname,
        }
 
        {
-               char *serv = lp_auto_services(talloc_tos());
+               const struct loadparm_substitution *lp_sub =
+                       loadparm_s3_global_substitution();
+               char *serv = lp_auto_services(talloc_tos(), lp_sub);
                lp_add_auto_services(serv);
                TALLOC_FREE(serv);
        }
@@ -4004,6 +4036,19 @@ static bool lp_load_ex(const char *pszFname,
 
        bAllowIncludeRegistry = true;
 
+       /* Check if command line max protocol < min protocol, if so
+        * report a warning to the user.
+        */
+       max_protocol = lp_client_max_protocol();
+       min_protocol = lp_client_min_protocol();
+       if (max_protocol < min_protocol) {
+               const char *max_protocolp, *min_protocolp;
+               max_protocolp = lpcfg_get_smb_protocol(max_protocol);
+               min_protocolp = lpcfg_get_smb_protocol(min_protocol);
+               DBG_ERR("Max protocol %s is less than min protocol %s.\n",
+                       max_protocolp, min_protocolp);
+       }
+
        TALLOC_FREE(frame);
        return (bRetval);
 }
@@ -4242,17 +4287,51 @@ int lp_servicenumber(const char *pszServiceName)
 
 const char *volume_label(TALLOC_CTX *ctx, int snum)
 {
+       const struct loadparm_substitution *lp_sub =
+               loadparm_s3_global_substitution();
        char *ret;
-       const char *label = lp_volume(ctx, snum);
+       const char *label = lp_volume(ctx, lp_sub, snum);
+       size_t end = 32;
+
        if (!*label) {
                label = lp_servicename(ctx, snum);
        }
 
-       /* This returns a 33 byte guarenteed null terminated string. */
-       ret = talloc_strndup(ctx, label, 32);
+       /*
+        * Volume label can be a max of 32 bytes. Make sure to truncate
+        * it at a codepoint boundary if it's longer than 32 and contains
+        * multibyte characters. Windows insists on a volume label being
+        * a valid mb sequence, and errors out if not.
+        */
+       if (strlen(label) > 32) {
+               /*
+                * A MB char can be a max of 5 bytes, thus
+                * we should have a valid mb character at a
+                * minimum position of (32-5) = 27.
+                */
+               while (end >= 27) {
+                       /*
+                        * Check if a codepoint starting from next byte
+                        * is valid. If yes, then the current byte is the
+                        * end of a MB or ascii sequence and the label can
+                        * be safely truncated here. If not, keep going
+                        * backwards till a valid codepoint is found.
+                        */
+                       size_t len = 0;
+                       const char *s = &label[end];
+                       codepoint_t c = next_codepoint(s, &len);
+                       if (c != INVALID_CODEPOINT) {
+                               break;
+                       }
+                       end--;
+               }
+       }
+
+       /* This returns a max of 33 byte guarenteed null terminated string. */
+       ret = talloc_strndup(ctx, label, end);
        if (!ret) {
                return "";
-       }               
+       }
        return ret;
 }
 
@@ -4346,9 +4425,12 @@ void lp_remove_service(int snum)
        ServicePtrs[snum]->valid = false;
 }
 
-const char *lp_printername(TALLOC_CTX *ctx, int snum)
+const char *lp_printername(TALLOC_CTX *ctx,
+                          const struct loadparm_substitution *lp_sub,
+                          int snum)
 {
-       const char *ret = lp__printername(ctx, snum);
+       const char *ret = lp__printername(ctx, lp_sub, snum);
+
        if (ret == NULL || *ret == '\0') {
                ret = lp_const_servicename(snum);
        }