param: use a single special handler for idmap parameters
[mat/samba.git] / source3 / param / loadparm.c
index 544d7c0062e435c4a4c1e1abdeb4ed579e5e9486..d5f7bacf1b05f6f512513e5c1cd09791f2997f20 100644 (file)
@@ -249,13 +249,6 @@ static struct loadparm_service sDefault =
        .dummy = ""
 };
 
-static struct file_lists {
-       struct file_lists *next;
-       char *name;
-       char *subfname;
-       time_t modtime;
-} *file_lists = NULL;
-
 /* local variables */
 static struct loadparm_service **ServicePtrs = NULL;
 static int iNumServices = 0;
@@ -263,23 +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_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_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);
-
 static void set_allowed_client_auth(void);
 
-static void add_to_file_list(TALLOC_CTX *mem_ctx, struct file_lists **f, 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);
 
@@ -331,7 +313,7 @@ bool lp_string_set(char **dest, const char *src) {
  Initialise the sDefault parameter structure for the printer values.
 ***************************************************************************/
 
-static void init_printer_values(TALLOC_CTX *ctx, 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) {
@@ -339,52 +321,52 @@ static void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pServi
                case PRINT_AIX:
                case PRINT_LPRNT:
                case PRINT_LPROS2:
-                       string_set(ctx, &pService->lpq_command, "lpq -P'%p'");
-                       string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
-                       string_set(ctx, &pService->print_command, "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(ctx, &pService->lpq_command, "lpq -P'%p'");
-                       string_set(ctx, &pService->lprm_command, "lprm -P'%p' %j");
-                       string_set(ctx, &pService->print_command, "lpr -r -P'%p' %s");
-                       string_set(ctx, &pService->queuepause_command, "lpc stop '%p'");
-                       string_set(ctx, &pService->queueresume_command, "lpc start '%p'");
-                       string_set(ctx, &pService->lppause_command, "lpc hold '%p' %j");
-                       string_set(ctx, &pService->lpresume_command, "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(ctx, &pService->lpq_command, "%p");
-                       string_set(ctx, &pService->lprm_command, "");
-                       string_set(ctx, &pService->print_command, "");
-                       string_set(ctx, &pService->lppause_command, "");
-                       string_set(ctx, &pService->lpresume_command, "");
-                       string_set(ctx, &pService->queuepause_command, "");
-                       string_set(ctx, &pService->queueresume_command, "");
+                       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(ctx, &pService->lpq_command, "lpstat -o%p");
-                       string_set(ctx, &pService->lprm_command, "cancel %p-%j");
-                       string_set(ctx, &pService->print_command, "lp -c -d%p %s; rm %s");
-                       string_set(ctx, &pService->queuepause_command, "disable %p");
-                       string_set(ctx, &pService->queueresume_command, "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(ctx, &pService->lppause_command, "lp -i %p-%j -H hold");
-                       string_set(ctx, &pService->lpresume_command, "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(ctx, &pService->lpq_command, "lpq -P%p");
-                       string_set(ctx, &pService->lprm_command, "lprm -P%p %j");
-                       string_set(ctx, &pService->print_command, "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)
@@ -392,7 +374,7 @@ static void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pServi
        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(
@@ -405,37 +387,37 @@ static void init_printer_values(TALLOC_CTX *ctx, struct loadparm_service *pServi
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s print %%p %%s",
                                      tdbfile);
-               string_set(ctx, &pService->print_command,
+               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(ctx, &pService->lpq_command,
+               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(ctx, &pService->lprm_command,
+               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(ctx, &pService->lppause_command,
+               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(ctx, &pService->lpresume_command,
+               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(ctx, &pService->queuepause_command,
+               lpcfg_string_set(ctx, &pService->queuepause_command,
                           tmp ? tmp : "vlp queuepause %p");
 
                tmp = talloc_asprintf(tmp_ctx, "vlp %s queueresume %%p",
                                      tdbfile);
-               string_set(ctx, &pService->queueresume_command,
+               lpcfg_string_set(ctx, &pService->queueresume_command,
                           tmp ? tmp : "vlp queueresume %p");
                TALLOC_FREE(tmp_ctx);
 
@@ -1180,12 +1162,9 @@ FN_LOCAL_BOOL(autoloaded, autoloaded)
 
 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 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);
@@ -1265,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.
 ********************************************************************/
@@ -1365,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;
 }
@@ -2079,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;
@@ -2358,51 +2291,6 @@ done:
 
 static uint8_t include_depth;
 
-/*******************************************************************
- 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(TALLOC_CTX *mem_ctx, struct file_lists **list,
-                            const char *fname, const char *subfname)
-{
-       struct file_lists *f = *list;
-
-       while (f) {
-               if (f->name && !strcmp(f->name, fname))
-                       break;
-               f = f->next;
-       }
-
-       if (!f) {
-               f = talloc(mem_ctx, struct file_lists);
-               if (!f)
-                       goto fail;
-               f->next = *list;
-               f->name = talloc_strdup(f, fname);
-               if (!f->name) {
-                       TALLOC_FREE(f);
-                       goto fail;
-               }
-               f->subfname = talloc_strdup(f, subfname);
-               if (!f->subfname) {
-                       TALLOC_FREE(f);
-                       goto fail;
-               }
-               *list = f;
-               f->modtime = file_modtime(subfname);
-       } else {
-               time_t t = file_modtime(subfname);
-               if (t)
-                       f->modtime = t;
-       }
-       return;
-
-fail:
-       DEBUG(0, ("Unable to add file to file list: %s\n", fname));
-
-}
-
 /**
  * Free the file lists
  */
@@ -2515,65 +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(Globals.ctx, 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(Globals.ctx, ptr, pszParmValue);
-               init_iconv();
-       }
-       return true;
-}
-
-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;
 
@@ -2626,38 +2461,6 @@ static bool handle_include(struct loadparm_context *unused, int snum, const char
        return true;
 }
 
-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;
@@ -2785,70 +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;
-               init_printer_values(Globals.ctx, s);
-       } else {
-               s = ServicePtrs[snum];
-               init_printer_values(s, 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
 */
@@ -2956,6 +2695,8 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                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);
@@ -3024,7 +2765,9 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue
                        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;
@@ -3103,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.