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