s3-loadparm: fixed a memory leak in parametric options
[nivanova/samba-autobuild/.git] / source3 / param / loadparm.c
index d1cc79f195f05fb7cea9ec8799a7057ddfd40301..21fa662141bd69addc6f2ab8cbdba7081290c69c 100644 (file)
@@ -65,7 +65,7 @@
 #include "../librpc/gen_ndr/svcctl.h"
 #include "intl.h"
 #include "smb_signing.h"
-#include "dbwrap.h"
+#include "dbwrap/dbwrap.h"
 #include "smbldap.h"
 #include "../lib/util/bitmap.h"
 
@@ -310,9 +310,11 @@ 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);
 
 static const struct enum_list enum_protocol[] = {
-       {PROTOCOL_SMB2_02, "SMB2"},
+       {PROTOCOL_SMB2_02, "SMB2"}, /* for now keep PROTOCOL_SMB2_02 */
+       {PROTOCOL_SMB2_10, "SMB2_10"},
        {PROTOCOL_SMB2_02, "SMB2_02"},
        {PROTOCOL_NT1, "NT1"},
        {PROTOCOL_LANMAN2, "LANMAN2"},
@@ -4604,6 +4606,7 @@ static void free_parameters_by_snum(int snum)
  */
 static void free_global_parameters(void)
 {
+       free_param_opts(&Globals.param_opt);
        free_parameters_by_snum(GLOBAL_SECTION_SNUM);
 }
 
@@ -4700,13 +4703,13 @@ static void init_globals(bool reinit_globals)
         * wipe out smb.conf options set with lp_set_cmdline().  The
         * apply_lp_set_cmdline() call puts these values back in the
         * table once the defaults are set */
-       memset((void *)&Globals, '\0', sizeof(Globals));
+       ZERO_STRUCT(Globals);
 
        for (i = 0; parm_table[i].label; i++) {
                if ((parm_table[i].type == P_STRING ||
                     parm_table[i].type == P_USTRING))
                {
-                       string_set(lp_parm_ptr(NULL, &parm_table[i]), "");
+                       string_set((char **)lp_parm_ptr(NULL, &parm_table[i]), "");
                }
        }
 
@@ -5419,7 +5422,6 @@ 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 free_param_opts(struct parmlist_entry **popts);
 static void show_parameter(int parmIndex);
 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
 
@@ -6743,6 +6745,35 @@ done:
        return ret;
 }
 
+/**
+ * reload those shares from registry that are already
+ * activated in the services array.
+ */
+static bool reload_registry_shares(void)
+{
+       int i;
+       bool ret = true;
+
+       for (i = 0; i < iNumServices; i++) {
+               if (!VALID(i)) {
+                       continue;
+               }
+
+               if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
+                       continue;
+               }
+
+               ret = process_registry_service(ServicePtrs[i]->szService);
+               if (!ret) {
+                       goto done;
+               }
+       }
+
+done:
+       return ret;
+}
+
+
 #define MAX_INCLUDE_DEPTH 100
 
 static uint8_t include_depth;
@@ -7391,7 +7422,23 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                        }
                        break;
 
+               case P_BYTES:
+               {
+                       uint64_t val;
+                       if (conv_str_size_error(pszParmValue, &val)) {
+                               if (val <= INT_MAX) {
+                                       *(int *)parm_ptr = (int)val;
+                                       break;
+                               }
+                       }
+
+                       DEBUG(0,("lp_do_parameter(%s): value is not "
+                           "a valid size specifier!\n", pszParmValue));
+                       return false;
+               }
+
                case P_LIST:
+               case P_CMDLIST:
                        TALLOC_FREE(*((char ***)parm_ptr));
                        *(char ***)parm_ptr = str_list_make_v3(
                                NULL, pszParmValue, NULL);
@@ -8895,7 +8942,7 @@ void gfree_loadparm(void)
 /***************************************************************************
  Allow client apps to specify that they are a client
 ***************************************************************************/
-void lp_set_in_client(bool b)
+static void lp_set_in_client(bool b)
 {
     in_client = b;
 }
@@ -8904,7 +8951,7 @@ void lp_set_in_client(bool b)
 /***************************************************************************
  Determine if we're running in a client app
 ***************************************************************************/
-bool lp_is_in_client(void)
+static bool lp_is_in_client(void)
 {
     return in_client;
 }
@@ -8920,7 +8967,7 @@ static bool lp_load_ex(const char *pszFname,
                       bool add_ipc,
                       bool initialize_globals,
                       bool allow_include_registry,
-                      bool allow_registry_shares)
+                      bool load_all_shares)
 {
        char *n2 = NULL;
        bool bRetval;
@@ -8987,7 +9034,7 @@ static bool lp_load_ex(const char *pszFname,
                        return lp_load_ex(pszFname, global_only, save_defaults,
                                          add_ipc, initialize_globals,
                                          allow_include_registry,
-                                         allow_registry_shares);
+                                         load_all_shares);
                }
        } else if (lp_config_backend_is_registry()) {
                bRetval = process_registry_globals();
@@ -8997,8 +9044,12 @@ static bool lp_load_ex(const char *pszFname,
                bRetval = false;
        }
 
-       if (bRetval && lp_registry_shares() && allow_registry_shares) {
-               bRetval = process_registry_shares();
+       if (bRetval && lp_registry_shares()) {
+               if (load_all_shares) {
+                       bRetval = process_registry_shares();
+               } else {
+                       bRetval = reload_registry_shares();
+               }
        }
 
        lp_add_auto_services(lp_auto_services());
@@ -9055,7 +9106,7 @@ bool lp_load(const char *pszFname,
                          add_ipc,
                          initialize_globals,
                          true,   /* allow_include_registry */
-                         false); /* allow_registry_shares*/
+                         false); /* load_all_shares*/
 }
 
 bool lp_load_initial_only(const char *pszFname)
@@ -9066,7 +9117,57 @@ bool lp_load_initial_only(const char *pszFname)
                          false,  /* add_ipc */
                          true,   /* initialize_globals */
                          false,  /* allow_include_registry */
-                         false); /* allow_registry_shares*/
+                         false); /* load_all_shares*/
+}
+
+/**
+ * most common lp_load wrapper, loading only the globals
+ */
+bool lp_load_global(const char *file_name)
+{
+       return lp_load_ex(file_name,
+                         true,   /* global_only */
+                         false,  /* save_defaults */
+                         false,  /* add_ipc */
+                         true,   /* initialize_globals */
+                         true,   /* allow_include_registry */
+                         false); /* load_all_shares*/
+}
+
+/**
+ * lp_load wrapper, especially for clients
+ */
+bool lp_load_client(const char *file_name)
+{
+       lp_set_in_client(true);
+
+       return lp_load_global(file_name);
+}
+
+/**
+ * lp_load wrapper, loading only globals, but intended
+ * for subsequent calls, not reinitializing the globals
+ * to default values
+ */
+bool lp_load_global_no_reinit(const char *file_name)
+{
+       return lp_load_ex(file_name,
+                         true,   /* global_only */
+                         false,  /* save_defaults */
+                         false,  /* add_ipc */
+                         false,  /* initialize_globals */
+                         true,   /* allow_include_registry */
+                         false); /* load_all_shares*/
+}
+
+/**
+ * lp_load wrapper, especially for clients, no reinitialization
+ */
+bool lp_load_client_no_reinit(const char *file_name)
+{
+       lp_set_in_client(true);
+
+       return lp_load_global_no_reinit(file_name);
 }
 
 bool lp_load_with_registry_shares(const char *pszFname,
@@ -9081,7 +9182,7 @@ bool lp_load_with_registry_shares(const char *pszFname,
                          add_ipc,
                          initialize_globals,
                          true,  /* allow_include_registry */
-                         true); /* allow_registry_shares*/
+                         true); /* load_all_shares*/
 }
 
 /***************************************************************************