param: make init_printer_values use lpcfg functions
[obnox/samba/samba-obnox.git] / lib / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough (jmcd@us.ibm.com)  2003.
12    Copyright (C) James Myers 2003 <myersjj@samba.org>
13    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14    Copyright (C) Andrew Bartlett 2011-2012
15
16    This program is free software; you can redistribute it and/or modify
17    it under the terms of the GNU General Public License as published by
18    the Free Software Foundation; either version 3 of the License, or
19    (at your option) any later version.
20
21    This program is distributed in the hope that it will be useful,
22    but WITHOUT ANY WARRANTY; without even the implied warranty of
23    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24    GNU General Public License for more details.
25
26    You should have received a copy of the GNU General Public License
27    along with this program.  If not, see <http://www.gnu.org/licenses/>.
28 */
29
30 /*
31  *  Load parameters.
32  *
33  *  This module provides suitable callback functions for the params
34  *  module. It builds the internal table of service details which is
35  *  then used by the rest of the server.
36  *
37  * To add a parameter:
38  *
39  * 1) add it to the global or service structure definition
40  * 2) add it to the parm_table
41  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
42  * 4) If it's a global then initialise it in init_globals. If a local
43  *    (ie. service) parameter then initialise it in the sDefault structure
44  *
45  *
46  * Notes:
47  *   The configuration file is processed sequentially for speed. It is NOT
48  *   accessed randomly as happens in 'real' Windows. For this reason, there
49  *   is a fair bit of sequence-dependent code here - ie., code which assumes
50  *   that certain things happen before others. In particular, the code which
51  *   happens at the boundary between sections is delicately poised, so be
52  *   careful!
53  *
54  */
55
56 #include "includes.h"
57 #include "version.h"
58 #include "dynconfig/dynconfig.h"
59 #include "system/time.h"
60 #include "system/locale.h"
61 #include "system/network.h" /* needed for TCP_NODELAY */
62 #include "../lib/util/dlinklist.h"
63 #include "lib/param/param.h"
64 #include "lib/param/loadparm.h"
65 #include "auth/gensec/gensec.h"
66 #include "lib/param/s3_param.h"
67 #include "lib/util/bitmap.h"
68 #include "libcli/smb/smb_constants.h"
69 #include "tdb.h"
70
71 #define standard_sub_basic talloc_strdup
72
73 static bool do_parameter(const char *, const char *, void *);
74 static bool defaults_saved = false;
75
76 #include "lib/param/param_global.h"
77
78 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
79
80 /* these are parameter handlers which are not needed in the
81  * non-source3 code
82  */
83 #define handle_netbios_aliases NULL
84 #define handle_printing NULL
85 #define handle_ldap_debug_level NULL
86 #define handle_idmap_backend NULL
87 #define handle_idmap_uid NULL
88 #define handle_idmap_gid NULL
89
90 #ifndef N_
91 #define N_(x) x
92 #endif
93
94 #include "lib/param/param_table.c"
95
96 /* local variables */
97 struct loadparm_context {
98         const char *szConfigFile;
99         struct loadparm_global *globals;
100         struct loadparm_service **services;
101         struct loadparm_service *sDefault;
102         struct smb_iconv_handle *iconv_handle;
103         int iNumServices;
104         struct loadparm_service *currentService;
105         bool bInGlobalSection;
106         struct file_lists *file_lists;
107         unsigned int flags[NUMPARAMETERS];
108         bool loaded;
109         bool refuse_free;
110         bool global; /* Is this the global context, which may set
111                       * global variables such as debug level etc? */
112         const struct loadparm_s3_helpers *s3_fns;
113 };
114
115
116 struct loadparm_service *lpcfg_default_service(struct loadparm_context *lp_ctx)
117 {
118         if (lp_ctx->s3_fns) {
119                 return lp_ctx->s3_fns->get_default_loadparm_service();
120         }
121         return lp_ctx->sDefault;
122 }
123
124 /**
125  * Convenience routine to grab string parameters into temporary memory
126  * and run standard_sub_basic on them.
127  *
128  * The buffers can be written to by
129  * callers without affecting the source string.
130  */
131
132 static const char *lpcfg_string(const char *s)
133 {
134 #if 0  /* until REWRITE done to make thread-safe */
135         size_t len = s ? strlen(s) : 0;
136         char *ret;
137 #endif
138
139         /* The follow debug is useful for tracking down memory problems
140            especially if you have an inner loop that is calling a lp_*()
141            function that returns a string.  Perhaps this debug should be
142            present all the time? */
143
144 #if 0
145         DEBUG(10, ("lpcfg_string(%s)\n", s));
146 #endif
147
148 #if 0  /* until REWRITE done to make thread-safe */
149         if (!lp_talloc)
150                 lp_talloc = talloc_init("lp_talloc");
151
152         ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
153
154         if (!ret)
155                 return NULL;
156
157         if (!s)
158                 *ret = 0;
159         else
160                 strlcpy(ret, s, len);
161
162         if (trim_string(ret, "\"", "\"")) {
163                 if (strchr(ret,'"') != NULL)
164                         strlcpy(ret, s, len);
165         }
166
167         standard_sub_basic(ret,len+100);
168         return (ret);
169 #endif
170         return s;
171 }
172
173 /*
174    In this section all the functions that are used to access the
175    parameters from the rest of the program are defined
176 */
177
178 /*
179  * the creation of separate lpcfg_*() and lp_*() functions is to allow
180  * for code compatibility between existing Samba4 and Samba3 code.
181  */
182
183 /* this global context supports the lp_*() function varients */
184 static struct loadparm_context *global_loadparm_context;
185
186 #define lpcfg_default_service global_loadparm_context->sDefault
187 #define lpcfg_global_service(i) global_loadparm_context->services[i]
188
189 #define FN_GLOBAL_STRING(fn_name,var_name) \
190  _PUBLIC_ char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx, TALLOC_CTX *ctx) {\
191          if (lp_ctx == NULL) return NULL;                               \
192          if (lp_ctx->s3_fns) {                                          \
193                  return lp_ctx->globals->var_name ? lp_ctx->s3_fns->lp_string(ctx, lp_ctx->globals->var_name) : talloc_strdup(ctx, ""); \
194          }                                                              \
195          return lp_ctx->globals->var_name ? talloc_strdup(ctx, lpcfg_string(lp_ctx->globals->var_name)) : talloc_strdup(ctx, ""); \
196 }
197
198 #define FN_GLOBAL_CONST_STRING(fn_name,var_name)                                \
199  _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
200         if (lp_ctx == NULL) return NULL;                                \
201         return lp_ctx->globals->var_name ? lpcfg_string(lp_ctx->globals->var_name) : ""; \
202 }
203
204 #define FN_GLOBAL_LIST(fn_name,var_name)                                \
205  _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
206          if (lp_ctx == NULL) return NULL;                               \
207          return lp_ctx->globals->var_name;                              \
208  }
209
210 #define FN_GLOBAL_BOOL(fn_name,var_name) \
211  _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) {\
212          if (lp_ctx == NULL) return false;                              \
213          return lp_ctx->globals->var_name;                              \
214 }
215
216 #define FN_GLOBAL_INTEGER(fn_name,var_name) \
217  _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_context *lp_ctx) { \
218          return lp_ctx->globals->var_name;                              \
219  }
220
221 /* Local parameters don't need the ->s3_fns because the struct
222  * loadparm_service is shared and lpcfg_service() checks the ->s3_fns
223  * hook */
224 #define FN_LOCAL_STRING(fn_name,val) \
225  _PUBLIC_ char *lpcfg_ ## fn_name(struct loadparm_service *service, \
226                                         struct loadparm_service *sDefault, TALLOC_CTX *ctx) { \
227          return(talloc_strdup(ctx, lpcfg_string((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)))); \
228  }
229
230 #define FN_LOCAL_CONST_STRING(fn_name,val) \
231  _PUBLIC_ const char *lpcfg_ ## fn_name(struct loadparm_service *service, \
232                                         struct loadparm_service *sDefault) { \
233          return((const char *)((service != NULL && service->val != NULL) ? service->val : sDefault->val)); \
234  }
235
236 #define FN_LOCAL_LIST(fn_name,val) \
237  _PUBLIC_ const char **lpcfg_ ## fn_name(struct loadparm_service *service, \
238                                          struct loadparm_service *sDefault) {\
239          return(const char **)(service != NULL && service->val != NULL? service->val : sDefault->val); \
240  }
241
242 #define FN_LOCAL_PARM_BOOL(fn_name, val) FN_LOCAL_BOOL(fn_name, val)
243
244 #define FN_LOCAL_BOOL(fn_name,val) \
245  _PUBLIC_ bool lpcfg_ ## fn_name(struct loadparm_service *service, \
246                                  struct loadparm_service *sDefault) {   \
247          return((service != NULL)? service->val : sDefault->val); \
248  }
249
250 #define FN_LOCAL_INTEGER(fn_name,val) \
251  _PUBLIC_ int lpcfg_ ## fn_name(struct loadparm_service *service, \
252                                 struct loadparm_service *sDefault) {    \
253          return((service != NULL)? service->val : sDefault->val); \
254  }
255
256 #define FN_LOCAL_PARM_INTEGER(fn_name, val) FN_LOCAL_INTEGER(fn_name, val)
257
258 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
259  _PUBLIC_ char lpcfg_ ## fn_name(struct loadparm_service *service, \
260                                 struct loadparm_service *sDefault) {    \
261          return((service != NULL)? service->val : sDefault->val); \
262  }
263
264 #include "lib/param/param_functions.c"
265
266 /* These functions cannot be auto-generated */
267 FN_LOCAL_BOOL(autoloaded, autoloaded)
268 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
269
270 /* local prototypes */
271 static struct loadparm_service *lpcfg_getservicebyname(struct loadparm_context *lp_ctx,
272                                         const char *pszServiceName);
273 static bool lpcfg_service_ok(struct loadparm_service *service);
274 static bool do_section(const char *pszSectionName, void *);
275
276 /* This is a helper function for parametrical options support. */
277 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
278 /* Actual parametrical functions are quite simple */
279 const char *lpcfg_get_parametric(struct loadparm_context *lp_ctx,
280                               struct loadparm_service *service,
281                               const char *type, const char *option)
282 {
283         char *vfskey_tmp = NULL;
284         char *vfskey = NULL;
285         struct parmlist_entry *data;
286
287         if (lp_ctx == NULL)
288                 return NULL;
289
290         if (lp_ctx->s3_fns) {
291                 return lp_ctx->s3_fns->get_parametric(service, type, option);
292         }
293
294         data = (service == NULL ? lp_ctx->globals->param_opt : service->param_opt);
295
296         vfskey_tmp = talloc_asprintf(NULL, "%s:%s", type, option);
297         if (vfskey_tmp == NULL) return NULL;
298         vfskey = strlower_talloc(NULL, vfskey_tmp);
299         talloc_free(vfskey_tmp);
300
301         while (data) {
302                 if (strcmp(data->key, vfskey) == 0) {
303                         talloc_free(vfskey);
304                         return data->value;
305                 }
306                 data = data->next;
307         }
308
309         if (service != NULL) {
310                 /* Try to fetch the same option but from globals */
311                 /* but only if we are not already working with globals */
312                 for (data = lp_ctx->globals->param_opt; data;
313                      data = data->next) {
314                         if (strcmp(data->key, vfskey) == 0) {
315                                 talloc_free(vfskey);
316                                 return data->value;
317                         }
318                 }
319         }
320
321         talloc_free(vfskey);
322
323         return NULL;
324 }
325
326
327 /**
328  * convenience routine to return int parameters.
329  */
330 int lp_int(const char *s)
331 {
332
333         if (!s || !*s) {
334                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
335                 return -1;
336         }
337
338         return strtol(s, NULL, 0);
339 }
340
341 /**
342  * convenience routine to return unsigned long parameters.
343  */
344 unsigned long lp_ulong(const char *s)
345 {
346
347         if (!s || !*s) {
348                 DEBUG(0,("lp_ulong(%s): is called with NULL!\n",s));
349                 return -1;
350         }
351
352         return strtoul(s, NULL, 0);
353 }
354
355 /**
356  * convenience routine to return unsigned long parameters.
357  */
358 static long lp_long(const char *s)
359 {
360
361         if (!s) {
362                 DEBUG(0,("lp_long(%s): is called with NULL!\n",s));
363                 return -1;
364         }
365
366         return strtol(s, NULL, 0);
367 }
368
369 /**
370  * convenience routine to return unsigned long parameters.
371  */
372 static double lp_double(const char *s)
373 {
374
375         if (!s) {
376                 DEBUG(0,("lp_double(%s): is called with NULL!\n",s));
377                 return -1;
378         }
379
380         return strtod(s, NULL);
381 }
382
383 /**
384  * convenience routine to return boolean parameters.
385  */
386 bool lp_bool(const char *s)
387 {
388         bool ret = false;
389
390         if (!s || !*s) {
391                 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
392                 return false;
393         }
394
395         if (!set_boolean(s, &ret)) {
396                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
397                 return false;
398         }
399
400         return ret;
401 }
402
403 /**
404  * Return parametric option from a given service. Type is a part of option before ':'
405  * Parametric option has following syntax: 'Type: option = value'
406  * Returned value is allocated in 'lp_talloc' context
407  */
408
409 const char *lpcfg_parm_string(struct loadparm_context *lp_ctx,
410                               struct loadparm_service *service, const char *type,
411                               const char *option)
412 {
413         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
414
415         if (value)
416                 return lpcfg_string(value);
417
418         return NULL;
419 }
420
421 /**
422  * Return parametric option from a given service. Type is a part of option before ':'
423  * Parametric option has following syntax: 'Type: option = value'
424  * Returned value is allocated in 'lp_talloc' context
425  */
426
427 const char **lpcfg_parm_string_list(TALLOC_CTX *mem_ctx,
428                                     struct loadparm_context *lp_ctx,
429                                     struct loadparm_service *service,
430                                     const char *type,
431                                     const char *option, const char *separator)
432 {
433         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
434
435         if (value != NULL)
436                 return (const char **)str_list_make(mem_ctx, value, separator);
437
438         return NULL;
439 }
440
441 /**
442  * Return parametric option from a given service. Type is a part of option before ':'
443  * Parametric option has following syntax: 'Type: option = value'
444  */
445
446 int lpcfg_parm_int(struct loadparm_context *lp_ctx,
447                    struct loadparm_service *service, const char *type,
448                    const char *option, int default_v)
449 {
450         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
451
452         if (value)
453                 return lp_int(value);
454
455         return default_v;
456 }
457
458 /**
459  * Return parametric option from a given service. Type is a part of
460  * option before ':'.
461  * Parametric option has following syntax: 'Type: option = value'.
462  */
463
464 int lpcfg_parm_bytes(struct loadparm_context *lp_ctx,
465                   struct loadparm_service *service, const char *type,
466                   const char *option, int default_v)
467 {
468         uint64_t bval;
469
470         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
471
472         if (value && conv_str_size_error(value, &bval)) {
473                 if (bval <= INT_MAX) {
474                         return (int)bval;
475                 }
476         }
477
478         return default_v;
479 }
480
481 /**
482  * Return parametric option from a given service.
483  * Type is a part of option before ':'
484  * Parametric option has following syntax: 'Type: option = value'
485  */
486 unsigned long lpcfg_parm_ulong(struct loadparm_context *lp_ctx,
487                             struct loadparm_service *service, const char *type,
488                             const char *option, unsigned long default_v)
489 {
490         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
491
492         if (value)
493                 return lp_ulong(value);
494
495         return default_v;
496 }
497
498 long lpcfg_parm_long(struct loadparm_context *lp_ctx,
499                      struct loadparm_service *service, const char *type,
500                      const char *option, long default_v)
501 {
502         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
503
504         if (value)
505                 return lp_long(value);
506
507         return default_v;
508 }
509
510 double lpcfg_parm_double(struct loadparm_context *lp_ctx,
511                       struct loadparm_service *service, const char *type,
512                       const char *option, double default_v)
513 {
514         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
515
516         if (value != NULL)
517                 return lp_double(value);
518
519         return default_v;
520 }
521
522 /**
523  * Return parametric option from a given service. Type is a part of option before ':'
524  * Parametric option has following syntax: 'Type: option = value'
525  */
526
527 bool lpcfg_parm_bool(struct loadparm_context *lp_ctx,
528                      struct loadparm_service *service, const char *type,
529                      const char *option, bool default_v)
530 {
531         const char *value = lpcfg_get_parametric(lp_ctx, service, type, option);
532
533         if (value != NULL)
534                 return lp_bool(value);
535
536         return default_v;
537 }
538
539
540 /**
541  * Set a string value, deallocating any existing space, and allocing the space
542  * for the string
543  */
544 bool lpcfg_string_set(TALLOC_CTX *mem_ctx, char **dest, const char *src)
545 {
546         talloc_free(*dest);
547
548         if (src == NULL)
549                 src = "";
550
551         *dest = talloc_strdup(mem_ctx, src);
552         if ((*dest) == NULL) {
553                 DEBUG(0,("Out of memory in string_set\n"));
554                 return false;
555         }
556
557         return true;
558 }
559
560 /**
561  * Set a string value, deallocating any existing space, and allocing the space
562  * for the string
563  */
564 static bool lpcfg_string_set_upper(TALLOC_CTX *mem_ctx, char **dest, const char *src)
565 {
566         talloc_free(*dest);
567
568         if (src == NULL)
569                 src = "";
570
571         *dest = strupper_talloc(mem_ctx, src);
572         if ((*dest) == NULL) {
573                 DEBUG(0,("Out of memory in string_set_upper\n"));
574                 return false;
575         }
576
577         return true;
578 }
579
580
581
582 /**
583  * Add a new service to the services array initialising it with the given
584  * service.
585  */
586
587 struct loadparm_service *lpcfg_add_service(struct loadparm_context *lp_ctx,
588                                            const struct loadparm_service *pservice,
589                                            const char *name)
590 {
591         int i;
592         int num_to_alloc = lp_ctx->iNumServices + 1;
593         struct parmlist_entry *data, *pdata;
594
595         if (pservice == NULL) {
596                 pservice = lp_ctx->sDefault;
597         }
598
599         /* it might already exist */
600         if (name) {
601                 struct loadparm_service *service = lpcfg_getservicebyname(lp_ctx,
602                                                                     name);
603                 if (service != NULL) {
604                         /* Clean all parametric options for service */
605                         /* They will be added during parsing again */
606                         data = service->param_opt;
607                         while (data) {
608                                 pdata = data->next;
609                                 talloc_free(data);
610                                 data = pdata;
611                         }
612                         service->param_opt = NULL;
613                         return service;
614                 }
615         }
616
617         /* find an invalid one */
618         for (i = 0; i < lp_ctx->iNumServices; i++)
619                 if (lp_ctx->services[i] == NULL)
620                         break;
621
622         /* if not, then create one */
623         if (i == lp_ctx->iNumServices) {
624                 struct loadparm_service **tsp;
625
626                 tsp = talloc_realloc(lp_ctx, lp_ctx->services, struct loadparm_service *, num_to_alloc);
627
628                 if (!tsp) {
629                         DEBUG(0,("lpcfg_add_service: failed to enlarge services!\n"));
630                         return NULL;
631                 } else {
632                         lp_ctx->services = tsp;
633                         lp_ctx->services[lp_ctx->iNumServices] = NULL;
634                 }
635
636                 lp_ctx->iNumServices++;
637         }
638
639         lp_ctx->services[i] = talloc_zero(lp_ctx->services, struct loadparm_service);
640         if (lp_ctx->services[i] == NULL) {
641                 DEBUG(0,("lpcfg_add_service: out of memory!\n"));
642                 return NULL;
643         }
644         copy_service(lp_ctx->services[i], pservice, NULL);
645         if (name != NULL)
646                 lpcfg_string_set(lp_ctx->services[i], &lp_ctx->services[i]->szService, name);
647         return lp_ctx->services[i];
648 }
649
650 /**
651  * Add a new home service, with the specified home directory, defaults coming
652  * from service ifrom.
653  */
654
655 bool lpcfg_add_home(struct loadparm_context *lp_ctx,
656                  const char *pszHomename,
657                  struct loadparm_service *default_service,
658                  const char *user, const char *pszHomedir)
659 {
660         struct loadparm_service *service;
661
662         service = lpcfg_add_service(lp_ctx, default_service, pszHomename);
663
664         if (service == NULL)
665                 return false;
666
667         if (!(*(default_service->path))
668             || strequal(default_service->path, lp_ctx->sDefault->path)) {
669                 service->path = talloc_strdup(service, pszHomedir);
670         } else {
671                 service->path = string_sub_talloc(service, lpcfg_path(default_service, lp_ctx->sDefault, service), "%H", pszHomedir);
672         }
673
674         if (!(*(service->comment))) {
675                 service->comment = talloc_asprintf(service, "Home directory of %s", user);
676         }
677         service->bAvailable = default_service->bAvailable;
678         service->browseable = default_service->browseable;
679
680         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n",
681                   pszHomename, user, service->path));
682
683         return true;
684 }
685
686 /**
687  * Add a new printer service, with defaults coming from service iFrom.
688  */
689
690 bool lpcfg_add_printer(struct loadparm_context *lp_ctx,
691                        const char *pszPrintername,
692                        struct loadparm_service *default_service)
693 {
694         const char *comment = "From Printcap";
695         struct loadparm_service *service;
696         service = lpcfg_add_service(lp_ctx, default_service, pszPrintername);
697
698         if (service == NULL)
699                 return false;
700
701         /* note that we do NOT default the availability flag to True - */
702         /* we take it from the default service passed. This allows all */
703         /* dynamic printers to be disabled by disabling the [printers] */
704         /* entry (if/when the 'available' keyword is implemented!).    */
705
706         /* the printer name is set to the service name. */
707         lpcfg_string_set(service, &service->_printername, pszPrintername);
708         lpcfg_string_set(service, &service->comment, comment);
709         service->browseable = default_service->browseable;
710         /* Printers cannot be read_only. */
711         service->read_only = false;
712         /* Printer services must be printable. */
713         service->printable = true;
714
715         DEBUG(3, ("adding printer service %s\n", pszPrintername));
716
717         return true;
718 }
719
720 /**
721  * Map a parameter's string representation to something we can use.
722  * Returns False if the parameter string is not recognised, else TRUE.
723  */
724
725 int lpcfg_map_parameter(const char *pszParmName)
726 {
727         int iIndex;
728
729         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
730                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
731                         return iIndex;
732
733         /* Warn only if it isn't parametric option */
734         if (strchr(pszParmName, ':') == NULL)
735                 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
736         /* We do return 'fail' for parametric options as well because they are
737            stored in different storage
738          */
739         return -1;
740 }
741
742
743 /**
744   return the parameter structure for a parameter
745 */
746 struct parm_struct *lpcfg_parm_struct(struct loadparm_context *lp_ctx, const char *name)
747 {
748         int parmnum;
749
750         if (lp_ctx->s3_fns) {
751                 return lp_ctx->s3_fns->get_parm_struct(name);
752         }
753
754         parmnum = lpcfg_map_parameter(name);
755         if (parmnum == -1) return NULL;
756         return &parm_table[parmnum];
757 }
758
759 /**
760   return the parameter pointer for a parameter
761 */
762 void *lpcfg_parm_ptr(struct loadparm_context *lp_ctx,
763                   struct loadparm_service *service, struct parm_struct *parm)
764 {
765         if (lp_ctx->s3_fns) {
766                 return lp_ctx->s3_fns->get_parm_ptr(service, parm);
767         }
768
769         if (service == NULL) {
770                 if (parm->p_class == P_LOCAL)
771                         return ((char *)lp_ctx->sDefault)+parm->offset;
772                 else if (parm->p_class == P_GLOBAL)
773                         return ((char *)lp_ctx->globals)+parm->offset;
774                 else return NULL;
775         } else {
776                 return ((char *)service) + parm->offset;
777         }
778 }
779
780 /**
781   return the parameter pointer for a parameter
782 */
783 bool lpcfg_parm_is_cmdline(struct loadparm_context *lp_ctx, const char *name)
784 {
785         int parmnum;
786
787         if (lp_ctx->s3_fns) {
788                 struct parm_struct *parm = lp_ctx->s3_fns->get_parm_struct(name);
789                 if (parm) {
790                         return parm->flags & FLAG_CMDLINE;
791                 }
792                 return false;
793         }
794
795         parmnum = lpcfg_map_parameter(name);
796         if (parmnum == -1) return false;
797
798         return lp_ctx->flags[parmnum] & FLAG_CMDLINE;
799 }
800
801 /**
802  * Find a service by name. Otherwise works like get_service.
803  */
804
805 static struct loadparm_service *lpcfg_getservicebyname(struct loadparm_context *lp_ctx,
806                                         const char *pszServiceName)
807 {
808         int iService;
809
810         if (lp_ctx->s3_fns) {
811                 return lp_ctx->s3_fns->get_service(pszServiceName);
812         }
813
814         for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--)
815                 if (lp_ctx->services[iService] != NULL &&
816                     strwicmp(lp_ctx->services[iService]->szService, pszServiceName) == 0) {
817                         return lp_ctx->services[iService];
818                 }
819
820         return NULL;
821 }
822
823 /**
824  * Add a parametric option to a parmlist_entry,
825  * replacing old value, if already present.
826  */
827 void set_param_opt(TALLOC_CTX *mem_ctx,
828                    struct parmlist_entry **opt_list,
829                    const char *opt_name,
830                    const char *opt_value,
831                    unsigned priority)
832 {
833         struct parmlist_entry *new_opt, *opt;
834         bool not_added;
835
836         opt = *opt_list;
837         not_added = true;
838
839         /* Traverse destination */
840         while (opt) {
841                 /* If we already have same option, override it */
842                 if (strwicmp(opt->key, opt_name) == 0) {
843                         if ((opt->priority & FLAG_CMDLINE) &&
844                             !(priority & FLAG_CMDLINE)) {
845                                 /* it's been marked as not to be
846                                    overridden */
847                                 return;
848                         }
849                         TALLOC_FREE(opt->value);
850                         TALLOC_FREE(opt->list);
851                         opt->value = talloc_strdup(opt, opt_value);
852                         opt->priority = priority;
853                         not_added = false;
854                         break;
855                 }
856                 opt = opt->next;
857         }
858         if (not_added) {
859                 new_opt = talloc(mem_ctx, struct parmlist_entry);
860                 if (new_opt == NULL) {
861                         smb_panic("OOM");
862                 }
863
864                 new_opt->key = talloc_strdup(new_opt, opt_name);
865                 if (new_opt->key == NULL) {
866                         smb_panic("talloc_strdup failed");
867                 }
868
869                 new_opt->value = talloc_strdup(new_opt, opt_value);
870                 if (new_opt->value == NULL) {
871                         smb_panic("talloc_strdup failed");
872                 }
873
874                 new_opt->list = NULL;
875                 new_opt->priority = priority;
876                 DLIST_ADD(*opt_list, new_opt);
877         }
878 }
879
880 /**
881  * Copy a service structure to another.
882  * If pcopymapDest is NULL then copy all fields
883  */
884
885 void copy_service(struct loadparm_service *pserviceDest,
886                   const struct loadparm_service *pserviceSource,
887                   struct bitmap *pcopymapDest)
888 {
889         int i;
890         bool bcopyall = (pcopymapDest == NULL);
891         struct parmlist_entry *data;
892
893         for (i = 0; parm_table[i].label; i++)
894                 if (parm_table[i].p_class == P_LOCAL &&
895                     (bcopyall || bitmap_query(pcopymapDest, i))) {
896                         const void *src_ptr =
897                                 ((const char *)pserviceSource) + parm_table[i].offset;
898                         void *dest_ptr =
899                                 ((char *)pserviceDest) + parm_table[i].offset;
900
901                         switch (parm_table[i].type) {
902                                 case P_BOOL:
903                                 case P_BOOLREV:
904                                         *(bool *)dest_ptr = *(const bool *)src_ptr;
905                                         break;
906
907                                 case P_INTEGER:
908                                 case P_BYTES:
909                                 case P_OCTAL:
910                                 case P_ENUM:
911                                         *(int *)dest_ptr = *(const int *)src_ptr;
912                                         break;
913
914                                 case P_CHAR:
915                                         *(char *)dest_ptr = *(const char *)src_ptr;
916                                         break;
917
918                                 case P_STRING:
919                                         lpcfg_string_set(pserviceDest,
920                                                    (char **)dest_ptr,
921                                                    *(const char * const *)src_ptr);
922                                         break;
923
924                                 case P_USTRING:
925                                         lpcfg_string_set_upper(pserviceDest,
926                                                          (char **)dest_ptr,
927                                                          *(const char * const *)src_ptr);
928                                         break;
929                                 case P_LIST:
930                                         TALLOC_FREE(*((char ***)dest_ptr));
931                                         *(const char * const **)dest_ptr = (const char * const *)str_list_copy(pserviceDest,
932                                                                                   *(const char * * const *)src_ptr);
933                                         break;
934                                 default:
935                                         break;
936                         }
937                 }
938
939         if (bcopyall) {
940                 init_copymap(pserviceDest);
941                 if (pserviceSource->copymap)
942                         bitmap_copy(pserviceDest->copymap,
943                                     pserviceSource->copymap);
944         }
945
946         for (data = pserviceSource->param_opt; data != NULL; data = data->next) {
947                 set_param_opt(pserviceDest, &pserviceDest->param_opt,
948                               data->key, data->value, data->priority);
949         }
950 }
951
952 /**
953  * Check a service for consistency. Return False if the service is in any way
954  * incomplete or faulty, else True.
955  */
956 static bool lpcfg_service_ok(struct loadparm_service *service)
957 {
958         bool bRetval;
959
960         bRetval = true;
961         if (service->szService[0] == '\0') {
962                 DEBUG(0, ("The following message indicates an internal error:\n"));
963                 DEBUG(0, ("No service name in service entry.\n"));
964                 bRetval = false;
965         }
966
967         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
968         /* I can't see why you'd want a non-printable printer service...        */
969         if (strwicmp(service->szService, PRINTERS_NAME) == 0) {
970                 if (!service->printable) {
971                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
972                                service->szService));
973                         service->printable = true;
974                 }
975                 /* [printers] service must also be non-browsable. */
976                 if (service->browseable)
977                         service->browseable = false;
978         }
979
980         /* If a service is flagged unavailable, log the fact at level 0. */
981         if (!service->bAvailable)
982                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
983                           service->szService));
984
985         return bRetval;
986 }
987
988
989 /*******************************************************************
990  Keep a linked list of all config files so we know when one has changed
991  it's date and needs to be reloaded.
992 ********************************************************************/
993
994 void add_to_file_list(TALLOC_CTX *mem_ctx, struct file_lists **list,
995                              const char *fname, const char *subfname)
996 {
997         struct file_lists *f = *list;
998
999         while (f) {
1000                 if (f->name && !strcmp(f->name, fname))
1001                         break;
1002                 f = f->next;
1003         }
1004
1005         if (!f) {
1006                 f = talloc(mem_ctx, struct file_lists);
1007                 if (!f)
1008                         goto fail;
1009                 f->next = *list;
1010                 f->name = talloc_strdup(f, fname);
1011                 if (!f->name) {
1012                         TALLOC_FREE(f);
1013                         goto fail;
1014                 }
1015                 f->subfname = talloc_strdup(f, subfname);
1016                 if (!f->subfname) {
1017                         TALLOC_FREE(f);
1018                         goto fail;
1019                 }
1020                 *list = f;
1021                 f->modtime = file_modtime(subfname);
1022         } else {
1023                 time_t t = file_modtime(subfname);
1024                 if (t)
1025                         f->modtime = t;
1026         }
1027         return;
1028
1029 fail:
1030         DEBUG(0, ("Unable to add file to file list: %s\n", fname));
1031
1032 }
1033
1034 /*******************************************************************
1035  Check if a config file has changed date.
1036 ********************************************************************/
1037 bool lpcfg_file_list_changed(struct loadparm_context *lp_ctx)
1038 {
1039         struct file_lists *f;
1040         DEBUG(6, ("lpcfg_file_list_changed()\n"));
1041
1042         for (f = lp_ctx->file_lists; f != NULL; f = f->next) {
1043                 char *n2;
1044                 time_t mod_time;
1045
1046                 n2 = standard_sub_basic(lp_ctx, f->name);
1047
1048                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
1049                              f->name, n2, ctime(&f->modtime)));
1050
1051                 mod_time = file_modtime(n2);
1052
1053                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1054                         DEBUGADD(6, ("file %s modified: %s\n", n2,
1055                                   ctime(&mod_time)));
1056                         f->modtime = mod_time;
1057                         talloc_free(f->subfname);
1058                         f->subfname = talloc_strdup(f, n2);
1059                         return true;
1060                 }
1061         }
1062         return false;
1063 }
1064
1065 /*
1066  * set the value for a P_ENUM
1067  */
1068 bool lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
1069                               int *ptr )
1070 {
1071         int i;
1072
1073         for (i = 0; parm->enum_list[i].name; i++) {
1074                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
1075                         *ptr = parm->enum_list[i].value;
1076                         return true;
1077                 }
1078         }
1079         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
1080                   pszParmValue, parm->label));
1081         return false;
1082 }
1083
1084
1085 /***************************************************************************
1086  Handle the "realm" parameter
1087 ***************************************************************************/
1088
1089 bool handle_realm(struct loadparm_context *lp_ctx, int unused,
1090                   const char *pszParmValue, char **ptr)
1091 {
1092         char *upper;
1093         char *lower;
1094
1095         upper = strupper_talloc(lp_ctx, pszParmValue);
1096         if (upper == NULL) {
1097                 return false;
1098         }
1099
1100         lower = strlower_talloc(lp_ctx, pszParmValue);
1101         if (lower == NULL) {
1102                 TALLOC_FREE(upper);
1103                 return false;
1104         }
1105
1106         if (lp_ctx->s3_fns != NULL) {
1107                 lp_ctx->s3_fns->lp_string_set(ptr, pszParmValue);
1108                 lp_ctx->s3_fns->lp_string_set(&lp_ctx->globals->realm, upper);
1109                 lp_ctx->s3_fns->lp_string_set(&lp_ctx->globals->dnsdomain, lower);
1110         } else {
1111                 lpcfg_string_set(lp_ctx, ptr, pszParmValue);
1112                 lpcfg_string_set(lp_ctx, &lp_ctx->globals->realm, upper);
1113                 lpcfg_string_set(lp_ctx, &lp_ctx->globals->dnsdomain, lower);
1114         }
1115
1116         return true;
1117 }
1118
1119 /***************************************************************************
1120  Handle the include operation.
1121 ***************************************************************************/
1122
1123 bool handle_include(struct loadparm_context *lp_ctx, int unused,
1124                            const char *pszParmValue, char **ptr)
1125 {
1126         char *fname;
1127
1128         if (lp_ctx->s3_fns) {
1129                 return lp_ctx->s3_fns->lp_include(lp_ctx, unused, pszParmValue, ptr);
1130         }
1131
1132         fname = standard_sub_basic(lp_ctx, pszParmValue);
1133
1134         add_to_file_list(lp_ctx, &lp_ctx->file_lists, pszParmValue, fname);
1135
1136         lpcfg_string_set(lp_ctx, ptr, fname);
1137
1138         if (file_exist(fname))
1139                 return pm_process(fname, do_section, do_parameter, lp_ctx);
1140
1141         DEBUG(2, ("Can't find include file %s\n", fname));
1142
1143         return false;
1144 }
1145
1146 /***************************************************************************
1147  Handle the interpretation of the copy parameter.
1148 ***************************************************************************/
1149
1150 bool handle_copy(struct loadparm_context *lp_ctx, int snum,
1151                         const char *pszParmValue, char **ptr)
1152 {
1153         bool bRetval;
1154         struct loadparm_service *serviceTemp = NULL;
1155         struct loadparm_service *current = NULL;
1156
1157         bRetval = false;
1158
1159         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
1160
1161         serviceTemp = lpcfg_getservicebyname(lp_ctx, pszParmValue);
1162         if (lp_ctx->s3_fns != NULL) {
1163                 current = lp_ctx->s3_fns->get_servicebynum(snum);
1164         } else {
1165                 current = lp_ctx->currentService;
1166         }
1167
1168         if (current == NULL) {
1169                 DEBUG(0, ("Unable to copy service - invalid service destination"));
1170                 return false;
1171         }
1172
1173         if (serviceTemp != NULL) {
1174                 if (serviceTemp == current) {
1175                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
1176                 } else {
1177                         copy_service(current,
1178                                      serviceTemp,
1179                                      current->copymap);
1180                         lpcfg_string_set(current, ptr, pszParmValue);
1181
1182                         bRetval = true;
1183                 }
1184         } else {
1185                 DEBUG(0, ("Unable to copy service - source not found: %s\n",
1186                           pszParmValue));
1187                 bRetval = false;
1188         }
1189
1190         return bRetval;
1191 }
1192
1193 bool handle_debug_list(struct loadparm_context *lp_ctx, int unused,
1194                         const char *pszParmValue, char **ptr)
1195 {
1196         if (lp_ctx->s3_fns != NULL) {
1197                 lp_ctx->s3_fns->lp_string_set(ptr, pszParmValue);
1198         } else {
1199                 lpcfg_string_set(lp_ctx, ptr, pszParmValue);
1200         }
1201
1202         return debug_parse_levels(pszParmValue);
1203 }
1204
1205 bool handle_logfile(struct loadparm_context *lp_ctx, int unused,
1206                     const char *pszParmValue, char **ptr)
1207 {
1208         if (lp_ctx->s3_fns != NULL) {
1209                 lp_ctx->s3_fns->lp_string_set(ptr, pszParmValue);
1210         } else {
1211                 debug_set_logfile(pszParmValue);
1212                 lpcfg_string_set(lp_ctx, ptr, pszParmValue);
1213         }
1214
1215         return true;
1216 }
1217
1218 /*
1219  * These special charset handling methods only run in the source3 code.
1220  */
1221
1222 bool handle_charset(struct loadparm_context *lp_ctx, int snum,
1223                         const char *pszParmValue, char **ptr)
1224 {
1225         if (lp_ctx->s3_fns) {
1226                 if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
1227                         lp_ctx->s3_fns->lp_string_set(ptr, pszParmValue);
1228                         global_iconv_handle = smb_iconv_handle_reinit(NULL,
1229                                                         lpcfg_dos_charset(lp_ctx),
1230                                                         lpcfg_unix_charset(lp_ctx),
1231                                                         true, global_iconv_handle);
1232                 }
1233
1234                 return true;
1235         }
1236         return lpcfg_string_set(lp_ctx, ptr, pszParmValue);
1237
1238 }
1239
1240 bool handle_dos_charset(struct loadparm_context *lp_ctx, int snum,
1241                         const char *pszParmValue, char **ptr)
1242 {
1243         bool is_utf8 = false;
1244         size_t len = strlen(pszParmValue);
1245
1246         if (lp_ctx->s3_fns) {
1247                 if (len == 4 || len == 5) {
1248                         /* Don't use StrCaseCmp here as we don't want to
1249                            initialize iconv. */
1250                         if ((toupper_m(pszParmValue[0]) == 'U') &&
1251                             (toupper_m(pszParmValue[1]) == 'T') &&
1252                             (toupper_m(pszParmValue[2]) == 'F')) {
1253                                 if (len == 4) {
1254                                         if (pszParmValue[3] == '8') {
1255                                                 is_utf8 = true;
1256                                         }
1257                                 } else {
1258                                         if (pszParmValue[3] == '-' &&
1259                                             pszParmValue[4] == '8') {
1260                                                 is_utf8 = true;
1261                                         }
1262                                 }
1263                         }
1264                 }
1265
1266                 if (*ptr == NULL || strcmp(*ptr, pszParmValue) != 0) {
1267                         if (is_utf8) {
1268                                 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
1269                                         "be UTF8, using (default value) %s instead.\n",
1270                                         DEFAULT_DOS_CHARSET));
1271                                 pszParmValue = DEFAULT_DOS_CHARSET;
1272                         }
1273                         lp_ctx->s3_fns->lp_string_set(ptr, pszParmValue);
1274                         global_iconv_handle = smb_iconv_handle_reinit(NULL,
1275                                                         lpcfg_dos_charset(lp_ctx),
1276                                                         lpcfg_unix_charset(lp_ctx),
1277                                                         true, global_iconv_handle);
1278                 }
1279                 return true;
1280         }
1281
1282         return lpcfg_string_set(lp_ctx, ptr, pszParmValue);
1283 }
1284
1285 /***************************************************************************
1286  Initialise a copymap.
1287 ***************************************************************************/
1288
1289 void init_copymap(struct loadparm_service *pservice)
1290 {
1291         int i;
1292
1293         TALLOC_FREE(pservice->copymap);
1294
1295         pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
1296         if (!pservice->copymap)
1297                 DEBUG(0,
1298                       ("Couldn't allocate copymap!! (size %d)\n",
1299                        (int)NUMPARAMETERS));
1300         else
1301                 for (i = 0; i < NUMPARAMETERS; i++)
1302                         bitmap_set(pservice->copymap, i);
1303 }
1304
1305 /**
1306  * Process a parametric option
1307  */
1308 static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx,
1309                                        struct loadparm_service *service,
1310                                        const char *pszParmName,
1311                                        const char *pszParmValue, int flags)
1312 {
1313         struct parmlist_entry *paramo, *data;
1314         char *name;
1315         TALLOC_CTX *mem_ctx;
1316
1317         while (isspace((unsigned char)*pszParmName)) {
1318                 pszParmName++;
1319         }
1320
1321         name = strlower_talloc(lp_ctx, pszParmName);
1322         if (!name) return false;
1323
1324         if (service == NULL) {
1325                 data = lp_ctx->globals->param_opt;
1326                 mem_ctx = lp_ctx->globals;
1327         } else {
1328                 data = service->param_opt;
1329                 mem_ctx = service;
1330         }
1331
1332         /* Traverse destination */
1333         for (paramo=data; paramo; paramo=paramo->next) {
1334                 /* If we already have the option set, override it unless
1335                    it was a command line option and the new one isn't */
1336                 if (strcmp(paramo->key, name) == 0) {
1337                         if ((paramo->priority & FLAG_CMDLINE) &&
1338                             !(flags & FLAG_CMDLINE)) {
1339                                 talloc_free(name);
1340                                 return true;
1341                         }
1342
1343                         talloc_free(paramo->value);
1344                         paramo->value = talloc_strdup(paramo, pszParmValue);
1345                         paramo->priority = flags;
1346                         talloc_free(name);
1347                         return true;
1348                 }
1349         }
1350
1351         paramo = talloc_zero(mem_ctx, struct parmlist_entry);
1352         if (!paramo)
1353                 smb_panic("OOM");
1354         paramo->key = talloc_strdup(paramo, name);
1355         paramo->value = talloc_strdup(paramo, pszParmValue);
1356         paramo->priority = flags;
1357         if (service == NULL) {
1358                 DLIST_ADD(lp_ctx->globals->param_opt, paramo);
1359         } else {
1360                 DLIST_ADD(service->param_opt, paramo);
1361         }
1362
1363         talloc_free(name);
1364
1365         return true;
1366 }
1367
1368 static bool set_variable(TALLOC_CTX *mem_ctx, int parmnum, void *parm_ptr,
1369                          const char *pszParmName, const char *pszParmValue,
1370                          struct loadparm_context *lp_ctx, bool on_globals)
1371 {
1372         int i;
1373         /* if it is a special case then go ahead */
1374         if (parm_table[parmnum].special) {
1375                 bool ret;
1376                 ret = parm_table[parmnum].special(lp_ctx, -1, pszParmValue,
1377                                                   (char **)parm_ptr);
1378                 if (!ret) {
1379                         return false;
1380                 }
1381                 goto mark_non_default;
1382         }
1383
1384         /* now switch on the type of variable it is */
1385         switch (parm_table[parmnum].type)
1386         {
1387                 case P_BOOL: {
1388                         bool b;
1389                         if (!set_boolean(pszParmValue, &b)) {
1390                                 DEBUG(0, ("set_variable(%s): value is not "
1391                                           "boolean!\n", pszParmValue));
1392                                 return false;
1393                         }
1394                         *(bool *)parm_ptr = b;
1395                         }
1396                         break;
1397
1398                 case P_BOOLREV: {
1399                         bool b;
1400                         if (!set_boolean(pszParmValue, &b)) {
1401                                 DEBUG(0, ("set_variable(%s): value is not "
1402                                           "boolean!\n", pszParmValue));
1403                                 return false;
1404                         }
1405                         *(bool *)parm_ptr = !b;
1406                         }
1407                         break;
1408
1409                 case P_INTEGER:
1410                         *(int *)parm_ptr = atoi(pszParmValue);
1411                         break;
1412
1413                 case P_CHAR:
1414                         *(char *)parm_ptr = *pszParmValue;
1415                         break;
1416
1417                 case P_OCTAL:
1418                         *(int *)parm_ptr = strtol(pszParmValue, NULL, 8);
1419                         break;
1420
1421                 case P_BYTES:
1422                 {
1423                         uint64_t val;
1424                         if (conv_str_size_error(pszParmValue, &val)) {
1425                                 if (val <= INT_MAX) {
1426                                         *(int *)parm_ptr = (int)val;
1427                                         break;
1428                                 }
1429                         }
1430
1431                         DEBUG(0, ("set_variable(%s): value is not "
1432                                   "a valid size specifier!\n", pszParmValue));
1433                         return false;
1434                 }
1435
1436                 case P_CMDLIST:
1437                         *(const char * const **)parm_ptr
1438                                 = (const char * const *)str_list_make(mem_ctx,
1439                                                                       pszParmValue, NULL);
1440                         break;
1441                 case P_LIST:
1442                 {
1443                         char **new_list = str_list_make(mem_ctx,
1444                                                         pszParmValue, NULL);
1445                         for (i=0; new_list[i]; i++) {
1446                                 if (*(const char ***)parm_ptr != NULL &&
1447                                     new_list[i][0] == '+' &&
1448                                     new_list[i][1])
1449                                 {
1450                                         if (!str_list_check(*(const char ***)parm_ptr,
1451                                                             &new_list[i][1])) {
1452                                                 *(const char ***)parm_ptr = str_list_add(*(const char ***)parm_ptr,
1453                                                                                          &new_list[i][1]);
1454                                         }
1455                                 } else if (*(const char ***)parm_ptr != NULL &&
1456                                            new_list[i][0] == '-' &&
1457                                            new_list[i][1])
1458                                 {
1459                                         str_list_remove(*(const char ***)parm_ptr,
1460                                                         &new_list[i][1]);
1461                                 } else {
1462                                         if (i != 0) {
1463                                                 DEBUG(0, ("Unsupported list syntax for: %s = %s\n",
1464                                                           pszParmName, pszParmValue));
1465                                                 return false;
1466                                         }
1467                                         *(const char * const **)parm_ptr = (const char * const *) new_list;
1468                                         break;
1469                                 }
1470                         }
1471                         break;
1472                 }
1473                 case P_STRING:
1474                         lpcfg_string_set(mem_ctx, (char **)parm_ptr, pszParmValue);
1475                         break;
1476
1477                 case P_USTRING:
1478                         lpcfg_string_set_upper(mem_ctx, (char **)parm_ptr, pszParmValue);
1479                         break;
1480
1481                 case P_ENUM:
1482                         if (!lp_set_enum_parm(&parm_table[parmnum], pszParmValue, (int*)parm_ptr)) {
1483                                 return false;
1484                         }
1485                         break;
1486
1487                 case P_SEP:
1488                         break;
1489         }
1490
1491 mark_non_default:
1492         if (on_globals && (lp_ctx->flags[parmnum] & FLAG_DEFAULT)) {
1493                 lp_ctx->flags[parmnum] &= ~FLAG_DEFAULT;
1494                 /* we have to also unset FLAG_DEFAULT on aliases */
1495                 for (i=parmnum-1;i>=0 && parm_table[i].offset == parm_table[parmnum].offset;i--) {
1496                         lp_ctx->flags[i] &= ~FLAG_DEFAULT;
1497                 }
1498                 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].offset == parm_table[parmnum].offset;i++) {
1499                         lp_ctx->flags[i] &= ~FLAG_DEFAULT;
1500                 }
1501         }
1502         return true;
1503 }
1504
1505
1506 bool lpcfg_do_global_parameter(struct loadparm_context *lp_ctx,
1507                                const char *pszParmName, const char *pszParmValue)
1508 {
1509         int parmnum = lpcfg_map_parameter(pszParmName);
1510         void *parm_ptr;
1511
1512         if (parmnum < 0) {
1513                 if (strchr(pszParmName, ':')) {
1514                         return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName, pszParmValue, 0);
1515                 }
1516                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1517                 return true;
1518         }
1519
1520         /* if the flag has been set on the command line, then don't allow override,
1521            but don't report an error */
1522         if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) {
1523                 return true;
1524         }
1525
1526         parm_ptr = lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[parmnum]);
1527
1528         return set_variable(lp_ctx->globals, parmnum, parm_ptr,
1529                             pszParmName, pszParmValue, lp_ctx, true);
1530 }
1531
1532 bool lpcfg_do_service_parameter(struct loadparm_context *lp_ctx,
1533                                 struct loadparm_service *service,
1534                                 const char *pszParmName, const char *pszParmValue)
1535 {
1536         void *parm_ptr;
1537         int i;
1538         int parmnum = lpcfg_map_parameter(pszParmName);
1539
1540         if (parmnum < 0) {
1541                 if (strchr(pszParmName, ':')) {
1542                         return lp_do_parameter_parametric(lp_ctx, service, pszParmName, pszParmValue, 0);
1543                 }
1544                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1545                 return true;
1546         }
1547
1548         /* if the flag has been set on the command line, then don't allow override,
1549            but don't report an error */
1550         if (lp_ctx->flags[parmnum] & FLAG_CMDLINE) {
1551                 return true;
1552         }
1553
1554         if (parm_table[parmnum].p_class == P_GLOBAL) {
1555                 DEBUG(0,
1556                       ("Global parameter %s found in service section!\n",
1557                        pszParmName));
1558                 return true;
1559         }
1560         parm_ptr = ((char *)service) + parm_table[parmnum].offset;
1561
1562         if (!service->copymap)
1563                 init_copymap(service);
1564
1565         /* this handles the aliases - set the copymap for other
1566          * entries with the same data pointer */
1567         for (i = 0; parm_table[i].label; i++)
1568                 if (parm_table[i].offset == parm_table[parmnum].offset &&
1569                     parm_table[i].p_class == parm_table[parmnum].p_class)
1570                         bitmap_clear(service->copymap, i);
1571
1572         return set_variable(service, parmnum, parm_ptr, pszParmName,
1573                             pszParmValue, lp_ctx, false);
1574 }
1575
1576 /**
1577  * Process a parameter.
1578  */
1579
1580 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1581                          void *userdata)
1582 {
1583         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
1584
1585         if (lp_ctx->bInGlobalSection)
1586                 return lpcfg_do_global_parameter(lp_ctx, pszParmName,
1587                                               pszParmValue);
1588         else
1589                 return lpcfg_do_service_parameter(lp_ctx, lp_ctx->currentService,
1590                                                   pszParmName, pszParmValue);
1591 }
1592
1593 /*
1594   variable argument do parameter
1595 */
1596 bool lpcfg_do_global_parameter_var(struct loadparm_context *lp_ctx, const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(3, 4);
1597 bool lpcfg_do_global_parameter_var(struct loadparm_context *lp_ctx,
1598                                 const char *pszParmName, const char *fmt, ...)
1599 {
1600         char *s;
1601         bool ret;
1602         va_list ap;
1603
1604         va_start(ap, fmt);
1605         s = talloc_vasprintf(NULL, fmt, ap);
1606         va_end(ap);
1607         ret = lpcfg_do_global_parameter(lp_ctx, pszParmName, s);
1608         talloc_free(s);
1609         return ret;
1610 }
1611
1612
1613 /*
1614   set a parameter from the commandline - this is called from command line parameter
1615   parsing code. It sets the parameter then marks the parameter as unable to be modified
1616   by smb.conf processing
1617 */
1618 bool lpcfg_set_cmdline(struct loadparm_context *lp_ctx, const char *pszParmName,
1619                        const char *pszParmValue)
1620 {
1621         int parmnum;
1622         int i;
1623
1624         while (isspace((unsigned char)*pszParmValue)) pszParmValue++;
1625
1626         if (lp_ctx->s3_fns) {
1627                 return lp_ctx->s3_fns->set_cmdline(pszParmName, pszParmValue);
1628         }
1629
1630         parmnum = lpcfg_map_parameter(pszParmName);
1631
1632         if (parmnum < 0 && strchr(pszParmName, ':')) {
1633                 /* set a parametric option */
1634                 return lp_do_parameter_parametric(lp_ctx, NULL, pszParmName,
1635                                                   pszParmValue, FLAG_CMDLINE);
1636         }
1637
1638         if (parmnum < 0) {
1639                 DEBUG(0,("Unknown option '%s'\n", pszParmName));
1640                 return false;
1641         }
1642
1643         /* reset the CMDLINE flag in case this has been called before */
1644         lp_ctx->flags[parmnum] &= ~FLAG_CMDLINE;
1645
1646         if (!lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue)) {
1647                 return false;
1648         }
1649
1650         lp_ctx->flags[parmnum] |= FLAG_CMDLINE;
1651
1652         /* we have to also set FLAG_CMDLINE on aliases */
1653         for (i=parmnum-1;
1654              i>=0 && parm_table[i].p_class == parm_table[parmnum].p_class &&
1655              parm_table[i].offset == parm_table[parmnum].offset;
1656              i--) {
1657                 lp_ctx->flags[i] |= FLAG_CMDLINE;
1658         }
1659         for (i=parmnum+1;
1660              i<NUMPARAMETERS &&
1661              parm_table[i].p_class == parm_table[parmnum].p_class &&
1662              parm_table[i].offset == parm_table[parmnum].offset;
1663              i++) {
1664                 lp_ctx->flags[i] |= FLAG_CMDLINE;
1665         }
1666
1667         return true;
1668 }
1669
1670 /*
1671   set a option from the commandline in 'a=b' format. Use to support --option
1672 */
1673 bool lpcfg_set_option(struct loadparm_context *lp_ctx, const char *option)
1674 {
1675         char *p, *s;
1676         bool ret;
1677
1678         s = talloc_strdup(NULL, option);
1679         if (!s) {
1680                 return false;
1681         }
1682
1683         p = strchr(s, '=');
1684         if (!p) {
1685                 talloc_free(s);
1686                 return false;
1687         }
1688
1689         *p = 0;
1690
1691         ret = lpcfg_set_cmdline(lp_ctx, s, p+1);
1692         talloc_free(s);
1693         return ret;
1694 }
1695
1696
1697 #define BOOLSTR(b) ((b) ? "Yes" : "No")
1698
1699 /**
1700  * Print a parameter of the specified type.
1701  */
1702
1703 void lpcfg_print_parameter(struct parm_struct *p, void *ptr, FILE * f)
1704 {
1705         /* For the seperation of lists values that we print below */
1706         const char *list_sep = ", ";
1707         int i;
1708         switch (p->type)
1709         {
1710                 case P_ENUM:
1711                         for (i = 0; p->enum_list[i].name; i++) {
1712                                 if (*(int *)ptr == p->enum_list[i].value) {
1713                                         fprintf(f, "%s",
1714                                                 p->enum_list[i].name);
1715                                         break;
1716                                 }
1717                         }
1718                         break;
1719
1720                 case P_BOOL:
1721                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
1722                         break;
1723
1724                 case P_BOOLREV:
1725                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
1726                         break;
1727
1728                 case P_INTEGER:
1729                 case P_BYTES:
1730                         fprintf(f, "%d", *(int *)ptr);
1731                         break;
1732
1733                 case P_CHAR:
1734                         fprintf(f, "%c", *(char *)ptr);
1735                         break;
1736
1737                 case P_OCTAL: {
1738                         int val = *(int *)ptr; 
1739                         if (val == -1) {
1740                                 fprintf(f, "-1");
1741                         } else {
1742                                 fprintf(f, "0%03o", val);
1743                         }
1744                         break;
1745                 }
1746
1747                 case P_CMDLIST:
1748                         list_sep = " ";
1749                         /* fall through */
1750                 case P_LIST:
1751                         if ((char ***)ptr && *(char ***)ptr) {
1752                                 char **list = *(char ***)ptr;
1753                                 for (; *list; list++) {
1754                                         /* surround strings with whitespace in double quotes */
1755                                         if (*(list+1) == NULL) {
1756                                                 /* last item, no extra separator */
1757                                                 list_sep = "";
1758                                         }
1759                                         if ( strchr_m( *list, ' ' ) ) {
1760                                                 fprintf(f, "\"%s\"%s", *list, list_sep);
1761                                         } else {
1762                                                 fprintf(f, "%s%s", *list, list_sep);
1763                                         }
1764                                 }
1765                         }
1766                         break;
1767
1768                 case P_STRING:
1769                 case P_USTRING:
1770                         if (*(char **)ptr) {
1771                                 fprintf(f, "%s", *(char **)ptr);
1772                         }
1773                         break;
1774                 case P_SEP:
1775                         break;
1776         }
1777 }
1778
1779 /**
1780  * Check if two parameters are equal.
1781  */
1782
1783  bool lpcfg_equal_parameter(parm_type type, void *ptr1, void *ptr2)
1784 {
1785         switch (type) {
1786                 case P_BOOL:
1787                 case P_BOOLREV:
1788                         return (*((bool *)ptr1) == *((bool *)ptr2));
1789
1790                 case P_INTEGER:
1791                 case P_ENUM:
1792                 case P_OCTAL:
1793                 case P_BYTES:
1794                         return (*((int *)ptr1) == *((int *)ptr2));
1795
1796                 case P_CHAR:
1797                         return (*((char *)ptr1) == *((char *)ptr2));
1798
1799                 case P_LIST:
1800                 case P_CMDLIST:
1801                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
1802
1803                 case P_STRING:
1804                 case P_USTRING:
1805                 {
1806                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
1807                         if (p1 && !*p1)
1808                                 p1 = NULL;
1809                         if (p2 && !*p2)
1810                                 p2 = NULL;
1811                         return (p1 == p2 || strequal(p1, p2));
1812                 }
1813                 case P_SEP:
1814                         break;
1815         }
1816         return false;
1817 }
1818
1819 /**
1820  * Process a new section (service).
1821  *
1822  * At this stage all sections are services.
1823  * Later we'll have special sections that permit server parameters to be set.
1824  * Returns True on success, False on failure.
1825  */
1826
1827 static bool do_section(const char *pszSectionName, void *userdata)
1828 {
1829         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
1830         bool bRetval;
1831         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
1832                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
1833         bRetval = false;
1834
1835         /* if we've just struck a global section, note the fact. */
1836         lp_ctx->bInGlobalSection = isglobal;
1837
1838         /* check for multiple global sections */
1839         if (lp_ctx->bInGlobalSection) {
1840                 DEBUG(4, ("Processing section \"[%s]\"\n", pszSectionName));
1841                 return true;
1842         }
1843
1844         /* if we have a current service, tidy it up before moving on */
1845         bRetval = true;
1846
1847         if (lp_ctx->currentService != NULL)
1848                 bRetval = lpcfg_service_ok(lp_ctx->currentService);
1849
1850         /* if all is still well, move to the next record in the services array */
1851         if (bRetval) {
1852                 /* We put this here to avoid an odd message order if messages are */
1853                 /* issued by the post-processing of a previous section. */
1854                 DEBUG(4, ("Processing section \"[%s]\"\n", pszSectionName));
1855
1856                 if ((lp_ctx->currentService = lpcfg_add_service(lp_ctx, lp_ctx->sDefault,
1857                                                                    pszSectionName))
1858                     == NULL) {
1859                         DEBUG(0, ("Failed to add a new service\n"));
1860                         return false;
1861                 }
1862         }
1863
1864         return bRetval;
1865 }
1866
1867
1868 /**
1869  * Determine if a particular base parameter is currently set to the default value.
1870  */
1871
1872 static bool is_default(struct loadparm_service *sDefault, int i)
1873 {
1874         void *def_ptr = ((char *)sDefault) + parm_table[i].offset;
1875         switch (parm_table[i].type) {
1876                 case P_CMDLIST:
1877                 case P_LIST:
1878                         return str_list_equal((const char * const *)parm_table[i].def.lvalue,
1879                                               (const char **)def_ptr);
1880                 case P_STRING:
1881                 case P_USTRING:
1882                         return strequal(parm_table[i].def.svalue,
1883                                         *(char **)def_ptr);
1884                 case P_BOOL:
1885                 case P_BOOLREV:
1886                         return parm_table[i].def.bvalue ==
1887                                 *(bool *)def_ptr;
1888                 case P_INTEGER:
1889                 case P_CHAR:
1890                 case P_OCTAL:
1891                 case P_BYTES:
1892                 case P_ENUM:
1893                         return parm_table[i].def.ivalue ==
1894                                 *(int *)def_ptr;
1895                 case P_SEP:
1896                         break;
1897         }
1898         return false;
1899 }
1900
1901 /**
1902  *Display the contents of the global structure.
1903  */
1904
1905 static void dump_globals(struct loadparm_context *lp_ctx, FILE *f,
1906                          bool show_defaults)
1907 {
1908         int i;
1909         struct parmlist_entry *data;
1910
1911         fprintf(f, "# Global parameters\n[global]\n");
1912
1913         for (i = 0; parm_table[i].label; i++)
1914                 if (parm_table[i].p_class == P_GLOBAL &&
1915                     (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset))) {
1916                         if (!show_defaults && (lp_ctx->flags[i] & FLAG_DEFAULT))
1917                                 continue;
1918                         fprintf(f, "\t%s = ", parm_table[i].label);
1919                         lpcfg_print_parameter(&parm_table[i], lpcfg_parm_ptr(lp_ctx, NULL, &parm_table[i]), f);
1920                         fprintf(f, "\n");
1921         }
1922         if (lp_ctx->globals->param_opt != NULL) {
1923                 for (data = lp_ctx->globals->param_opt; data;
1924                      data = data->next) {
1925                         if (!show_defaults && (data->priority & FLAG_DEFAULT)) {
1926                                 continue;
1927                         }
1928                         fprintf(f, "\t%s = %s\n", data->key, data->value);
1929                 }
1930         }
1931
1932 }
1933
1934 /**
1935  * Display the contents of a single services record.
1936  */
1937
1938 static void dump_a_service(struct loadparm_service * pService, struct loadparm_service *sDefault, FILE * f,
1939                            unsigned int *flags)
1940 {
1941         int i;
1942         struct parmlist_entry *data;
1943
1944         if (pService != sDefault)
1945                 fprintf(f, "\n[%s]\n", pService->szService);
1946
1947         for (i = 0; parm_table[i].label; i++) {
1948                 if (parm_table[i].p_class == P_LOCAL &&
1949                     (*parm_table[i].label != '-') &&
1950                     (i == 0 || (parm_table[i].offset != parm_table[i - 1].offset)))
1951                 {
1952                         if (pService == sDefault) {
1953                                 if (flags && (flags[i] & FLAG_DEFAULT)) {
1954                                         continue;
1955                                 }
1956                                 if (defaults_saved) {
1957                                         if (is_default(sDefault, i)) {
1958                                                 continue;
1959                                         }
1960                                 }
1961                         } else {
1962                                 if (lpcfg_equal_parameter(parm_table[i].type,
1963                                                           ((char *)pService) +
1964                                                           parm_table[i].offset,
1965                                                           ((char *)sDefault) +
1966                                                           parm_table[i].offset))
1967                                         continue;
1968                         }
1969
1970                         fprintf(f, "\t%s = ", parm_table[i].label);
1971                         lpcfg_print_parameter(&parm_table[i],
1972                                         ((char *)pService) + parm_table[i].offset, f);
1973                         fprintf(f, "\n");
1974                 }
1975         }
1976         if (pService->param_opt != NULL) {
1977                 for (data = pService->param_opt; data; data = data->next) {
1978                         fprintf(f, "\t%s = %s\n", data->key, data->value);
1979                 }
1980         }
1981 }
1982
1983 bool lpcfg_dump_a_parameter(struct loadparm_context *lp_ctx,
1984                             struct loadparm_service *service,
1985                             const char *parm_name, FILE * f)
1986 {
1987         struct parm_struct *parm;
1988         void *ptr;
1989
1990         parm = lpcfg_parm_struct(lp_ctx, parm_name);
1991         if (!parm) {
1992                 return false;
1993         }
1994
1995         if (service != NULL && parm->p_class == P_GLOBAL) {
1996                 return false;
1997         }
1998
1999         ptr = lpcfg_parm_ptr(lp_ctx, service,parm);
2000
2001         lpcfg_print_parameter(parm, ptr, f);
2002         fprintf(f, "\n");
2003         return true;
2004 }
2005
2006 /**
2007  * Auto-load some home services.
2008  */
2009 static void lpcfg_add_auto_services(struct loadparm_context *lp_ctx,
2010                                     const char *str)
2011 {
2012         return;
2013 }
2014
2015
2016 /**
2017  * Unload unused services.
2018  */
2019
2020 void lpcfg_killunused(struct loadparm_context *lp_ctx,
2021                    struct smbsrv_connection *smb,
2022                    bool (*snumused) (struct smbsrv_connection *, int))
2023 {
2024         int i;
2025         for (i = 0; i < lp_ctx->iNumServices; i++) {
2026                 if (lp_ctx->services[i] == NULL)
2027                         continue;
2028
2029                 if (!snumused || !snumused(smb, i)) {
2030                         talloc_free(lp_ctx->services[i]);
2031                         lp_ctx->services[i] = NULL;
2032                 }
2033         }
2034 }
2035
2036
2037 static int lpcfg_destructor(struct loadparm_context *lp_ctx)
2038 {
2039         struct parmlist_entry *data;
2040
2041         if (lp_ctx->refuse_free) {
2042                 /* someone is trying to free the
2043                    global_loadparm_context.
2044                    We can't allow that. */
2045                 return -1;
2046         }
2047
2048         if (lp_ctx->globals->param_opt != NULL) {
2049                 struct parmlist_entry *next;
2050                 for (data = lp_ctx->globals->param_opt; data; data=next) {
2051                         next = data->next;
2052                         if (data->priority & FLAG_CMDLINE) continue;
2053                         DLIST_REMOVE(lp_ctx->globals->param_opt, data);
2054                         talloc_free(data);
2055                 }
2056         }
2057
2058         return 0;
2059 }
2060
2061 /**
2062  * Initialise the global parameter structure.
2063  *
2064  * Note that most callers should use loadparm_init_global() instead
2065  */
2066 struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
2067 {
2068         int i;
2069         char *myname;
2070         struct loadparm_context *lp_ctx;
2071         struct parmlist_entry *parm;
2072         char *logfile;
2073
2074         lp_ctx = talloc_zero(mem_ctx, struct loadparm_context);
2075         if (lp_ctx == NULL)
2076                 return NULL;
2077
2078         talloc_set_destructor(lp_ctx, lpcfg_destructor);
2079         lp_ctx->bInGlobalSection = true;
2080         lp_ctx->globals = talloc_zero(lp_ctx, struct loadparm_global);
2081         lp_ctx->sDefault = talloc_zero(lp_ctx, struct loadparm_service);
2082
2083         lp_ctx->sDefault->iMaxPrintJobs = 1000;
2084         lp_ctx->sDefault->bAvailable = true;
2085         lp_ctx->sDefault->browseable = true;
2086         lp_ctx->sDefault->read_only = true;
2087         lp_ctx->sDefault->map_archive = true;
2088         lp_ctx->sDefault->strict_locking = true;
2089         lp_ctx->sDefault->oplocks = true;
2090         lp_ctx->sDefault->create_mask = 0744;
2091         lp_ctx->sDefault->force_create_mode = 0000;
2092         lp_ctx->sDefault->directory_mask = 0755;
2093         lp_ctx->sDefault->force_directory_mode = 0000;
2094
2095         DEBUG(3, ("Initialising global parameters\n"));
2096
2097         for (i = 0; parm_table[i].label; i++) {
2098                 if ((parm_table[i].type == P_STRING ||
2099                      parm_table[i].type == P_USTRING) &&
2100                     !(lp_ctx->flags[i] & FLAG_CMDLINE)) {
2101                         char **r;
2102                         if (parm_table[i].p_class == P_LOCAL) {
2103                                 r = (char **)(((char *)lp_ctx->sDefault) + parm_table[i].offset);
2104                         } else {
2105                                 r = (char **)(((char *)lp_ctx->globals) + parm_table[i].offset);
2106                         }
2107                         *r = talloc_strdup(lp_ctx, "");
2108                 }
2109         }
2110
2111         logfile = talloc_asprintf(lp_ctx, "%s/log.samba", dyn_LOGFILEBASE);
2112         lpcfg_do_global_parameter(lp_ctx, "log file", logfile);
2113         talloc_free(logfile);
2114
2115         lpcfg_do_global_parameter(lp_ctx, "log level", "0");
2116
2117         lpcfg_do_global_parameter(lp_ctx, "syslog", "1");
2118         lpcfg_do_global_parameter(lp_ctx, "syslog only", "No");
2119         lpcfg_do_global_parameter(lp_ctx, "debug timestamp", "Yes");
2120         lpcfg_do_global_parameter(lp_ctx, "debug prefix timestamp", "No");
2121         lpcfg_do_global_parameter(lp_ctx, "debug hires timestamp", "Yes");
2122         lpcfg_do_global_parameter(lp_ctx, "debug pid", "No");
2123         lpcfg_do_global_parameter(lp_ctx, "debug uid", "No");
2124         lpcfg_do_global_parameter(lp_ctx, "debug class", "No");
2125
2126         lpcfg_do_global_parameter(lp_ctx, "share backend", "classic");
2127
2128         lpcfg_do_global_parameter(lp_ctx, "server role", "auto");
2129         lpcfg_do_global_parameter(lp_ctx, "domain logons", "No");
2130         lpcfg_do_global_parameter(lp_ctx, "domain master", "Auto");
2131
2132         /* options that can be set on the command line must be initialised via
2133            the slower lpcfg_do_global_parameter() to ensure that FLAG_CMDLINE is obeyed */
2134 #ifdef TCP_NODELAY
2135         lpcfg_do_global_parameter(lp_ctx, "socket options", "TCP_NODELAY");
2136 #endif
2137         lpcfg_do_global_parameter(lp_ctx, "workgroup", DEFAULT_WORKGROUP);
2138         myname = get_myname(lp_ctx);
2139         lpcfg_do_global_parameter(lp_ctx, "netbios name", myname);
2140         talloc_free(myname);
2141         lpcfg_do_global_parameter(lp_ctx, "name resolve order", "lmhosts wins host bcast");
2142
2143         lpcfg_do_global_parameter(lp_ctx, "fstype", "NTFS");
2144
2145         lpcfg_do_global_parameter(lp_ctx, "ntvfs handler", "unixuid default");
2146         lpcfg_do_global_parameter(lp_ctx, "max connections", "0");
2147
2148         lpcfg_do_global_parameter(lp_ctx, "dcerpc endpoint servers", "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver");
2149         lpcfg_do_global_parameter(lp_ctx, "server services", "s3fs rpc nbt wrepl ldap cldap kdc drepl winbind ntp_signd kcc dnsupdate dns");
2150         lpcfg_do_global_parameter(lp_ctx, "kccsrv:samba_kcc", "true");
2151         /* the winbind method for domain controllers is for both RODC
2152            auth forwarding and for trusted domains */
2153         lpcfg_do_global_parameter(lp_ctx, "private dir", dyn_PRIVATE_DIR);
2154         lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_LOCAL_MACHINE", "hklm.ldb");
2155
2156         /* This hive should be dynamically generated by Samba using
2157            data from the sam, but for the moment leave it in a tdb to
2158            keep regedt32 from popping up an annoying dialog. */
2159         lpcfg_do_global_parameter(lp_ctx, "registry:HKEY_USERS", "hku.ldb");
2160
2161         /* using UTF8 by default allows us to support all chars */
2162         lpcfg_do_global_parameter(lp_ctx, "unix charset", "UTF-8");
2163
2164         /* Use codepage 850 as a default for the dos character set */
2165         lpcfg_do_global_parameter(lp_ctx, "dos charset", "CP850");
2166
2167         /*
2168          * Allow the default PASSWD_CHAT to be overridden in local.h.
2169          */
2170         lpcfg_do_global_parameter(lp_ctx, "passwd chat", DEFAULT_PASSWD_CHAT);
2171
2172         lpcfg_do_global_parameter(lp_ctx, "pid directory", dyn_PIDDIR);
2173         lpcfg_do_global_parameter(lp_ctx, "lock dir", dyn_LOCKDIR);
2174         lpcfg_do_global_parameter(lp_ctx, "state directory", dyn_STATEDIR);
2175         lpcfg_do_global_parameter(lp_ctx, "cache directory", dyn_CACHEDIR);
2176         lpcfg_do_global_parameter(lp_ctx, "ncalrpc dir", dyn_NCALRPCDIR);
2177
2178         lpcfg_do_global_parameter(lp_ctx, "nbt client socket address", "0.0.0.0");
2179         lpcfg_do_global_parameter_var(lp_ctx, "server string",
2180                                    "Samba %s", SAMBA_VERSION_STRING);
2181
2182         lpcfg_do_global_parameter(lp_ctx, "password server", "*");
2183
2184         lpcfg_do_global_parameter(lp_ctx, "max mux", "50");
2185         lpcfg_do_global_parameter(lp_ctx, "max xmit", "16644");
2186         lpcfg_do_global_parameter(lp_ctx, "host msdfs", "true");
2187
2188         lpcfg_do_global_parameter(lp_ctx, "LargeReadwrite", "True");
2189         lpcfg_do_global_parameter(lp_ctx, "server min protocol", "LANMAN1");
2190         lpcfg_do_global_parameter(lp_ctx, "server max protocol", "SMB3");
2191         lpcfg_do_global_parameter(lp_ctx, "client min protocol", "CORE");
2192         lpcfg_do_global_parameter(lp_ctx, "client max protocol", "NT1");
2193         lpcfg_do_global_parameter(lp_ctx, "security", "AUTO");
2194         lpcfg_do_global_parameter(lp_ctx, "EncryptPasswords", "True");
2195         lpcfg_do_global_parameter(lp_ctx, "ReadRaw", "True");
2196         lpcfg_do_global_parameter(lp_ctx, "WriteRaw", "True");
2197         lpcfg_do_global_parameter(lp_ctx, "NullPasswords", "False");
2198         lpcfg_do_global_parameter(lp_ctx, "old password allowed period", "60");
2199         lpcfg_do_global_parameter(lp_ctx, "ObeyPamRestrictions", "False");
2200
2201         lpcfg_do_global_parameter(lp_ctx, "TimeServer", "False");
2202         lpcfg_do_global_parameter(lp_ctx, "BindInterfacesOnly", "False");
2203         lpcfg_do_global_parameter(lp_ctx, "Unicode", "True");
2204         lpcfg_do_global_parameter(lp_ctx, "ClientLanManAuth", "False");
2205         lpcfg_do_global_parameter(lp_ctx, "ClientNTLMv2Auth", "True");
2206         lpcfg_do_global_parameter(lp_ctx, "LanmanAuth", "False");
2207         lpcfg_do_global_parameter(lp_ctx, "NTLMAuth", "True");
2208         lpcfg_do_global_parameter(lp_ctx, "client use spnego principal", "False");
2209
2210         lpcfg_do_global_parameter(lp_ctx, "UnixExtensions", "True");
2211
2212         lpcfg_do_global_parameter(lp_ctx, "PreferredMaster", "Auto");
2213         lpcfg_do_global_parameter(lp_ctx, "LocalMaster", "True");
2214
2215         lpcfg_do_global_parameter(lp_ctx, "wins support", "False");
2216         lpcfg_do_global_parameter(lp_ctx, "dns proxy", "True");
2217
2218         lpcfg_do_global_parameter(lp_ctx, "winbind separator", "\\");
2219         lpcfg_do_global_parameter(lp_ctx, "winbind sealed pipes", "True");
2220         lpcfg_do_global_parameter(lp_ctx, "require strong key", "True");
2221         lpcfg_do_global_parameter(lp_ctx, "winbindd socket directory", dyn_WINBINDD_SOCKET_DIR);
2222         lpcfg_do_global_parameter(lp_ctx, "winbindd privileged socket directory", dyn_WINBINDD_PRIVILEGED_SOCKET_DIR);
2223         lpcfg_do_global_parameter(lp_ctx, "ntp signd socket directory", dyn_NTP_SIGND_SOCKET_DIR);
2224         lpcfg_do_global_parameter_var(lp_ctx, "dns update command", "%s/samba_dnsupdate", dyn_SCRIPTSBINDIR);
2225         lpcfg_do_global_parameter_var(lp_ctx, "spn update command", "%s/samba_spnupdate", dyn_SCRIPTSBINDIR);
2226         lpcfg_do_global_parameter_var(lp_ctx, "samba kcc command",
2227                                         "%s/samba_kcc", dyn_SCRIPTSBINDIR);
2228         lpcfg_do_global_parameter(lp_ctx, "template shell", "/bin/false");
2229         lpcfg_do_global_parameter(lp_ctx, "template homedir", "/home/%WORKGROUP%/%ACCOUNTNAME%");
2230
2231         lpcfg_do_global_parameter(lp_ctx, "client signing", "default");
2232         lpcfg_do_global_parameter(lp_ctx, "server signing", "default");
2233
2234         lpcfg_do_global_parameter(lp_ctx, "use spnego", "True");
2235
2236         lpcfg_do_global_parameter(lp_ctx, "use mmap", "True");
2237
2238         lpcfg_do_global_parameter(lp_ctx, "smb ports", "445 139");
2239         lpcfg_do_global_parameter(lp_ctx, "nbt port", "137");
2240         lpcfg_do_global_parameter(lp_ctx, "dgram port", "138");
2241         lpcfg_do_global_parameter(lp_ctx, "cldap port", "389");
2242         lpcfg_do_global_parameter(lp_ctx, "krb5 port", "88");
2243         lpcfg_do_global_parameter(lp_ctx, "kpasswd port", "464");
2244         lpcfg_do_global_parameter(lp_ctx, "web port", "901");
2245
2246         lpcfg_do_global_parameter(lp_ctx, "nt status support", "True");
2247
2248         lpcfg_do_global_parameter(lp_ctx, "max wins ttl", "518400"); /* 6 days */
2249         lpcfg_do_global_parameter(lp_ctx, "min wins ttl", "21600");
2250
2251         lpcfg_do_global_parameter(lp_ctx, "tls enabled", "True");
2252         lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
2253         lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
2254         lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
2255         lpcfg_do_global_parameter(lp_ctx, "prefork children:smb", "4");
2256
2257         lpcfg_do_global_parameter(lp_ctx, "rndc command", "/usr/sbin/rndc");
2258         lpcfg_do_global_parameter(lp_ctx, "nsupdate command", "/usr/bin/nsupdate -g");
2259
2260         lpcfg_do_global_parameter(lp_ctx, "allow dns updates", "secure only");
2261         lpcfg_do_global_parameter(lp_ctx, "dns forwarder", "");
2262
2263         lpcfg_do_global_parameter(lp_ctx, "algorithmic rid base", "1000");
2264
2265         lpcfg_do_global_parameter(lp_ctx, "enhanced browsing", "True");
2266
2267         lpcfg_do_global_parameter(lp_ctx, "winbind nss info", "template");
2268
2269         lpcfg_do_global_parameter(lp_ctx, "server schannel", "Auto");
2270
2271         lpcfg_do_global_parameter(lp_ctx, "short preserve case", "True");
2272
2273         lpcfg_do_global_parameter(lp_ctx, "max open files", "16384");
2274
2275         lpcfg_do_global_parameter(lp_ctx, "cups connection timeout", "30");
2276
2277         lpcfg_do_global_parameter(lp_ctx, "locking", "True");
2278
2279         lpcfg_do_global_parameter(lp_ctx, "block size", "1024");
2280
2281         lpcfg_do_global_parameter(lp_ctx, "client use spnego", "True");
2282
2283         lpcfg_do_global_parameter(lp_ctx, "change notify", "True");
2284
2285         lpcfg_do_global_parameter(lp_ctx, "name cache timeout", "660");
2286
2287         lpcfg_do_global_parameter(lp_ctx, "defer sharing violations", "True");
2288
2289         lpcfg_do_global_parameter(lp_ctx, "ldap replication sleep", "1000");
2290
2291         lpcfg_do_global_parameter(lp_ctx, "idmap backend", "tdb");
2292
2293         lpcfg_do_global_parameter(lp_ctx, "enable privileges", "True");
2294
2295         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max write", "%u", DEFAULT_SMB2_MAX_WRITE);
2296
2297         lpcfg_do_global_parameter(lp_ctx, "passdb backend", "tdbsam");
2298
2299         lpcfg_do_global_parameter(lp_ctx, "getwd cache", "True");
2300
2301         lpcfg_do_global_parameter(lp_ctx, "winbind nested groups", "True");
2302
2303         lpcfg_do_global_parameter(lp_ctx, "mangled names", "True");
2304
2305         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max credits", "%u", DEFAULT_SMB2_MAX_CREDITS);
2306
2307         lpcfg_do_global_parameter(lp_ctx, "ldap ssl", "start tls");
2308
2309         lpcfg_do_global_parameter(lp_ctx, "ldap deref", "auto");
2310
2311         lpcfg_do_global_parameter(lp_ctx, "lm interval", "60");
2312
2313         lpcfg_do_global_parameter(lp_ctx, "mangling method", "hash2");
2314
2315         lpcfg_do_global_parameter(lp_ctx, "hide dot files", "True");
2316
2317         lpcfg_do_global_parameter(lp_ctx, "browse list", "True");
2318
2319         lpcfg_do_global_parameter(lp_ctx, "passwd chat timeout", "2");
2320
2321         lpcfg_do_global_parameter(lp_ctx, "guest account", GUEST_ACCOUNT);
2322
2323         lpcfg_do_global_parameter(lp_ctx, "client schannel", "auto");
2324
2325         lpcfg_do_global_parameter(lp_ctx, "smb encrypt", "default");
2326
2327         lpcfg_do_global_parameter(lp_ctx, "max log size", "5000");
2328
2329         lpcfg_do_global_parameter(lp_ctx, "idmap negative cache time", "120");
2330
2331         lpcfg_do_global_parameter(lp_ctx, "ldap follow referral", "auto");
2332
2333         lpcfg_do_global_parameter(lp_ctx, "multicast dns register", "yes");
2334
2335         lpcfg_do_global_parameter(lp_ctx, "winbind reconnect delay", "30");
2336
2337         lpcfg_do_global_parameter(lp_ctx, "nt acl support", "yes");
2338
2339         lpcfg_do_global_parameter(lp_ctx, "acl check permissions", "yes");
2340
2341         lpcfg_do_global_parameter(lp_ctx, "keepalive", "300");
2342
2343         lpcfg_do_global_parameter(lp_ctx, "winbind cache time", "300");
2344
2345         lpcfg_do_global_parameter(lp_ctx, "level2 oplocks", "yes");
2346
2347         lpcfg_do_global_parameter(lp_ctx, "show add printer wizard", "yes");
2348
2349         lpcfg_do_global_parameter(lp_ctx, "allocation roundup size", "1048576");
2350
2351         lpcfg_do_global_parameter(lp_ctx, "ldap page size", "1024");
2352
2353         lpcfg_do_global_parameter(lp_ctx, "kernel share modes", "yes");
2354
2355         lpcfg_do_global_parameter(lp_ctx, "strict locking", "Auto");
2356
2357         lpcfg_do_global_parameter(lp_ctx, "map readonly", "yes");
2358
2359         lpcfg_do_global_parameter(lp_ctx, "allow trusted domains", "yes");
2360
2361         lpcfg_do_global_parameter(lp_ctx, "default devmode", "yes");
2362
2363         lpcfg_do_global_parameter(lp_ctx, "os level", "20");
2364
2365         lpcfg_do_global_parameter(lp_ctx, "dos filetimes", "yes");
2366
2367         lpcfg_do_global_parameter(lp_ctx, "mangling char", "~");
2368
2369         lpcfg_do_global_parameter(lp_ctx, "printcap cache time", "750");
2370
2371         lpcfg_do_global_parameter(lp_ctx, "create krb5 conf", "yes");
2372
2373         lpcfg_do_global_parameter(lp_ctx, "winbind max clients", "200");
2374
2375         lpcfg_do_global_parameter(lp_ctx, "acl map full control", "yes");
2376
2377         lpcfg_do_global_parameter(lp_ctx, "nt pipe support", "yes");
2378
2379         lpcfg_do_global_parameter(lp_ctx, "ldap debug threshold", "10");
2380
2381         lpcfg_do_global_parameter(lp_ctx, "follow symlinks", "yes");
2382
2383         lpcfg_do_global_parameter(lp_ctx, "machine password timeout", "604800");
2384
2385         lpcfg_do_global_parameter(lp_ctx, "ldap connection timeout", "2");
2386
2387         lpcfg_do_global_parameter(lp_ctx, "winbind expand groups", "1");
2388
2389         lpcfg_do_global_parameter(lp_ctx, "stat cache", "yes");
2390
2391         lpcfg_do_global_parameter(lp_ctx, "lpq cache time", "30");
2392
2393         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max trans", "%u", DEFAULT_SMB2_MAX_TRANSACT);
2394
2395         lpcfg_do_global_parameter_var(lp_ctx, "smb2 max read", "%u", DEFAULT_SMB2_MAX_READ);
2396
2397         lpcfg_do_global_parameter(lp_ctx, "durable handles", "yes");
2398
2399         lpcfg_do_global_parameter(lp_ctx, "max stat cache size", "256");
2400
2401         lpcfg_do_global_parameter(lp_ctx, "ldap passwd sync", "no");
2402
2403         lpcfg_do_global_parameter(lp_ctx, "kernel change notify", "yes");
2404
2405         lpcfg_do_global_parameter(lp_ctx, "max ttl", "259200");
2406
2407         lpcfg_do_global_parameter(lp_ctx, "blocking locks", "yes");
2408
2409         lpcfg_do_global_parameter(lp_ctx, "oplock contention limit", "2");
2410
2411         lpcfg_do_global_parameter(lp_ctx, "load printers", "yes");
2412
2413         lpcfg_do_global_parameter(lp_ctx, "idmap cache time", "604800");
2414
2415         lpcfg_do_global_parameter(lp_ctx, "preserve case", "yes");
2416
2417         lpcfg_do_global_parameter(lp_ctx, "lm announce", "auto");
2418
2419         lpcfg_do_global_parameter(lp_ctx, "afs token lifetime", "604800");
2420
2421         lpcfg_do_global_parameter(lp_ctx, "enable core files", "yes");
2422
2423         lpcfg_do_global_parameter(lp_ctx, "winbind max domain connections", "1");
2424
2425         lpcfg_do_global_parameter(lp_ctx, "case sensitive", "auto");
2426
2427         lpcfg_do_global_parameter(lp_ctx, "ldap timeout", "15");
2428
2429         lpcfg_do_global_parameter(lp_ctx, "mangle prefix", "1");
2430
2431         lpcfg_do_global_parameter(lp_ctx, "posix locking", "yes");
2432
2433         lpcfg_do_global_parameter(lp_ctx, "lock spin time", "200");
2434
2435         lpcfg_do_global_parameter(lp_ctx, "directory name cache size", "100");
2436
2437         lpcfg_do_global_parameter(lp_ctx, "nmbd bind explicit broadcast", "yes");
2438
2439         lpcfg_do_global_parameter(lp_ctx, "init logon delay", "100");
2440
2441         lpcfg_do_global_parameter(lp_ctx, "usershare owner only", "yes");
2442
2443         lpcfg_do_global_parameter(lp_ctx, "-valid", "yes");
2444
2445         lpcfg_do_global_parameter_var(lp_ctx, "usershare path", "%s/usershares", get_dyn_STATEDIR());
2446
2447 #ifdef DEVELOPER
2448         lpcfg_do_global_parameter_var(lp_ctx, "panic action", "/bin/sleep 999999999");
2449 #endif
2450
2451         lpcfg_do_global_parameter(lp_ctx, "smb passwd file", get_dyn_SMB_PASSWD_FILE());
2452
2453         lpcfg_do_global_parameter(lp_ctx, "logon home", "\\\\%N\\%U");
2454
2455         lpcfg_do_global_parameter(lp_ctx, "logon path", "\\\\%N\\%U\\profile");
2456
2457         lpcfg_do_global_parameter(lp_ctx, "printjob username", "%U");
2458
2459         for (i = 0; parm_table[i].label; i++) {
2460                 if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) {
2461                         lp_ctx->flags[i] |= FLAG_DEFAULT;
2462                 }
2463         }
2464
2465         for (parm=lp_ctx->globals->param_opt; parm; parm=parm->next) {
2466                 if (!(parm->priority & FLAG_CMDLINE)) {
2467                         parm->priority |= FLAG_DEFAULT;
2468                 }
2469         }
2470
2471         return lp_ctx;
2472 }
2473
2474 /**
2475  * Initialise the global parameter structure.
2476  */
2477 struct loadparm_context *loadparm_init_global(bool load_default)
2478 {
2479         if (global_loadparm_context == NULL) {
2480                 global_loadparm_context = loadparm_init(NULL);
2481         }
2482         if (global_loadparm_context == NULL) {
2483                 return NULL;
2484         }
2485         global_loadparm_context->global = true;
2486         if (load_default && !global_loadparm_context->loaded) {
2487                 lpcfg_load_default(global_loadparm_context);
2488         }
2489         global_loadparm_context->refuse_free = true;
2490         return global_loadparm_context;
2491 }
2492
2493 /**
2494  * Initialise the global parameter structure.
2495  */
2496 struct loadparm_context *loadparm_init_s3(TALLOC_CTX *mem_ctx, 
2497                                           const struct loadparm_s3_helpers *s3_fns)
2498 {
2499         struct loadparm_context *loadparm_context = talloc_zero(mem_ctx, struct loadparm_context);
2500         if (!loadparm_context) {
2501                 return NULL;
2502         }
2503         loadparm_context->s3_fns = s3_fns;
2504         loadparm_context->globals = s3_fns->globals;
2505         return loadparm_context;
2506 }
2507
2508 const char *lpcfg_configfile(struct loadparm_context *lp_ctx)
2509 {
2510         return lp_ctx->szConfigFile;
2511 }
2512
2513 const char *lp_default_path(void)
2514 {
2515     if (getenv("SMB_CONF_PATH"))
2516         return getenv("SMB_CONF_PATH");
2517     else
2518         return dyn_CONFIGFILE;
2519 }
2520
2521 /**
2522  * Update the internal state of a loadparm context after settings 
2523  * have changed.
2524  */
2525 static bool lpcfg_update(struct loadparm_context *lp_ctx)
2526 {
2527         struct debug_settings settings;
2528         TALLOC_CTX *tmp_ctx;
2529
2530         tmp_ctx = talloc_new(lp_ctx);
2531         if (tmp_ctx == NULL) {
2532                 return false;
2533         }
2534
2535         lpcfg_add_auto_services(lp_ctx, lpcfg_auto_services(lp_ctx, tmp_ctx));
2536
2537         if (!lp_ctx->globals->wins_server_list && lp_ctx->globals->we_are_a_wins_server) {
2538                 lpcfg_do_global_parameter(lp_ctx, "wins server", "127.0.0.1");
2539         }
2540
2541         if (!lp_ctx->global) {
2542                 TALLOC_FREE(tmp_ctx);
2543                 return true;
2544         }
2545
2546         panic_action = lp_ctx->globals->panic_action;
2547
2548         reload_charcnv(lp_ctx);
2549
2550         ZERO_STRUCT(settings);
2551         /* Add any more debug-related smb.conf parameters created in
2552          * future here */
2553         settings.syslog = lp_ctx->globals->syslog;
2554         settings.syslog_only = lp_ctx->globals->syslog_only;
2555         settings.timestamp_logs = lp_ctx->globals->timestamp_logs;
2556         settings.debug_prefix_timestamp = lp_ctx->globals->debug_prefix_timestamp;
2557         settings.debug_hires_timestamp = lp_ctx->globals->debug_hires_timestamp;
2558         settings.debug_pid = lp_ctx->globals->debug_pid;
2559         settings.debug_uid = lp_ctx->globals->debug_uid;
2560         settings.debug_class = lp_ctx->globals->debug_class;
2561         debug_set_settings(&settings);
2562
2563         /* FIXME: This is a bit of a hack, but we can't use a global, since 
2564          * not everything that uses lp also uses the socket library */
2565         if (lpcfg_parm_bool(lp_ctx, NULL, "socket", "testnonblock", false)) {
2566                 setenv("SOCKET_TESTNONBLOCK", "1", 1);
2567         } else {
2568                 unsetenv("SOCKET_TESTNONBLOCK");
2569         }
2570
2571         TALLOC_FREE(tmp_ctx);
2572         return true;
2573 }
2574
2575 bool lpcfg_load_default(struct loadparm_context *lp_ctx)
2576 {
2577     const char *path;
2578
2579     path = lp_default_path();
2580
2581     if (!file_exist(path)) {
2582             /* We allow the default smb.conf file to not exist, 
2583              * basically the equivalent of an empty file. */
2584             return lpcfg_update(lp_ctx);
2585     }
2586
2587     return lpcfg_load(lp_ctx, path);
2588 }
2589
2590 /**
2591  * Load the services array from the services file.
2592  *
2593  * Return True on success, False on failure.
2594  */
2595 bool lpcfg_load(struct loadparm_context *lp_ctx, const char *filename)
2596 {
2597         char *n2;
2598         bool bRetval;
2599
2600         filename = talloc_strdup(lp_ctx, filename);
2601
2602         lp_ctx->szConfigFile = filename;
2603
2604         if (lp_ctx->s3_fns) {
2605                 return lp_ctx->s3_fns->load(filename);
2606         }
2607
2608         lp_ctx->bInGlobalSection = true;
2609         n2 = standard_sub_basic(lp_ctx, lp_ctx->szConfigFile);
2610         DEBUG(2, ("lpcfg_load: refreshing parameters from %s\n", n2));
2611
2612         add_to_file_list(lp_ctx, &lp_ctx->file_lists, lp_ctx->szConfigFile, n2);
2613
2614         /* We get sections first, so have to start 'behind' to make up */
2615         lp_ctx->currentService = NULL;
2616         bRetval = pm_process(n2, do_section, do_parameter, lp_ctx);
2617
2618         /* finish up the last section */
2619         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
2620         if (bRetval)
2621                 if (lp_ctx->currentService != NULL)
2622                         bRetval = lpcfg_service_ok(lp_ctx->currentService);
2623
2624         bRetval = bRetval && lpcfg_update(lp_ctx);
2625
2626         /* we do this unconditionally, so that it happens even
2627            for a missing smb.conf */
2628         reload_charcnv(lp_ctx);
2629
2630         if (bRetval == true) {
2631                 /* set this up so that any child python tasks will
2632                    find the right smb.conf */
2633                 setenv("SMB_CONF_PATH", filename, 1);
2634
2635                 /* set the context used by the lp_*() function
2636                    varients */
2637                 global_loadparm_context = lp_ctx;
2638                 lp_ctx->loaded = true;
2639         }
2640
2641         return bRetval;
2642 }
2643
2644 /**
2645  * Return the max number of services.
2646  */
2647
2648 int lpcfg_numservices(struct loadparm_context *lp_ctx)
2649 {
2650         if (lp_ctx->s3_fns) {
2651                 return lp_ctx->s3_fns->get_numservices();
2652         }
2653
2654         return lp_ctx->iNumServices;
2655 }
2656
2657 /**
2658  * Display the contents of the services array in human-readable form.
2659  */
2660
2661 void lpcfg_dump(struct loadparm_context *lp_ctx, FILE *f, bool show_defaults,
2662              int maxtoprint)
2663 {
2664         int iService;
2665
2666         if (lp_ctx->s3_fns) {
2667                 lp_ctx->s3_fns->dump(f, show_defaults, maxtoprint);
2668                 return;
2669         }
2670
2671         defaults_saved = !show_defaults;
2672
2673         dump_globals(lp_ctx, f, show_defaults);
2674
2675         dump_a_service(lp_ctx->sDefault, lp_ctx->sDefault, f, lp_ctx->flags);
2676
2677         for (iService = 0; iService < maxtoprint; iService++)
2678                 lpcfg_dump_one(f, show_defaults, lp_ctx->services[iService], lp_ctx->sDefault);
2679 }
2680
2681 /**
2682  * Display the contents of one service in human-readable form.
2683  */
2684 void lpcfg_dump_one(FILE *f, bool show_defaults, struct loadparm_service *service, struct loadparm_service *sDefault)
2685 {
2686         if (service != NULL) {
2687                 if (service->szService[0] == '\0')
2688                         return;
2689                 dump_a_service(service, sDefault, f, NULL);
2690         }
2691 }
2692
2693 struct loadparm_service *lpcfg_servicebynum(struct loadparm_context *lp_ctx,
2694                                             int snum)
2695 {
2696         if (lp_ctx->s3_fns) {
2697                 return lp_ctx->s3_fns->get_servicebynum(snum);
2698         }
2699
2700         return lp_ctx->services[snum];
2701 }
2702
2703 struct loadparm_service *lpcfg_service(struct loadparm_context *lp_ctx,
2704                                     const char *service_name)
2705 {
2706         int iService;
2707         char *serviceName;
2708
2709         if (lp_ctx->s3_fns) {
2710                 return lp_ctx->s3_fns->get_service(service_name);
2711         }
2712
2713         for (iService = lp_ctx->iNumServices - 1; iService >= 0; iService--) {
2714                 if (lp_ctx->services[iService] &&
2715                     lp_ctx->services[iService]->szService) {
2716                         /*
2717                          * The substitution here is used to support %U is
2718                          * service names
2719                          */
2720                         serviceName = standard_sub_basic(
2721                                         lp_ctx->services[iService],
2722                                         lp_ctx->services[iService]->szService);
2723                         if (strequal(serviceName, service_name)) {
2724                                 talloc_free(serviceName);
2725                                 return lp_ctx->services[iService];
2726                         }
2727                         talloc_free(serviceName);
2728                 }
2729         }
2730
2731         DEBUG(7,("lpcfg_servicenumber: couldn't find %s\n", service_name));
2732         return NULL;
2733 }
2734
2735 const char *lpcfg_servicename(const struct loadparm_service *service)
2736 {
2737         return lpcfg_string((const char *)service->szService);
2738 }
2739
2740 /**
2741  * A useful volume label function.
2742  */
2743 const char *lpcfg_volume_label(struct loadparm_service *service, struct loadparm_service *sDefault)
2744 {
2745         const char *ret;
2746         ret = lpcfg_string((const char *)((service != NULL && service->volume != NULL) ?
2747                                        service->volume : sDefault->volume));
2748         if (!*ret)
2749                 return lpcfg_servicename(service);
2750         return ret;
2751 }
2752
2753 /**
2754  * Return the correct printer name.
2755  */
2756 const char *lpcfg_printername(struct loadparm_service *service, struct loadparm_service *sDefault)
2757 {
2758         const char *ret;
2759         ret = lpcfg_string((const char *)((service != NULL && service->_printername != NULL) ?
2760                                        service->_printername : sDefault->_printername));
2761         if (ret == NULL || (ret != NULL && *ret == '\0'))
2762                 ret = lpcfg_servicename(service);
2763
2764         return ret;
2765 }
2766
2767
2768 /**
2769  * Return the max print jobs per queue.
2770  */
2771 int lpcfg_maxprintjobs(struct loadparm_service *service, struct loadparm_service *sDefault)
2772 {
2773         int maxjobs = (service != NULL) ? service->iMaxPrintJobs : sDefault->iMaxPrintJobs;
2774         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
2775                 maxjobs = PRINT_MAX_JOBID - 1;
2776
2777         return maxjobs;
2778 }
2779
2780 struct smb_iconv_handle *lpcfg_iconv_handle(struct loadparm_context *lp_ctx)
2781 {
2782         if (lp_ctx == NULL) {
2783                 return get_iconv_handle();
2784         }
2785         return lp_ctx->iconv_handle;
2786 }
2787
2788 _PUBLIC_ void reload_charcnv(struct loadparm_context *lp_ctx)
2789 {
2790         struct smb_iconv_handle *old_ic = lp_ctx->iconv_handle;
2791         if (!lp_ctx->global) {
2792                 return;
2793         }
2794
2795         if (old_ic == NULL) {
2796                 old_ic = global_iconv_handle;
2797         }
2798         lp_ctx->iconv_handle = smb_iconv_handle_reinit_lp(lp_ctx, lp_ctx, old_ic);
2799         global_iconv_handle = lp_ctx->iconv_handle;
2800 }
2801
2802 _PUBLIC_ char *lpcfg_tls_keyfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
2803 {
2804         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_keyfile(lp_ctx));
2805 }
2806
2807 _PUBLIC_ char *lpcfg_tls_certfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
2808 {
2809         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_certfile(lp_ctx));
2810 }
2811
2812 _PUBLIC_ char *lpcfg_tls_cafile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
2813 {
2814         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_cafile(lp_ctx));
2815 }
2816
2817 _PUBLIC_ char *lpcfg_tls_crlfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
2818 {
2819         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_crlfile(lp_ctx));
2820 }
2821
2822 _PUBLIC_ char *lpcfg_tls_dhpfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
2823 {
2824         return lpcfg_private_path(mem_ctx, lp_ctx, lpcfg__tls_dhpfile(lp_ctx));
2825 }
2826
2827 struct gensec_settings *lpcfg_gensec_settings(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
2828 {
2829         struct gensec_settings *settings = talloc_zero(mem_ctx, struct gensec_settings);
2830         if (settings == NULL)
2831                 return NULL;
2832         SMB_ASSERT(lp_ctx != NULL);
2833         settings->lp_ctx = talloc_reference(settings, lp_ctx);
2834         settings->target_hostname = lpcfg_parm_string(lp_ctx, NULL, "gensec", "target_hostname");
2835         return settings;
2836 }
2837
2838 int lpcfg_server_role(struct loadparm_context *lp_ctx)
2839 {
2840         int domain_master = lpcfg__domain_master(lp_ctx);
2841
2842         return lp_find_server_role(lpcfg__server_role(lp_ctx),
2843                                    lpcfg__security(lp_ctx),
2844                                    lpcfg__domain_logons(lp_ctx),
2845                                    (domain_master == true) ||
2846                                    (domain_master == Auto));
2847 }
2848
2849 int lpcfg_security(struct loadparm_context *lp_ctx)
2850 {
2851         return lp_find_security(lpcfg__server_role(lp_ctx),
2852                                 lpcfg__security(lp_ctx));
2853 }
2854
2855 bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandatory)
2856 {
2857         bool allowed = true;
2858         enum smb_signing_setting signing_setting = lpcfg_server_signing(lp_ctx);
2859
2860         *mandatory = false;
2861
2862         if (signing_setting == SMB_SIGNING_DEFAULT) {
2863                 /*
2864                  * If we are a domain controller, SMB signing is
2865                  * really important, as it can prevent a number of
2866                  * attacks on communications between us and the
2867                  * clients
2868                  *
2869                  * However, it really sucks (no sendfile, CPU
2870                  * overhead) performance-wise when used on a
2871                  * file server, so disable it by default
2872                  * on non-DCs
2873                  */
2874
2875                 if (lpcfg_server_role(lp_ctx) >= ROLE_ACTIVE_DIRECTORY_DC) {
2876                         signing_setting = SMB_SIGNING_REQUIRED;
2877                 } else {
2878                         signing_setting = SMB_SIGNING_OFF;
2879                 }
2880         }
2881
2882         switch (signing_setting) {
2883         case SMB_SIGNING_REQUIRED:
2884                 *mandatory = true;
2885                 break;
2886         case SMB_SIGNING_IF_REQUIRED:
2887                 break;
2888         case SMB_SIGNING_DEFAULT:
2889         case SMB_SIGNING_OFF:
2890                 allowed = false;
2891                 break;
2892         }
2893
2894         return allowed;
2895 }
2896
2897 int lpcfg_tdb_hash_size(struct loadparm_context *lp_ctx, const char *name)
2898 {
2899         const char *base;
2900
2901         if (name == NULL) {
2902                 return 0;
2903         }
2904
2905         base = strrchr_m(name, '/');
2906         if (base != NULL) {
2907                 base += 1;
2908         } else {
2909                 base = name;
2910         }
2911         return lpcfg_parm_int(lp_ctx, NULL, "tdb_hashsize", base, 0);
2912
2913 }
2914
2915 int lpcfg_tdb_flags(struct loadparm_context *lp_ctx, int tdb_flags)
2916 {
2917         if (!lpcfg_use_mmap(lp_ctx)) {
2918                 tdb_flags |= TDB_NOMMAP;
2919         }
2920         return tdb_flags;
2921 }