make parametic options case insensitive
[kai/samba.git] / source3 / param / loadparm.c
index 71632cd7537a6e89e2de07924d47e28f95586aab..9698feb06097f15693f1e9df740900f6c8427432 100644 (file)
@@ -70,9 +70,16 @@ extern userdom_struct current_user_info;
 #define HOMES_NAME "homes"
 #endif
 
+/* the special value for the include parameter
+ * to be interpreted not as a file name but to
+ * trigger loading of the global smb.conf options
+ * from registry. */
+#ifndef INCLUDE_REGISTRY_NAME
+#define INCLUDE_REGISTRY_NAME "registry"
+#endif
+
 static bool in_client = False;         /* Not in the client by default */
 static struct smbconf_csn conf_last_csn;
-static struct smbconf_ctx *conf_ctx = NULL;
 
 #define CONFIG_BACKEND_FILE 0
 #define CONFIG_BACKEND_REGISTRY 1
@@ -256,6 +263,7 @@ struct global {
        int ldap_passwd_sync;
        int ldap_replication_sleep;
        int ldap_timeout; /* This is initialised in init_globals */
+       int ldap_connection_timeout;
        int ldap_page_size;
        bool ldap_delete_dn;
        bool bMsAddPrinterWizard;
@@ -3554,6 +3562,15 @@ static struct parm_struct parm_table[] = {
                .enum_list      = NULL,
                .flags          = FLAG_ADVANCED,
        },
+       {
+               .label          = "ldap connection timeout",
+               .type           = P_INTEGER,
+               .p_class        = P_GLOBAL,
+               .ptr            = &Globals.ldap_connection_timeout,
+               .special        = NULL,
+               .enum_list      = NULL,
+               .flags          = FLAG_ADVANCED,
+       },
        {
                .label          = "ldap page size",
                .type           = P_INTEGER,
@@ -4748,7 +4765,8 @@ static void init_globals(bool first_time_only)
        Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
        Globals.ldap_delete_dn = False;
        Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
-       Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
+       Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
+       Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
        Globals.ldap_page_size = LDAP_PAGE_SIZE;
 
        Globals.ldap_debug_level = 0;
@@ -5067,6 +5085,7 @@ FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
+FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
@@ -5361,7 +5380,7 @@ static param_opt_struct *get_parametrics(int snum, const char *type, const char
        }
 
        while (data) {
-               if (strcmp(data->key, param_key) == 0) {
+               if (strcasecmp(data->key, param_key) == 0) {
                        string_free(&param_key);
                        return data;
                }
@@ -6483,25 +6502,65 @@ bool service_ok(int iService)
        return (bRetval);
 }
 
+static struct smbconf_ctx *lp_smbconf_ctx(void)
+{
+       WERROR werr;
+       static struct smbconf_ctx *conf_ctx = NULL;
+
+       if (conf_ctx == NULL) {
+               werr = smbconf_init(NULL, &conf_ctx, "registry:");
+               if (!W_ERROR_IS_OK(werr)) {
+                       DEBUG(1, ("error initializing registry configuration: "
+                                 "%s\n", dos_errstr(werr)));
+                       conf_ctx = NULL;
+               }
+       }
+
+       return conf_ctx;
+}
+
+static bool process_registry_service(struct smbconf_service *service)
+{
+       uint32_t count;
+       bool ret;
+
+       if (service == NULL) {
+               return false;
+       }
+
+       ret = do_section(service->name, NULL);
+       if (ret != true) {
+               return false;
+       }
+       for (count = 0; count < service->num_params; count++) {
+               ret = do_parameter(service->param_names[count],
+                                  service->param_values[count],
+                                  NULL);
+               if (ret != true) {
+                       return false;
+               }
+       }
+       return true;
+}
+
 /*
  * process_registry_globals
  */
 static bool process_registry_globals(void)
 {
        WERROR werr;
-       char **param_names;
-       char **param_values;
-       uint32_t num_params;
-       uint32_t count;
+       struct smbconf_service *service = NULL;
        TALLOC_CTX *mem_ctx = talloc_stackframe();
+       struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
        bool ret = false;
 
        if (conf_ctx == NULL) {
-               /* first time */
-               werr = smbconf_init(NULL, &conf_ctx, "registry:");
-               if (!W_ERROR_IS_OK(werr)) {
-                       goto done;
-               }
+               goto done;
+       }
+
+       ret = do_parameter("registry shares", "yes", NULL);
+       if (!ret) {
+               goto done;
        }
 
        if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
@@ -6511,21 +6570,55 @@ static bool process_registry_globals(void)
                goto done;
        }
 
-       werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME,
-                                &num_params, &param_names, &param_values);
+       werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
        if (!W_ERROR_IS_OK(werr)) {
                goto done;
        }
 
-       for (count = 0; count < num_params; count++) {
-               ret = do_parameter(param_names[count], param_values[count],
-                                  NULL);
-               if (ret != true) {
+       ret = process_registry_service(service);
+       if (!ret) {
+               goto done;
+       }
+
+       /* store the csn */
+       smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
+
+done:
+       TALLOC_FREE(mem_ctx);
+       return ret;
+}
+
+static bool process_registry_shares(void)
+{
+       WERROR werr;
+       uint32_t count;
+       struct smbconf_service **service = NULL;
+       uint32_t num_shares = 0;
+       TALLOC_CTX *mem_ctx = talloc_stackframe();
+       struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
+       bool ret = false;
+
+       if (conf_ctx == NULL) {
+               goto done;
+       }
+
+       werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
+       if (!W_ERROR_IS_OK(werr)) {
+               goto done;
+       }
+
+       ret = true;
+
+       for (count = 0; count < num_shares; count++) {
+               if (strequal(service[count]->name, GLOBAL_NAME)) {
+                       continue;
+               }
+               ret = process_registry_service(service[count]);
+               if (!ret) {
                        goto done;
                }
        }
 
-       ret = do_parameter("registry shares", "yes", NULL);
        /* store the csn */
        smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
 
@@ -6607,14 +6700,10 @@ bool lp_file_list_changed(void)
        DEBUG(6, ("lp_file_list_changed()\n"));
 
        if (lp_config_backend_is_registry()) {
+               struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
+
                if (conf_ctx == NULL) {
-                       WERROR werr;
-                       werr = smbconf_init(NULL, &conf_ctx, "registry:");
-                       if (!W_ERROR_IS_OK(werr)) {
-                               DEBUG(0, ("error opening configuration: %s\n",
-                                         dos_errstr(werr)));
-                               return false;
-                       }
+                       return false;
                }
                if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
                        DEBUGADD(6, ("registry config changed\n"));
@@ -6719,11 +6808,25 @@ static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **pt
 /***************************************************************************
  Handle the include operation.
 ***************************************************************************/
+static bool bAllowIncludeRegistry = true;
 
 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
 {
        char *fname;
 
+       if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
+               if (!bAllowIncludeRegistry) {
+                       return true;
+               }
+               if (bInGlobalSection) {
+                       return process_registry_globals();
+               } else {
+                       DEBUG(1, ("\"include = registry\" only effective "
+                                 "in %s section\n", GLOBAL_NAME));
+                       return false;
+               }
+       }
+
        fname = alloc_sub_basic(get_current_username(),
                                current_user_info.domain,
                                pszParmValue);
@@ -6740,7 +6843,7 @@ static bool handle_include(int snum, const char *pszParmValue, char **ptr)
 
        DEBUG(2, ("Can't find include file %s\n", fname));
        SAFE_FREE(fname);
-       return false;
+       return true;
 }
 
 /***************************************************************************
@@ -7105,8 +7208,8 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
 
        /* if it is a special case then go ahead */
        if (parm_table[parmnum].special) {
-               parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
-               return (True);
+               return parm_table[parmnum].special(snum, pszParmValue,
+                                                  (char **)parm_ptr);
        }
 
        /* now switch on the type of variable it is */
@@ -8633,11 +8736,13 @@ bool lp_is_in_client(void)
  False on failure.
 ***************************************************************************/
 
-bool lp_load(const char *pszFname,
-             bool global_only,
-             bool save_defaults,
-            bool add_ipc,
-             bool initialize_globals)
+bool lp_load_ex(const char *pszFname,
+               bool global_only,
+               bool save_defaults,
+               bool add_ipc,
+               bool initialize_globals,
+               bool allow_include_registry,
+               bool allow_registry_shares)
 {
        char *n2 = NULL;
        bool bRetval;
@@ -8645,10 +8750,11 @@ bool lp_load(const char *pszFname,
 
        bRetval = False;
 
-       DEBUG(3, ("lp_load: refreshing parameters\n"));
+       DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
 
        bInGlobalSection = True;
        bGlobalOnly = global_only;
+       bAllowIncludeRegistry = allow_include_registry;
 
        init_globals(! initialize_globals);
        debug_init();
@@ -8658,6 +8764,9 @@ bool lp_load(const char *pszFname,
                lp_save_defaults();
        }
 
+       /* We get sections first, so have to start 'behind' to make up */
+       iServiceIndex = -1;
+
        if (Globals.param_opt != NULL) {
                data = Globals.param_opt;
                while (data) {
@@ -8676,13 +8785,11 @@ bool lp_load(const char *pszFname,
                                        current_user_info.domain,
                                        pszFname);
                if (!n2) {
-                       smb_panic("lp_load: out of memory");
+                       smb_panic("lp_load_ex: out of memory");
                }
 
                add_to_file_list(pszFname, n2);
 
-               /* We get sections first, so have to start 'behind' to make up */
-               iServiceIndex = -1;
                bRetval = pm_process(n2, do_section, do_parameter, NULL);
                SAFE_FREE(n2);
 
@@ -8704,12 +8811,14 @@ bool lp_load(const char *pszFname,
                         */
                        config_backend = CONFIG_BACKEND_REGISTRY;
                        /* start over */
-                       DEBUG(1, ("lp_load: changing to config backend "
+                       DEBUG(1, ("lp_load_ex: changing to config backend "
                                  "registry\n"));
                        init_globals(false);
                        lp_kill_all_services();
-                       return lp_load(pszFname, global_only, save_defaults,
-                                      add_ipc, initialize_globals);
+                       return lp_load_ex(pszFname, global_only, save_defaults,
+                                         add_ipc, initialize_globals,
+                                         allow_include_registry,
+                                         allow_registry_shares);
                }
        } else if (lp_config_backend_is_registry()) {
                bRetval = process_registry_globals();
@@ -8719,6 +8828,10 @@ bool lp_load(const char *pszFname,
                bRetval = false;
        }
 
+       if (bRetval && lp_registry_shares() && allow_registry_shares) {
+               bRetval = process_registry_shares();
+       }
+
        lp_add_auto_services(lp_auto_services());
 
        if (add_ipc) {
@@ -8744,9 +8857,51 @@ bool lp_load(const char *pszFname,
 
        init_iconv();
 
+       bAllowIncludeRegistry = true;
+
        return (bRetval);
 }
 
+bool lp_load(const char *pszFname,
+            bool global_only,
+            bool save_defaults,
+            bool add_ipc,
+            bool initialize_globals)
+{
+       return lp_load_ex(pszFname,
+                         global_only,
+                         save_defaults,
+                         add_ipc,
+                         initialize_globals,
+                         true, false);
+}
+
+bool lp_load_initial_only(const char *pszFname)
+{
+       return lp_load_ex(pszFname,
+                         true,
+                         false,
+                         false,
+                         true,
+                         false,
+                         false);
+}
+
+bool lp_load_with_registry_shares(const char *pszFname,
+                                 bool global_only,
+                                 bool save_defaults,
+                                 bool add_ipc,
+                                 bool initialize_globals)
+{
+       return lp_load_ex(pszFname,
+                         global_only,
+                         save_defaults,
+                         add_ipc,
+                         initialize_globals,
+                         true,
+                         true);
+}
+
 /***************************************************************************
  Reset the max number of services.
 ***************************************************************************/