s3-mdssvc: add new option 'spotlight'
[kai/samba-autobuild/.git] / source3 / 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) Michael Adam 2008
13    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
14    Copyright (C) Andrew Bartlett 2011
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 "system/filesys.h"
58 #include "util_tdb.h"
59 #include "lib/param/loadparm.h"
60 #include "lib/param/param.h"
61 #include "printing.h"
62 #include "lib/smbconf/smbconf.h"
63 #include "lib/smbconf/smbconf_init.h"
64
65 #include "ads.h"
66 #include "../librpc/gen_ndr/svcctl.h"
67 #include "intl.h"
68 #include "../libcli/smb/smb_signing.h"
69 #include "dbwrap/dbwrap.h"
70 #include "dbwrap/dbwrap_rbt.h"
71 #include "../lib/util/bitmap.h"
72 #include "librpc/gen_ndr/nbt.h"
73
74 #ifdef HAVE_SYS_SYSCTL_H
75 #include <sys/sysctl.h>
76 #endif
77
78 #ifdef HAVE_HTTPCONNECTENCRYPT
79 #include <cups/http.h>
80 #endif
81
82 bool bLoaded = false;
83
84 extern userdom_struct current_user_info;
85
86 /* the special value for the include parameter
87  * to be interpreted not as a file name but to
88  * trigger loading of the global smb.conf options
89  * from registry. */
90 #ifndef INCLUDE_REGISTRY_NAME
91 #define INCLUDE_REGISTRY_NAME "registry"
92 #endif
93
94 static bool in_client = false;          /* Not in the client by default */
95 static struct smbconf_csn conf_last_csn;
96
97 static int config_backend = CONFIG_BACKEND_FILE;
98
99 /* some helpful bits */
100 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
101 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
102
103 #define USERSHARE_VALID 1
104 #define USERSHARE_PENDING_DELETE 2
105
106 static bool defaults_saved = false;
107
108 #include "lib/param/param_global.h"
109
110 static struct loadparm_global Globals;
111
112 /* This is a default service used to prime a services structure */
113 static struct loadparm_service sDefault =
114 {
115         .valid = true,
116         .autoloaded = false,
117         .usershare = 0,
118         .usershare_last_mod = {0, 0},
119         .szService = NULL,
120         .path = NULL,
121         .username = NULL,
122         .invalid_users = NULL,
123         .valid_users = NULL,
124         .admin_users = NULL,
125         .szCopy = NULL,
126         .szInclude = NULL,
127         .preexec = NULL,
128         .postexec = NULL,
129         .root_preexec = NULL,
130         .root_postexec = NULL,
131         .cups_options = NULL,
132         .print_command = NULL,
133         .lpq_command = NULL,
134         .lprm_command = NULL,
135         .lppause_command = NULL,
136         .lpresume_command = NULL,
137         .queuepause_command = NULL,
138         .queueresume_command = NULL,
139         ._printername = NULL,
140         .printjob_username = NULL,
141         .dont_descend = NULL,
142         .hosts_allow = NULL,
143         .hosts_deny = NULL,
144         .magic_script = NULL,
145         .magic_output = NULL,
146         .veto_files = NULL,
147         .hide_files = NULL,
148         .veto_oplock_files = NULL,
149         .comment = NULL,
150         .force_user = NULL,
151         .force_group = NULL,
152         .read_list = NULL,
153         .write_list = NULL,
154         .volume = NULL,
155         .fstype = NULL,
156         .vfs_objects = NULL,
157         .msdfs_proxy = NULL,
158         .aio_write_behind = NULL,
159         .dfree_command = NULL,
160         .min_print_space = 0,
161         .iMaxPrintJobs = 1000,
162         .max_reported_print_jobs = 0,
163         .write_cache_size = 0,
164         .create_mask = 0744,
165         .force_create_mode = 0,
166         .directory_mask = 0755,
167         .force_directory_mode = 0,
168         .max_connections = 0,
169         .default_case = CASE_LOWER,
170         .printing = DEFAULT_PRINTING,
171         .oplock_contention_limit = 2,
172         .csc_policy = 0,
173         .block_size = 1024,
174         .dfree_cache_time = 0,
175         .preexec_close = false,
176         .root_preexec_close = false,
177         .case_sensitive = Auto,
178         .preserve_case = true,
179         .short_preserve_case = true,
180         .hide_dot_files = true,
181         .hide_special_files = false,
182         .hide_unreadable = false,
183         .hide_unwriteable_files = false,
184         .browseable = true,
185         .access_based_share_enum = false,
186         .bAvailable = true,
187         .read_only = true,
188         .spotlight = false,
189         .guest_only = false,
190         .administrative_share = false,
191         .guest_ok = false,
192         .printable = false,
193         .print_notify_backchannel = false,
194         .map_system = false,
195         .map_hidden = false,
196         .map_archive = true,
197         .store_dos_attributes = false,
198         .dmapi_support = false,
199         .locking = true,
200         .strict_locking = Auto,
201         .posix_locking = true,
202         .oplocks = true,
203         .kernel_oplocks = false,
204         .level2_oplocks = true,
205         .only_user = false,
206         .mangled_names = true,
207         .bWidelinks = false,
208         .follow_symlinks = true,
209         .sync_always = false,
210         .strict_allocate = false,
211         .strict_rename = false,
212         .strict_sync = false,
213         .mangling_char = '~',
214         .copymap = NULL,
215         .delete_readonly = false,
216         .fake_oplocks = false,
217         .delete_veto_files = false,
218         .dos_filemode = false,
219         .dos_filetimes = true,
220         .dos_filetime_resolution = false,
221         .fake_directory_create_times = false,
222         .blocking_locks = true,
223         .inherit_permissions = false,
224         .inherit_acls = false,
225         .inherit_owner = false,
226         .msdfs_root = false,
227         .msdfs_shuffle_referrals = false,
228         .use_client_driver = false,
229         .default_devmode = true,
230         .force_printername = false,
231         .nt_acl_support = true,
232         .force_unknown_acl_user = false,
233         ._use_sendfile = false,
234         .profile_acls = false,
235         .map_acl_inherit = false,
236         .afs_share = false,
237         .ea_support = false,
238         .acl_check_permissions = true,
239         .acl_map_full_control = true,
240         .acl_group_control = false,
241         .acl_allow_execute_always = false,
242         .change_notify = true,
243         .kernel_change_notify = true,
244         .allocation_roundup_size = SMB_ROUNDUP_ALLOCATION_SIZE,
245         .aio_read_size = 0,
246         .aio_write_size = 0,
247         .map_readonly = MAP_READONLY_YES,
248         .directory_name_cache_size = 100,
249         .smb_encrypt = SMB_SIGNING_DEFAULT,
250         .kernel_share_modes = true,
251         .durable_handles = true,
252         .param_opt = NULL,
253         .dummy = ""
254 };
255
256 /* local variables */
257 static struct loadparm_service **ServicePtrs = NULL;
258 static int iNumServices = 0;
259 static int iServiceIndex = 0;
260 static struct db_context *ServiceHash;
261 static bool bInGlobalSection = true;
262 static bool bGlobalOnly = false;
263 static struct file_lists *file_lists = NULL;
264 static unsigned int *flags_list = NULL;
265
266 static void set_allowed_client_auth(void);
267
268 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue);
269 static void free_param_opts(struct parmlist_entry **popts);
270
271 /* this is used to prevent lots of mallocs of size 1 */
272 static const char null_string[] = "";
273
274 /**
275  Free a string value.
276 **/
277
278 static void string_free(char **s)
279 {
280         if (!s || !(*s))
281                 return;
282         if (*s == null_string)
283                 *s = NULL;
284         TALLOC_FREE(*s);
285 }
286
287 /**
288  Set a string value, deallocating any existing space, and allocing the space
289  for the string
290 **/
291
292 static bool string_set(TALLOC_CTX *mem_ctx, char **dest,const char *src)
293 {
294         string_free(dest);
295
296         if (!src) {
297                 src = "";
298         }
299
300         (*dest) = talloc_strdup(mem_ctx, src);
301         if ((*dest) == NULL) {
302                 DEBUG(0,("Out of memory in string_init\n"));
303                 return false;
304         }
305
306         return true;
307 }
308
309 /**
310  *  Function to return the default value for the maximum number of open
311  *  file descriptors permitted.  This function tries to consult the
312  *  kernel-level (sysctl) and ulimit (getrlimit()) values and goes
313  *  the smaller of those.
314  */
315 static int max_open_files(void)
316 {
317         int sysctl_max = MAX_OPEN_FILES;
318         int rlimit_max = MAX_OPEN_FILES;
319
320 #ifdef HAVE_SYSCTLBYNAME
321         {
322                 size_t size = sizeof(sysctl_max);
323                 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
324                              0);
325         }
326 #endif
327
328 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
329         {
330                 struct rlimit rl;
331
332                 ZERO_STRUCT(rl);
333
334                 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
335                         rlimit_max = rl.rlim_cur;
336
337 #if defined(RLIM_INFINITY)
338                 if(rl.rlim_cur == RLIM_INFINITY)
339                         rlimit_max = MAX_OPEN_FILES;
340 #endif
341         }
342 #endif
343
344         if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
345                 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
346                         "minimum Windows limit (%d)\n",
347                         sysctl_max,
348                         MIN_OPEN_FILES_WINDOWS));
349                 sysctl_max = MIN_OPEN_FILES_WINDOWS;
350         }
351
352         if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
353                 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
354                         "minimum Windows limit (%d)\n",
355                         rlimit_max,
356                         MIN_OPEN_FILES_WINDOWS));
357                 rlimit_max = MIN_OPEN_FILES_WINDOWS;
358         }
359
360         return MIN(sysctl_max, rlimit_max);
361 }
362
363 /**
364  * Common part of freeing allocated data for one parameter.
365  */
366 static void free_one_parameter_common(void *parm_ptr,
367                                       struct parm_struct parm)
368 {
369         if ((parm.type == P_STRING) ||
370             (parm.type == P_USTRING))
371         {
372                 string_free((char**)parm_ptr);
373         } else if (parm.type == P_LIST || parm.type == P_CMDLIST) {
374                 TALLOC_FREE(*((char***)parm_ptr));
375         }
376 }
377
378 /**
379  * Free the allocated data for one parameter for a share
380  * given as a service struct.
381  */
382 static void free_one_parameter(struct loadparm_service *service,
383                                struct parm_struct parm)
384 {
385         void *parm_ptr;
386
387         if (parm.p_class != P_LOCAL) {
388                 return;
389         }
390
391         parm_ptr = lp_parm_ptr(service, &parm);
392
393         free_one_parameter_common(parm_ptr, parm);
394 }
395
396 /**
397  * Free the allocated parameter data of a share given
398  * as a service struct.
399  */
400 static void free_parameters(struct loadparm_service *service)
401 {
402         uint32_t i;
403
404         for (i=0; parm_table[i].label; i++) {
405                 free_one_parameter(service, parm_table[i]);
406         }
407 }
408
409 /**
410  * Free the allocated data for one parameter for a given share
411  * specified by an snum.
412  */
413 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
414 {
415         void *parm_ptr;
416
417         if (snum < 0) {
418                 parm_ptr = lp_parm_ptr(NULL, &parm);
419         } else if (parm.p_class != P_LOCAL) {
420                 return;
421         } else {
422                 parm_ptr = lp_parm_ptr(ServicePtrs[snum], &parm);
423         }
424
425         free_one_parameter_common(parm_ptr, parm);
426 }
427
428 /**
429  * Free the allocated parameter data for a share specified
430  * by an snum.
431  */
432 static void free_parameters_by_snum(int snum)
433 {
434         uint32_t i;
435
436         for (i=0; parm_table[i].label; i++) {
437                 free_one_parameter_by_snum(snum, parm_table[i]);
438         }
439 }
440
441 /**
442  * Free the allocated global parameters.
443  */
444 static void free_global_parameters(void)
445 {
446         free_param_opts(&Globals.param_opt);
447         free_parameters_by_snum(GLOBAL_SECTION_SNUM);
448         TALLOC_FREE(Globals.ctx);
449 }
450
451 struct lp_stored_option {
452         struct lp_stored_option *prev, *next;
453         const char *label;
454         const char *value;
455 };
456
457 static struct lp_stored_option *stored_options;
458
459 /*
460   save options set by lp_set_cmdline() into a list. This list is
461   re-applied when we do a globals reset, so that cmdline set options
462   are sticky across reloads of smb.conf
463  */
464 bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
465 {
466         struct lp_stored_option *entry, *entry_next;
467         for (entry = stored_options; entry != NULL; entry = entry_next) {
468                 entry_next = entry->next;
469                 if (strcmp(pszParmName, entry->label) == 0) {
470                         DLIST_REMOVE(stored_options, entry);
471                         talloc_free(entry);
472                         break;
473                 }
474         }
475
476         entry = talloc(NULL, struct lp_stored_option);
477         if (!entry) {
478                 return false;
479         }
480
481         entry->label = talloc_strdup(entry, pszParmName);
482         if (!entry->label) {
483                 talloc_free(entry);
484                 return false;
485         }
486
487         entry->value = talloc_strdup(entry, pszParmValue);
488         if (!entry->value) {
489                 talloc_free(entry);
490                 return false;
491         }
492
493         DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
494
495         return true;
496 }
497
498 static bool apply_lp_set_cmdline(void)
499 {
500         struct lp_stored_option *entry = NULL;
501         for (entry = stored_options; entry != NULL; entry = entry->next) {
502                 if (!lp_set_cmdline_helper(entry->label, entry->value)) {
503                         DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
504                                   entry->label, entry->value));
505                         return false;
506                 }
507         }
508         return true;
509 }
510
511 /***************************************************************************
512  Initialise the global parameter structure.
513 ***************************************************************************/
514
515 static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
516 {
517         static bool done_init = false;
518         char *s = NULL;
519         int i;
520
521         /* If requested to initialize only once and we've already done it... */
522         if (!reinit_globals && done_init) {
523                 /* ... then we have nothing more to do */
524                 return;
525         }
526
527         if (!done_init) {
528                 /* The logfile can be set before this is invoked. Free it if so. */
529                 if (Globals.logfile != NULL) {
530                         string_free(&Globals.logfile);
531                         Globals.logfile = NULL;
532                 }
533                 done_init = true;
534         } else {
535                 free_global_parameters();
536         }
537
538         /* This memset and the free_global_parameters() above will
539          * wipe out smb.conf options set with lp_set_cmdline().  The
540          * apply_lp_set_cmdline() call puts these values back in the
541          * table once the defaults are set */
542         ZERO_STRUCT(Globals);
543
544         Globals.ctx = talloc_pooled_object(NULL, char, 272, 2048);
545
546         /* Initialize the flags list if necessary */
547         if (flags_list == NULL) {
548                 get_flags();
549         }
550
551         for (i = 0; parm_table[i].label; i++) {
552                 if ((parm_table[i].type == P_STRING ||
553                      parm_table[i].type == P_USTRING))
554                 {
555                         string_set(Globals.ctx, (char **)lp_parm_ptr(NULL, &parm_table[i]), "");
556                 }
557         }
558
559
560         string_set(Globals.ctx, &sDefault.fstype, FSTYPE_STRING);
561         string_set(Globals.ctx, &sDefault.printjob_username, "%U");
562
563         init_printer_values(lp_ctx, Globals.ctx, &sDefault);
564
565         sDefault.ntvfs_handler = str_list_make_v3_const(NULL, "unixuid default", NULL);
566
567         DEBUG(3, ("Initialising global parameters\n"));
568
569         /* Must manually force to upper case here, as this does not go via the handler */
570         string_set(Globals.ctx, &Globals.netbios_name, myhostname_upper());
571
572         string_set(Globals.ctx, &Globals.smb_passwd_file, get_dyn_SMB_PASSWD_FILE());
573         string_set(Globals.ctx, &Globals.private_dir, get_dyn_PRIVATE_DIR());
574
575         /* use the new 'hash2' method by default, with a prefix of 1 */
576         string_set(Globals.ctx, &Globals.mangling_method, "hash2");
577         Globals.mangle_prefix = 1;
578
579         string_set(Globals.ctx, &Globals.guest_account, GUEST_ACCOUNT);
580
581         /* using UTF8 by default allows us to support all chars */
582         string_set(Globals.ctx, &Globals.unix_charset, DEFAULT_UNIX_CHARSET);
583
584         /* Use codepage 850 as a default for the dos character set */
585         string_set(Globals.ctx, &Globals.dos_charset, DEFAULT_DOS_CHARSET);
586
587         /*
588          * Allow the default PASSWD_CHAT to be overridden in local.h.
589          */
590         string_set(Globals.ctx, &Globals.passwd_chat, DEFAULT_PASSWD_CHAT);
591
592         string_set(Globals.ctx, &Globals.workgroup, DEFAULT_WORKGROUP);
593
594         string_set(Globals.ctx, &Globals.passwd_program, "");
595         string_set(Globals.ctx, &Globals.lock_directory, get_dyn_LOCKDIR());
596         string_set(Globals.ctx, &Globals.state_directory, get_dyn_STATEDIR());
597         string_set(Globals.ctx, &Globals.cache_directory, get_dyn_CACHEDIR());
598         string_set(Globals.ctx, &Globals.pid_directory, get_dyn_PIDDIR());
599         string_set(Globals.ctx, &Globals.nbt_client_socket_address, "0.0.0.0");
600         /*
601          * By default support explicit binding to broadcast
602          * addresses.
603          */
604         Globals.nmbd_bind_explicit_broadcast = true;
605
606         s = talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
607         if (s == NULL) {
608                 smb_panic("init_globals: ENOMEM");
609         }
610         string_set(Globals.ctx, &Globals.server_string, s);
611         TALLOC_FREE(s);
612 #ifdef DEVELOPER
613         string_set(Globals.ctx, &Globals.panic_action, "/bin/sleep 999999999");
614 #endif
615
616         string_set(Globals.ctx, &Globals.socket_options, DEFAULT_SOCKET_OPTIONS);
617
618         string_set(Globals.ctx, &Globals.logon_drive, "");
619         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
620         string_set(Globals.ctx, &Globals.logon_home, "\\\\%N\\%U");
621         string_set(Globals.ctx, &Globals.logon_path, "\\\\%N\\%U\\profile");
622
623         Globals.name_resolve_order = str_list_make_v3_const(NULL, "lmhosts wins host bcast", NULL);
624         string_set(Globals.ctx, &Globals.password_server, "*");
625
626         Globals.algorithmic_rid_base = BASE_RID;
627
628         Globals.load_printers = true;
629         Globals.printcap_cache_time = 750;      /* 12.5 minutes */
630
631         Globals.config_backend = config_backend;
632         Globals._server_role = ROLE_AUTO;
633
634         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
635         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
636         Globals.max_xmit = 0x4104;
637         Globals.max_mux = 50;   /* This is *needed* for profile support. */
638         Globals.lpq_cache_time = 30;    /* changed to handle large print servers better -- jerry */
639         Globals._disable_spoolss = false;
640         Globals.max_smbd_processes = 0;/* no limit specified */
641         Globals.username_level = 0;
642         Globals.deadtime = 0;
643         Globals.getwd_cache = true;
644         Globals.large_readwrite = true;
645         Globals.max_log_size = 5000;
646         Globals.max_open_files = max_open_files();
647         Globals.server_max_protocol = PROTOCOL_SMB3_11;
648         Globals.server_min_protocol = PROTOCOL_LANMAN1;
649         Globals._client_max_protocol = PROTOCOL_DEFAULT;
650         Globals.client_min_protocol = PROTOCOL_CORE;
651         Globals._security = SEC_AUTO;
652         Globals.encrypt_passwords = true;
653         Globals.client_schannel = Auto;
654         Globals.winbind_sealed_pipes = true;
655         Globals.require_strong_key = true;
656         Globals.server_schannel = Auto;
657         Globals.read_raw = true;
658         Globals.write_raw = true;
659         Globals.null_passwords = false;
660         Globals.old_password_allowed_period = 60;
661         Globals.obey_pam_restrictions = false;
662         Globals.syslog = 1;
663         Globals.syslog_only = false;
664         Globals.timestamp_logs = true;
665         string_set(Globals.ctx, &Globals.log_level, "0");
666         Globals.debug_prefix_timestamp = false;
667         Globals.debug_hires_timestamp = true;
668         Globals.debug_pid = false;
669         Globals.debug_uid = false;
670         Globals.debug_class = false;
671         Globals.enable_core_files = true;
672         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
673         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
674         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
675         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
676         Globals.lm_announce = Auto;     /* = Auto: send only if LM clients found */
677         Globals.lm_interval = 60;
678 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
679         Globals.nis_homedir = false;
680 #ifdef WITH_NISPLUS_HOME
681         string_set(Globals.ctx, &Globals.homedir_map, "auto_home.org_dir");
682 #else
683         string_set(Globals.ctx, &Globals.homedir_map, "auto.home");
684 #endif
685 #endif
686         Globals.time_server = false;
687         Globals.bind_interfaces_only = false;
688         Globals.unix_password_sync = false;
689         Globals.pam_password_change = false;
690         Globals.passwd_chat_debug = false;
691         Globals.passwd_chat_timeout = 2; /* 2 second default. */
692         Globals.nt_pipe_support = true; /* Do NT pipes by default. */
693         Globals.nt_status_support = true; /* Use NT status by default. */
694         Globals.smbd_profiling_level = 0;
695         Globals.stat_cache = true;      /* use stat cache by default */
696         Globals.max_stat_cache_size = 256; /* 256k by default */
697         Globals.restrict_anonymous = 0;
698         Globals.client_lanman_auth = false;     /* Do NOT use the LanMan hash if it is available */
699         Globals.client_plaintext_auth = false;  /* Do NOT use a plaintext password even if is requested by the server */
700         Globals.lanman_auth = false;    /* Do NOT use the LanMan hash, even if it is supplied */
701         Globals.ntlm_auth = true;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
702         Globals.client_ntlmv2_auth = true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
703         /* Note, that we will also use NTLM2 session security (which is different), if it is available */
704
705         Globals.map_to_guest = 0;       /* By Default, "Never" */
706         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
707         Globals.enhanced_browsing = true;
708         Globals.lock_spin_time = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
709 #ifdef MMAP_BLACKLIST
710         Globals.use_mmap = false;
711 #else
712         Globals.use_mmap = true;
713 #endif
714         Globals.unicode = true;
715         Globals.unix_extensions = true;
716         Globals.reset_on_zero_vc = false;
717         Globals.log_writeable_files_on_exit = false;
718         Globals.create_krb5_conf = true;
719         Globals.winbindMaxDomainConnections = 1;
720
721         /* hostname lookups can be very expensive and are broken on
722            a large number of sites (tridge) */
723         Globals.hostname_lookups = false;
724
725         string_set(Globals.ctx, &Globals.passdb_backend, "tdbsam");
726         string_set(Globals.ctx, &Globals.ldap_suffix, "");
727         string_set(Globals.ctx, &Globals.szLdapMachineSuffix, "");
728         string_set(Globals.ctx, &Globals.szLdapUserSuffix, "");
729         string_set(Globals.ctx, &Globals.szLdapGroupSuffix, "");
730         string_set(Globals.ctx, &Globals.szLdapIdmapSuffix, "");
731
732         string_set(Globals.ctx, &Globals.ldap_admin_dn, "");
733         Globals.ldap_ssl = LDAP_SSL_START_TLS;
734         Globals.ldap_ssl_ads = false;
735         Globals.ldap_deref = -1;
736         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
737         Globals.ldap_delete_dn = false;
738         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
739         Globals.ldap_follow_referral = Auto;
740         Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
741         Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
742         Globals.ldap_page_size = LDAP_PAGE_SIZE;
743
744         Globals.ldap_debug_level = 0;
745         Globals.ldap_debug_threshold = 10;
746
747         Globals.client_ldap_sasl_wrapping = ADS_AUTH_SASL_SIGN;
748
749         /* This is what we tell the afs client. in reality we set the token 
750          * to never expire, though, when this runs out the afs client will 
751          * forget the token. Set to 0 to get NEVERDATE.*/
752         Globals.afs_token_lifetime = 604800;
753         Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
754
755 /* these parameters are set to defaults that are more appropriate
756    for the increasing samba install base:
757
758    as a member of the workgroup, that will possibly become a
759    _local_ master browser (lm = true).  this is opposed to a forced
760    local master browser startup (pm = true).
761
762    doesn't provide WINS server service by default (wsupp = false),
763    and doesn't provide domain master browser services by default, either.
764
765 */
766
767         Globals.show_add_printer_wizard = true;
768         Globals.os_level = 20;
769         Globals.local_master = true;
770         Globals._domain_master = Auto;  /* depending on _domain_logons */
771         Globals._domain_logons = false;
772         Globals.browse_list = true;
773         Globals.we_are_a_wins_server = false;
774         Globals.wins_proxy = false;
775
776         TALLOC_FREE(Globals.init_logon_delayed_hosts);
777         Globals.init_logon_delay = 100; /* 100 ms default delay */
778
779         Globals.wins_dns_proxy = true;
780
781         Globals.allow_trusted_domains = true;
782         string_set(Globals.ctx, &Globals.szIdmapBackend, "tdb");
783
784         string_set(Globals.ctx, &Globals.template_shell, "/bin/false");
785         string_set(Globals.ctx, &Globals.template_homedir, "/home/%D/%U");
786         string_set(Globals.ctx, &Globals.winbind_separator, "\\");
787         string_set(Globals.ctx, &Globals.winbindd_socket_directory, dyn_WINBINDD_SOCKET_DIR);
788
789         string_set(Globals.ctx, &Globals.cups_server, "");
790         string_set(Globals.ctx, &Globals.iprint_server, "");
791
792         string_set(Globals.ctx, &Globals._ctdbd_socket, "");
793
794         Globals.cluster_addresses = NULL;
795         Globals.clustering = false;
796         Globals.ctdb_timeout = 0;
797         Globals.ctdb_locktime_warn_threshold = 0;
798
799         Globals.winbind_cache_time = 300;       /* 5 minutes */
800         Globals.winbind_reconnect_delay = 30;   /* 30 seconds */
801         Globals.winbind_request_timeout = 60;   /* 60 seconds */
802         Globals.winbind_max_clients = 200;
803         Globals.winbind_enum_users = false;
804         Globals.winbind_enum_groups = false;
805         Globals.winbind_use_default_domain = false;
806         Globals.winbind_trusted_domains_only = false;
807         Globals.winbind_nested_groups = true;
808         Globals.winbind_expand_groups = 0;
809         Globals.winbind_nss_info = str_list_make_v3_const(NULL, "template", NULL);
810         Globals.winbind_refresh_tickets = false;
811         Globals.winbind_offline_logon = false;
812
813         Globals.idmap_cache_time = 86400 * 7; /* a week by default */
814         Globals.idmap_negative_cache_time = 120; /* 2 minutes by default */
815
816         Globals.passdb_expand_explicit = false;
817
818         Globals.name_cache_timeout = 660; /* In seconds */
819
820         Globals.use_spnego = true;
821         Globals.client_use_spnego = true;
822
823         Globals.client_signing = SMB_SIGNING_DEFAULT;
824         Globals.server_signing = SMB_SIGNING_DEFAULT;
825
826         Globals.defer_sharing_violations = true;
827         Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL);
828
829         Globals.enable_privileges = true;
830         Globals.host_msdfs        = true;
831         Globals.enable_asu_support       = false;
832
833         /* User defined shares. */
834         s = talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
835         if (s == NULL) {
836                 smb_panic("init_globals: ENOMEM");
837         }
838         string_set(Globals.ctx, &Globals.usershare_path, s);
839         TALLOC_FREE(s);
840         string_set(Globals.ctx, &Globals.usershare_template_share, "");
841         Globals.usershare_max_shares = 0;
842         /* By default disallow sharing of directories not owned by the sharer. */
843         Globals.usershare_owner_only = true;
844         /* By default disallow guest access to usershares. */
845         Globals.usershare_allow_guests = false;
846
847         Globals.keepalive = DEFAULT_KEEPALIVE;
848
849         /* By default no shares out of the registry */
850         Globals.registry_shares = false;
851
852         Globals.iminreceivefile = 0;
853
854         Globals.map_untrusted_to_domain = false;
855         Globals.multicast_dns_register = true;
856
857         Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
858         Globals.smb2_max_write = DEFAULT_SMB2_MAX_WRITE;
859         Globals.smb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
860         Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
861         Globals.smb2_leases = false;
862
863         string_set(Globals.ctx, &Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
864
865         Globals.server_services = str_list_make_v3_const(NULL, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbindd ntp_signd kcc dnsupdate dns", NULL);
866
867         Globals.dcerpc_endpoint_servers = str_list_make_v3_const(NULL, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL);
868
869         Globals.tls_enabled = true;
870
871         string_set(Globals.ctx, &Globals._tls_keyfile, "tls/key.pem");
872         string_set(Globals.ctx, &Globals._tls_certfile, "tls/cert.pem");
873         string_set(Globals.ctx, &Globals._tls_cafile, "tls/ca.pem");
874
875         string_set(Globals.ctx, &Globals.share_backend, "classic");
876
877         Globals.iPreferredMaster = Auto;
878
879         Globals.allow_dns_updates = DNS_UPDATE_SIGNED;
880
881         string_set(Globals.ctx, &Globals.ntp_signd_socket_directory, get_dyn_NTP_SIGND_SOCKET_DIR());
882
883         string_set(Globals.ctx, &Globals.winbindd_privileged_socket_directory, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
884
885         s = talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
886         if (s == NULL) {
887                 smb_panic("init_globals: ENOMEM");
888         }
889         Globals.samba_kcc_command = str_list_make_v3_const(NULL, s, NULL);
890         TALLOC_FREE(s);
891
892         s = talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
893         if (s == NULL) {
894                 smb_panic("init_globals: ENOMEM");
895         }
896         Globals.dns_update_command = str_list_make_v3_const(NULL, s, NULL);
897         TALLOC_FREE(s);
898
899         s = talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
900         if (s == NULL) {
901                 smb_panic("init_globals: ENOMEM");
902         }
903         Globals.spn_update_command = str_list_make_v3_const(NULL, s, NULL);
904         TALLOC_FREE(s);
905
906         Globals.nsupdate_command = str_list_make_v3_const(NULL, "/usr/bin/nsupdate -g", NULL);
907
908         Globals.rndc_command = str_list_make_v3_const(NULL, "/usr/sbin/rndc", NULL);
909
910         Globals.cldap_port = 389;
911
912         Globals.dgram_port = NBT_DGRAM_SERVICE_PORT;
913
914         Globals.nbt_port = NBT_NAME_SERVICE_PORT;
915
916         Globals.krb5_port = 88;
917
918         Globals.kpasswd_port = 464;
919
920         Globals.web_port = 901;
921
922         /* Now put back the settings that were set with lp_set_cmdline() */
923         apply_lp_set_cmdline();
924 }
925
926 /* Convenience routine to setup an lp_context with additional s3 variables */
927 static struct loadparm_context *setup_lp_context(TALLOC_CTX *mem_ctx)
928 {
929         struct loadparm_context *lp_ctx;
930
931         lp_ctx = loadparm_init_s3(mem_ctx,
932                                   loadparm_s3_helpers());
933         if (lp_ctx == NULL) {
934                 DEBUG(0, ("loadparm_init_s3 failed\n"));
935                 return NULL;
936         }
937
938         lp_ctx->sDefault = &sDefault;
939         lp_ctx->services = NULL; /* We do not want to access this directly */
940         lp_ctx->bInGlobalSection = bInGlobalSection;
941         lp_ctx->flags = flags_list;
942
943         return lp_ctx;
944 }
945
946 /*******************************************************************
947  Convenience routine to grab string parameters into talloced memory
948  and run standard_sub_basic on them. The buffers can be written to by
949  callers without affecting the source string.
950 ********************************************************************/
951
952 char *lp_string(TALLOC_CTX *ctx, const char *s)
953 {
954         char *ret;
955
956         /* The follow debug is useful for tracking down memory problems
957            especially if you have an inner loop that is calling a lp_*()
958            function that returns a string.  Perhaps this debug should be
959            present all the time? */
960
961 #if 0
962         DEBUG(10, ("lp_string(%s)\n", s));
963 #endif
964         if (!s) {
965                 return NULL;
966         }
967
968         ret = talloc_sub_basic(ctx,
969                         get_current_username(),
970                         current_user_info.domain,
971                         s);
972         if (trim_char(ret, '\"', '\"')) {
973                 if (strchr(ret,'\"') != NULL) {
974                         TALLOC_FREE(ret);
975                         ret = talloc_sub_basic(ctx,
976                                         get_current_username(),
977                                         current_user_info.domain,
978                                         s);
979                 }
980         }
981         return ret;
982 }
983
984 /*
985    In this section all the functions that are used to access the
986    parameters from the rest of the program are defined
987 */
988
989 #define FN_GLOBAL_STRING(fn_name,ptr) \
990 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
991 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
992  const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
993 #define FN_GLOBAL_LIST(fn_name,ptr) \
994  const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
995 #define FN_GLOBAL_BOOL(fn_name,ptr) \
996  bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
997 #define FN_GLOBAL_CHAR(fn_name,ptr) \
998  char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
999 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1000  int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1001
1002 #define FN_LOCAL_STRING(fn_name,val) \
1003 char *lp_ ## fn_name(TALLOC_CTX *ctx,int i) {return(lp_string((ctx), (LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1004 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1005  const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1006 #define FN_LOCAL_LIST(fn_name,val) \
1007  const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1008 #define FN_LOCAL_BOOL(fn_name,val) \
1009  bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1010 #define FN_LOCAL_INTEGER(fn_name,val) \
1011  int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1012
1013 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1014  bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1015 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1016  int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1017 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1018  char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1019
1020 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int,
1021                   winbindMaxDomainConnections)
1022
1023 int lp_winbind_max_domain_connections(void)
1024 {
1025         if (lp_winbind_offline_logon() &&
1026             lp_winbind_max_domain_connections_int() > 1) {
1027                 DEBUG(1, ("offline logons active, restricting max domain "
1028                           "connections to 1\n"));
1029                 return 1;
1030         }
1031         return MAX(1, lp_winbind_max_domain_connections_int());
1032 }
1033
1034 int lp_smb2_max_credits(void)
1035 {
1036         if (Globals.ismb2_max_credits == 0) {
1037                 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
1038         }
1039         return Globals.ismb2_max_credits;
1040 }
1041 int lp_cups_encrypt(void)
1042 {
1043         int result = 0;
1044 #ifdef HAVE_HTTPCONNECTENCRYPT
1045         switch (Globals.CupsEncrypt) {
1046                 case Auto:
1047                         result = HTTP_ENCRYPT_REQUIRED;
1048                         break;
1049                 case true:
1050                         result = HTTP_ENCRYPT_ALWAYS;
1051                         break;
1052                 case false:
1053                         result = HTTP_ENCRYPT_NEVER;
1054                         break;
1055         }
1056 #endif
1057         return result;
1058 }
1059
1060 /* These functions remain in source3/param for now */
1061
1062 #include "lib/param/param_functions.c"
1063
1064 FN_LOCAL_STRING(servicename, szService)
1065 FN_LOCAL_CONST_STRING(const_servicename, szService)
1066
1067 /* These functions cannot be auto-generated */
1068 FN_LOCAL_BOOL(autoloaded, autoloaded)
1069 FN_GLOBAL_CONST_STRING(dnsdomain, dnsdomain)
1070
1071 /* local prototypes */
1072
1073 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
1074 static const char *get_boolean(bool bool_value);
1075 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
1076                          void *userdata);
1077 static bool hash_a_service(const char *name, int number);
1078 static void free_service_byindex(int iService);
1079 static void show_parameter(int parmIndex);
1080 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
1081
1082 /*
1083  * This is a helper function for parametrical options support.  It returns a
1084  * pointer to parametrical option value if it exists or NULL otherwise. Actual
1085  * parametrical functions are quite simple
1086  */
1087 static struct parmlist_entry *get_parametrics(int snum, const char *type,
1088                                                 const char *option)
1089 {
1090         if (snum >= iNumServices) return NULL;
1091
1092         if (snum < 0) {
1093                 return get_parametric_helper(NULL, type, option, Globals.param_opt);
1094         } else {
1095                 return get_parametric_helper(ServicePtrs[snum],
1096                                              type, option, Globals.param_opt);
1097         }
1098 }
1099
1100
1101 #define MISSING_PARAMETER(name) \
1102     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1103
1104 /*******************************************************************
1105 convenience routine to return enum parameters.
1106 ********************************************************************/
1107 static int lp_enum(const char *s,const struct enum_list *_enum)
1108 {
1109         int i;
1110
1111         if (!s || !*s || !_enum) {
1112                 MISSING_PARAMETER(lp_enum);
1113                 return (-1);
1114         }
1115
1116         for (i=0; _enum[i].name; i++) {
1117                 if (strequal(_enum[i].name,s))
1118                         return _enum[i].value;
1119         }
1120
1121         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1122         return (-1);
1123 }
1124
1125 #undef MISSING_PARAMETER
1126
1127 /* Return parametric option from a given service. Type is a part of option before ':' */
1128 /* Parametric option has following syntax: 'Type: option = value' */
1129 char *lp_parm_talloc_string(TALLOC_CTX *ctx, int snum, const char *type, const char *option, const char *def)
1130 {
1131         struct parmlist_entry *data = get_parametrics(snum, type, option);
1132
1133         if (data == NULL||data->value==NULL) {
1134                 if (def) {
1135                         return lp_string(ctx, def);
1136                 } else {
1137                         return NULL;
1138                 }
1139         }
1140
1141         return lp_string(ctx, data->value);
1142 }
1143
1144 /* Return parametric option from a given service. Type is a part of option before ':' */
1145 /* Parametric option has following syntax: 'Type: option = value' */
1146 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
1147 {
1148         struct parmlist_entry *data = get_parametrics(snum, type, option);
1149
1150         if (data == NULL||data->value==NULL)
1151                 return def;
1152
1153         return data->value;
1154 }
1155
1156
1157 /* Return parametric option from a given service. Type is a part of option before ':' */
1158 /* Parametric option has following syntax: 'Type: option = value' */
1159
1160 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
1161 {
1162         struct parmlist_entry *data = get_parametrics(snum, type, option);
1163
1164         if (data == NULL||data->value==NULL)
1165                 return (const char **)def;
1166
1167         if (data->list==NULL) {
1168                 data->list = str_list_make_v3(NULL, data->value, NULL);
1169         }
1170
1171         return discard_const_p(const char *, data->list);
1172 }
1173
1174 /* Return parametric option from a given service. Type is a part of option before ':' */
1175 /* Parametric option has following syntax: 'Type: option = value' */
1176
1177 int lp_parm_int(int snum, const char *type, const char *option, int def)
1178 {
1179         struct parmlist_entry *data = get_parametrics(snum, type, option);
1180
1181         if (data && data->value && *data->value)
1182                 return lp_int(data->value);
1183
1184         return def;
1185 }
1186
1187 /* Return parametric option from a given service. Type is a part of option before ':' */
1188 /* Parametric option has following syntax: 'Type: option = value' */
1189
1190 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
1191 {
1192         struct parmlist_entry *data = get_parametrics(snum, type, option);
1193
1194         if (data && data->value && *data->value)
1195                 return lp_ulong(data->value);
1196
1197         return def;
1198 }
1199
1200 /* Return parametric option from a given service. Type is a part of option before ':' */
1201 /* Parametric option has following syntax: 'Type: option = value' */
1202
1203 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
1204 {
1205         struct parmlist_entry *data = get_parametrics(snum, type, option);
1206
1207         if (data && data->value && *data->value)
1208                 return lp_bool(data->value);
1209
1210         return def;
1211 }
1212
1213 /* Return parametric option from a given service. Type is a part of option before ':' */
1214 /* Parametric option has following syntax: 'Type: option = value' */
1215
1216 int lp_parm_enum(int snum, const char *type, const char *option,
1217                  const struct enum_list *_enum, int def)
1218 {
1219         struct parmlist_entry *data = get_parametrics(snum, type, option);
1220
1221         if (data && data->value && *data->value && _enum)
1222                 return lp_enum(data->value, _enum);
1223
1224         return def;
1225 }
1226
1227 /**
1228  * free a param_opts structure.
1229  * param_opts handling should be moved to talloc;
1230  * then this whole functions reduces to a TALLOC_FREE().
1231  */
1232
1233 static void free_param_opts(struct parmlist_entry **popts)
1234 {
1235         struct parmlist_entry *opt, *next_opt;
1236
1237         if (*popts != NULL) {
1238                 DEBUG(5, ("Freeing parametrics:\n"));
1239         }
1240         opt = *popts;
1241         while (opt != NULL) {
1242                 string_free(&opt->key);
1243                 string_free(&opt->value);
1244                 TALLOC_FREE(opt->list);
1245                 next_opt = opt->next;
1246                 TALLOC_FREE(opt);
1247                 opt = next_opt;
1248         }
1249         *popts = NULL;
1250 }
1251
1252 /***************************************************************************
1253  Free the dynamically allocated parts of a service struct.
1254 ***************************************************************************/
1255
1256 static void free_service(struct loadparm_service *pservice)
1257 {
1258         if (!pservice)
1259                 return;
1260
1261         if (pservice->szService)
1262                 DEBUG(5, ("free_service: Freeing service %s\n",
1263                        pservice->szService));
1264
1265         free_parameters(pservice);
1266
1267         string_free(&pservice->szService);
1268         TALLOC_FREE(pservice->copymap);
1269
1270         free_param_opts(&pservice->param_opt);
1271
1272         ZERO_STRUCTP(pservice);
1273 }
1274
1275
1276 /***************************************************************************
1277  remove a service indexed in the ServicePtrs array from the ServiceHash
1278  and free the dynamically allocated parts
1279 ***************************************************************************/
1280
1281 static void free_service_byindex(int idx)
1282 {
1283         if ( !LP_SNUM_OK(idx) ) 
1284                 return;
1285
1286         ServicePtrs[idx]->valid = false;
1287
1288         /* we have to cleanup the hash record */
1289
1290         if (ServicePtrs[idx]->szService) {
1291                 char *canon_name = canonicalize_servicename(
1292                         talloc_tos(),
1293                         ServicePtrs[idx]->szService );
1294
1295                 dbwrap_delete_bystring(ServiceHash, canon_name );
1296                 TALLOC_FREE(canon_name);
1297         }
1298
1299         free_service(ServicePtrs[idx]);
1300         talloc_free_children(ServicePtrs[idx]);
1301 }
1302
1303 /***************************************************************************
1304  Add a new service to the services array initialising it with the given 
1305  service. 
1306 ***************************************************************************/
1307
1308 static int add_a_service(const struct loadparm_service *pservice, const char *name)
1309 {
1310         int i;
1311         int num_to_alloc = iNumServices + 1;
1312         struct loadparm_service **tsp = NULL;
1313
1314         /* it might already exist */
1315         if (name) {
1316                 i = getservicebyname(name, NULL);
1317                 if (i >= 0) {
1318                         return (i);
1319                 }
1320         }
1321
1322         /* if not, then create one */
1323         i = iNumServices;
1324         tsp = talloc_realloc(NULL, ServicePtrs, struct loadparm_service *, num_to_alloc);
1325         if (tsp == NULL) {
1326                 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1327                 return (-1);
1328         }
1329         ServicePtrs = tsp;
1330         ServicePtrs[iNumServices] = talloc_zero(NULL, struct loadparm_service);
1331         if (!ServicePtrs[iNumServices]) {
1332                 DEBUG(0,("add_a_service: out of memory!\n"));
1333                 return (-1);
1334         }
1335         iNumServices++;
1336
1337         ServicePtrs[i]->valid = true;
1338
1339         copy_service(ServicePtrs[i], pservice, NULL);
1340         if (name)
1341                 string_set(ServicePtrs[i], &ServicePtrs[i]->szService, name);
1342
1343         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
1344                 i, ServicePtrs[i]->szService));
1345
1346         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
1347                 return (-1);
1348         }
1349
1350         return (i);
1351 }
1352
1353 /***************************************************************************
1354   Convert a string to uppercase and remove whitespaces.
1355 ***************************************************************************/
1356
1357 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
1358 {
1359         char *result;
1360
1361         if ( !src ) {
1362                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1363                 return NULL;
1364         }
1365
1366         result = talloc_strdup(ctx, src);
1367         SMB_ASSERT(result != NULL);
1368
1369         if (!strlower_m(result)) {
1370                 TALLOC_FREE(result);
1371                 return NULL;
1372         }
1373         return result;
1374 }
1375
1376 /***************************************************************************
1377   Add a name/index pair for the services array to the hash table.
1378 ***************************************************************************/
1379
1380 static bool hash_a_service(const char *name, int idx)
1381 {
1382         char *canon_name;
1383
1384         if ( !ServiceHash ) {
1385                 DEBUG(10,("hash_a_service: creating servicehash\n"));
1386                 ServiceHash = db_open_rbt(NULL);
1387                 if ( !ServiceHash ) {
1388                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1389                         return false;
1390                 }
1391         }
1392
1393         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1394                 idx, name));
1395
1396         canon_name = canonicalize_servicename(talloc_tos(), name );
1397
1398         dbwrap_store_bystring(ServiceHash, canon_name,
1399                               make_tdb_data((uint8_t *)&idx, sizeof(idx)),
1400                               TDB_REPLACE);
1401
1402         TALLOC_FREE(canon_name);
1403
1404         return true;
1405 }
1406
1407 /***************************************************************************
1408  Add a new home service, with the specified home directory, defaults coming
1409  from service ifrom.
1410 ***************************************************************************/
1411
1412 bool lp_add_home(const char *pszHomename, int iDefaultService,
1413                  const char *user, const char *pszHomedir)
1414 {
1415         int i;
1416
1417         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
1418                         pszHomedir[0] == '\0') {
1419                 return false;
1420         }
1421
1422         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1423
1424         if (i < 0)
1425                 return false;
1426
1427         if (!(*(ServicePtrs[iDefaultService]->path))
1428             || strequal(ServicePtrs[iDefaultService]->path,
1429                         lp_path(talloc_tos(), GLOBAL_SECTION_SNUM))) {
1430                 string_set(ServicePtrs[i], &ServicePtrs[i]->path, pszHomedir);
1431         }
1432
1433         if (!(*(ServicePtrs[i]->comment))) {
1434                 char *comment = talloc_asprintf(talloc_tos(), "Home directory of %s", user);
1435                 if (comment == NULL) {
1436                         return false;
1437                 }
1438                 string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1439                 TALLOC_FREE(comment);
1440         }
1441
1442         /* set the browseable flag from the global default */
1443
1444         ServicePtrs[i]->browseable = sDefault.browseable;
1445         ServicePtrs[i]->access_based_share_enum = sDefault.access_based_share_enum;
1446
1447         ServicePtrs[i]->autoloaded = true;
1448
1449         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
1450                user, ServicePtrs[i]->path ));
1451
1452         return true;
1453 }
1454
1455 /***************************************************************************
1456  Add a new service, based on an old one.
1457 ***************************************************************************/
1458
1459 int lp_add_service(const char *pszService, int iDefaultService)
1460 {
1461         if (iDefaultService < 0) {
1462                 return add_a_service(&sDefault, pszService);
1463         }
1464
1465         return (add_a_service(ServicePtrs[iDefaultService], pszService));
1466 }
1467
1468 /***************************************************************************
1469  Add the IPC service.
1470 ***************************************************************************/
1471
1472 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
1473 {
1474         char *comment = NULL;
1475         int i = add_a_service(&sDefault, ipc_name);
1476
1477         if (i < 0)
1478                 return false;
1479
1480         comment = talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1481                                   Globals.server_string);
1482         if (comment == NULL) {
1483                 return false;
1484         }
1485
1486         string_set(ServicePtrs[i], &ServicePtrs[i]->path, tmpdir());
1487         string_set(ServicePtrs[i], &ServicePtrs[i]->username, "");
1488         string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1489         string_set(ServicePtrs[i], &ServicePtrs[i]->fstype, "IPC");
1490         ServicePtrs[i]->max_connections = 0;
1491         ServicePtrs[i]->bAvailable = true;
1492         ServicePtrs[i]->read_only = true;
1493         ServicePtrs[i]->guest_only = false;
1494         ServicePtrs[i]->administrative_share = true;
1495         ServicePtrs[i]->guest_ok = guest_ok;
1496         ServicePtrs[i]->printable = false;
1497         ServicePtrs[i]->browseable = sDefault.browseable;
1498
1499         DEBUG(3, ("adding IPC service\n"));
1500
1501         TALLOC_FREE(comment);
1502         return true;
1503 }
1504
1505 /***************************************************************************
1506  Add a new printer service, with defaults coming from service iFrom.
1507 ***************************************************************************/
1508
1509 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
1510 {
1511         const char *comment = "From Printcap";
1512         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1513
1514         if (i < 0)
1515                 return false;
1516
1517         /* note that we do NOT default the availability flag to true - */
1518         /* we take it from the default service passed. This allows all */
1519         /* dynamic printers to be disabled by disabling the [printers] */
1520         /* entry (if/when the 'available' keyword is implemented!).    */
1521
1522         /* the printer name is set to the service name. */
1523         string_set(ServicePtrs[i], &ServicePtrs[i]->_printername, pszPrintername);
1524         string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
1525
1526         /* set the browseable flag from the gloabl default */
1527         ServicePtrs[i]->browseable = sDefault.browseable;
1528
1529         /* Printers cannot be read_only. */
1530         ServicePtrs[i]->read_only = false;
1531         /* No oplocks on printer services. */
1532         ServicePtrs[i]->oplocks = false;
1533         /* Printer services must be printable. */
1534         ServicePtrs[i]->printable = true;
1535
1536         DEBUG(3, ("adding printer service %s\n", pszPrintername));
1537
1538         return true;
1539 }
1540
1541
1542 /***************************************************************************
1543  Check whether the given parameter name is valid.
1544  Parametric options (names containing a colon) are considered valid.
1545 ***************************************************************************/
1546
1547 bool lp_parameter_is_valid(const char *pszParmName)
1548 {
1549         return ((lpcfg_map_parameter(pszParmName) != -1) ||
1550                 (strchr(pszParmName, ':') != NULL));
1551 }
1552
1553 /***************************************************************************
1554  Check whether the given name is the name of a global parameter.
1555  Returns true for strings belonging to parameters of class
1556  P_GLOBAL, false for all other strings, also for parametric options
1557  and strings not belonging to any option.
1558 ***************************************************************************/
1559
1560 bool lp_parameter_is_global(const char *pszParmName)
1561 {
1562         int num = lpcfg_map_parameter(pszParmName);
1563
1564         if (num >= 0) {
1565                 return (parm_table[num].p_class == P_GLOBAL);
1566         }
1567
1568         return false;
1569 }
1570
1571 /**************************************************************************
1572  Determine the canonical name for a parameter.
1573  Indicate when it is an inverse (boolean) synonym instead of a
1574  "usual" synonym.
1575 **************************************************************************/
1576
1577 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
1578                                bool *inverse)
1579 {
1580         int num;
1581
1582         if (!lp_parameter_is_valid(parm_name)) {
1583                 *canon_parm = NULL;
1584                 return false;
1585         }
1586
1587         num = map_parameter_canonical(parm_name, inverse);
1588         if (num < 0) {
1589                 /* parametric option */
1590                 *canon_parm = parm_name;
1591         } else {
1592                 *canon_parm = parm_table[num].label;
1593         }
1594
1595         return true;
1596
1597 }
1598
1599 /**************************************************************************
1600  Determine the canonical name for a parameter.
1601  Turn the value given into the inverse boolean expression when
1602  the synonym is an invers boolean synonym.
1603
1604  Return true if parm_name is a valid parameter name and
1605  in case it is an invers boolean synonym, if the val string could
1606  successfully be converted to the reverse bool.
1607  Return false in all other cases.
1608 **************************************************************************/
1609
1610 bool lp_canonicalize_parameter_with_value(const char *parm_name,
1611                                           const char *val,
1612                                           const char **canon_parm,
1613                                           const char **canon_val)
1614 {
1615         int num;
1616         bool inverse;
1617
1618         if (!lp_parameter_is_valid(parm_name)) {
1619                 *canon_parm = NULL;
1620                 *canon_val = NULL;
1621                 return false;
1622         }
1623
1624         num = map_parameter_canonical(parm_name, &inverse);
1625         if (num < 0) {
1626                 /* parametric option */
1627                 *canon_parm = parm_name;
1628                 *canon_val = val;
1629         } else {
1630                 *canon_parm = parm_table[num].label;
1631                 if (inverse) {
1632                         if (!lp_invert_boolean(val, canon_val)) {
1633                                 *canon_val = NULL;
1634                                 return false;
1635                         }
1636                 } else {
1637                         *canon_val = val;
1638                 }
1639         }
1640
1641         return true;
1642 }
1643
1644 /***************************************************************************
1645  Map a parameter's string representation to the index of the canonical
1646  form of the parameter (it might be a synonym).
1647  Returns -1 if the parameter string is not recognised.
1648 ***************************************************************************/
1649
1650 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
1651 {
1652         int parm_num, canon_num;
1653         bool loc_inverse = false;
1654
1655         parm_num = lpcfg_map_parameter(pszParmName);
1656         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_SYNONYM)) {
1657                 /* invalid, parametric or no canidate for synonyms ... */
1658                 goto done;
1659         }
1660
1661         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
1662                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
1663                         parm_num = canon_num;
1664                         goto done;
1665                 }
1666         }
1667
1668 done:
1669         if (inverse != NULL) {
1670                 *inverse = loc_inverse;
1671         }
1672         return parm_num;
1673 }
1674
1675 /***************************************************************************
1676  return true if parameter number parm1 is a synonym of parameter
1677  number parm2 (parm2 being the principal name).
1678  set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1679  false otherwise.
1680 ***************************************************************************/
1681
1682 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
1683 {
1684         if ((parm_table[parm1].offset == parm_table[parm2].offset) &&
1685             (parm_table[parm1].p_class == parm_table[parm2].p_class) &&
1686             (parm_table[parm1].flags & FLAG_SYNONYM) &&
1687             !(parm_table[parm2].flags & FLAG_SYNONYM))
1688         {
1689                 if (inverse != NULL) {
1690                         if ((parm_table[parm1].type == P_BOOLREV) &&
1691                             (parm_table[parm2].type == P_BOOL))
1692                         {
1693                                 *inverse = true;
1694                         } else {
1695                                 *inverse = false;
1696                         }
1697                 }
1698                 return true;
1699         }
1700         return false;
1701 }
1702
1703 /***************************************************************************
1704  Show one parameter's name, type, [values,] and flags.
1705  (helper functions for show_parameter_list)
1706 ***************************************************************************/
1707
1708 static void show_parameter(int parmIndex)
1709 {
1710         int enumIndex, flagIndex;
1711         int parmIndex2;
1712         bool hadFlag;
1713         bool hadSyn;
1714         bool inverse;
1715         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1716                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1717                 "P_ENUM", "P_BYTES", "P_CMDLIST" };
1718         unsigned flags[] = { FLAG_DEPRECATED, FLAG_SYNONYM };
1719         const char *flag_names[] = { "FLAG_DEPRECATED", "FLAG_SYNONYM", NULL};
1720
1721         printf("%s=%s", parm_table[parmIndex].label,
1722                type[parm_table[parmIndex].type]);
1723         if (parm_table[parmIndex].type == P_ENUM) {
1724                 printf(",");
1725                 for (enumIndex=0;
1726                      parm_table[parmIndex].enum_list[enumIndex].name;
1727                      enumIndex++)
1728                 {
1729                         printf("%s%s",
1730                                enumIndex ? "|" : "",
1731                                parm_table[parmIndex].enum_list[enumIndex].name);
1732                 }
1733         }
1734         printf(",");
1735         hadFlag = false;
1736         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
1737                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
1738                         printf("%s%s",
1739                                 hadFlag ? "|" : "",
1740                                 flag_names[flagIndex]);
1741                         hadFlag = true;
1742                 }
1743         }
1744
1745         /* output synonyms */
1746         hadSyn = false;
1747         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
1748                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
1749                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
1750                                parm_table[parmIndex2].label);
1751                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
1752                         if (!hadSyn) {
1753                                 printf(" (synonyms: ");
1754                                 hadSyn = true;
1755                         } else {
1756                                 printf(", ");
1757                         }
1758                         printf("%s%s", parm_table[parmIndex2].label,
1759                                inverse ? "[i]" : "");
1760                 }
1761         }
1762         if (hadSyn) {
1763                 printf(")");
1764         }
1765
1766         printf("\n");
1767 }
1768
1769 /***************************************************************************
1770  Show all parameter's name, type, [values,] and flags.
1771 ***************************************************************************/
1772
1773 void show_parameter_list(void)
1774 {
1775         int classIndex, parmIndex;
1776         const char *section_names[] = { "local", "global", NULL};
1777
1778         for (classIndex=0; section_names[classIndex]; classIndex++) {
1779                 printf("[%s]\n", section_names[classIndex]);
1780                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
1781                         if (parm_table[parmIndex].p_class == classIndex) {
1782                                 show_parameter(parmIndex);
1783                         }
1784                 }
1785         }
1786 }
1787
1788 /***************************************************************************
1789  Get the standard string representation of a boolean value ("yes" or "no")
1790 ***************************************************************************/
1791
1792 static const char *get_boolean(bool bool_value)
1793 {
1794         static const char *yes_str = "yes";
1795         static const char *no_str = "no";
1796
1797         return (bool_value ? yes_str : no_str);
1798 }
1799
1800 /***************************************************************************
1801  Provide the string of the negated boolean value associated to the boolean
1802  given as a string. Returns false if the passed string does not correctly
1803  represent a boolean.
1804 ***************************************************************************/
1805
1806 bool lp_invert_boolean(const char *str, const char **inverse_str)
1807 {
1808         bool val;
1809
1810         if (!set_boolean(str, &val)) {
1811                 return false;
1812         }
1813
1814         *inverse_str = get_boolean(!val);
1815         return true;
1816 }
1817
1818 /***************************************************************************
1819  Provide the canonical string representation of a boolean value given
1820  as a string. Return true on success, false if the string given does
1821  not correctly represent a boolean.
1822 ***************************************************************************/
1823
1824 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
1825 {
1826         bool val;
1827
1828         if (!set_boolean(str, &val)) {
1829                 return false;
1830         }
1831
1832         *canon_str = get_boolean(val);
1833         return true;
1834 }
1835
1836 /***************************************************************************
1837 Find a service by name. Otherwise works like get_service.
1838 ***************************************************************************/
1839
1840 int getservicebyname(const char *pszServiceName, struct loadparm_service *pserviceDest)
1841 {
1842         int iService = -1;
1843         char *canon_name;
1844         TDB_DATA data;
1845         NTSTATUS status;
1846
1847         if (ServiceHash == NULL) {
1848                 return -1;
1849         }
1850
1851         canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
1852
1853         status = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name,
1854                                        &data);
1855
1856         if (NT_STATUS_IS_OK(status) &&
1857             (data.dptr != NULL) &&
1858             (data.dsize == sizeof(iService)))
1859         {
1860                 iService = *(int *)data.dptr;
1861         }
1862
1863         TALLOC_FREE(canon_name);
1864
1865         if ((iService != -1) && (LP_SNUM_OK(iService))
1866             && (pserviceDest != NULL)) {
1867                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1868         }
1869
1870         return (iService);
1871 }
1872
1873 /* Return a pointer to a service by name.  Unlike getservicebyname, it does not copy the service */
1874 struct loadparm_service *lp_service(const char *pszServiceName)
1875 {
1876         int iService = getservicebyname(pszServiceName, NULL);
1877         if (iService == -1 || !LP_SNUM_OK(iService)) {
1878                 return NULL;
1879         }
1880         return ServicePtrs[iService];
1881 }
1882
1883 struct loadparm_service *lp_servicebynum(int snum)
1884 {
1885         if ((snum == -1) || !LP_SNUM_OK(snum)) {
1886                 return NULL;
1887         }
1888         return ServicePtrs[snum];
1889 }
1890
1891 struct loadparm_service *lp_default_loadparm_service()
1892 {
1893         return &sDefault;
1894 }
1895
1896 static struct smbconf_ctx *lp_smbconf_ctx(void)
1897 {
1898         sbcErr err;
1899         static struct smbconf_ctx *conf_ctx = NULL;
1900
1901         if (conf_ctx == NULL) {
1902                 err = smbconf_init(NULL, &conf_ctx, "registry:");
1903                 if (!SBC_ERROR_IS_OK(err)) {
1904                         DEBUG(1, ("error initializing registry configuration: "
1905                                   "%s\n", sbcErrorString(err)));
1906                         conf_ctx = NULL;
1907                 }
1908         }
1909
1910         return conf_ctx;
1911 }
1912
1913 static bool process_smbconf_service(struct smbconf_service *service)
1914 {
1915         uint32_t count;
1916         bool ret;
1917
1918         if (service == NULL) {
1919                 return false;
1920         }
1921
1922         ret = lp_do_section(service->name, NULL);
1923         if (ret != true) {
1924                 return false;
1925         }
1926         for (count = 0; count < service->num_params; count++) {
1927
1928                 if (!bInGlobalSection && bGlobalOnly) {
1929                         ret = true;
1930                 } else {
1931                         const char *pszParmName = service->param_names[count];
1932                         const char *pszParmValue = service->param_values[count];
1933
1934                         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
1935
1936                         ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
1937                                               pszParmName, pszParmValue);
1938                 }
1939
1940                 if (ret != true) {
1941                         return false;
1942                 }
1943         }
1944         if (iServiceIndex >= 0) {
1945                 return lpcfg_service_ok(ServicePtrs[iServiceIndex]);
1946         }
1947         return true;
1948 }
1949
1950 /**
1951  * load a service from registry and activate it
1952  */
1953 bool process_registry_service(const char *service_name)
1954 {
1955         sbcErr err;
1956         struct smbconf_service *service = NULL;
1957         TALLOC_CTX *mem_ctx = talloc_stackframe();
1958         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
1959         bool ret = false;
1960
1961         if (conf_ctx == NULL) {
1962                 goto done;
1963         }
1964
1965         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
1966
1967         if (!smbconf_share_exists(conf_ctx, service_name)) {
1968                 /*
1969                  * Registry does not contain data for this service (yet),
1970                  * but make sure lp_load doesn't return false.
1971                  */
1972                 ret = true;
1973                 goto done;
1974         }
1975
1976         err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
1977         if (!SBC_ERROR_IS_OK(err)) {
1978                 goto done;
1979         }
1980
1981         ret = process_smbconf_service(service);
1982         if (!ret) {
1983                 goto done;
1984         }
1985
1986         /* store the csn */
1987         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
1988
1989 done:
1990         TALLOC_FREE(mem_ctx);
1991         return ret;
1992 }
1993
1994 /*
1995  * process_registry_globals
1996  */
1997 static bool process_registry_globals(void)
1998 {
1999         bool ret;
2000
2001         add_to_file_list(NULL, &file_lists, INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
2002
2003         if (!bInGlobalSection && bGlobalOnly) {
2004                 ret = true;
2005         } else {
2006                 const char *pszParmName = "registry shares";
2007                 const char *pszParmValue = "yes";
2008
2009                 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2010
2011                 ret = lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2012                                       pszParmName, pszParmValue);
2013         }
2014
2015         if (!ret) {
2016                 return ret;
2017         }
2018
2019         return process_registry_service(GLOBAL_NAME);
2020 }
2021
2022 bool process_registry_shares(void)
2023 {
2024         sbcErr err;
2025         uint32_t count;
2026         struct smbconf_service **service = NULL;
2027         uint32_t num_shares = 0;
2028         TALLOC_CTX *mem_ctx = talloc_stackframe();
2029         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2030         bool ret = false;
2031
2032         if (conf_ctx == NULL) {
2033                 goto done;
2034         }
2035
2036         err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
2037         if (!SBC_ERROR_IS_OK(err)) {
2038                 goto done;
2039         }
2040
2041         ret = true;
2042
2043         for (count = 0; count < num_shares; count++) {
2044                 if (strequal(service[count]->name, GLOBAL_NAME)) {
2045                         continue;
2046                 }
2047                 ret = process_smbconf_service(service[count]);
2048                 if (!ret) {
2049                         goto done;
2050                 }
2051         }
2052
2053         /* store the csn */
2054         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
2055
2056 done:
2057         TALLOC_FREE(mem_ctx);
2058         return ret;
2059 }
2060
2061 /**
2062  * reload those shares from registry that are already
2063  * activated in the services array.
2064  */
2065 static bool reload_registry_shares(void)
2066 {
2067         int i;
2068         bool ret = true;
2069
2070         for (i = 0; i < iNumServices; i++) {
2071                 if (!VALID(i)) {
2072                         continue;
2073                 }
2074
2075                 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
2076                         continue;
2077                 }
2078
2079                 ret = process_registry_service(ServicePtrs[i]->szService);
2080                 if (!ret) {
2081                         goto done;
2082                 }
2083         }
2084
2085 done:
2086         return ret;
2087 }
2088
2089
2090 #define MAX_INCLUDE_DEPTH 100
2091
2092 static uint8_t include_depth;
2093
2094 /**
2095  * Free the file lists
2096  */
2097 static void free_file_list(void)
2098 {
2099         struct file_lists *f;
2100         struct file_lists *next;
2101
2102         f = file_lists;
2103         while( f ) {
2104                 next = f->next;
2105                 TALLOC_FREE( f );
2106                 f = next;
2107         }
2108         file_lists = NULL;
2109 }
2110
2111
2112 /**
2113  * Utility function for outsiders to check if we're running on registry.
2114  */
2115 bool lp_config_backend_is_registry(void)
2116 {
2117         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
2118 }
2119
2120 /**
2121  * Utility function to check if the config backend is FILE.
2122  */
2123 bool lp_config_backend_is_file(void)
2124 {
2125         return (lp_config_backend() == CONFIG_BACKEND_FILE);
2126 }
2127
2128 /*******************************************************************
2129  Check if a config file has changed date.
2130 ********************************************************************/
2131
2132 bool lp_file_list_changed(void)
2133 {
2134         struct file_lists *f = file_lists;
2135
2136         DEBUG(6, ("lp_file_list_changed()\n"));
2137
2138         while (f) {
2139                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
2140                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
2141
2142                         if (conf_ctx == NULL) {
2143                                 return false;
2144                         }
2145                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
2146                                             NULL))
2147                         {
2148                                 DEBUGADD(6, ("registry config changed\n"));
2149                                 return true;
2150                         }
2151                 } else {
2152                         time_t mod_time;
2153                         char *n2 = NULL;
2154
2155                         n2 = talloc_sub_basic(talloc_tos(),
2156                                               get_current_username(),
2157                                               current_user_info.domain,
2158                                               f->name);
2159                         if (!n2) {
2160                                 return false;
2161                         }
2162                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2163                                      f->name, n2, ctime(&f->modtime)));
2164
2165                         mod_time = file_modtime(n2);
2166
2167                         if (mod_time &&
2168                             ((f->modtime != mod_time) ||
2169                              (f->subfname == NULL) ||
2170                              (strcmp(n2, f->subfname) != 0)))
2171                         {
2172                                 DEBUGADD(6,
2173                                          ("file %s modified: %s\n", n2,
2174                                           ctime(&mod_time)));
2175                                 f->modtime = mod_time;
2176                                 TALLOC_FREE(f->subfname);
2177                                 f->subfname = talloc_strdup(f, n2);
2178                                 if (f->subfname == NULL) {
2179                                         smb_panic("talloc_strdup failed");
2180                                 }
2181                                 TALLOC_FREE(n2);
2182                                 return true;
2183                         }
2184                         TALLOC_FREE(n2);
2185                 }
2186                 f = f->next;
2187         }
2188         return false;
2189 }
2190
2191
2192 /**
2193  * Initialize iconv conversion descriptors.
2194  *
2195  * This is called the first time it is needed, and also called again
2196  * every time the configuration is reloaded, because the charset or
2197  * codepage might have changed.
2198  **/
2199 static void init_iconv(void)
2200 {
2201         global_iconv_handle = smb_iconv_handle_reinit(NULL, lp_dos_charset(),
2202                                                       lp_unix_charset(),
2203                                                       true, global_iconv_handle);
2204 }
2205
2206 /***************************************************************************
2207  Handle the include operation.
2208 ***************************************************************************/
2209 static bool bAllowIncludeRegistry = true;
2210
2211 bool lp_include(struct loadparm_context *lp_ctx, struct loadparm_service *service,
2212                 const char *pszParmValue, char **ptr)
2213 {
2214         char *fname;
2215
2216         if (include_depth >= MAX_INCLUDE_DEPTH) {
2217                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2218                           include_depth));
2219                 return false;
2220         }
2221
2222         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
2223                 if (!bAllowIncludeRegistry) {
2224                         return true;
2225                 }
2226                 if (lp_ctx->bInGlobalSection) {
2227                         bool ret;
2228                         include_depth++;
2229                         ret = process_registry_globals();
2230                         include_depth--;
2231                         return ret;
2232                 } else {
2233                         DEBUG(1, ("\"include = registry\" only effective "
2234                                   "in %s section\n", GLOBAL_NAME));
2235                         return false;
2236                 }
2237         }
2238
2239         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
2240                                  current_user_info.domain,
2241                                  pszParmValue);
2242
2243         add_to_file_list(NULL, &file_lists, pszParmValue, fname);
2244
2245         if (service == NULL) {
2246                 string_set(Globals.ctx, ptr, fname);
2247         } else {
2248                 string_set(service, ptr, fname);
2249         }
2250
2251         if (file_exist(fname)) {
2252                 bool ret;
2253                 include_depth++;
2254                 ret = pm_process(fname, lp_do_section, do_parameter, lp_ctx);
2255                 include_depth--;
2256                 TALLOC_FREE(fname);
2257                 return ret;
2258         }
2259
2260         DEBUG(2, ("Can't find include file %s\n", fname));
2261         TALLOC_FREE(fname);
2262         return true;
2263 }
2264
2265 bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high)
2266 {
2267         char *config_option = NULL;
2268         const char *range = NULL;
2269         bool ret = false;
2270
2271         SMB_ASSERT(low != NULL);
2272         SMB_ASSERT(high != NULL);
2273
2274         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2275                 domain_name = "*";
2276         }
2277
2278         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2279                                         domain_name);
2280         if (config_option == NULL) {
2281                 DEBUG(0, ("out of memory\n"));
2282                 return false;
2283         }
2284
2285         range = lp_parm_const_string(-1, config_option, "range", NULL);
2286         if (range == NULL) {
2287                 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name));
2288                 goto done;
2289         }
2290
2291         if (sscanf(range, "%u - %u", low, high) != 2) {
2292                 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2293                           range, domain_name));
2294                 goto done;
2295         }
2296
2297         ret = true;
2298
2299 done:
2300         talloc_free(config_option);
2301         return ret;
2302
2303 }
2304
2305 bool lp_idmap_default_range(uint32_t *low, uint32_t *high)
2306 {
2307         return lp_idmap_range("*", low, high);
2308 }
2309
2310 const char *lp_idmap_backend(const char *domain_name)
2311 {
2312         char *config_option = NULL;
2313         const char *backend = NULL;
2314
2315         if ((domain_name == NULL) || (domain_name[0] == '\0')) {
2316                 domain_name = "*";
2317         }
2318
2319         config_option = talloc_asprintf(talloc_tos(), "idmap config %s",
2320                                         domain_name);
2321         if (config_option == NULL) {
2322                 DEBUG(0, ("out of memory\n"));
2323                 return false;
2324         }
2325
2326         backend = lp_parm_const_string(-1, config_option, "backend", NULL);
2327         if (backend == NULL) {
2328                 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name));
2329                 goto done;
2330         }
2331
2332 done:
2333         talloc_free(config_option);
2334         return backend;
2335 }
2336
2337 const char *lp_idmap_default_backend(void)
2338 {
2339         return lp_idmap_backend("*");
2340 }
2341
2342 /***************************************************************************
2343  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2344 ***************************************************************************/
2345
2346 static const char *append_ldap_suffix(TALLOC_CTX *ctx, const char *str )
2347 {
2348         const char *suffix_string;
2349
2350         suffix_string = talloc_asprintf(ctx, "%s,%s", str,
2351                                         Globals.ldap_suffix );
2352         if ( !suffix_string ) {
2353                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2354                 return "";
2355         }
2356
2357         return suffix_string;
2358 }
2359
2360 const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx)
2361 {
2362         if (Globals.szLdapMachineSuffix[0])
2363                 return append_ldap_suffix(ctx, Globals.szLdapMachineSuffix);
2364
2365         return lp_string(ctx, Globals.ldap_suffix);
2366 }
2367
2368 const char *lp_ldap_user_suffix(TALLOC_CTX *ctx)
2369 {
2370         if (Globals.szLdapUserSuffix[0])
2371                 return append_ldap_suffix(ctx, Globals.szLdapUserSuffix);
2372
2373         return lp_string(ctx, Globals.ldap_suffix);
2374 }
2375
2376 const char *lp_ldap_group_suffix(TALLOC_CTX *ctx)
2377 {
2378         if (Globals.szLdapGroupSuffix[0])
2379                 return append_ldap_suffix(ctx, Globals.szLdapGroupSuffix);
2380
2381         return lp_string(ctx, Globals.ldap_suffix);
2382 }
2383
2384 const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx)
2385 {
2386         if (Globals.szLdapIdmapSuffix[0])
2387                 return append_ldap_suffix(ctx, Globals.szLdapIdmapSuffix);
2388
2389         return lp_string(ctx, Globals.ldap_suffix);
2390 }
2391
2392 /**
2393   return the parameter pointer for a parameter
2394 */
2395 void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm)
2396 {
2397         if (service == NULL) {
2398                 if (parm->p_class == P_LOCAL)
2399                         return (void *)(((char *)&sDefault)+parm->offset);
2400                 else if (parm->p_class == P_GLOBAL)
2401                         return (void *)(((char *)&Globals)+parm->offset);
2402                 else return NULL;
2403         } else {
2404                 return (void *)(((char *)service) + parm->offset);
2405         }
2406 }
2407
2408 /***************************************************************************
2409  Process a parameter for a particular service number. If snum < 0
2410  then assume we are in the globals.
2411 ***************************************************************************/
2412
2413 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2414 {
2415         TALLOC_CTX *frame = talloc_stackframe();
2416         struct loadparm_context *lp_ctx;
2417         bool ok;
2418
2419         lp_ctx = setup_lp_context(frame);
2420         if (lp_ctx == NULL) {
2421                 TALLOC_FREE(frame);
2422                 return false;
2423         }
2424
2425         if (snum < 0) {
2426                 ok = lpcfg_do_global_parameter(lp_ctx, pszParmName, pszParmValue);
2427         } else {
2428                 ok = lpcfg_do_service_parameter(lp_ctx, ServicePtrs[snum],
2429                                                 pszParmName, pszParmValue);
2430         }
2431
2432         TALLOC_FREE(frame);
2433
2434         return ok;
2435 }
2436
2437 /***************************************************************************
2438 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2439 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2440 ***************************************************************************/
2441
2442 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue)
2443 {
2444         int parmnum, i;
2445         parmnum = lpcfg_map_parameter(pszParmName);
2446         if (parmnum >= 0) {
2447                 flags_list[parmnum] &= ~FLAG_CMDLINE;
2448                 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
2449                         return false;
2450                 }
2451                 flags_list[parmnum] |= FLAG_CMDLINE;
2452
2453                 /* we have to also set FLAG_CMDLINE on aliases.  Aliases must
2454                  * be grouped in the table, so we don't have to search the
2455                  * whole table */
2456                 for (i=parmnum-1;
2457                      i>=0 && parm_table[i].offset == parm_table[parmnum].offset
2458                              && parm_table[i].p_class == parm_table[parmnum].p_class;
2459                      i--) {
2460                         flags_list[i] |= FLAG_CMDLINE;
2461                 }
2462                 for (i=parmnum+1;i<num_parameters() && parm_table[i].offset == parm_table[parmnum].offset
2463                              && parm_table[i].p_class == parm_table[parmnum].p_class;i++) {
2464                         flags_list[i] |= FLAG_CMDLINE;
2465                 }
2466
2467                 return true;
2468         }
2469
2470         /* it might be parametric */
2471         if (strchr(pszParmName, ':') != NULL) {
2472                 set_param_opt(NULL, &Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
2473                 return true;
2474         }
2475
2476         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",  pszParmName));
2477         return false;
2478 }
2479
2480 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2481 {
2482         bool ret;
2483         TALLOC_CTX *frame = talloc_stackframe();
2484         struct loadparm_context *lp_ctx;
2485
2486         lp_ctx = setup_lp_context(frame);
2487         if (lp_ctx == NULL) {
2488                 TALLOC_FREE(frame);
2489                 return false;
2490         }
2491
2492         ret = lpcfg_set_cmdline(lp_ctx, pszParmName, pszParmValue);
2493
2494         TALLOC_FREE(frame);
2495         return ret;
2496 }
2497
2498 /***************************************************************************
2499  Process a parameter.
2500 ***************************************************************************/
2501
2502 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
2503                          void *userdata)
2504 {
2505         if (!bInGlobalSection && bGlobalOnly)
2506                 return true;
2507
2508         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2509
2510         if (bInGlobalSection) {
2511                 return lpcfg_do_global_parameter(userdata, pszParmName, pszParmValue);
2512         } else {
2513                 return lpcfg_do_service_parameter(userdata, ServicePtrs[iServiceIndex],
2514                                                   pszParmName, pszParmValue);
2515         }
2516 }
2517
2518 /***************************************************************************
2519  Initialize any local variables in the sDefault table, after parsing a
2520  [globals] section.
2521 ***************************************************************************/
2522
2523 static void init_locals(void)
2524 {
2525         /*
2526          * We run this check once the [globals] is parsed, to force
2527          * the VFS objects and other per-share settings we need for
2528          * the standard way a AD DC is operated.  We may change these
2529          * as our code evolves, which is why we force these settings.
2530          *
2531          * We can't do this at the end of lp_load_ex(), as by that
2532          * point the services have been loaded and they will already
2533          * have "" as their vfs objects.
2534          */
2535         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
2536                 const char **vfs_objects = lp_vfs_objects(-1);
2537                 if (!vfs_objects || !vfs_objects[0]) {
2538                         if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) {
2539                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
2540                         } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) {
2541                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
2542                         } else {
2543                                 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
2544                         }
2545                 }
2546
2547                 lp_do_parameter(-1, "map hidden", "no");
2548                 lp_do_parameter(-1, "map system", "no");
2549                 lp_do_parameter(-1, "map readonly", "no");
2550                 lp_do_parameter(-1, "map archive", "no");
2551                 lp_do_parameter(-1, "store dos attributes", "yes");
2552         }
2553 }
2554
2555 /***************************************************************************
2556  Process a new section (service). At this stage all sections are services.
2557  Later we'll have special sections that permit server parameters to be set.
2558  Returns true on success, false on failure.
2559 ***************************************************************************/
2560
2561 bool lp_do_section(const char *pszSectionName, void *userdata)
2562 {
2563         struct loadparm_context *lp_ctx = (struct loadparm_context *)userdata;
2564         bool bRetval;
2565         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2566                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2567         bRetval = false;
2568
2569         /* if we were in a global section then do the local inits */
2570         if (bInGlobalSection && !isglobal)
2571                 init_locals();
2572
2573         /* if we've just struck a global section, note the fact. */
2574         bInGlobalSection = isglobal;
2575         if (lp_ctx != NULL) {
2576                 lp_ctx->bInGlobalSection = isglobal;
2577         }
2578
2579         /* check for multiple global sections */
2580         if (bInGlobalSection) {
2581                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2582                 return true;
2583         }
2584
2585         if (!bInGlobalSection && bGlobalOnly)
2586                 return true;
2587
2588         /* if we have a current service, tidy it up before moving on */
2589         bRetval = true;
2590
2591         if (iServiceIndex >= 0)
2592                 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
2593
2594         /* if all is still well, move to the next record in the services array */
2595         if (bRetval) {
2596                 /* We put this here to avoid an odd message order if messages are */
2597                 /* issued by the post-processing of a previous section. */
2598                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2599
2600                 iServiceIndex = add_a_service(&sDefault, pszSectionName);
2601                 if (iServiceIndex < 0) {
2602                         DEBUG(0, ("Failed to add a new service\n"));
2603                         return false;
2604                 }
2605                 /* Clean all parametric options for service */
2606                 /* They will be added during parsing again */
2607                 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
2608         }
2609
2610         return bRetval;
2611 }
2612
2613 /***************************************************************************
2614  Display the contents of a parameter of a single services record.
2615 ***************************************************************************/
2616
2617 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
2618 {
2619         bool result = false;
2620         struct loadparm_context *lp_ctx;
2621
2622         lp_ctx = setup_lp_context(talloc_tos());
2623         if (lp_ctx == NULL) {
2624                 return false;
2625         }
2626
2627         if (isGlobal) {
2628                 result = lpcfg_dump_a_parameter(lp_ctx, NULL, parm_name, f);
2629         } else {
2630                 result = lpcfg_dump_a_parameter(lp_ctx, ServicePtrs[snum], parm_name, f);
2631         }
2632         TALLOC_FREE(lp_ctx);
2633         return result;
2634 }
2635
2636 #if 0
2637 /***************************************************************************
2638  Display the contents of a single copy structure.
2639 ***************************************************************************/
2640 static void dump_copy_map(bool *pcopymap)
2641 {
2642         int i;
2643         if (!pcopymap)
2644                 return;
2645
2646         printf("\n\tNon-Copied parameters:\n");
2647
2648         for (i = 0; parm_table[i].label; i++)
2649                 if (parm_table[i].p_class == P_LOCAL &&
2650                     parm_table[i].ptr && !pcopymap[i] &&
2651                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
2652                 {
2653                         printf("\t\t%s\n", parm_table[i].label);
2654                 }
2655 }
2656 #endif
2657
2658 /***************************************************************************
2659  Return TRUE if the passed service number is within range.
2660 ***************************************************************************/
2661
2662 bool lp_snum_ok(int iService)
2663 {
2664         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2665 }
2666
2667 /***************************************************************************
2668  Auto-load some home services.
2669 ***************************************************************************/
2670
2671 static void lp_add_auto_services(char *str)
2672 {
2673         char *s;
2674         char *p;
2675         int homes;
2676         char *saveptr;
2677
2678         if (!str)
2679                 return;
2680
2681         s = talloc_strdup(talloc_tos(), str);
2682         if (!s) {
2683                 smb_panic("talloc_strdup failed");
2684                 return;
2685         }
2686
2687         homes = lp_servicenumber(HOMES_NAME);
2688
2689         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
2690              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
2691                 char *home;
2692
2693                 if (lp_servicenumber(p) >= 0)
2694                         continue;
2695
2696                 home = get_user_home_dir(talloc_tos(), p);
2697
2698                 if (home && home[0] && homes >= 0)
2699                         lp_add_home(p, homes, p, home);
2700
2701                 TALLOC_FREE(home);
2702         }
2703         TALLOC_FREE(s);
2704 }
2705
2706 /***************************************************************************
2707  Auto-load one printer.
2708 ***************************************************************************/
2709
2710 void lp_add_one_printer(const char *name, const char *comment,
2711                         const char *location, void *pdata)
2712 {
2713         int printers = lp_servicenumber(PRINTERS_NAME);
2714         int i;
2715
2716         if (lp_servicenumber(name) < 0) {
2717                 lp_add_printer(name, printers);
2718                 if ((i = lp_servicenumber(name)) >= 0) {
2719                         string_set(ServicePtrs[i], &ServicePtrs[i]->comment, comment);
2720                         ServicePtrs[i]->autoloaded = true;
2721                 }
2722         }
2723 }
2724
2725 /***************************************************************************
2726  Have we loaded a services file yet?
2727 ***************************************************************************/
2728
2729 bool lp_loaded(void)
2730 {
2731         return (bLoaded);
2732 }
2733
2734 /***************************************************************************
2735  Unload unused services.
2736 ***************************************************************************/
2737
2738 void lp_killunused(struct smbd_server_connection *sconn,
2739                    bool (*snumused) (struct smbd_server_connection *, int))
2740 {
2741         int i;
2742         for (i = 0; i < iNumServices; i++) {
2743                 if (!VALID(i))
2744                         continue;
2745
2746                 /* don't kill autoloaded or usershare services */
2747                 if ( ServicePtrs[i]->autoloaded ||
2748                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
2749                         continue;
2750                 }
2751
2752                 if (!snumused || !snumused(sconn, i)) {
2753                         free_service_byindex(i);
2754                 }
2755         }
2756 }
2757
2758 /**
2759  * Kill all except autoloaded and usershare services - convenience wrapper
2760  */
2761 void lp_kill_all_services(void)
2762 {
2763         lp_killunused(NULL, NULL);
2764 }
2765
2766 /***************************************************************************
2767  Unload a service.
2768 ***************************************************************************/
2769
2770 void lp_killservice(int iServiceIn)
2771 {
2772         if (VALID(iServiceIn)) {
2773                 free_service_byindex(iServiceIn);
2774         }
2775 }
2776
2777 /***************************************************************************
2778  Save the curent values of all global and sDefault parameters into the 
2779  defaults union. This allows testparm to show only the
2780  changed (ie. non-default) parameters.
2781 ***************************************************************************/
2782
2783 static void lp_save_defaults(void)
2784 {
2785         int i;
2786         struct parmlist_entry * parm;
2787         for (i = 0; parm_table[i].label; i++) {
2788                 if (!(flags_list[i] & FLAG_CMDLINE)) {
2789                         flags_list[i] |= FLAG_DEFAULT;
2790                 }
2791
2792                 if (i > 0 && parm_table[i].offset == parm_table[i - 1].offset
2793                     && parm_table[i].p_class == parm_table[i - 1].p_class)
2794                         continue;
2795                 switch (parm_table[i].type) {
2796                         case P_LIST:
2797                         case P_CMDLIST:
2798                                 parm_table[i].def.lvalue = str_list_copy(
2799                                         NULL, *(const char ***)lp_parm_ptr(NULL, &parm_table[i]));
2800                                 break;
2801                         case P_STRING:
2802                         case P_USTRING:
2803                                 parm_table[i].def.svalue = talloc_strdup(Globals.ctx, *(char **)lp_parm_ptr(NULL, &parm_table[i]));
2804                                 if (parm_table[i].def.svalue == NULL) {
2805                                         smb_panic("talloc_strdup failed");
2806                                 }
2807                                 break;
2808                         case P_BOOL:
2809                         case P_BOOLREV:
2810                                 parm_table[i].def.bvalue =
2811                                         *(bool *)lp_parm_ptr(NULL, &parm_table[i]);
2812                                 break;
2813                         case P_CHAR:
2814                                 parm_table[i].def.cvalue =
2815                                         *(char *)lp_parm_ptr(NULL, &parm_table[i]);
2816                                 break;
2817                         case P_INTEGER:
2818                         case P_OCTAL:
2819                         case P_ENUM:
2820                         case P_BYTES:
2821                                 parm_table[i].def.ivalue =
2822                                         *(int *)lp_parm_ptr(NULL, &parm_table[i]);
2823                                 break;
2824                 }
2825         }
2826
2827         for (parm=Globals.param_opt; parm; parm=parm->next) {
2828                 if (!(parm->priority & FLAG_CMDLINE)) {
2829                         parm->priority |= FLAG_DEFAULT;
2830                 }
2831         }
2832
2833         for (parm=sDefault.param_opt; parm; parm=parm->next) {
2834                 if (!(parm->priority & FLAG_CMDLINE)) {
2835                         parm->priority |= FLAG_DEFAULT;
2836                 }
2837         }
2838
2839         defaults_saved = true;
2840 }
2841
2842 /***********************************************************
2843  If we should send plaintext/LANMAN passwords in the clinet
2844 ************************************************************/
2845
2846 static void set_allowed_client_auth(void)
2847 {
2848         if (Globals.client_ntlmv2_auth) {
2849                 Globals.client_lanman_auth = false;
2850         }
2851         if (!Globals.client_lanman_auth) {
2852                 Globals.client_plaintext_auth = false;
2853         }
2854 }
2855
2856 /***************************************************************************
2857  JRA.
2858  The following code allows smbd to read a user defined share file.
2859  Yes, this is my intent. Yes, I'm comfortable with that...
2860
2861  THE FOLLOWING IS SECURITY CRITICAL CODE.
2862
2863  It washes your clothes, it cleans your house, it guards you while you sleep...
2864  Do not f%^k with it....
2865 ***************************************************************************/
2866
2867 #define MAX_USERSHARE_FILE_SIZE (10*1024)
2868
2869 /***************************************************************************
2870  Check allowed stat state of a usershare file.
2871  Ensure we print out who is dicking with us so the admin can
2872  get their sorry ass fired.
2873 ***************************************************************************/
2874
2875 static bool check_usershare_stat(const char *fname,
2876                                  const SMB_STRUCT_STAT *psbuf)
2877 {
2878         if (!S_ISREG(psbuf->st_ex_mode)) {
2879                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2880                         "not a regular file\n",
2881                         fname, (unsigned int)psbuf->st_ex_uid ));
2882                 return false;
2883         }
2884
2885         /* Ensure this doesn't have the other write bit set. */
2886         if (psbuf->st_ex_mode & S_IWOTH) {
2887                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
2888                         "public write. Refusing to allow as a usershare file.\n",
2889                         fname, (unsigned int)psbuf->st_ex_uid ));
2890                 return false;
2891         }
2892
2893         /* Should be 10k or less. */
2894         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
2895                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
2896                         "too large (%u) to be a user share file.\n",
2897                         fname, (unsigned int)psbuf->st_ex_uid,
2898                         (unsigned int)psbuf->st_ex_size ));
2899                 return false;
2900         }
2901
2902         return true;
2903 }
2904
2905 /***************************************************************************
2906  Parse the contents of a usershare file.
2907 ***************************************************************************/
2908
2909 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
2910                         SMB_STRUCT_STAT *psbuf,
2911                         const char *servicename,
2912                         int snum,
2913                         char **lines,
2914                         int numlines,
2915                         char **pp_sharepath,
2916                         char **pp_comment,
2917                         char **pp_cp_servicename,
2918                         struct security_descriptor **ppsd,
2919                         bool *pallow_guest)
2920 {
2921         const char **prefixallowlist = lp_usershare_prefix_allow_list();
2922         const char **prefixdenylist = lp_usershare_prefix_deny_list();
2923         int us_vers;
2924         DIR *dp;
2925         SMB_STRUCT_STAT sbuf;
2926         char *sharepath = NULL;
2927         char *comment = NULL;
2928
2929         *pp_sharepath = NULL;
2930         *pp_comment = NULL;
2931
2932         *pallow_guest = false;
2933
2934         if (numlines < 4) {
2935                 return USERSHARE_MALFORMED_FILE;
2936         }
2937
2938         if (strcmp(lines[0], "#VERSION 1") == 0) {
2939                 us_vers = 1;
2940         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
2941                 us_vers = 2;
2942                 if (numlines < 5) {
2943                         return USERSHARE_MALFORMED_FILE;
2944                 }
2945         } else {
2946                 return USERSHARE_BAD_VERSION;
2947         }
2948
2949         if (strncmp(lines[1], "path=", 5) != 0) {
2950                 return USERSHARE_MALFORMED_PATH;
2951         }
2952
2953         sharepath = talloc_strdup(ctx, &lines[1][5]);
2954         if (!sharepath) {
2955                 return USERSHARE_POSIX_ERR;
2956         }
2957         trim_string(sharepath, " ", " ");
2958
2959         if (strncmp(lines[2], "comment=", 8) != 0) {
2960                 return USERSHARE_MALFORMED_COMMENT_DEF;
2961         }
2962
2963         comment = talloc_strdup(ctx, &lines[2][8]);
2964         if (!comment) {
2965                 return USERSHARE_POSIX_ERR;
2966         }
2967         trim_string(comment, " ", " ");
2968         trim_char(comment, '"', '"');
2969
2970         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
2971                 return USERSHARE_MALFORMED_ACL_DEF;
2972         }
2973
2974         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
2975                 return USERSHARE_ACL_ERR;
2976         }
2977
2978         if (us_vers == 2) {
2979                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
2980                         return USERSHARE_MALFORMED_ACL_DEF;
2981                 }
2982                 if (lines[4][9] == 'y') {
2983                         *pallow_guest = true;
2984                 }
2985
2986                 /* Backwards compatible extension to file version #2. */
2987                 if (numlines > 5) {
2988                         if (strncmp(lines[5], "sharename=", 10) != 0) {
2989                                 return USERSHARE_MALFORMED_SHARENAME_DEF;
2990                         }
2991                         if (!strequal(&lines[5][10], servicename)) {
2992                                 return USERSHARE_BAD_SHARENAME;
2993                         }
2994                         *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
2995                         if (!*pp_cp_servicename) {
2996                                 return USERSHARE_POSIX_ERR;
2997                         }
2998                 }
2999         }
3000
3001         if (*pp_cp_servicename == NULL) {
3002                 *pp_cp_servicename = talloc_strdup(ctx, servicename);
3003                 if (!*pp_cp_servicename) {
3004                         return USERSHARE_POSIX_ERR;
3005                 }
3006         }
3007
3008         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->path) == 0)) {
3009                 /* Path didn't change, no checks needed. */
3010                 *pp_sharepath = sharepath;
3011                 *pp_comment = comment;
3012                 return USERSHARE_OK;
3013         }
3014
3015         /* The path *must* be absolute. */
3016         if (sharepath[0] != '/') {
3017                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3018                         servicename, sharepath));
3019                 return USERSHARE_PATH_NOT_ABSOLUTE;
3020         }
3021
3022         /* If there is a usershare prefix deny list ensure one of these paths
3023            doesn't match the start of the user given path. */
3024         if (prefixdenylist) {
3025                 int i;
3026                 for ( i=0; prefixdenylist[i]; i++ ) {
3027                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3028                                 servicename, i, prefixdenylist[i], sharepath ));
3029                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
3030                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3031                                         "usershare prefix deny list entries.\n",
3032                                         servicename, sharepath));
3033                                 return USERSHARE_PATH_IS_DENIED;
3034                         }
3035                 }
3036         }
3037
3038         /* If there is a usershare prefix allow list ensure one of these paths
3039            does match the start of the user given path. */
3040
3041         if (prefixallowlist) {
3042                 int i;
3043                 for ( i=0; prefixallowlist[i]; i++ ) {
3044                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3045                                 servicename, i, prefixallowlist[i], sharepath ));
3046                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
3047                                 break;
3048                         }
3049                 }
3050                 if (prefixallowlist[i] == NULL) {
3051                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3052                                 "usershare prefix allow list entries.\n",
3053                                 servicename, sharepath));
3054                         return USERSHARE_PATH_NOT_ALLOWED;
3055                 }
3056         }
3057
3058         /* Ensure this is pointing to a directory. */
3059         dp = opendir(sharepath);
3060
3061         if (!dp) {
3062                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3063                         servicename, sharepath));
3064                 return USERSHARE_PATH_NOT_DIRECTORY;
3065         }
3066
3067         /* Ensure the owner of the usershare file has permission to share
3068            this directory. */
3069
3070         if (sys_stat(sharepath, &sbuf, false) == -1) {
3071                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3072                         servicename, sharepath, strerror(errno) ));
3073                 closedir(dp);
3074                 return USERSHARE_POSIX_ERR;
3075         }
3076
3077         closedir(dp);
3078
3079         if (!S_ISDIR(sbuf.st_ex_mode)) {
3080                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3081                         servicename, sharepath ));
3082                 return USERSHARE_PATH_NOT_DIRECTORY;
3083         }
3084
3085         /* Check if sharing is restricted to owner-only. */
3086         /* psbuf is the stat of the usershare definition file,
3087            sbuf is the stat of the target directory to be shared. */
3088
3089         if (lp_usershare_owner_only()) {
3090                 /* root can share anything. */
3091                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
3092                         return USERSHARE_PATH_NOT_ALLOWED;
3093                 }
3094         }
3095
3096         *pp_sharepath = sharepath;
3097         *pp_comment = comment;
3098         return USERSHARE_OK;
3099 }
3100
3101 /***************************************************************************
3102  Deal with a usershare file.
3103  Returns:
3104         >= 0 - snum
3105         -1 - Bad name, invalid contents.
3106            - service name already existed and not a usershare, problem
3107             with permissions to share directory etc.
3108 ***************************************************************************/
3109
3110 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
3111 {
3112         SMB_STRUCT_STAT sbuf;
3113         SMB_STRUCT_STAT lsbuf;
3114         char *fname = NULL;
3115         char *sharepath = NULL;
3116         char *comment = NULL;
3117         char *cp_service_name = NULL;
3118         char **lines = NULL;
3119         int numlines = 0;
3120         int fd = -1;
3121         int iService = -1;
3122         TALLOC_CTX *ctx = talloc_stackframe();
3123         struct security_descriptor *psd = NULL;
3124         bool guest_ok = false;
3125         char *canon_name = NULL;
3126         bool added_service = false;
3127         int ret = -1;
3128
3129         /* Ensure share name doesn't contain invalid characters. */
3130         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
3131                 DEBUG(0,("process_usershare_file: share name %s contains "
3132                         "invalid characters (any of %s)\n",
3133                         file_name, INVALID_SHARENAME_CHARS ));
3134                 goto out;
3135         }
3136
3137         canon_name = canonicalize_servicename(ctx, file_name);
3138         if (!canon_name) {
3139                 goto out;
3140         }
3141
3142         fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
3143         if (!fname) {
3144                 goto out;
3145         }
3146
3147         /* Minimize the race condition by doing an lstat before we
3148            open and fstat. Ensure this isn't a symlink link. */
3149
3150         if (sys_lstat(fname, &lsbuf, false) != 0) {
3151                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3152                         fname, strerror(errno) ));
3153                 goto out;
3154         }
3155
3156         /* This must be a regular file, not a symlink, directory or
3157            other strange filetype. */
3158         if (!check_usershare_stat(fname, &lsbuf)) {
3159                 goto out;
3160         }
3161
3162         {
3163                 TDB_DATA data;
3164                 NTSTATUS status;
3165
3166                 status = dbwrap_fetch_bystring(ServiceHash, canon_name,
3167                                                canon_name, &data);
3168
3169                 iService = -1;
3170
3171                 if (NT_STATUS_IS_OK(status) &&
3172                     (data.dptr != NULL) &&
3173                     (data.dsize == sizeof(iService))) {
3174                         memcpy(&iService, data.dptr, sizeof(iService));
3175                 }
3176         }
3177
3178         if (iService != -1 &&
3179             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3180                              &lsbuf.st_ex_mtime) == 0) {
3181                 /* Nothing changed - Mark valid and return. */
3182                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3183                         canon_name ));
3184                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
3185                 ret = iService;
3186                 goto out;
3187         }
3188
3189         /* Try and open the file read only - no symlinks allowed. */
3190 #ifdef O_NOFOLLOW
3191         fd = open(fname, O_RDONLY|O_NOFOLLOW, 0);
3192 #else
3193         fd = open(fname, O_RDONLY, 0);
3194 #endif
3195
3196         if (fd == -1) {
3197                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3198                         fname, strerror(errno) ));
3199                 goto out;
3200         }
3201
3202         /* Now fstat to be *SURE* it's a regular file. */
3203         if (sys_fstat(fd, &sbuf, false) != 0) {
3204                 close(fd);
3205                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3206                         fname, strerror(errno) ));
3207                 goto out;
3208         }
3209
3210         /* Is it the same dev/inode as was lstated ? */
3211         if (!check_same_stat(&lsbuf, &sbuf)) {
3212                 close(fd);
3213                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3214                         "Symlink spoofing going on ?\n", fname ));
3215                 goto out;
3216         }
3217
3218         /* This must be a regular file, not a symlink, directory or
3219            other strange filetype. */
3220         if (!check_usershare_stat(fname, &sbuf)) {
3221                 close(fd);
3222                 goto out;
3223         }
3224
3225         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
3226
3227         close(fd);
3228         if (lines == NULL) {
3229                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3230                         fname, (unsigned int)sbuf.st_ex_uid ));
3231                 goto out;
3232         }
3233
3234         if (parse_usershare_file(ctx, &sbuf, file_name,
3235                         iService, lines, numlines, &sharepath,
3236                         &comment, &cp_service_name,
3237                         &psd, &guest_ok) != USERSHARE_OK) {
3238                 goto out;
3239         }
3240
3241         /* Everything ok - add the service possibly using a template. */
3242         if (iService < 0) {
3243                 const struct loadparm_service *sp = &sDefault;
3244                 if (snum_template != -1) {
3245                         sp = ServicePtrs[snum_template];
3246                 }
3247
3248                 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
3249                         DEBUG(0, ("process_usershare_file: Failed to add "
3250                                 "new service %s\n", cp_service_name));
3251                         goto out;
3252                 }
3253
3254                 added_service = true;
3255
3256                 /* Read only is controlled by usershare ACL below. */
3257                 ServicePtrs[iService]->read_only = false;
3258         }
3259
3260         /* Write the ACL of the new/modified share. */
3261         if (!set_share_security(canon_name, psd)) {
3262                  DEBUG(0, ("process_usershare_file: Failed to set share "
3263                         "security for user share %s\n",
3264                         canon_name ));
3265                 goto out;
3266         }
3267
3268         /* If from a template it may be marked invalid. */
3269         ServicePtrs[iService]->valid = true;
3270
3271         /* Set the service as a valid usershare. */
3272         ServicePtrs[iService]->usershare = USERSHARE_VALID;
3273
3274         /* Set guest access. */
3275         if (lp_usershare_allow_guests()) {
3276                 ServicePtrs[iService]->guest_ok = guest_ok;
3277         }
3278
3279         /* And note when it was loaded. */
3280         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
3281         string_set(ServicePtrs[iService], &ServicePtrs[iService]->path, sharepath);
3282         string_set(ServicePtrs[iService], &ServicePtrs[iService]->comment, comment);
3283
3284         ret = iService;
3285
3286   out:
3287
3288         if (ret == -1 && iService != -1 && added_service) {
3289                 lp_remove_service(iService);
3290         }
3291
3292         TALLOC_FREE(lines);
3293         TALLOC_FREE(ctx);
3294         return ret;
3295 }
3296
3297 /***************************************************************************
3298  Checks if a usershare entry has been modified since last load.
3299 ***************************************************************************/
3300
3301 static bool usershare_exists(int iService, struct timespec *last_mod)
3302 {
3303         SMB_STRUCT_STAT lsbuf;
3304         const char *usersharepath = Globals.usershare_path;
3305         char *fname;
3306
3307         fname = talloc_asprintf(talloc_tos(),
3308                                 "%s/%s",
3309                                 usersharepath,
3310                                 ServicePtrs[iService]->szService);
3311         if (fname == NULL) {
3312                 return false;
3313         }
3314
3315         if (sys_lstat(fname, &lsbuf, false) != 0) {
3316                 TALLOC_FREE(fname);
3317                 return false;
3318         }
3319
3320         if (!S_ISREG(lsbuf.st_ex_mode)) {
3321                 TALLOC_FREE(fname);
3322                 return false;
3323         }
3324
3325         TALLOC_FREE(fname);
3326         *last_mod = lsbuf.st_ex_mtime;
3327         return true;
3328 }
3329
3330 /***************************************************************************
3331  Load a usershare service by name. Returns a valid servicenumber or -1.
3332 ***************************************************************************/
3333
3334 int load_usershare_service(const char *servicename)
3335 {
3336         SMB_STRUCT_STAT sbuf;
3337         const char *usersharepath = Globals.usershare_path;
3338         int max_user_shares = Globals.usershare_max_shares;
3339         int snum_template = -1;
3340
3341         if (*usersharepath == 0 ||  max_user_shares == 0) {
3342                 return -1;
3343         }
3344
3345         if (sys_stat(usersharepath, &sbuf, false) != 0) {
3346                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
3347                         usersharepath, strerror(errno) ));
3348                 return -1;
3349         }
3350
3351         if (!S_ISDIR(sbuf.st_ex_mode)) {
3352                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
3353                         usersharepath ));
3354                 return -1;
3355         }
3356
3357         /*
3358          * This directory must be owned by root, and have the 't' bit set.
3359          * It also must not be writable by "other".
3360          */
3361
3362 #ifdef S_ISVTX
3363         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3364 #else
3365         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3366 #endif
3367                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
3368                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
3369                         usersharepath ));
3370                 return -1;
3371         }
3372
3373         /* Ensure the template share exists if it's set. */
3374         if (Globals.usershare_template_share[0]) {
3375                 /* We can't use lp_servicenumber here as we are recommending that
3376                    template shares have -valid=false set. */
3377                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3378                         if (ServicePtrs[snum_template]->szService &&
3379                                         strequal(ServicePtrs[snum_template]->szService,
3380                                                 Globals.usershare_template_share)) {
3381                                 break;
3382                         }
3383                 }
3384
3385                 if (snum_template == -1) {
3386                         DEBUG(0,("load_usershare_service: usershare template share %s "
3387                                 "does not exist.\n",
3388                                 Globals.usershare_template_share ));
3389                         return -1;
3390                 }
3391         }
3392
3393         return process_usershare_file(usersharepath, servicename, snum_template);
3394 }
3395
3396 /***************************************************************************
3397  Load all user defined shares from the user share directory.
3398  We only do this if we're enumerating the share list.
3399  This is the function that can delete usershares that have
3400  been removed.
3401 ***************************************************************************/
3402
3403 int load_usershare_shares(struct smbd_server_connection *sconn,
3404                           bool (*snumused) (struct smbd_server_connection *, int))
3405 {
3406         DIR *dp;
3407         SMB_STRUCT_STAT sbuf;
3408         struct dirent *de;
3409         int num_usershares = 0;
3410         int max_user_shares = Globals.usershare_max_shares;
3411         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
3412         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
3413         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
3414         int iService;
3415         int snum_template = -1;
3416         const char *usersharepath = Globals.usershare_path;
3417         int ret = lp_numservices();
3418         TALLOC_CTX *tmp_ctx;
3419
3420         if (max_user_shares == 0 || *usersharepath == '\0') {
3421                 return lp_numservices();
3422         }
3423
3424         if (sys_stat(usersharepath, &sbuf, false) != 0) {
3425                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
3426                         usersharepath, strerror(errno) ));
3427                 return ret;
3428         }
3429
3430         /*
3431          * This directory must be owned by root, and have the 't' bit set.
3432          * It also must not be writable by "other".
3433          */
3434
3435 #ifdef S_ISVTX
3436         if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
3437 #else
3438         if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
3439 #endif
3440                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
3441                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
3442                         usersharepath ));
3443                 return ret;
3444         }
3445
3446         /* Ensure the template share exists if it's set. */
3447         if (Globals.usershare_template_share[0]) {
3448                 /* We can't use lp_servicenumber here as we are recommending that
3449                    template shares have -valid=false set. */
3450                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
3451                         if (ServicePtrs[snum_template]->szService &&
3452                                         strequal(ServicePtrs[snum_template]->szService,
3453                                                 Globals.usershare_template_share)) {
3454                                 break;
3455                         }
3456                 }
3457
3458                 if (snum_template == -1) {
3459                         DEBUG(0,("load_usershare_shares: usershare template share %s "
3460                                 "does not exist.\n",
3461                                 Globals.usershare_template_share ));
3462                         return ret;
3463                 }
3464         }
3465
3466         /* Mark all existing usershares as pending delete. */
3467         for (iService = iNumServices - 1; iService >= 0; iService--) {
3468                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
3469                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
3470                 }
3471         }
3472
3473         dp = opendir(usersharepath);
3474         if (!dp) {
3475                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
3476                         usersharepath, strerror(errno) ));
3477                 return ret;
3478         }
3479
3480         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
3481                         (de = readdir(dp));
3482                         num_dir_entries++ ) {
3483                 int r;
3484                 const char *n = de->d_name;
3485
3486                 /* Ignore . and .. */
3487                 if (*n == '.') {
3488                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
3489                                 continue;
3490                         }
3491                 }
3492
3493                 if (n[0] == ':') {
3494                         /* Temporary file used when creating a share. */
3495                         num_tmp_dir_entries++;
3496                 }
3497
3498                 /* Allow 20% tmp entries. */
3499                 if (num_tmp_dir_entries > allowed_tmp_entries) {
3500                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
3501                                 "in directory %s\n",
3502                                 num_tmp_dir_entries, usersharepath));
3503                         break;
3504                 }
3505
3506                 r = process_usershare_file(usersharepath, n, snum_template);
3507                 if (r == 0) {
3508                         /* Update the services count. */
3509                         num_usershares++;
3510                         if (num_usershares >= max_user_shares) {
3511                                 DEBUG(0,("load_usershare_shares: max user shares reached "
3512                                         "on file %s in directory %s\n",
3513                                         n, usersharepath ));
3514                                 break;
3515                         }
3516                 } else if (r == -1) {
3517                         num_bad_dir_entries++;
3518                 }
3519
3520                 /* Allow 20% bad entries. */
3521                 if (num_bad_dir_entries > allowed_bad_entries) {
3522                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
3523                                 "in directory %s\n",
3524                                 num_bad_dir_entries, usersharepath));
3525                         break;
3526                 }
3527
3528                 /* Allow 20% bad entries. */
3529                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
3530                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
3531                         "in directory %s\n",
3532                         num_dir_entries, usersharepath));
3533                         break;
3534                 }
3535         }
3536
3537         closedir(dp);
3538
3539         /* Sweep through and delete any non-refreshed usershares that are
3540            not currently in use. */
3541         tmp_ctx = talloc_stackframe();
3542         for (iService = iNumServices - 1; iService >= 0; iService--) {
3543                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
3544                         char *servname;
3545
3546                         if (snumused && snumused(sconn, iService)) {
3547                                 continue;
3548                         }
3549
3550                         servname = lp_servicename(tmp_ctx, iService);
3551
3552                         /* Remove from the share ACL db. */
3553                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
3554                                   servname ));
3555                         delete_share_security(servname);
3556                         free_service_byindex(iService);
3557                 }
3558         }
3559         talloc_free(tmp_ctx);
3560
3561         return lp_numservices();
3562 }
3563
3564 /********************************************************
3565  Destroy global resources allocated in this file
3566 ********************************************************/
3567
3568 void gfree_loadparm(void)
3569 {
3570         int i;
3571
3572         free_file_list();
3573
3574         /* Free resources allocated to services */
3575
3576         for ( i = 0; i < iNumServices; i++ ) {
3577                 if ( VALID(i) ) {
3578                         free_service_byindex(i);
3579                 }
3580         }
3581
3582         TALLOC_FREE( ServicePtrs );
3583         iNumServices = 0;
3584
3585         /* Now release all resources allocated to global
3586            parameters and the default service */
3587
3588         free_global_parameters();
3589 }
3590
3591
3592 /***************************************************************************
3593  Allow client apps to specify that they are a client
3594 ***************************************************************************/
3595 static void lp_set_in_client(bool b)
3596 {
3597     in_client = b;
3598 }
3599
3600
3601 /***************************************************************************
3602  Determine if we're running in a client app
3603 ***************************************************************************/
3604 static bool lp_is_in_client(void)
3605 {
3606     return in_client;
3607 }
3608
3609 static void lp_enforce_ad_dc_settings(void)
3610 {
3611         lp_do_parameter(GLOBAL_SECTION_SNUM, "passdb backend", "samba_dsdb");
3612         lp_do_parameter(GLOBAL_SECTION_SNUM,
3613                         "winbindd:use external pipes", "true");
3614         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:default", "external");
3615         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:svcctl", "embedded");
3616         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:srvsvc", "embedded");
3617         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:eventlog", "embedded");
3618         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:ntsvcs", "embedded");
3619         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:winreg", "embedded");
3620         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:spoolss", "embedded");
3621         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_daemon:spoolssd", "embedded");
3622         lp_do_parameter(GLOBAL_SECTION_SNUM, "rpc_server:tcpip", "no");
3623 }
3624
3625 /***************************************************************************
3626  Load the services array from the services file. Return true on success,
3627  false on failure.
3628 ***************************************************************************/
3629
3630 static bool lp_load_ex(const char *pszFname,
3631                        bool global_only,
3632                        bool save_defaults,
3633                        bool add_ipc,
3634                        bool reinit_globals,
3635                        bool allow_include_registry,
3636                        bool load_all_shares)
3637 {
3638         char *n2 = NULL;
3639         bool bRetval;
3640         TALLOC_CTX *frame = talloc_stackframe();
3641         struct loadparm_context *lp_ctx;
3642
3643         bRetval = false;
3644
3645         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
3646
3647         bInGlobalSection = true;
3648         bGlobalOnly = global_only;
3649         bAllowIncludeRegistry = allow_include_registry;
3650
3651         lp_ctx = setup_lp_context(talloc_tos());
3652
3653         init_globals(lp_ctx, reinit_globals);
3654
3655         free_file_list();
3656
3657         if (save_defaults) {
3658                 init_locals();
3659                 lp_save_defaults();
3660         }
3661
3662         if (!reinit_globals) {
3663                 free_param_opts(&Globals.param_opt);
3664                 apply_lp_set_cmdline();
3665         }
3666
3667         lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
3668
3669         /* We get sections first, so have to start 'behind' to make up */
3670         iServiceIndex = -1;
3671
3672         if (lp_config_backend_is_file()) {
3673                 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
3674                                         current_user_info.domain,
3675                                         pszFname);
3676                 if (!n2) {
3677                         smb_panic("lp_load_ex: out of memory");
3678                 }
3679
3680                 add_to_file_list(NULL, &file_lists, pszFname, n2);
3681
3682                 bRetval = pm_process(n2, lp_do_section, do_parameter, lp_ctx);
3683                 TALLOC_FREE(n2);
3684
3685                 /* finish up the last section */
3686                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3687                 if (bRetval) {
3688                         if (iServiceIndex >= 0) {
3689                                 bRetval = lpcfg_service_ok(ServicePtrs[iServiceIndex]);
3690                         }
3691                 }
3692
3693                 if (lp_config_backend_is_registry()) {
3694                         bool ok;
3695                         /* config backend changed to registry in config file */
3696                         /*
3697                          * We need to use this extra global variable here to
3698                          * survive restart: init_globals uses this as a default
3699                          * for config_backend. Otherwise, init_globals would
3700                          *  send us into an endless loop here.
3701                          */
3702
3703                         config_backend = CONFIG_BACKEND_REGISTRY;
3704                         /* start over */
3705                         DEBUG(1, ("lp_load_ex: changing to config backend "
3706                                   "registry\n"));
3707                         init_globals(lp_ctx, true);
3708
3709                         TALLOC_FREE(lp_ctx);
3710
3711                         lp_kill_all_services();
3712                         ok = lp_load_ex(pszFname, global_only, save_defaults,
3713                                         add_ipc, reinit_globals,
3714                                         allow_include_registry,
3715                                         load_all_shares);
3716                         TALLOC_FREE(frame);
3717                         return ok;
3718                 }
3719         } else if (lp_config_backend_is_registry()) {
3720                 bRetval = process_registry_globals();
3721         } else {
3722                 DEBUG(0, ("Illegal config  backend given: %d\n",
3723                           lp_config_backend()));
3724                 bRetval = false;
3725         }
3726
3727         if (bRetval && lp_registry_shares()) {
3728                 if (load_all_shares) {
3729                         bRetval = process_registry_shares();
3730                 } else {
3731                         bRetval = reload_registry_shares();
3732                 }
3733         }
3734
3735         {
3736                 char *serv = lp_auto_services(talloc_tos());
3737                 lp_add_auto_services(serv);
3738                 TALLOC_FREE(serv);
3739         }
3740
3741         if (add_ipc) {
3742                 /* When 'restrict anonymous = 2' guest connections to ipc$
3743                    are denied */
3744                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3745                 if ( lp_enable_asu_support() ) {
3746                         lp_add_ipc("ADMIN$", false);
3747                 }
3748         }
3749
3750         set_allowed_client_auth();
3751
3752         if (lp_security() == SEC_ADS && strchr(lp_password_server(), ':')) {
3753                 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
3754                           lp_password_server()));
3755         }
3756
3757         bLoaded = true;
3758
3759         /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
3760         /* if we_are_a_wins_server is true and we are in the client            */
3761         if (lp_is_in_client() && Globals.we_are_a_wins_server) {
3762                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
3763         }
3764
3765         init_iconv();
3766
3767         fault_configure(smb_panic_s3);
3768
3769         /*
3770          * We run this check once the whole smb.conf is parsed, to
3771          * force some settings for the standard way a AD DC is
3772          * operated.  We may change these as our code evolves, which
3773          * is why we force these settings.
3774          */
3775         if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
3776                 lp_enforce_ad_dc_settings();
3777         }
3778
3779         bAllowIncludeRegistry = true;
3780
3781         TALLOC_FREE(frame);
3782         return (bRetval);
3783 }
3784
3785 static bool lp_load(const char *pszFname,
3786                     bool global_only,
3787                     bool save_defaults,
3788                     bool add_ipc,
3789                     bool reinit_globals)
3790 {
3791         return lp_load_ex(pszFname,
3792                           global_only,
3793                           save_defaults,
3794                           add_ipc,
3795                           reinit_globals,
3796                           true,   /* allow_include_registry */
3797                           false); /* load_all_shares*/
3798 }
3799
3800 bool lp_load_initial_only(const char *pszFname)
3801 {
3802         return lp_load_ex(pszFname,
3803                           true,   /* global only */
3804                           true,   /* save_defaults */
3805                           false,  /* add_ipc */
3806                           true,   /* reinit_globals */
3807                           false,  /* allow_include_registry */
3808                           false); /* load_all_shares*/
3809 }
3810
3811 /**
3812  * most common lp_load wrapper, loading only the globals
3813  */
3814 bool lp_load_global(const char *file_name)
3815 {
3816         return lp_load(file_name,
3817                        true,   /* global_only */
3818                        false,  /* save_defaults */
3819                        false,  /* add_ipc */
3820                        true);  /* reinit_globals */
3821 }
3822
3823 /**
3824  * The typical lp_load wrapper with shares, loads global and
3825  * shares, including IPC, but does not force immediate
3826  * loading of all shares from registry.
3827  */
3828 bool lp_load_with_shares(const char *file_name)
3829 {
3830         return lp_load(file_name,
3831                        false,  /* global_only */
3832                        false,  /* save_defaults */
3833                        true,   /* add_ipc */
3834                        true);  /* reinit_globals */
3835 }
3836
3837 /**
3838  * lp_load wrapper, especially for clients
3839  */
3840 bool lp_load_client(const char *file_name)
3841 {
3842         lp_set_in_client(true);
3843
3844         return lp_load_global(file_name);
3845 }
3846
3847 /**
3848  * lp_load wrapper, loading only globals, but intended
3849  * for subsequent calls, not reinitializing the globals
3850  * to default values
3851  */
3852 bool lp_load_global_no_reinit(const char *file_name)
3853 {
3854         return lp_load(file_name,
3855                        true,   /* global_only */
3856                        false,  /* save_defaults */
3857                        false,  /* add_ipc */
3858                        false); /* reinit_globals */
3859 }
3860
3861 /**
3862  * lp_load wrapper, loading globals and shares,
3863  * intended for subsequent calls, i.e. not reinitializing
3864  * the globals to default values.
3865  */
3866 bool lp_load_no_reinit(const char *file_name)
3867 {
3868         return lp_load(file_name,
3869                        false,  /* global_only */
3870                        false,  /* save_defaults */
3871                        false,  /* add_ipc */
3872                        false); /* reinit_globals */
3873 }
3874
3875
3876 /**
3877  * lp_load wrapper, especially for clients, no reinitialization
3878  */
3879 bool lp_load_client_no_reinit(const char *file_name)
3880 {
3881         lp_set_in_client(true);
3882
3883         return lp_load_global_no_reinit(file_name);
3884 }
3885
3886 bool lp_load_with_registry_shares(const char *pszFname)
3887 {
3888         return lp_load_ex(pszFname,
3889                           false, /* global_only */
3890                           true,  /* save_defaults */
3891                           false, /* add_ipc */
3892                           false, /* reinit_globals */
3893                           true,  /* allow_include_registry */
3894                           true); /* load_all_shares*/
3895 }
3896
3897 /***************************************************************************
3898  Return the max number of services.
3899 ***************************************************************************/
3900
3901 int lp_numservices(void)
3902 {
3903         return (iNumServices);
3904 }
3905
3906 /***************************************************************************
3907 Display the contents of the services array in human-readable form.
3908 ***************************************************************************/
3909
3910 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
3911 {
3912         int iService;
3913         struct loadparm_context *lp_ctx;
3914
3915         if (show_defaults)
3916                 defaults_saved = false;
3917
3918         lp_ctx = setup_lp_context(talloc_tos());
3919         if (lp_ctx == NULL) {
3920                 return;
3921         }
3922
3923         lpcfg_dump_globals(lp_ctx, f, !defaults_saved);
3924
3925         lpcfg_dump_a_service(&sDefault, &sDefault, f, flags_list, show_defaults);
3926
3927         for (iService = 0; iService < maxtoprint; iService++) {
3928                 fprintf(f,"\n");
3929                 lp_dump_one(f, show_defaults, iService);
3930         }
3931 }
3932
3933 /***************************************************************************
3934 Display the contents of one service in human-readable form.
3935 ***************************************************************************/
3936
3937 void lp_dump_one(FILE * f, bool show_defaults, int snum)
3938 {
3939         if (VALID(snum)) {
3940                 if (ServicePtrs[snum]->szService[0] == '\0')
3941                         return;
3942                 lpcfg_dump_a_service(ServicePtrs[snum], &sDefault, f,
3943                                      flags_list, show_defaults);
3944         }
3945 }
3946
3947 /***************************************************************************
3948 Return the number of the service with the given name, or -1 if it doesn't
3949 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3950 getservicebyname()! This works ONLY if all services have been loaded, and
3951 does not copy the found service.
3952 ***************************************************************************/
3953
3954 int lp_servicenumber(const char *pszServiceName)
3955 {
3956         int iService;
3957         fstring serviceName;
3958
3959         if (!pszServiceName) {
3960                 return GLOBAL_SECTION_SNUM;
3961         }
3962
3963         for (iService = iNumServices - 1; iService >= 0; iService--) {
3964                 if (VALID(iService) && ServicePtrs[iService]->szService) {
3965                         /*
3966                          * The substitution here is used to support %U in
3967                          * service names
3968                          */
3969                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
3970                         standard_sub_basic(get_current_username(),
3971                                            current_user_info.domain,
3972                                            serviceName,sizeof(serviceName));
3973                         if (strequal(serviceName, pszServiceName)) {
3974                                 break;
3975                         }
3976                 }
3977         }
3978
3979         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
3980                 struct timespec last_mod;
3981
3982                 if (!usershare_exists(iService, &last_mod)) {
3983                         /* Remove the share security tdb entry for it. */
3984                         delete_share_security(lp_servicename(talloc_tos(), iService));
3985                         /* Remove it from the array. */
3986                         free_service_byindex(iService);
3987                         /* Doesn't exist anymore. */
3988                         return GLOBAL_SECTION_SNUM;
3989                 }
3990
3991                 /* Has it been modified ? If so delete and reload. */
3992                 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
3993                                      &last_mod) < 0) {
3994                         /* Remove it from the array. */
3995                         free_service_byindex(iService);
3996                         /* and now reload it. */
3997                         iService = load_usershare_service(pszServiceName);
3998                 }
3999         }
4000
4001         if (iService < 0) {
4002                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4003                 return GLOBAL_SECTION_SNUM;
4004         }
4005
4006         return (iService);
4007 }
4008
4009 /*******************************************************************
4010  A useful volume label function. 
4011 ********************************************************************/
4012
4013 const char *volume_label(TALLOC_CTX *ctx, int snum)
4014 {
4015         char *ret;
4016         const char *label = lp_volume(ctx, snum);
4017         if (!*label) {
4018                 label = lp_servicename(ctx, snum);
4019         }
4020
4021         /* This returns a 33 byte guarenteed null terminated string. */
4022         ret = talloc_strndup(ctx, label, 32);
4023         if (!ret) {
4024                 return "";
4025         }               
4026         return ret;
4027 }
4028
4029 /*******************************************************************
4030  Get the default server type we will announce as via nmbd.
4031 ********************************************************************/
4032
4033 int lp_default_server_announce(void)
4034 {
4035         int default_server_announce = 0;
4036         default_server_announce |= SV_TYPE_WORKSTATION;
4037         default_server_announce |= SV_TYPE_SERVER;
4038         default_server_announce |= SV_TYPE_SERVER_UNIX;
4039
4040         /* note that the flag should be set only if we have a 
4041            printer service but nmbd doesn't actually load the 
4042            services so we can't tell   --jerry */
4043
4044         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
4045
4046         default_server_announce |= SV_TYPE_SERVER_NT;
4047         default_server_announce |= SV_TYPE_NT;
4048
4049         switch (lp_server_role()) {
4050                 case ROLE_DOMAIN_MEMBER:
4051                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4052                         break;
4053                 case ROLE_DOMAIN_PDC:
4054                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4055                         break;
4056                 case ROLE_DOMAIN_BDC:
4057                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4058                         break;
4059                 case ROLE_STANDALONE:
4060                 default:
4061                         break;
4062         }
4063         if (lp_time_server())
4064                 default_server_announce |= SV_TYPE_TIME_SOURCE;
4065
4066         if (lp_host_msdfs())
4067                 default_server_announce |= SV_TYPE_DFS_SERVER;
4068
4069         return default_server_announce;
4070 }
4071
4072 /***********************************************************
4073  If we are PDC then prefer us as DMB
4074 ************************************************************/
4075
4076 bool lp_domain_master(void)
4077 {
4078         if (Globals._domain_master == Auto)
4079                 return (lp_server_role() == ROLE_DOMAIN_PDC);
4080
4081         return (bool)Globals._domain_master;
4082 }
4083
4084 /***********************************************************
4085  If we are PDC then prefer us as DMB
4086 ************************************************************/
4087
4088 static bool lp_domain_master_true_or_auto(void)
4089 {
4090         if (Globals._domain_master) /* auto or yes */
4091                 return true;
4092
4093         return false;
4094 }
4095
4096 /***********************************************************
4097  If we are DMB then prefer us as LMB
4098 ************************************************************/
4099
4100 bool lp_preferred_master(void)
4101 {
4102         if (Globals.iPreferredMaster == Auto)
4103                 return (lp_local_master() && lp_domain_master());
4104
4105         return (bool)Globals.iPreferredMaster;
4106 }
4107
4108 /*******************************************************************
4109  Remove a service.
4110 ********************************************************************/
4111
4112 void lp_remove_service(int snum)
4113 {
4114         ServicePtrs[snum]->valid = false;
4115 }
4116
4117 const char *lp_printername(TALLOC_CTX *ctx, int snum)
4118 {
4119         const char *ret = lp__printername(ctx, snum);
4120         if (ret == NULL || *ret == '\0') {
4121                 ret = lp_const_servicename(snum);
4122         }
4123
4124         return ret;
4125 }
4126
4127
4128 /***********************************************************
4129  Allow daemons such as winbindd to fix their logfile name.
4130 ************************************************************/
4131
4132 void lp_set_logfile(const char *name)
4133 {
4134         string_set(Globals.ctx, &Globals.logfile, name);
4135         debug_set_logfile(name);
4136 }
4137
4138 /*******************************************************************
4139  Return the max print jobs per queue.
4140 ********************************************************************/
4141
4142 int lp_maxprintjobs(int snum)
4143 {
4144         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4145         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4146                 maxjobs = PRINT_MAX_JOBID - 1;
4147
4148         return maxjobs;
4149 }
4150
4151 const char *lp_printcapname(void)
4152 {
4153         if ((Globals.szPrintcapname != NULL) &&
4154             (Globals.szPrintcapname[0] != '\0'))
4155                 return Globals.szPrintcapname;
4156
4157         if (sDefault.printing == PRINT_CUPS) {
4158                 return "cups";
4159         }
4160
4161         if (sDefault.printing == PRINT_BSD)
4162                 return "/etc/printcap";
4163
4164         return PRINTCAP_NAME;
4165 }
4166
4167 static uint32_t spoolss_state;
4168
4169 bool lp_disable_spoolss( void )
4170 {
4171         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
4172                 spoolss_state = lp__disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4173
4174         return spoolss_state == SVCCTL_STOPPED ? true : false;
4175 }
4176
4177 void lp_set_spoolss_state( uint32_t state )
4178 {
4179         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
4180
4181         spoolss_state = state;
4182 }
4183
4184 uint32_t lp_get_spoolss_state( void )
4185 {
4186         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
4187 }
4188
4189 /*******************************************************************
4190  Ensure we don't use sendfile if server smb signing is active.
4191 ********************************************************************/
4192
4193 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
4194 {
4195         bool sign_active = false;
4196
4197         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4198         if (get_Protocol() < PROTOCOL_NT1) {
4199                 return false;
4200         }
4201         if (signing_state) {
4202                 sign_active = smb_signing_is_active(signing_state);
4203         }
4204         return (lp__use_sendfile(snum) &&
4205                         (get_remote_arch() != RA_WIN95) &&
4206                         !sign_active);
4207 }
4208
4209 /*******************************************************************
4210  Turn off sendfile if we find the underlying OS doesn't support it.
4211 ********************************************************************/
4212
4213 void set_use_sendfile(int snum, bool val)
4214 {
4215         if (LP_SNUM_OK(snum))
4216                 ServicePtrs[snum]->_use_sendfile = val;
4217         else
4218                 sDefault._use_sendfile = val;
4219 }
4220
4221 /*******************************************************************
4222  Turn off storing DOS attributes if this share doesn't support it.
4223 ********************************************************************/
4224
4225 void set_store_dos_attributes(int snum, bool val)
4226 {
4227         if (!LP_SNUM_OK(snum))
4228                 return;
4229         ServicePtrs[(snum)]->store_dos_attributes = val;
4230 }
4231
4232 void lp_set_mangling_method(const char *new_method)
4233 {
4234         string_set(Globals.ctx, &Globals.mangling_method, new_method);
4235 }
4236
4237 /*******************************************************************
4238  Global state for POSIX pathname processing.
4239 ********************************************************************/
4240
4241 static bool posix_pathnames;
4242
4243 bool lp_posix_pathnames(void)
4244 {
4245         return posix_pathnames;
4246 }
4247
4248 /*******************************************************************
4249  Change everything needed to ensure POSIX pathname processing (currently
4250  not much).
4251 ********************************************************************/
4252
4253 void lp_set_posix_pathnames(void)
4254 {
4255         posix_pathnames = true;
4256 }
4257
4258 /*******************************************************************
4259  Global state for POSIX lock processing - CIFS unix extensions.
4260 ********************************************************************/
4261
4262 bool posix_default_lock_was_set;
4263 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
4264
4265 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
4266 {
4267         if (posix_default_lock_was_set) {
4268                 return posix_cifsx_locktype;
4269         } else {
4270                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
4271         }
4272 }
4273
4274 /*******************************************************************
4275 ********************************************************************/
4276
4277 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
4278 {
4279         posix_default_lock_was_set = true;
4280         posix_cifsx_locktype = val;
4281 }
4282
4283 int lp_min_receive_file_size(void)
4284 {
4285         if (Globals.iminreceivefile < 0) {
4286                 return 0;
4287         }
4288         return Globals.iminreceivefile;
4289 }
4290
4291 /*******************************************************************
4292  Safe wide links checks.
4293  This helper function always verify the validity of wide links,
4294  even after a configuration file reload.
4295 ********************************************************************/
4296
4297 static bool lp_widelinks_internal(int snum)
4298 {
4299         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
4300                         sDefault.bWidelinks);
4301 }
4302
4303 void widelinks_warning(int snum)
4304 {
4305         if (lp_allow_insecure_wide_links()) {
4306                 return;
4307         }
4308
4309         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
4310                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4311                         "These parameters are incompatible. "
4312                         "Wide links will be disabled for this share.\n",
4313                          lp_servicename(talloc_tos(), snum) ));
4314         }
4315 }
4316
4317 bool lp_widelinks(int snum)
4318 {
4319         /* wide links is always incompatible with unix extensions */
4320         if (lp_unix_extensions()) {
4321                 /*
4322                  * Unless we have "allow insecure widelinks"
4323                  * turned on.
4324                  */
4325                 if (!lp_allow_insecure_wide_links()) {
4326                         return false;
4327                 }
4328         }
4329
4330         return lp_widelinks_internal(snum);
4331 }
4332
4333 int lp_server_role(void)
4334 {
4335         return lp_find_server_role(lp__server_role(),
4336                                    lp__security(),
4337                                    lp__domain_logons(),
4338                                    lp_domain_master_true_or_auto());
4339 }
4340
4341 int lp_security(void)
4342 {
4343         return lp_find_security(lp__server_role(),
4344                                 lp__security());
4345 }
4346
4347 int lp_client_max_protocol(void)
4348 {
4349         int client_max_protocol = lp__client_max_protocol();
4350         if (client_max_protocol == PROTOCOL_DEFAULT) {
4351                 return PROTOCOL_NT1;
4352         }
4353         return client_max_protocol;
4354 }
4355
4356 int lp_winbindd_max_protocol(void)
4357 {
4358         int client_max_protocol = lp__client_max_protocol();
4359         if (client_max_protocol == PROTOCOL_DEFAULT) {
4360                 return PROTOCOL_LATEST;
4361         }
4362         return client_max_protocol;
4363 }
4364
4365 struct loadparm_global * get_globals(void)
4366 {
4367         return &Globals;
4368 }
4369
4370 unsigned int * get_flags(void)
4371 {
4372         if (flags_list == NULL) {
4373                 flags_list = talloc_zero_array(NULL, unsigned int, num_parameters());
4374         }
4375
4376         return flags_list;
4377 }