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