2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
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
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.
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.
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/>.
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.
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
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
57 #include "system/filesys.h"
59 #include "lib/param/loadparm.h"
60 #include "lib/param/param.h"
62 #include "lib/smbconf/smbconf.h"
63 #include "lib/smbconf/smbconf_init.h"
66 #include "../librpc/gen_ndr/svcctl.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"
73 #ifdef HAVE_SYS_SYSCTL_H
74 #include <sys/sysctl.h>
77 #ifdef HAVE_HTTPCONNECTENCRYPT
78 #include <cups/http.h>
83 extern userdom_struct current_user_info
;
85 /* the special value for the include parameter
86 * to be interpreted not as a file name but to
87 * trigger loading of the global smb.conf options
89 #ifndef INCLUDE_REGISTRY_NAME
90 #define INCLUDE_REGISTRY_NAME "registry"
93 static bool in_client
= false; /* Not in the client by default */
94 static struct smbconf_csn conf_last_csn
;
96 static int config_backend
= CONFIG_BACKEND_FILE
;
98 /* some helpful bits */
99 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
100 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
102 #define USERSHARE_VALID 1
103 #define USERSHARE_PENDING_DELETE 2
105 static bool defaults_saved
= false;
107 #include "lib/param/param_global.h"
109 static struct loadparm_global Globals
;
111 /* This is a default service used to prime a services structure */
112 static struct loadparm_service sDefault
=
117 .usershare_last_mod
= {0, 0},
121 .invalid_users
= NULL
,
128 .root_preexec
= NULL
,
129 .root_postexec
= NULL
,
130 .cups_options
= NULL
,
131 .print_command
= NULL
,
133 .lprm_command
= NULL
,
134 .lppause_command
= NULL
,
135 .lpresume_command
= NULL
,
136 .queuepause_command
= NULL
,
137 .queueresume_command
= NULL
,
138 ._printername
= NULL
,
139 .printjob_username
= NULL
,
140 .dont_descend
= NULL
,
143 .magic_script
= NULL
,
144 .magic_output
= NULL
,
147 .veto_oplock_files
= NULL
,
157 .aio_write_behind
= NULL
,
158 .dfree_command
= NULL
,
159 .min_print_space
= 0,
160 .iMaxPrintJobs
= 1000,
161 .max_reported_print_jobs
= 0,
162 .write_cache_size
= 0,
164 .force_create_mode
= 0,
165 .directory_mask
= 0755,
166 .force_directory_mode
= 0,
167 .max_connections
= 0,
168 .default_case
= CASE_LOWER
,
169 .printing
= DEFAULT_PRINTING
,
170 .oplock_contention_limit
= 2,
173 .dfree_cache_time
= 0,
174 .preexec_close
= false,
175 .root_preexec_close
= false,
176 .case_sensitive
= Auto
,
177 .preserve_case
= true,
178 .short_preserve_case
= true,
179 .hide_dot_files
= true,
180 .hide_special_files
= false,
181 .hide_unreadable
= false,
182 .hide_unwriteable_files
= false,
184 .access_based_share_enum
= false,
188 .administrative_share
= false,
191 .print_notify_backchannel
= false,
195 .store_dos_attributes
= false,
196 .dmapi_support
= false,
198 .strict_locking
= Auto
,
199 .posix_locking
= true,
201 .kernel_oplocks
= false,
202 .level2_oplocks
= true,
204 .mangled_names
= true,
206 .follow_symlinks
= true,
207 .sync_always
= false,
208 .strict_allocate
= false,
209 .strict_sync
= false,
210 .mangling_char
= '~',
212 .delete_readonly
= false,
213 .fake_oplocks
= false,
214 .delete_veto_files
= false,
215 .dos_filemode
= false,
216 .dos_filetimes
= true,
217 .dos_filetime_resolution
= false,
218 .fake_directory_create_times
= false,
219 .blocking_locks
= true,
220 .inherit_permissions
= false,
221 .inherit_acls
= false,
222 .inherit_owner
= false,
224 .use_client_driver
= false,
225 .default_devmode
= true,
226 .force_printername
= false,
227 .nt_acl_support
= true,
228 .force_unknown_acl_user
= false,
229 ._use_sendfile
= false,
230 .profile_acls
= false,
231 .map_acl_inherit
= false,
234 .acl_check_permissions
= true,
235 .acl_map_full_control
= true,
236 .acl_group_control
= false,
237 .acl_allow_execute_always
= false,
238 .change_notify
= true,
239 .kernel_change_notify
= true,
240 .allocation_roundup_size
= SMB_ROUNDUP_ALLOCATION_SIZE
,
243 .map_readonly
= MAP_READONLY_YES
,
244 .directory_name_cache_size
= 100,
245 .smb_encrypt
= SMB_SIGNING_DEFAULT
,
246 .kernel_share_modes
= true,
247 .durable_handles
= true,
252 /* local variables */
253 static struct loadparm_service
**ServicePtrs
= NULL
;
254 static int iNumServices
= 0;
255 static int iServiceIndex
= 0;
256 static struct db_context
*ServiceHash
;
257 static bool bInGlobalSection
= true;
258 static bool bGlobalOnly
= false;
259 static struct file_lists
*file_lists
= NULL
;
261 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
263 /* prototypes for the special type handlers */
264 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
265 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
266 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
267 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
268 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
269 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
270 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
271 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
272 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
274 static void set_allowed_client_auth(void);
276 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
);
277 static void free_param_opts(struct parmlist_entry
**popts
);
279 #include "lib/param/param_table.c"
281 /* this is used to prevent lots of mallocs of size 1 */
282 static const char null_string
[] = "";
288 static void string_free(char **s
)
292 if (*s
== null_string
)
298 Set a string value, deallocating any existing space, and allocing the space
302 static bool string_set(TALLOC_CTX
*mem_ctx
, char **dest
,const char *src
)
310 (*dest
) = talloc_strdup(mem_ctx
, src
);
311 if ((*dest
) == NULL
) {
312 DEBUG(0,("Out of memory in string_init\n"));
319 bool lp_string_set(char **dest
, const char *src
) {
320 return string_set(Globals
.ctx
, dest
, src
);
323 /***************************************************************************
324 Initialise the sDefault parameter structure for the printer values.
325 ***************************************************************************/
327 static void init_printer_values(TALLOC_CTX
*ctx
, struct loadparm_service
*pService
)
329 /* choose defaults depending on the type of printing */
330 switch (pService
->printing
) {
335 string_set(ctx
, &pService
->lpq_command
, "lpq -P'%p'");
336 string_set(ctx
, &pService
->lprm_command
, "lprm -P'%p' %j");
337 string_set(ctx
, &pService
->print_command
, "lpr -r -P'%p' %s");
342 string_set(ctx
, &pService
->lpq_command
, "lpq -P'%p'");
343 string_set(ctx
, &pService
->lprm_command
, "lprm -P'%p' %j");
344 string_set(ctx
, &pService
->print_command
, "lpr -r -P'%p' %s");
345 string_set(ctx
, &pService
->queuepause_command
, "lpc stop '%p'");
346 string_set(ctx
, &pService
->queueresume_command
, "lpc start '%p'");
347 string_set(ctx
, &pService
->lppause_command
, "lpc hold '%p' %j");
348 string_set(ctx
, &pService
->lpresume_command
, "lpc release '%p' %j");
353 /* set the lpq command to contain the destination printer
354 name only. This is used by cups_queue_get() */
355 string_set(ctx
, &pService
->lpq_command
, "%p");
356 string_set(ctx
, &pService
->lprm_command
, "");
357 string_set(ctx
, &pService
->print_command
, "");
358 string_set(ctx
, &pService
->lppause_command
, "");
359 string_set(ctx
, &pService
->lpresume_command
, "");
360 string_set(ctx
, &pService
->queuepause_command
, "");
361 string_set(ctx
, &pService
->queueresume_command
, "");
366 string_set(ctx
, &pService
->lpq_command
, "lpstat -o%p");
367 string_set(ctx
, &pService
->lprm_command
, "cancel %p-%j");
368 string_set(ctx
, &pService
->print_command
, "lp -c -d%p %s; rm %s");
369 string_set(ctx
, &pService
->queuepause_command
, "disable %p");
370 string_set(ctx
, &pService
->queueresume_command
, "enable %p");
372 string_set(ctx
, &pService
->lppause_command
, "lp -i %p-%j -H hold");
373 string_set(ctx
, &pService
->lpresume_command
, "lp -i %p-%j -H resume");
378 string_set(ctx
, &pService
->lpq_command
, "lpq -P%p");
379 string_set(ctx
, &pService
->lprm_command
, "lprm -P%p %j");
380 string_set(ctx
, &pService
->print_command
, "lp -r -P%p %s");
383 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
388 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
391 tdbfile
= talloc_asprintf(
392 tmp_ctx
, "tdbfile=%s",
393 lp_parm_const_string(-1, "vlp", "tdbfile",
395 if (tdbfile
== NULL
) {
396 tdbfile
="tdbfile=/tmp/vlp.tdb";
399 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s print %%p %%s",
401 string_set(ctx
, &pService
->print_command
,
402 tmp
? tmp
: "vlp print %p %s");
404 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpq %%p",
406 string_set(ctx
, &pService
->lpq_command
,
407 tmp
? tmp
: "vlp lpq %p");
409 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lprm %%p %%j",
411 string_set(ctx
, &pService
->lprm_command
,
412 tmp
? tmp
: "vlp lprm %p %j");
414 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lppause %%p %%j",
416 string_set(ctx
, &pService
->lppause_command
,
417 tmp
? tmp
: "vlp lppause %p %j");
419 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpresume %%p %%j",
421 string_set(ctx
, &pService
->lpresume_command
,
422 tmp
? tmp
: "vlp lpresume %p %j");
424 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queuepause %%p",
426 string_set(ctx
, &pService
->queuepause_command
,
427 tmp
? tmp
: "vlp queuepause %p");
429 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queueresume %%p",
431 string_set(ctx
, &pService
->queueresume_command
,
432 tmp
? tmp
: "vlp queueresume %p");
433 TALLOC_FREE(tmp_ctx
);
437 #endif /* DEVELOPER */
442 * Function to return the default value for the maximum number of open
443 * file descriptors permitted. This function tries to consult the
444 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
445 * the smaller of those.
447 static int max_open_files(void)
449 int sysctl_max
= MAX_OPEN_FILES
;
450 int rlimit_max
= MAX_OPEN_FILES
;
452 #ifdef HAVE_SYSCTLBYNAME
454 size_t size
= sizeof(sysctl_max
);
455 sysctlbyname("kern.maxfilesperproc", &sysctl_max
, &size
, NULL
,
460 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
466 if (getrlimit(RLIMIT_NOFILE
, &rl
) == 0)
467 rlimit_max
= rl
.rlim_cur
;
469 #if defined(RLIM_INFINITY)
470 if(rl
.rlim_cur
== RLIM_INFINITY
)
471 rlimit_max
= MAX_OPEN_FILES
;
476 if (sysctl_max
< MIN_OPEN_FILES_WINDOWS
) {
477 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
478 "minimum Windows limit (%d)\n",
480 MIN_OPEN_FILES_WINDOWS
));
481 sysctl_max
= MIN_OPEN_FILES_WINDOWS
;
484 if (rlimit_max
< MIN_OPEN_FILES_WINDOWS
) {
485 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
486 "minimum Windows limit (%d)\n",
488 MIN_OPEN_FILES_WINDOWS
));
489 rlimit_max
= MIN_OPEN_FILES_WINDOWS
;
492 return MIN(sysctl_max
, rlimit_max
);
496 * Common part of freeing allocated data for one parameter.
498 static void free_one_parameter_common(void *parm_ptr
,
499 struct parm_struct parm
)
501 if ((parm
.type
== P_STRING
) ||
502 (parm
.type
== P_USTRING
))
504 string_free((char**)parm_ptr
);
505 } else if (parm
.type
== P_LIST
) {
506 TALLOC_FREE(*((char***)parm_ptr
));
511 * Free the allocated data for one parameter for a share
512 * given as a service struct.
514 static void free_one_parameter(struct loadparm_service
*service
,
515 struct parm_struct parm
)
519 if (parm
.p_class
!= P_LOCAL
) {
523 parm_ptr
= lp_parm_ptr(service
, &parm
);
525 free_one_parameter_common(parm_ptr
, parm
);
529 * Free the allocated parameter data of a share given
530 * as a service struct.
532 static void free_parameters(struct loadparm_service
*service
)
536 for (i
=0; parm_table
[i
].label
; i
++) {
537 free_one_parameter(service
, parm_table
[i
]);
542 * Free the allocated data for one parameter for a given share
543 * specified by an snum.
545 static void free_one_parameter_by_snum(int snum
, struct parm_struct parm
)
550 parm_ptr
= lp_parm_ptr(NULL
, &parm
);
551 } else if (parm
.p_class
!= P_LOCAL
) {
554 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm
);
557 free_one_parameter_common(parm_ptr
, parm
);
561 * Free the allocated parameter data for a share specified
564 static void free_parameters_by_snum(int snum
)
568 for (i
=0; parm_table
[i
].label
; i
++) {
569 free_one_parameter_by_snum(snum
, parm_table
[i
]);
574 * Free the allocated global parameters.
576 static void free_global_parameters(void)
578 free_param_opts(&Globals
.param_opt
);
579 free_parameters_by_snum(GLOBAL_SECTION_SNUM
);
580 TALLOC_FREE(Globals
.ctx
);
583 struct lp_stored_option
{
584 struct lp_stored_option
*prev
, *next
;
589 static struct lp_stored_option
*stored_options
;
592 save options set by lp_set_cmdline() into a list. This list is
593 re-applied when we do a globals reset, so that cmdline set options
594 are sticky across reloads of smb.conf
596 static bool store_lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
598 struct lp_stored_option
*entry
, *entry_next
;
599 for (entry
= stored_options
; entry
!= NULL
; entry
= entry_next
) {
600 entry_next
= entry
->next
;
601 if (strcmp(pszParmName
, entry
->label
) == 0) {
602 DLIST_REMOVE(stored_options
, entry
);
608 entry
= talloc(NULL
, struct lp_stored_option
);
613 entry
->label
= talloc_strdup(entry
, pszParmName
);
619 entry
->value
= talloc_strdup(entry
, pszParmValue
);
625 DLIST_ADD_END(stored_options
, entry
, struct lp_stored_option
);
630 static bool apply_lp_set_cmdline(void)
632 struct lp_stored_option
*entry
= NULL
;
633 for (entry
= stored_options
; entry
!= NULL
; entry
= entry
->next
) {
634 if (!lp_set_cmdline_helper(entry
->label
, entry
->value
, false)) {
635 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
636 entry
->label
, entry
->value
));
643 /***************************************************************************
644 Initialise the global parameter structure.
645 ***************************************************************************/
647 static void init_globals(bool reinit_globals
)
649 static bool done_init
= false;
653 /* If requested to initialize only once and we've already done it... */
654 if (!reinit_globals
&& done_init
) {
655 /* ... then we have nothing more to do */
660 /* The logfile can be set before this is invoked. Free it if so. */
661 if (Globals
.logfile
!= NULL
) {
662 string_free(&Globals
.logfile
);
663 Globals
.logfile
= NULL
;
667 free_global_parameters();
670 /* This memset and the free_global_parameters() above will
671 * wipe out smb.conf options set with lp_set_cmdline(). The
672 * apply_lp_set_cmdline() call puts these values back in the
673 * table once the defaults are set */
674 ZERO_STRUCT(Globals
);
676 Globals
.ctx
= talloc_pooled_object(NULL
, char, 272, 2048);
678 for (i
= 0; parm_table
[i
].label
; i
++) {
679 if ((parm_table
[i
].type
== P_STRING
||
680 parm_table
[i
].type
== P_USTRING
))
682 string_set(Globals
.ctx
, (char **)lp_parm_ptr(NULL
, &parm_table
[i
]), "");
687 string_set(Globals
.ctx
, &sDefault
.fstype
, FSTYPE_STRING
);
688 string_set(Globals
.ctx
, &sDefault
.printjob_username
, "%U");
690 init_printer_values(Globals
.ctx
, &sDefault
);
692 sDefault
.ntvfs_handler
= (const char **)str_list_make_v3(NULL
, "unixuid default", NULL
);
694 DEBUG(3, ("Initialising global parameters\n"));
696 /* Must manually force to upper case here, as this does not go via the handler */
697 string_set(Globals
.ctx
, &Globals
.netbios_name
, myhostname_upper());
699 string_set(Globals
.ctx
, &Globals
.smb_passwd_file
, get_dyn_SMB_PASSWD_FILE());
700 string_set(Globals
.ctx
, &Globals
.private_dir
, get_dyn_PRIVATE_DIR());
702 /* use the new 'hash2' method by default, with a prefix of 1 */
703 string_set(Globals
.ctx
, &Globals
.mangling_method
, "hash2");
704 Globals
.mangle_prefix
= 1;
706 string_set(Globals
.ctx
, &Globals
.guest_account
, GUEST_ACCOUNT
);
708 /* using UTF8 by default allows us to support all chars */
709 string_set(Globals
.ctx
, &Globals
.unix_charset
, DEFAULT_UNIX_CHARSET
);
711 /* Use codepage 850 as a default for the dos character set */
712 string_set(Globals
.ctx
, &Globals
.dos_charset
, DEFAULT_DOS_CHARSET
);
715 * Allow the default PASSWD_CHAT to be overridden in local.h.
717 string_set(Globals
.ctx
, &Globals
.passwd_chat
, DEFAULT_PASSWD_CHAT
);
719 string_set(Globals
.ctx
, &Globals
.workgroup
, DEFAULT_WORKGROUP
);
721 string_set(Globals
.ctx
, &Globals
.passwd_program
, "");
722 string_set(Globals
.ctx
, &Globals
.lock_directory
, get_dyn_LOCKDIR());
723 string_set(Globals
.ctx
, &Globals
.state_directory
, get_dyn_STATEDIR());
724 string_set(Globals
.ctx
, &Globals
.cache_directory
, get_dyn_CACHEDIR());
725 string_set(Globals
.ctx
, &Globals
.pid_directory
, get_dyn_PIDDIR());
726 string_set(Globals
.ctx
, &Globals
.nbt_client_socket_address
, "0.0.0.0");
728 * By default support explicit binding to broadcast
731 Globals
.nmbd_bind_explicit_broadcast
= true;
733 s
= talloc_asprintf(talloc_tos(), "Samba %s", samba_version_string());
735 smb_panic("init_globals: ENOMEM");
737 string_set(Globals
.ctx
, &Globals
.server_string
, s
);
740 string_set(Globals
.ctx
, &Globals
.panic_action
, "/bin/sleep 999999999");
743 string_set(Globals
.ctx
, &Globals
.socket_options
, DEFAULT_SOCKET_OPTIONS
);
745 string_set(Globals
.ctx
, &Globals
.logon_drive
, "");
746 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
747 string_set(Globals
.ctx
, &Globals
.logon_home
, "\\\\%N\\%U");
748 string_set(Globals
.ctx
, &Globals
.logon_path
, "\\\\%N\\%U\\profile");
750 Globals
.name_resolve_order
= (const char **)str_list_make_v3(NULL
, "lmhosts wins host bcast", NULL
);
751 string_set(Globals
.ctx
, &Globals
.password_server
, "*");
753 Globals
.algorithmic_rid_base
= BASE_RID
;
755 Globals
.load_printers
= true;
756 Globals
.printcap_cache_time
= 750; /* 12.5 minutes */
758 Globals
.config_backend
= config_backend
;
759 Globals
._server_role
= ROLE_AUTO
;
761 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
762 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
763 Globals
.max_xmit
= 0x4104;
764 Globals
.max_mux
= 50; /* This is *needed* for profile support. */
765 Globals
.lpq_cache_time
= 30; /* changed to handle large print servers better -- jerry */
766 Globals
._disable_spoolss
= false;
767 Globals
.max_smbd_processes
= 0;/* no limit specified */
768 Globals
.username_level
= 0;
769 Globals
.deadtime
= 0;
770 Globals
.getwd_cache
= true;
771 Globals
.large_readwrite
= true;
772 Globals
.max_log_size
= 5000;
773 Globals
.max_open_files
= max_open_files();
774 Globals
.server_max_protocol
= PROTOCOL_SMB3_00
;
775 Globals
.server_min_protocol
= PROTOCOL_LANMAN1
;
776 Globals
.client_max_protocol
= PROTOCOL_NT1
;
777 Globals
.client_min_protocol
= PROTOCOL_CORE
;
778 Globals
._security
= SEC_AUTO
;
779 Globals
.encrypt_passwords
= true;
780 Globals
.client_schannel
= Auto
;
781 Globals
.winbind_sealed_pipes
= true;
782 Globals
.require_strong_key
= true;
783 Globals
.server_schannel
= Auto
;
784 Globals
.read_raw
= true;
785 Globals
.write_raw
= true;
786 Globals
.null_passwords
= false;
787 Globals
.old_password_allowed_period
= 60;
788 Globals
.obey_pam_restrictions
= false;
790 Globals
.syslog_only
= false;
791 Globals
.timestamp_logs
= true;
792 string_set(Globals
.ctx
, &Globals
.log_level
, "0");
793 Globals
.debug_prefix_timestamp
= false;
794 Globals
.debug_hires_timestamp
= true;
795 Globals
.debug_pid
= false;
796 Globals
.debug_uid
= false;
797 Globals
.debug_class
= false;
798 Globals
.enable_core_files
= true;
799 Globals
.max_ttl
= 60 * 60 * 24 * 3; /* 3 days default. */
800 Globals
.max_wins_ttl
= 60 * 60 * 24 * 6; /* 6 days default. */
801 Globals
.min_wins_ttl
= 60 * 60 * 6; /* 6 hours default. */
802 Globals
.machine_password_timeout
= 60 * 60 * 24 * 7; /* 7 days default. */
803 Globals
.lm_announce
= Auto
; /* = Auto: send only if LM clients found */
804 Globals
.lm_interval
= 60;
805 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
806 Globals
.nis_homedir
= false;
807 #ifdef WITH_NISPLUS_HOME
808 string_set(Globals
.ctx
, &Globals
.homedir_map
, "auto_home.org_dir");
810 string_set(Globals
.ctx
, &Globals
.homedir_map
, "auto.home");
813 Globals
.time_server
= false;
814 Globals
.bind_interfaces_only
= false;
815 Globals
.unix_password_sync
= false;
816 Globals
.pam_password_change
= false;
817 Globals
.passwd_chat_debug
= false;
818 Globals
.passwd_chat_timeout
= 2; /* 2 second default. */
819 Globals
.nt_pipe_support
= true; /* Do NT pipes by default. */
820 Globals
.nt_status_support
= true; /* Use NT status by default. */
821 Globals
.stat_cache
= true; /* use stat cache by default */
822 Globals
.max_stat_cache_size
= 256; /* 256k by default */
823 Globals
.restrict_anonymous
= 0;
824 Globals
.client_lanman_auth
= false; /* Do NOT use the LanMan hash if it is available */
825 Globals
.client_plaintext_auth
= false; /* Do NOT use a plaintext password even if is requested by the server */
826 Globals
.lanman_auth
= false; /* Do NOT use the LanMan hash, even if it is supplied */
827 Globals
.ntlm_auth
= true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
828 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 */
829 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
831 Globals
.map_to_guest
= 0; /* By Default, "Never" */
832 Globals
.oplock_break_wait_time
= 0; /* By Default, 0 msecs. */
833 Globals
.enhanced_browsing
= true;
834 Globals
.lock_spin_time
= WINDOWS_MINIMUM_LOCK_TIMEOUT_MS
; /* msec. */
835 #ifdef MMAP_BLACKLIST
836 Globals
.use_mmap
= false;
838 Globals
.use_mmap
= true;
840 Globals
.unicode
= true;
841 Globals
.unix_extensions
= true;
842 Globals
.reset_on_zero_vc
= false;
843 Globals
.log_writeable_files_on_exit
= false;
844 Globals
.create_krb5_conf
= true;
845 Globals
.winbindMaxDomainConnections
= 1;
847 /* hostname lookups can be very expensive and are broken on
848 a large number of sites (tridge) */
849 Globals
.hostname_lookups
= false;
851 string_set(Globals
.ctx
, &Globals
.passdb_backend
, "tdbsam");
852 string_set(Globals
.ctx
, &Globals
.ldap_suffix
, "");
853 string_set(Globals
.ctx
, &Globals
.szLdapMachineSuffix
, "");
854 string_set(Globals
.ctx
, &Globals
.szLdapUserSuffix
, "");
855 string_set(Globals
.ctx
, &Globals
.szLdapGroupSuffix
, "");
856 string_set(Globals
.ctx
, &Globals
.szLdapIdmapSuffix
, "");
858 string_set(Globals
.ctx
, &Globals
.ldap_admin_dn
, "");
859 Globals
.ldap_ssl
= LDAP_SSL_START_TLS
;
860 Globals
.ldap_ssl_ads
= false;
861 Globals
.ldap_deref
= -1;
862 Globals
.ldap_passwd_sync
= LDAP_PASSWD_SYNC_OFF
;
863 Globals
.ldap_delete_dn
= false;
864 Globals
.ldap_replication_sleep
= 1000; /* wait 1 sec for replication */
865 Globals
.ldap_follow_referral
= Auto
;
866 Globals
.ldap_timeout
= LDAP_DEFAULT_TIMEOUT
;
867 Globals
.ldap_connection_timeout
= LDAP_CONNECTION_DEFAULT_TIMEOUT
;
868 Globals
.ldap_page_size
= LDAP_PAGE_SIZE
;
870 Globals
.ldap_debug_level
= 0;
871 Globals
.ldap_debug_threshold
= 10;
873 /* This is what we tell the afs client. in reality we set the token
874 * to never expire, though, when this runs out the afs client will
875 * forget the token. Set to 0 to get NEVERDATE.*/
876 Globals
.afs_token_lifetime
= 604800;
877 Globals
.cups_connection_timeout
= CUPS_DEFAULT_CONNECTION_TIMEOUT
;
879 /* these parameters are set to defaults that are more appropriate
880 for the increasing samba install base:
882 as a member of the workgroup, that will possibly become a
883 _local_ master browser (lm = true). this is opposed to a forced
884 local master browser startup (pm = true).
886 doesn't provide WINS server service by default (wsupp = false),
887 and doesn't provide domain master browser services by default, either.
891 Globals
.show_add_printer_wizard
= true;
892 Globals
.os_level
= 20;
893 Globals
.local_master
= true;
894 Globals
._domain_master
= Auto
; /* depending on _domain_logons */
895 Globals
._domain_logons
= false;
896 Globals
.browse_list
= true;
897 Globals
.we_are_a_wins_server
= false;
898 Globals
.wins_proxy
= false;
900 TALLOC_FREE(Globals
.init_logon_delayed_hosts
);
901 Globals
.init_logon_delay
= 100; /* 100 ms default delay */
903 Globals
.wins_dns_proxy
= true;
905 Globals
.allow_trusted_domains
= true;
906 string_set(Globals
.ctx
, &Globals
.szIdmapBackend
, "tdb");
908 string_set(Globals
.ctx
, &Globals
.template_shell
, "/bin/false");
909 string_set(Globals
.ctx
, &Globals
.template_homedir
, "/home/%D/%U");
910 string_set(Globals
.ctx
, &Globals
.winbind_separator
, "\\");
911 string_set(Globals
.ctx
, &Globals
.winbindd_socket_directory
, dyn_WINBINDD_SOCKET_DIR
);
913 string_set(Globals
.ctx
, &Globals
.cups_server
, "");
914 string_set(Globals
.ctx
, &Globals
.iprint_server
, "");
916 string_set(Globals
.ctx
, &Globals
._ctdbd_socket
, "");
918 Globals
.cluster_addresses
= NULL
;
919 Globals
.clustering
= false;
920 Globals
.ctdb_timeout
= 0;
921 Globals
.ctdb_locktime_warn_threshold
= 0;
923 Globals
.winbind_cache_time
= 300; /* 5 minutes */
924 Globals
.winbind_reconnect_delay
= 30; /* 30 seconds */
925 Globals
.winbind_max_clients
= 200;
926 Globals
.winbind_enum_users
= false;
927 Globals
.winbind_enum_groups
= false;
928 Globals
.winbind_use_default_domain
= false;
929 Globals
.winbind_trusted_domains_only
= false;
930 Globals
.winbind_nested_groups
= true;
931 Globals
.winbind_expand_groups
= 1;
932 Globals
.winbind_nss_info
= (const char **)str_list_make_v3(NULL
, "template", NULL
);
933 Globals
.winbind_refresh_tickets
= false;
934 Globals
.winbind_offline_logon
= false;
936 Globals
.idmap_cache_time
= 86400 * 7; /* a week by default */
937 Globals
.idmap_negative_cache_time
= 120; /* 2 minutes by default */
939 Globals
.passdb_expand_explicit
= false;
941 Globals
.name_cache_timeout
= 660; /* In seconds */
943 Globals
.use_spnego
= true;
944 Globals
.client_use_spnego
= true;
946 Globals
.client_signing
= SMB_SIGNING_DEFAULT
;
947 Globals
.server_signing
= SMB_SIGNING_DEFAULT
;
949 Globals
.defer_sharing_violations
= true;
950 Globals
.smb_ports
= (const char **)str_list_make_v3(NULL
, SMB_PORTS
, NULL
);
952 Globals
.enable_privileges
= true;
953 Globals
.host_msdfs
= true;
954 Globals
.enable_asu_support
= false;
956 /* User defined shares. */
957 s
= talloc_asprintf(talloc_tos(), "%s/usershares", get_dyn_STATEDIR());
959 smb_panic("init_globals: ENOMEM");
961 string_set(Globals
.ctx
, &Globals
.usershare_path
, s
);
963 string_set(Globals
.ctx
, &Globals
.usershare_template_share
, "");
964 Globals
.usershare_max_shares
= 0;
965 /* By default disallow sharing of directories not owned by the sharer. */
966 Globals
.usershare_owner_only
= true;
967 /* By default disallow guest access to usershares. */
968 Globals
.usershare_allow_guests
= false;
970 Globals
.keepalive
= DEFAULT_KEEPALIVE
;
972 /* By default no shares out of the registry */
973 Globals
.registry_shares
= false;
975 Globals
.iminreceivefile
= 0;
977 Globals
.map_untrusted_to_domain
= false;
978 Globals
.multicast_dns_register
= true;
980 Globals
.smb2_max_read
= DEFAULT_SMB2_MAX_READ
;
981 Globals
.smb2_max_write
= DEFAULT_SMB2_MAX_WRITE
;
982 Globals
.smb2_max_trans
= DEFAULT_SMB2_MAX_TRANSACT
;
983 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
985 string_set(Globals
.ctx
, &Globals
.ncalrpc_dir
, get_dyn_NCALRPCDIR());
987 Globals
.server_services
= (const char **)str_list_make_v3(NULL
, "s3fs rpc nbt wrepl ldap cldap kdc drepl winbind ntp_signd kcc dnsupdate dns", NULL
);
989 Globals
.dcerpc_endpoint_servers
= (const char **)str_list_make_v3(NULL
, "epmapper wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi dssetup unixinfo browser eventlog6 backupkey dnsserver", NULL
);
991 Globals
.tls_enabled
= true;
993 string_set(Globals
.ctx
, &Globals
._tls_keyfile
, "tls/key.pem");
994 string_set(Globals
.ctx
, &Globals
._tls_certfile
, "tls/cert.pem");
995 string_set(Globals
.ctx
, &Globals
._tls_cafile
, "tls/ca.pem");
997 string_set(Globals
.ctx
, &Globals
.share_backend
, "classic");
999 Globals
.iPreferredMaster
= Auto
;
1001 Globals
.allow_dns_updates
= DNS_UPDATE_SIGNED
;
1003 string_set(Globals
.ctx
, &Globals
.ntp_signd_socket_directory
, get_dyn_NTP_SIGND_SOCKET_DIR());
1005 string_set(Globals
.ctx
, &Globals
.winbindd_privileged_socket_directory
, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
1007 s
= talloc_asprintf(talloc_tos(), "%s/samba_kcc", get_dyn_SCRIPTSBINDIR());
1009 smb_panic("init_globals: ENOMEM");
1011 Globals
.samba_kcc_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1014 s
= talloc_asprintf(talloc_tos(), "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR());
1016 smb_panic("init_globals: ENOMEM");
1018 Globals
.dns_update_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1021 s
= talloc_asprintf(talloc_tos(), "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR());
1023 smb_panic("init_globals: ENOMEM");
1025 Globals
.spn_update_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1028 Globals
.nsupdate_command
= (const char **)str_list_make_v3(NULL
, "/usr/bin/nsupdate -g", NULL
);
1030 Globals
.rndc_command
= (const char **)str_list_make_v3(NULL
, "/usr/sbin/rndc", NULL
);
1032 Globals
.cldap_port
= 389;
1034 Globals
.dgram_port
= 138;
1036 Globals
.nbt_port
= 137;
1038 Globals
.krb5_port
= 88;
1040 Globals
.kpasswd_port
= 464;
1042 Globals
.web_port
= 901;
1044 /* Now put back the settings that were set with lp_set_cmdline() */
1045 apply_lp_set_cmdline();
1048 /*******************************************************************
1049 Convenience routine to grab string parameters into talloced memory
1050 and run standard_sub_basic on them. The buffers can be written to by
1051 callers without affecting the source string.
1052 ********************************************************************/
1054 char *lp_string(TALLOC_CTX
*ctx
, const char *s
)
1058 /* The follow debug is useful for tracking down memory problems
1059 especially if you have an inner loop that is calling a lp_*()
1060 function that returns a string. Perhaps this debug should be
1061 present all the time? */
1064 DEBUG(10, ("lp_string(%s)\n", s
));
1070 ret
= talloc_sub_basic(ctx
,
1071 get_current_username(),
1072 current_user_info
.domain
,
1074 if (trim_char(ret
, '\"', '\"')) {
1075 if (strchr(ret
,'\"') != NULL
) {
1077 ret
= talloc_sub_basic(ctx
,
1078 get_current_username(),
1079 current_user_info
.domain
,
1087 In this section all the functions that are used to access the
1088 parameters from the rest of the program are defined
1091 #define FN_GLOBAL_STRING(fn_name,ptr) \
1092 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1093 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1094 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1095 #define FN_GLOBAL_LIST(fn_name,ptr) \
1096 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1097 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1098 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1099 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1100 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1101 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1102 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1104 #define FN_LOCAL_STRING(fn_name,val) \
1105 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));}
1106 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1107 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1108 #define FN_LOCAL_LIST(fn_name,val) \
1109 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1110 #define FN_LOCAL_BOOL(fn_name,val) \
1111 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1112 #define FN_LOCAL_INTEGER(fn_name,val) \
1113 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1115 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1116 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1117 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1118 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1119 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1120 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1122 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int
,
1123 winbindMaxDomainConnections
)
1125 int lp_winbind_max_domain_connections(void)
1127 if (lp_winbind_offline_logon() &&
1128 lp_winbind_max_domain_connections_int() > 1) {
1129 DEBUG(1, ("offline logons active, restricting max domain "
1130 "connections to 1\n"));
1133 return MAX(1, lp_winbind_max_domain_connections_int());
1136 int lp_smb2_max_credits(void)
1138 if (Globals
.ismb2_max_credits
== 0) {
1139 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
1141 return Globals
.ismb2_max_credits
;
1143 int lp_cups_encrypt(void)
1146 #ifdef HAVE_HTTPCONNECTENCRYPT
1147 switch (Globals
.CupsEncrypt
) {
1149 result
= HTTP_ENCRYPT_REQUIRED
;
1152 result
= HTTP_ENCRYPT_ALWAYS
;
1155 result
= HTTP_ENCRYPT_NEVER
;
1162 /* These functions remain in source3/param for now */
1164 #include "lib/param/param_functions.c"
1166 FN_LOCAL_STRING(servicename
, szService
)
1167 FN_LOCAL_CONST_STRING(const_servicename
, szService
)
1169 /* These functions cannot be auto-generated */
1170 FN_LOCAL_BOOL(autoloaded
, autoloaded
)
1172 /* local prototypes */
1174 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
);
1175 static const char *get_boolean(bool bool_value
);
1176 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
1178 static bool do_section(const char *pszSectionName
, void *userdata
);
1179 static bool hash_a_service(const char *name
, int number
);
1180 static void free_service_byindex(int iService
);
1181 static void show_parameter(int parmIndex
);
1182 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
);
1185 * This is a helper function for parametrical options support. It returns a
1186 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1187 * parametrical functions are quite simple
1189 static struct parmlist_entry
*get_parametrics_by_service(struct loadparm_service
*service
, const char *type
,
1192 bool global_section
= false;
1194 struct parmlist_entry
*data
;
1195 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
1197 if (service
== NULL
) {
1198 data
= Globals
.param_opt
;
1199 global_section
= true;
1201 data
= service
->param_opt
;
1204 param_key
= talloc_asprintf(mem_ctx
, "%s:%s", type
, option
);
1205 if (param_key
== NULL
) {
1206 DEBUG(0,("asprintf failed!\n"));
1207 TALLOC_FREE(mem_ctx
);
1212 if (strwicmp(data
->key
, param_key
) == 0) {
1213 TALLOC_FREE(mem_ctx
);
1219 if (!global_section
) {
1220 /* Try to fetch the same option but from globals */
1221 /* but only if we are not already working with Globals */
1222 data
= Globals
.param_opt
;
1224 if (strwicmp(data
->key
, param_key
) == 0) {
1225 TALLOC_FREE(mem_ctx
);
1232 TALLOC_FREE(mem_ctx
);
1238 * This is a helper function for parametrical options support. It returns a
1239 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1240 * parametrical functions are quite simple
1242 static struct parmlist_entry
*get_parametrics(int snum
, const char *type
,
1245 if (snum
>= iNumServices
) return NULL
;
1248 return get_parametrics_by_service(NULL
, type
, option
);
1250 return get_parametrics_by_service(ServicePtrs
[snum
], type
, option
);
1255 #define MISSING_PARAMETER(name) \
1256 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1258 /*******************************************************************
1259 convenience routine to return int parameters.
1260 ********************************************************************/
1261 static int lp_int(const char *s
)
1265 MISSING_PARAMETER(lp_int
);
1269 return (int)strtol(s
, NULL
, 0);
1272 /*******************************************************************
1273 convenience routine to return unsigned long parameters.
1274 ********************************************************************/
1275 static unsigned long lp_ulong(const char *s
)
1279 MISSING_PARAMETER(lp_ulong
);
1283 return strtoul(s
, NULL
, 0);
1286 /*******************************************************************
1287 convenience routine to return boolean parameters.
1288 ********************************************************************/
1289 static bool lp_bool(const char *s
)
1294 MISSING_PARAMETER(lp_bool
);
1298 if (!set_boolean(s
, &ret
)) {
1299 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s
));
1306 /*******************************************************************
1307 convenience routine to return enum parameters.
1308 ********************************************************************/
1309 static int lp_enum(const char *s
,const struct enum_list
*_enum
)
1313 if (!s
|| !*s
|| !_enum
) {
1314 MISSING_PARAMETER(lp_enum
);
1318 for (i
=0; _enum
[i
].name
; i
++) {
1319 if (strequal(_enum
[i
].name
,s
))
1320 return _enum
[i
].value
;
1323 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s
));
1327 #undef MISSING_PARAMETER
1329 /* Return parametric option from a given service. Type is a part of option before ':' */
1330 /* Parametric option has following syntax: 'Type: option = value' */
1331 char *lp_parm_talloc_string(TALLOC_CTX
*ctx
, int snum
, const char *type
, const char *option
, const char *def
)
1333 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1335 if (data
== NULL
||data
->value
==NULL
) {
1337 return lp_string(ctx
, def
);
1343 return lp_string(ctx
, data
->value
);
1346 /* Return parametric option from a given service. Type is a part of option before ':' */
1347 /* Parametric option has following syntax: 'Type: option = value' */
1348 const char *lp_parm_const_string(int snum
, const char *type
, const char *option
, const char *def
)
1350 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1352 if (data
== NULL
||data
->value
==NULL
)
1358 const char *lp_parm_const_string_service(struct loadparm_service
*service
, const char *type
, const char *option
)
1360 struct parmlist_entry
*data
= get_parametrics_by_service(service
, type
, option
);
1362 if (data
== NULL
||data
->value
==NULL
)
1369 /* Return parametric option from a given service. Type is a part of option before ':' */
1370 /* Parametric option has following syntax: 'Type: option = value' */
1372 const char **lp_parm_string_list(int snum
, const char *type
, const char *option
, const char **def
)
1374 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1376 if (data
== NULL
||data
->value
==NULL
)
1377 return (const char **)def
;
1379 if (data
->list
==NULL
) {
1380 data
->list
= str_list_make_v3(NULL
, data
->value
, NULL
);
1383 return (const char **)data
->list
;
1386 /* Return parametric option from a given service. Type is a part of option before ':' */
1387 /* Parametric option has following syntax: 'Type: option = value' */
1389 int lp_parm_int(int snum
, const char *type
, const char *option
, int def
)
1391 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1393 if (data
&& data
->value
&& *data
->value
)
1394 return lp_int(data
->value
);
1399 /* Return parametric option from a given service. Type is a part of option before ':' */
1400 /* Parametric option has following syntax: 'Type: option = value' */
1402 unsigned long lp_parm_ulong(int snum
, const char *type
, const char *option
, unsigned long def
)
1404 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1406 if (data
&& data
->value
&& *data
->value
)
1407 return lp_ulong(data
->value
);
1412 /* Return parametric option from a given service. Type is a part of option before ':' */
1413 /* Parametric option has following syntax: 'Type: option = value' */
1415 bool lp_parm_bool(int snum
, const char *type
, const char *option
, bool def
)
1417 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1419 if (data
&& data
->value
&& *data
->value
)
1420 return lp_bool(data
->value
);
1425 /* Return parametric option from a given service. Type is a part of option before ':' */
1426 /* Parametric option has following syntax: 'Type: option = value' */
1428 int lp_parm_enum(int snum
, const char *type
, const char *option
,
1429 const struct enum_list
*_enum
, int def
)
1431 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1433 if (data
&& data
->value
&& *data
->value
&& _enum
)
1434 return lp_enum(data
->value
, _enum
);
1440 * free a param_opts structure.
1441 * param_opts handling should be moved to talloc;
1442 * then this whole functions reduces to a TALLOC_FREE().
1445 static void free_param_opts(struct parmlist_entry
**popts
)
1447 struct parmlist_entry
*opt
, *next_opt
;
1449 if (*popts
!= NULL
) {
1450 DEBUG(5, ("Freeing parametrics:\n"));
1453 while (opt
!= NULL
) {
1454 string_free(&opt
->key
);
1455 string_free(&opt
->value
);
1456 TALLOC_FREE(opt
->list
);
1457 next_opt
= opt
->next
;
1464 /***************************************************************************
1465 Free the dynamically allocated parts of a service struct.
1466 ***************************************************************************/
1468 static void free_service(struct loadparm_service
*pservice
)
1473 if (pservice
->szService
)
1474 DEBUG(5, ("free_service: Freeing service %s\n",
1475 pservice
->szService
));
1477 free_parameters(pservice
);
1479 string_free(&pservice
->szService
);
1480 TALLOC_FREE(pservice
->copymap
);
1482 free_param_opts(&pservice
->param_opt
);
1484 ZERO_STRUCTP(pservice
);
1488 /***************************************************************************
1489 remove a service indexed in the ServicePtrs array from the ServiceHash
1490 and free the dynamically allocated parts
1491 ***************************************************************************/
1493 static void free_service_byindex(int idx
)
1495 if ( !LP_SNUM_OK(idx
) )
1498 ServicePtrs
[idx
]->valid
= false;
1500 /* we have to cleanup the hash record */
1502 if (ServicePtrs
[idx
]->szService
) {
1503 char *canon_name
= canonicalize_servicename(
1505 ServicePtrs
[idx
]->szService
);
1507 dbwrap_delete_bystring(ServiceHash
, canon_name
);
1508 TALLOC_FREE(canon_name
);
1511 free_service(ServicePtrs
[idx
]);
1512 talloc_free_children(ServicePtrs
[idx
]);
1515 /***************************************************************************
1516 Add a new service to the services array initialising it with the given
1518 ***************************************************************************/
1520 static int add_a_service(const struct loadparm_service
*pservice
, const char *name
)
1523 int num_to_alloc
= iNumServices
+ 1;
1524 struct loadparm_service
**tsp
= NULL
;
1526 /* it might already exist */
1528 i
= getservicebyname(name
, NULL
);
1534 /* if not, then create one */
1536 tsp
= talloc_realloc(NULL
, ServicePtrs
, struct loadparm_service
*, num_to_alloc
);
1538 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1542 ServicePtrs
[iNumServices
] = talloc_zero(NULL
, struct loadparm_service
);
1543 if (!ServicePtrs
[iNumServices
]) {
1544 DEBUG(0,("add_a_service: out of memory!\n"));
1549 ServicePtrs
[i
]->valid
= true;
1551 copy_service(ServicePtrs
[i
], pservice
, NULL
);
1553 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->szService
, name
);
1555 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1556 i
, ServicePtrs
[i
]->szService
));
1558 if (!hash_a_service(ServicePtrs
[i
]->szService
, i
)) {
1565 /***************************************************************************
1566 Convert a string to uppercase and remove whitespaces.
1567 ***************************************************************************/
1569 char *canonicalize_servicename(TALLOC_CTX
*ctx
, const char *src
)
1574 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1578 result
= talloc_strdup(ctx
, src
);
1579 SMB_ASSERT(result
!= NULL
);
1581 if (!strlower_m(result
)) {
1582 TALLOC_FREE(result
);
1588 /***************************************************************************
1589 Add a name/index pair for the services array to the hash table.
1590 ***************************************************************************/
1592 static bool hash_a_service(const char *name
, int idx
)
1596 if ( !ServiceHash
) {
1597 DEBUG(10,("hash_a_service: creating servicehash\n"));
1598 ServiceHash
= db_open_rbt(NULL
);
1599 if ( !ServiceHash
) {
1600 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1605 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1608 canon_name
= canonicalize_servicename(talloc_tos(), name
);
1610 dbwrap_store_bystring(ServiceHash
, canon_name
,
1611 make_tdb_data((uint8
*)&idx
, sizeof(idx
)),
1614 TALLOC_FREE(canon_name
);
1619 /***************************************************************************
1620 Add a new home service, with the specified home directory, defaults coming
1622 ***************************************************************************/
1624 bool lp_add_home(const char *pszHomename
, int iDefaultService
,
1625 const char *user
, const char *pszHomedir
)
1629 if (pszHomename
== NULL
|| user
== NULL
|| pszHomedir
== NULL
||
1630 pszHomedir
[0] == '\0') {
1634 i
= add_a_service(ServicePtrs
[iDefaultService
], pszHomename
);
1639 if (!(*(ServicePtrs
[iDefaultService
]->path
))
1640 || strequal(ServicePtrs
[iDefaultService
]->path
,
1641 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM
))) {
1642 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->path
, pszHomedir
);
1645 if (!(*(ServicePtrs
[i
]->comment
))) {
1646 char *comment
= talloc_asprintf(talloc_tos(), "Home directory of %s", user
);
1647 if (comment
== NULL
) {
1650 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
1651 TALLOC_FREE(comment
);
1654 /* set the browseable flag from the global default */
1656 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1657 ServicePtrs
[i
]->access_based_share_enum
= sDefault
.access_based_share_enum
;
1659 ServicePtrs
[i
]->autoloaded
= true;
1661 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename
,
1662 user
, ServicePtrs
[i
]->path
));
1667 /***************************************************************************
1668 Add a new service, based on an old one.
1669 ***************************************************************************/
1671 int lp_add_service(const char *pszService
, int iDefaultService
)
1673 if (iDefaultService
< 0) {
1674 return add_a_service(&sDefault
, pszService
);
1677 return (add_a_service(ServicePtrs
[iDefaultService
], pszService
));
1680 /***************************************************************************
1681 Add the IPC service.
1682 ***************************************************************************/
1684 static bool lp_add_ipc(const char *ipc_name
, bool guest_ok
)
1686 char *comment
= NULL
;
1687 int i
= add_a_service(&sDefault
, ipc_name
);
1692 comment
= talloc_asprintf(talloc_tos(), "IPC Service (%s)",
1693 Globals
.server_string
);
1694 if (comment
== NULL
) {
1698 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->path
, tmpdir());
1699 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->username
, "");
1700 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
1701 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->fstype
, "IPC");
1702 ServicePtrs
[i
]->max_connections
= 0;
1703 ServicePtrs
[i
]->bAvailable
= true;
1704 ServicePtrs
[i
]->read_only
= true;
1705 ServicePtrs
[i
]->guest_only
= false;
1706 ServicePtrs
[i
]->administrative_share
= true;
1707 ServicePtrs
[i
]->guest_ok
= guest_ok
;
1708 ServicePtrs
[i
]->printable
= false;
1709 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1711 DEBUG(3, ("adding IPC service\n"));
1713 TALLOC_FREE(comment
);
1717 /***************************************************************************
1718 Add a new printer service, with defaults coming from service iFrom.
1719 ***************************************************************************/
1721 bool lp_add_printer(const char *pszPrintername
, int iDefaultService
)
1723 const char *comment
= "From Printcap";
1724 int i
= add_a_service(ServicePtrs
[iDefaultService
], pszPrintername
);
1729 /* note that we do NOT default the availability flag to true - */
1730 /* we take it from the default service passed. This allows all */
1731 /* dynamic printers to be disabled by disabling the [printers] */
1732 /* entry (if/when the 'available' keyword is implemented!). */
1734 /* the printer name is set to the service name. */
1735 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->_printername
, pszPrintername
);
1736 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
1738 /* set the browseable flag from the gloabl default */
1739 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1741 /* Printers cannot be read_only. */
1742 ServicePtrs
[i
]->read_only
= false;
1743 /* No oplocks on printer services. */
1744 ServicePtrs
[i
]->oplocks
= false;
1745 /* Printer services must be printable. */
1746 ServicePtrs
[i
]->printable
= true;
1748 DEBUG(3, ("adding printer service %s\n", pszPrintername
));
1754 /***************************************************************************
1755 Check whether the given parameter name is valid.
1756 Parametric options (names containing a colon) are considered valid.
1757 ***************************************************************************/
1759 bool lp_parameter_is_valid(const char *pszParmName
)
1761 return ((lpcfg_map_parameter(pszParmName
) != -1) ||
1762 (strchr(pszParmName
, ':') != NULL
));
1765 /***************************************************************************
1766 Check whether the given name is the name of a global parameter.
1767 Returns true for strings belonging to parameters of class
1768 P_GLOBAL, false for all other strings, also for parametric options
1769 and strings not belonging to any option.
1770 ***************************************************************************/
1772 bool lp_parameter_is_global(const char *pszParmName
)
1774 int num
= lpcfg_map_parameter(pszParmName
);
1777 return (parm_table
[num
].p_class
== P_GLOBAL
);
1783 /**************************************************************************
1784 Check whether the given name is the canonical name of a parameter.
1785 Returns false if it is not a valid parameter Name.
1786 For parametric options, true is returned.
1787 **************************************************************************/
1789 bool lp_parameter_is_canonical(const char *parm_name
)
1791 if (!lp_parameter_is_valid(parm_name
)) {
1795 return (lpcfg_map_parameter(parm_name
) ==
1796 map_parameter_canonical(parm_name
, NULL
));
1799 /**************************************************************************
1800 Determine the canonical name for a parameter.
1801 Indicate when it is an inverse (boolean) synonym instead of a
1803 **************************************************************************/
1805 bool lp_canonicalize_parameter(const char *parm_name
, const char **canon_parm
,
1810 if (!lp_parameter_is_valid(parm_name
)) {
1815 num
= map_parameter_canonical(parm_name
, inverse
);
1817 /* parametric option */
1818 *canon_parm
= parm_name
;
1820 *canon_parm
= parm_table
[num
].label
;
1827 /**************************************************************************
1828 Determine the canonical name for a parameter.
1829 Turn the value given into the inverse boolean expression when
1830 the synonym is an invers boolean synonym.
1832 Return true if parm_name is a valid parameter name and
1833 in case it is an invers boolean synonym, if the val string could
1834 successfully be converted to the reverse bool.
1835 Return false in all other cases.
1836 **************************************************************************/
1838 bool lp_canonicalize_parameter_with_value(const char *parm_name
,
1840 const char **canon_parm
,
1841 const char **canon_val
)
1846 if (!lp_parameter_is_valid(parm_name
)) {
1852 num
= map_parameter_canonical(parm_name
, &inverse
);
1854 /* parametric option */
1855 *canon_parm
= parm_name
;
1858 *canon_parm
= parm_table
[num
].label
;
1860 if (!lp_invert_boolean(val
, canon_val
)) {
1872 /***************************************************************************
1873 Map a parameter's string representation to the index of the canonical
1874 form of the parameter (it might be a synonym).
1875 Returns -1 if the parameter string is not recognised.
1876 ***************************************************************************/
1878 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
)
1880 int parm_num
, canon_num
;
1881 bool loc_inverse
= false;
1883 parm_num
= lpcfg_map_parameter(pszParmName
);
1884 if ((parm_num
< 0) || !(parm_table
[parm_num
].flags
& FLAG_HIDE
)) {
1885 /* invalid, parametric or no canidate for synonyms ... */
1889 for (canon_num
= 0; parm_table
[canon_num
].label
; canon_num
++) {
1890 if (is_synonym_of(parm_num
, canon_num
, &loc_inverse
)) {
1891 parm_num
= canon_num
;
1897 if (inverse
!= NULL
) {
1898 *inverse
= loc_inverse
;
1903 /***************************************************************************
1904 return true if parameter number parm1 is a synonym of parameter
1905 number parm2 (parm2 being the principal name).
1906 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1908 ***************************************************************************/
1910 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
)
1912 if ((parm_table
[parm1
].offset
== parm_table
[parm2
].offset
) &&
1913 (parm_table
[parm1
].p_class
== parm_table
[parm2
].p_class
) &&
1914 (parm_table
[parm1
].flags
& FLAG_HIDE
) &&
1915 !(parm_table
[parm2
].flags
& FLAG_HIDE
))
1917 if (inverse
!= NULL
) {
1918 if ((parm_table
[parm1
].type
== P_BOOLREV
) &&
1919 (parm_table
[parm2
].type
== P_BOOL
))
1931 /***************************************************************************
1932 Show one parameter's name, type, [values,] and flags.
1933 (helper functions for show_parameter_list)
1934 ***************************************************************************/
1936 static void show_parameter(int parmIndex
)
1938 int enumIndex
, flagIndex
;
1943 const char *type
[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1944 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1946 unsigned flags
[] = { FLAG_BASIC
, FLAG_SHARE
, FLAG_PRINT
, FLAG_GLOBAL
,
1947 FLAG_WIZARD
, FLAG_ADVANCED
, FLAG_DEVELOPER
, FLAG_DEPRECATED
,
1949 const char *flag_names
[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1950 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1951 "FLAG_DEPRECATED", "FLAG_HIDE", NULL
};
1953 printf("%s=%s", parm_table
[parmIndex
].label
,
1954 type
[parm_table
[parmIndex
].type
]);
1955 if (parm_table
[parmIndex
].type
== P_ENUM
) {
1958 parm_table
[parmIndex
].enum_list
[enumIndex
].name
;
1962 enumIndex
? "|" : "",
1963 parm_table
[parmIndex
].enum_list
[enumIndex
].name
);
1968 for (flagIndex
=0; flag_names
[flagIndex
]; flagIndex
++) {
1969 if (parm_table
[parmIndex
].flags
& flags
[flagIndex
]) {
1972 flag_names
[flagIndex
]);
1977 /* output synonyms */
1979 for (parmIndex2
=0; parm_table
[parmIndex2
].label
; parmIndex2
++) {
1980 if (is_synonym_of(parmIndex
, parmIndex2
, &inverse
)) {
1981 printf(" (%ssynonym of %s)", inverse
? "inverse " : "",
1982 parm_table
[parmIndex2
].label
);
1983 } else if (is_synonym_of(parmIndex2
, parmIndex
, &inverse
)) {
1985 printf(" (synonyms: ");
1990 printf("%s%s", parm_table
[parmIndex2
].label
,
1991 inverse
? "[i]" : "");
2001 /***************************************************************************
2002 Show all parameter's name, type, [values,] and flags.
2003 ***************************************************************************/
2005 void show_parameter_list(void)
2007 int classIndex
, parmIndex
;
2008 const char *section_names
[] = { "local", "global", NULL
};
2010 for (classIndex
=0; section_names
[classIndex
]; classIndex
++) {
2011 printf("[%s]\n", section_names
[classIndex
]);
2012 for (parmIndex
= 0; parm_table
[parmIndex
].label
; parmIndex
++) {
2013 if (parm_table
[parmIndex
].p_class
== classIndex
) {
2014 show_parameter(parmIndex
);
2020 /***************************************************************************
2021 Get the standard string representation of a boolean value ("yes" or "no")
2022 ***************************************************************************/
2024 static const char *get_boolean(bool bool_value
)
2026 static const char *yes_str
= "yes";
2027 static const char *no_str
= "no";
2029 return (bool_value
? yes_str
: no_str
);
2032 /***************************************************************************
2033 Provide the string of the negated boolean value associated to the boolean
2034 given as a string. Returns false if the passed string does not correctly
2035 represent a boolean.
2036 ***************************************************************************/
2038 bool lp_invert_boolean(const char *str
, const char **inverse_str
)
2042 if (!set_boolean(str
, &val
)) {
2046 *inverse_str
= get_boolean(!val
);
2050 /***************************************************************************
2051 Provide the canonical string representation of a boolean value given
2052 as a string. Return true on success, false if the string given does
2053 not correctly represent a boolean.
2054 ***************************************************************************/
2056 bool lp_canonicalize_boolean(const char *str
, const char**canon_str
)
2060 if (!set_boolean(str
, &val
)) {
2064 *canon_str
= get_boolean(val
);
2068 /***************************************************************************
2069 Find a service by name. Otherwise works like get_service.
2070 ***************************************************************************/
2072 int getservicebyname(const char *pszServiceName
, struct loadparm_service
*pserviceDest
)
2079 if (ServiceHash
== NULL
) {
2083 canon_name
= canonicalize_servicename(talloc_tos(), pszServiceName
);
2085 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
, canon_name
,
2088 if (NT_STATUS_IS_OK(status
) &&
2089 (data
.dptr
!= NULL
) &&
2090 (data
.dsize
== sizeof(iService
)))
2092 iService
= *(int *)data
.dptr
;
2095 TALLOC_FREE(canon_name
);
2097 if ((iService
!= -1) && (LP_SNUM_OK(iService
))
2098 && (pserviceDest
!= NULL
)) {
2099 copy_service(pserviceDest
, ServicePtrs
[iService
], NULL
);
2105 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2106 struct loadparm_service
*lp_service(const char *pszServiceName
)
2108 int iService
= getservicebyname(pszServiceName
, NULL
);
2109 if (iService
== -1 || !LP_SNUM_OK(iService
)) {
2112 return ServicePtrs
[iService
];
2115 struct loadparm_service
*lp_servicebynum(int snum
)
2117 if ((snum
== -1) || !LP_SNUM_OK(snum
)) {
2120 return ServicePtrs
[snum
];
2123 struct loadparm_service
*lp_default_loadparm_service()
2128 /***************************************************************************
2129 Check a service for consistency. Return false if the service is in any way
2130 incomplete or faulty, else true.
2131 ***************************************************************************/
2133 bool service_ok(int iService
)
2138 if (ServicePtrs
[iService
]->szService
[0] == '\0') {
2139 DEBUG(0, ("The following message indicates an internal error:\n"));
2140 DEBUG(0, ("No service name in service entry.\n"));
2144 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2145 /* I can't see why you'd want a non-printable printer service... */
2146 if (strwicmp(ServicePtrs
[iService
]->szService
, PRINTERS_NAME
) == 0) {
2147 if (!ServicePtrs
[iService
]->printable
) {
2148 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2149 ServicePtrs
[iService
]->szService
));
2150 ServicePtrs
[iService
]->printable
= true;
2152 /* [printers] service must also be non-browsable. */
2153 if (ServicePtrs
[iService
]->browseable
)
2154 ServicePtrs
[iService
]->browseable
= false;
2157 if (ServicePtrs
[iService
]->path
[0] == '\0' &&
2158 strwicmp(ServicePtrs
[iService
]->szService
, HOMES_NAME
) != 0 &&
2159 ServicePtrs
[iService
]->msdfs_proxy
[0] == '\0'
2161 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2162 ServicePtrs
[iService
]->szService
));
2163 ServicePtrs
[iService
]->bAvailable
= false;
2166 /* If a service is flagged unavailable, log the fact at level 1. */
2167 if (!ServicePtrs
[iService
]->bAvailable
)
2168 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2169 ServicePtrs
[iService
]->szService
));
2174 static struct smbconf_ctx
*lp_smbconf_ctx(void)
2177 static struct smbconf_ctx
*conf_ctx
= NULL
;
2179 if (conf_ctx
== NULL
) {
2180 err
= smbconf_init(NULL
, &conf_ctx
, "registry:");
2181 if (!SBC_ERROR_IS_OK(err
)) {
2182 DEBUG(1, ("error initializing registry configuration: "
2183 "%s\n", sbcErrorString(err
)));
2191 static bool process_smbconf_service(struct smbconf_service
*service
)
2196 if (service
== NULL
) {
2200 ret
= do_section(service
->name
, NULL
);
2204 for (count
= 0; count
< service
->num_params
; count
++) {
2205 ret
= do_parameter(service
->param_names
[count
],
2206 service
->param_values
[count
],
2212 if (iServiceIndex
>= 0) {
2213 return service_ok(iServiceIndex
);
2219 * load a service from registry and activate it
2221 bool process_registry_service(const char *service_name
)
2224 struct smbconf_service
*service
= NULL
;
2225 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2226 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2229 if (conf_ctx
== NULL
) {
2233 DEBUG(5, ("process_registry_service: service name %s\n", service_name
));
2235 if (!smbconf_share_exists(conf_ctx
, service_name
)) {
2237 * Registry does not contain data for this service (yet),
2238 * but make sure lp_load doesn't return false.
2244 err
= smbconf_get_share(conf_ctx
, mem_ctx
, service_name
, &service
);
2245 if (!SBC_ERROR_IS_OK(err
)) {
2249 ret
= process_smbconf_service(service
);
2255 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2258 TALLOC_FREE(mem_ctx
);
2263 * process_registry_globals
2265 static bool process_registry_globals(void)
2269 add_to_file_list(NULL
, &file_lists
, INCLUDE_REGISTRY_NAME
, INCLUDE_REGISTRY_NAME
);
2271 ret
= do_parameter("registry shares", "yes", NULL
);
2276 return process_registry_service(GLOBAL_NAME
);
2279 bool process_registry_shares(void)
2283 struct smbconf_service
**service
= NULL
;
2284 uint32_t num_shares
= 0;
2285 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2286 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2289 if (conf_ctx
== NULL
) {
2293 err
= smbconf_get_config(conf_ctx
, mem_ctx
, &num_shares
, &service
);
2294 if (!SBC_ERROR_IS_OK(err
)) {
2300 for (count
= 0; count
< num_shares
; count
++) {
2301 if (strequal(service
[count
]->name
, GLOBAL_NAME
)) {
2304 ret
= process_smbconf_service(service
[count
]);
2311 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2314 TALLOC_FREE(mem_ctx
);
2319 * reload those shares from registry that are already
2320 * activated in the services array.
2322 static bool reload_registry_shares(void)
2327 for (i
= 0; i
< iNumServices
; i
++) {
2332 if (ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
2336 ret
= process_registry_service(ServicePtrs
[i
]->szService
);
2347 #define MAX_INCLUDE_DEPTH 100
2349 static uint8_t include_depth
;
2352 * Free the file lists
2354 static void free_file_list(void)
2356 struct file_lists
*f
;
2357 struct file_lists
*next
;
2370 * Utility function for outsiders to check if we're running on registry.
2372 bool lp_config_backend_is_registry(void)
2374 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY
);
2378 * Utility function to check if the config backend is FILE.
2380 bool lp_config_backend_is_file(void)
2382 return (lp_config_backend() == CONFIG_BACKEND_FILE
);
2385 /*******************************************************************
2386 Check if a config file has changed date.
2387 ********************************************************************/
2389 bool lp_file_list_changed(void)
2391 struct file_lists
*f
= file_lists
;
2393 DEBUG(6, ("lp_file_list_changed()\n"));
2398 if (strequal(f
->name
, INCLUDE_REGISTRY_NAME
)) {
2399 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2401 if (conf_ctx
== NULL
) {
2404 if (smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
,
2407 DEBUGADD(6, ("registry config changed\n"));
2412 n2
= talloc_sub_basic(talloc_tos(),
2413 get_current_username(),
2414 current_user_info
.domain
,
2419 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2420 f
->name
, n2
, ctime(&f
->modtime
)));
2422 mod_time
= file_modtime(n2
);
2425 ((f
->modtime
!= mod_time
) ||
2426 (f
->subfname
== NULL
) ||
2427 (strcmp(n2
, f
->subfname
) != 0)))
2430 ("file %s modified: %s\n", n2
,
2432 f
->modtime
= mod_time
;
2433 TALLOC_FREE(f
->subfname
);
2434 f
->subfname
= talloc_strdup(f
, n2
);
2435 if (f
->subfname
== NULL
) {
2436 smb_panic("talloc_strdup failed");
2450 * Initialize iconv conversion descriptors.
2452 * This is called the first time it is needed, and also called again
2453 * every time the configuration is reloaded, because the charset or
2454 * codepage might have changed.
2456 static void init_iconv(void)
2458 global_iconv_handle
= smb_iconv_handle_reinit(NULL
, lp_dos_charset(),
2460 true, global_iconv_handle
);
2463 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2465 if (*ptr
== NULL
|| strcmp(*ptr
, pszParmValue
) != 0) {
2466 string_set(Globals
.ctx
, ptr
, pszParmValue
);
2467 global_iconv_handle
= smb_iconv_handle_reinit(NULL
, lp_dos_charset(),
2469 true, global_iconv_handle
);
2474 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2476 bool is_utf8
= false;
2477 size_t len
= strlen(pszParmValue
);
2479 if (len
== 4 || len
== 5) {
2480 /* Don't use StrCaseCmp here as we don't want to
2481 initialize iconv. */
2482 if ((toupper_m(pszParmValue
[0]) == 'U') &&
2483 (toupper_m(pszParmValue
[1]) == 'T') &&
2484 (toupper_m(pszParmValue
[2]) == 'F')) {
2486 if (pszParmValue
[3] == '8') {
2490 if (pszParmValue
[3] == '-' &&
2491 pszParmValue
[4] == '8') {
2498 if (*ptr
== NULL
|| strcmp(*ptr
, pszParmValue
) != 0) {
2500 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2501 "be UTF8, using (default value) %s instead.\n",
2502 DEFAULT_DOS_CHARSET
));
2503 pszParmValue
= DEFAULT_DOS_CHARSET
;
2505 string_set(Globals
.ctx
, ptr
, pszParmValue
);
2506 global_iconv_handle
= smb_iconv_handle_reinit(NULL
, lp_dos_charset(),
2508 true, global_iconv_handle
);
2513 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2515 TALLOC_FREE(Globals
.netbios_aliases
);
2516 Globals
.netbios_aliases
= (const char **)str_list_make_v3(NULL
, pszParmValue
, NULL
);
2517 return set_netbios_aliases(Globals
.netbios_aliases
);
2520 /***************************************************************************
2521 Handle the include operation.
2522 ***************************************************************************/
2523 static bool bAllowIncludeRegistry
= true;
2525 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2529 if (include_depth
>= MAX_INCLUDE_DEPTH
) {
2530 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2535 if (strequal(pszParmValue
, INCLUDE_REGISTRY_NAME
)) {
2536 if (!bAllowIncludeRegistry
) {
2539 if (bInGlobalSection
) {
2542 ret
= process_registry_globals();
2546 DEBUG(1, ("\"include = registry\" only effective "
2547 "in %s section\n", GLOBAL_NAME
));
2552 fname
= talloc_sub_basic(talloc_tos(), get_current_username(),
2553 current_user_info
.domain
,
2556 add_to_file_list(NULL
, &file_lists
, pszParmValue
, fname
);
2559 string_set(Globals
.ctx
, ptr
, fname
);
2561 string_set(ServicePtrs
[snum
], ptr
, fname
);
2564 if (file_exist(fname
)) {
2567 ret
= pm_process(fname
, do_section
, do_parameter
, NULL
);
2573 DEBUG(2, ("Can't find include file %s\n", fname
));
2578 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2580 Globals
.ldap_debug_level
= lp_int(pszParmValue
);
2581 init_ldap_debugging();
2586 * idmap related parameters
2589 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2591 lp_do_parameter(snum
, "idmap config * : backend", pszParmValue
);
2596 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2598 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
2603 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2605 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
2610 bool lp_idmap_range(const char *domain_name
, uint32_t *low
, uint32_t *high
)
2612 char *config_option
= NULL
;
2613 const char *range
= NULL
;
2616 SMB_ASSERT(low
!= NULL
);
2617 SMB_ASSERT(high
!= NULL
);
2619 if ((domain_name
== NULL
) || (domain_name
[0] == '\0')) {
2623 config_option
= talloc_asprintf(talloc_tos(), "idmap config %s",
2625 if (config_option
== NULL
) {
2626 DEBUG(0, ("out of memory\n"));
2630 range
= lp_parm_const_string(-1, config_option
, "range", NULL
);
2631 if (range
== NULL
) {
2632 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name
));
2636 if (sscanf(range
, "%u - %u", low
, high
) != 2) {
2637 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2638 range
, domain_name
));
2645 talloc_free(config_option
);
2650 bool lp_idmap_default_range(uint32_t *low
, uint32_t *high
)
2652 return lp_idmap_range("*", low
, high
);
2655 const char *lp_idmap_backend(const char *domain_name
)
2657 char *config_option
= NULL
;
2658 const char *backend
= NULL
;
2660 if ((domain_name
== NULL
) || (domain_name
[0] == '\0')) {
2664 config_option
= talloc_asprintf(talloc_tos(), "idmap config %s",
2666 if (config_option
== NULL
) {
2667 DEBUG(0, ("out of memory\n"));
2671 backend
= lp_parm_const_string(-1, config_option
, "backend", NULL
);
2672 if (backend
== NULL
) {
2673 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name
));
2678 talloc_free(config_option
);
2682 const char *lp_idmap_default_backend(void)
2684 return lp_idmap_backend("*");
2687 /***************************************************************************
2688 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2689 ***************************************************************************/
2691 static const char *append_ldap_suffix(TALLOC_CTX
*ctx
, const char *str
)
2693 const char *suffix_string
;
2695 suffix_string
= talloc_asprintf(ctx
, "%s,%s", str
,
2696 Globals
.ldap_suffix
);
2697 if ( !suffix_string
) {
2698 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2702 return suffix_string
;
2705 const char *lp_ldap_machine_suffix(TALLOC_CTX
*ctx
)
2707 if (Globals
.szLdapMachineSuffix
[0])
2708 return append_ldap_suffix(ctx
, Globals
.szLdapMachineSuffix
);
2710 return lp_string(ctx
, Globals
.ldap_suffix
);
2713 const char *lp_ldap_user_suffix(TALLOC_CTX
*ctx
)
2715 if (Globals
.szLdapUserSuffix
[0])
2716 return append_ldap_suffix(ctx
, Globals
.szLdapUserSuffix
);
2718 return lp_string(ctx
, Globals
.ldap_suffix
);
2721 const char *lp_ldap_group_suffix(TALLOC_CTX
*ctx
)
2723 if (Globals
.szLdapGroupSuffix
[0])
2724 return append_ldap_suffix(ctx
, Globals
.szLdapGroupSuffix
);
2726 return lp_string(ctx
, Globals
.ldap_suffix
);
2729 const char *lp_ldap_idmap_suffix(TALLOC_CTX
*ctx
)
2731 if (Globals
.szLdapIdmapSuffix
[0])
2732 return append_ldap_suffix(ctx
, Globals
.szLdapIdmapSuffix
);
2734 return lp_string(ctx
, Globals
.ldap_suffix
);
2737 /****************************************************************************
2738 set the value for a P_ENUM
2739 ***************************************************************************/
2741 static void lp_set_enum_parm( struct parm_struct
*parm
, const char *pszParmValue
,
2746 for (i
= 0; parm
->enum_list
[i
].name
; i
++) {
2747 if ( strequal(pszParmValue
, parm
->enum_list
[i
].name
)) {
2748 *ptr
= parm
->enum_list
[i
].value
;
2752 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
2753 pszParmValue
, parm
->label
));
2756 /***************************************************************************
2757 ***************************************************************************/
2759 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2761 static int parm_num
= -1;
2762 struct loadparm_service
*s
;
2764 if ( parm_num
== -1 )
2765 parm_num
= lpcfg_map_parameter( "printing" );
2767 lp_set_enum_parm( &parm_table
[parm_num
], pszParmValue
, (int*)ptr
);
2771 init_printer_values(Globals
.ctx
, s
);
2773 s
= ServicePtrs
[snum
];
2774 init_printer_values(s
, s
);
2781 return the parameter pointer for a parameter
2783 void *lp_parm_ptr(struct loadparm_service
*service
, struct parm_struct
*parm
)
2785 if (service
== NULL
) {
2786 if (parm
->p_class
== P_LOCAL
)
2787 return (void *)(((char *)&sDefault
)+parm
->offset
);
2788 else if (parm
->p_class
== P_GLOBAL
)
2789 return (void *)(((char *)&Globals
)+parm
->offset
);
2792 return (void *)(((char *)service
) + parm
->offset
);
2796 /***************************************************************************
2797 Return the local pointer to a parameter given the service number and parameter
2798 ***************************************************************************/
2800 void *lp_local_ptr_by_snum(int snum
, struct parm_struct
*parm
)
2802 return lp_parm_ptr(ServicePtrs
[snum
], parm
);
2805 /***************************************************************************
2806 Process a parameter for a particular service number. If snum < 0
2807 then assume we are in the globals.
2808 ***************************************************************************/
2810 bool lp_do_parameter(int snum
, const char *pszParmName
, const char *pszParmValue
)
2813 void *parm_ptr
= NULL
; /* where we are going to store the result */
2814 struct parmlist_entry
**opt_list
;
2815 TALLOC_CTX
*mem_ctx
;
2817 parmnum
= lpcfg_map_parameter(pszParmName
);
2820 if (strchr(pszParmName
, ':') == NULL
) {
2821 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
2827 * We've got a parametric option
2831 opt_list
= &Globals
.param_opt
;
2832 set_param_opt(NULL
, opt_list
, pszParmName
, pszParmValue
, 0);
2834 opt_list
= &ServicePtrs
[snum
]->param_opt
;
2835 set_param_opt(ServicePtrs
[snum
], opt_list
, pszParmName
, pszParmValue
, 0);
2841 /* if it's already been set by the command line, then we don't
2843 if (parm_table
[parmnum
].flags
& FLAG_CMDLINE
) {
2847 if (parm_table
[parmnum
].flags
& FLAG_DEPRECATED
) {
2848 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2852 /* we might point at a service, the default service or a global */
2854 parm_ptr
= lp_parm_ptr(NULL
, &parm_table
[parmnum
]);
2856 if (parm_table
[parmnum
].p_class
== P_GLOBAL
) {
2858 ("Global parameter %s found in service section!\n",
2862 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm_table
[parmnum
]);
2866 if (!ServicePtrs
[snum
]->copymap
)
2867 init_copymap(ServicePtrs
[snum
]);
2869 /* this handles the aliases - set the copymap for other entries with
2870 the same data pointer */
2871 for (i
= 0; parm_table
[i
].label
; i
++) {
2872 if ((parm_table
[i
].offset
== parm_table
[parmnum
].offset
)
2873 && (parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
)) {
2874 bitmap_clear(ServicePtrs
[snum
]->copymap
, i
);
2877 mem_ctx
= ServicePtrs
[snum
];
2879 mem_ctx
= Globals
.ctx
;
2882 /* if it is a special case then go ahead */
2883 if (parm_table
[parmnum
].special
) {
2885 struct loadparm_context
*lp_ctx
= loadparm_init_s3(talloc_tos(),
2886 loadparm_s3_helpers());
2887 ok
= parm_table
[parmnum
].special(lp_ctx
, snum
, pszParmValue
,
2889 TALLOC_FREE(lp_ctx
);
2894 /* now switch on the type of variable it is */
2895 switch (parm_table
[parmnum
].type
)
2898 *(bool *)parm_ptr
= lp_bool(pszParmValue
);
2902 *(bool *)parm_ptr
= !lp_bool(pszParmValue
);
2906 *(int *)parm_ptr
= lp_int(pszParmValue
);
2910 *(char *)parm_ptr
= *pszParmValue
;
2914 i
= sscanf(pszParmValue
, "%o", (int *)parm_ptr
);
2916 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName
));
2923 if (conv_str_size_error(pszParmValue
, &val
)) {
2924 if (val
<= INT_MAX
) {
2925 *(int *)parm_ptr
= (int)val
;
2930 DEBUG(0,("lp_do_parameter(%s): value is not "
2931 "a valid size specifier!\n", pszParmValue
));
2937 TALLOC_FREE(*((char ***)parm_ptr
));
2938 *(char ***)parm_ptr
= str_list_make_v3(
2939 NULL
, pszParmValue
, NULL
);
2943 string_set(mem_ctx
, (char **)parm_ptr
, pszParmValue
);
2948 char *upper_string
= strupper_talloc(talloc_tos(),
2950 string_set(mem_ctx
, (char **)parm_ptr
, upper_string
);
2951 TALLOC_FREE(upper_string
);
2955 lp_set_enum_parm( &parm_table
[parmnum
], pszParmValue
, (int*)parm_ptr
);
2964 /***************************************************************************
2965 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
2966 FLAG_CMDLINE won't be overridden by loads from smb.conf.
2967 ***************************************************************************/
2969 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
)
2972 parmnum
= lpcfg_map_parameter(pszParmName
);
2974 parm_table
[parmnum
].flags
&= ~FLAG_CMDLINE
;
2975 if (!lp_do_parameter(-1, pszParmName
, pszParmValue
)) {
2978 parm_table
[parmnum
].flags
|= FLAG_CMDLINE
;
2980 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
2981 * be grouped in the table, so we don't have to search the
2984 i
>=0 && parm_table
[i
].offset
== parm_table
[parmnum
].offset
2985 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;
2987 parm_table
[i
].flags
|= FLAG_CMDLINE
;
2989 for (i
=parmnum
+1;i
<NUMPARAMETERS
&& parm_table
[i
].offset
== parm_table
[parmnum
].offset
2990 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;i
++) {
2991 parm_table
[i
].flags
|= FLAG_CMDLINE
;
2995 store_lp_set_cmdline(pszParmName
, pszParmValue
);
3000 /* it might be parametric */
3001 if (strchr(pszParmName
, ':') != NULL
) {
3002 set_param_opt(NULL
, &Globals
.param_opt
, pszParmName
, pszParmValue
, FLAG_CMDLINE
);
3004 store_lp_set_cmdline(pszParmName
, pszParmValue
);
3009 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName
));
3013 bool lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
3015 return lp_set_cmdline_helper(pszParmName
, pszParmValue
, true);
3018 /***************************************************************************
3019 Process a parameter.
3020 ***************************************************************************/
3022 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
3025 if (!bInGlobalSection
&& bGlobalOnly
)
3028 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName
, pszParmValue
));
3030 return (lp_do_parameter(bInGlobalSection
? -2 : iServiceIndex
,
3031 pszParmName
, pszParmValue
));
3035 set a option from the commandline in 'a=b' format. Use to support --option
3037 bool lp_set_option(const char *option
)
3042 s
= talloc_strdup(NULL
, option
);
3055 /* skip white spaces after the = sign */
3058 } while (*p
== ' ');
3060 ret
= lp_set_cmdline(s
, p
);
3065 /***************************************************************************
3066 Initialize any local variables in the sDefault table, after parsing a
3068 ***************************************************************************/
3070 static void init_locals(void)
3073 * We run this check once the [globals] is parsed, to force
3074 * the VFS objects and other per-share settings we need for
3075 * the standard way a AD DC is operated. We may change these
3076 * as our code evolves, which is why we force these settings.
3078 * We can't do this at the end of lp_load_ex(), as by that
3079 * point the services have been loaded and they will already
3080 * have "" as their vfs objects.
3082 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
3083 const char **vfs_objects
= lp_vfs_objects(-1);
3084 if (!vfs_objects
|| !vfs_objects
[0]) {
3085 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL
)) {
3086 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3087 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL
)) {
3088 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3090 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3094 lp_do_parameter(-1, "map hidden", "no");
3095 lp_do_parameter(-1, "map system", "no");
3096 lp_do_parameter(-1, "map readonly", "no");
3097 lp_do_parameter(-1, "map archive", "no");
3098 lp_do_parameter(-1, "store dos attributes", "yes");
3102 /***************************************************************************
3103 Process a new section (service). At this stage all sections are services.
3104 Later we'll have special sections that permit server parameters to be set.
3105 Returns true on success, false on failure.
3106 ***************************************************************************/
3108 static bool do_section(const char *pszSectionName
, void *userdata
)
3111 bool isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
3112 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
3115 /* if we were in a global section then do the local inits */
3116 if (bInGlobalSection
&& !isglobal
)
3119 /* if we've just struck a global section, note the fact. */
3120 bInGlobalSection
= isglobal
;
3122 /* check for multiple global sections */
3123 if (bInGlobalSection
) {
3124 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName
));
3128 if (!bInGlobalSection
&& bGlobalOnly
)
3131 /* if we have a current service, tidy it up before moving on */
3134 if (iServiceIndex
>= 0)
3135 bRetval
= service_ok(iServiceIndex
);
3137 /* if all is still well, move to the next record in the services array */
3139 /* We put this here to avoid an odd message order if messages are */
3140 /* issued by the post-processing of a previous section. */
3141 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName
));
3143 iServiceIndex
= add_a_service(&sDefault
, pszSectionName
);
3144 if (iServiceIndex
< 0) {
3145 DEBUG(0, ("Failed to add a new service\n"));
3148 /* Clean all parametric options for service */
3149 /* They will be added during parsing again */
3150 free_param_opts(&ServicePtrs
[iServiceIndex
]->param_opt
);
3157 /***************************************************************************
3158 Determine if a partcular base parameter is currentl set to the default value.
3159 ***************************************************************************/
3161 static bool is_default(int i
)
3163 switch (parm_table
[i
].type
) {
3166 return str_list_equal((const char * const *)parm_table
[i
].def
.lvalue
,
3167 *(const char ***)lp_parm_ptr(NULL
,
3171 return strequal(parm_table
[i
].def
.svalue
,
3172 *(char **)lp_parm_ptr(NULL
,
3176 return parm_table
[i
].def
.bvalue
==
3177 *(bool *)lp_parm_ptr(NULL
,
3180 return parm_table
[i
].def
.cvalue
==
3181 *(char *)lp_parm_ptr(NULL
,
3187 return parm_table
[i
].def
.ivalue
==
3188 *(int *)lp_parm_ptr(NULL
,
3196 /***************************************************************************
3197 Display the contents of the global structure.
3198 ***************************************************************************/
3200 static void dump_globals(FILE *f
)
3203 struct parmlist_entry
*data
;
3205 fprintf(f
, "[global]\n");
3207 for (i
= 0; parm_table
[i
].label
; i
++)
3208 if (parm_table
[i
].p_class
== P_GLOBAL
&&
3209 !(parm_table
[i
].flags
& FLAG_META
) &&
3210 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
))) {
3211 if (defaults_saved
&& is_default(i
))
3213 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
3214 lpcfg_print_parameter(&parm_table
[i
], lp_parm_ptr(NULL
,
3219 if (Globals
.param_opt
!= NULL
) {
3220 data
= Globals
.param_opt
;
3222 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
3229 /***************************************************************************
3230 Display the contents of a single services record.
3231 ***************************************************************************/
3233 static void dump_a_service(struct loadparm_service
*pService
, FILE * f
)
3236 struct parmlist_entry
*data
;
3238 if (pService
!= &sDefault
)
3239 fprintf(f
, "[%s]\n", pService
->szService
);
3241 for (i
= 0; parm_table
[i
].label
; i
++) {
3243 if (parm_table
[i
].p_class
== P_LOCAL
&&
3244 !(parm_table
[i
].flags
& FLAG_META
) &&
3245 (*parm_table
[i
].label
!= '-') &&
3246 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
)))
3248 if (pService
== &sDefault
) {
3249 if (defaults_saved
&& is_default(i
))
3252 if (lpcfg_equal_parameter(parm_table
[i
].type
,
3253 lp_parm_ptr(pService
, &parm_table
[i
]),
3254 lp_parm_ptr(NULL
, &parm_table
[i
])))
3258 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
3259 lpcfg_print_parameter(&parm_table
[i
],
3260 lp_parm_ptr(pService
, &parm_table
[i
]),
3266 if (pService
->param_opt
!= NULL
) {
3267 data
= pService
->param_opt
;
3269 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
3275 /***************************************************************************
3276 Display the contents of a parameter of a single services record.
3277 ***************************************************************************/
3279 bool dump_a_parameter(int snum
, char *parm_name
, FILE * f
, bool isGlobal
)
3281 bool result
= false;
3282 fstring local_parm_name
;
3284 const char *parm_opt_value
;
3286 struct loadparm_context
*lp_ctx
;
3288 /* check for parametrical option */
3289 fstrcpy( local_parm_name
, parm_name
);
3290 parm_opt
= strchr( local_parm_name
, ':');
3295 if (strlen(parm_opt
)) {
3296 parm_opt_value
= lp_parm_const_string( snum
,
3297 local_parm_name
, parm_opt
, NULL
);
3298 if (parm_opt_value
) {
3299 printf( "%s\n", parm_opt_value
);
3306 lp_ctx
= loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3307 if (lp_ctx
== NULL
) {
3312 result
= lpcfg_dump_a_parameter(lp_ctx
, NULL
, parm_name
, f
);
3314 result
= lpcfg_dump_a_parameter(lp_ctx
, ServicePtrs
[snum
], parm_name
, f
);
3316 TALLOC_FREE(lp_ctx
);
3320 /***************************************************************************
3321 Return info about the requested parameter (given as a string).
3322 Return NULL when the string is not a valid parameter name.
3323 ***************************************************************************/
3325 struct parm_struct
*lp_get_parameter(const char *param_name
)
3327 int num
= lpcfg_map_parameter(param_name
);
3333 return &parm_table
[num
];
3337 /***************************************************************************
3338 Display the contents of a single copy structure.
3339 ***************************************************************************/
3340 static void dump_copy_map(bool *pcopymap
)
3346 printf("\n\tNon-Copied parameters:\n");
3348 for (i
= 0; parm_table
[i
].label
; i
++)
3349 if (parm_table
[i
].p_class
== P_LOCAL
&&
3350 parm_table
[i
].ptr
&& !pcopymap
[i
] &&
3351 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
- 1].ptr
)))
3353 printf("\t\t%s\n", parm_table
[i
].label
);
3358 /***************************************************************************
3359 Return TRUE if the passed service number is within range.
3360 ***************************************************************************/
3362 bool lp_snum_ok(int iService
)
3364 return (LP_SNUM_OK(iService
) && ServicePtrs
[iService
]->bAvailable
);
3367 /***************************************************************************
3368 Auto-load some home services.
3369 ***************************************************************************/
3371 static void lp_add_auto_services(char *str
)
3381 s
= talloc_strdup(talloc_tos(), str
);
3383 smb_panic("talloc_strdup failed");
3387 homes
= lp_servicenumber(HOMES_NAME
);
3389 for (p
= strtok_r(s
, LIST_SEP
, &saveptr
); p
;
3390 p
= strtok_r(NULL
, LIST_SEP
, &saveptr
)) {
3393 if (lp_servicenumber(p
) >= 0)
3396 home
= get_user_home_dir(talloc_tos(), p
);
3398 if (home
&& home
[0] && homes
>= 0)
3399 lp_add_home(p
, homes
, p
, home
);
3406 /***************************************************************************
3407 Auto-load one printer.
3408 ***************************************************************************/
3410 void lp_add_one_printer(const char *name
, const char *comment
,
3411 const char *location
, void *pdata
)
3413 int printers
= lp_servicenumber(PRINTERS_NAME
);
3416 if (lp_servicenumber(name
) < 0) {
3417 lp_add_printer(name
, printers
);
3418 if ((i
= lp_servicenumber(name
)) >= 0) {
3419 string_set(ServicePtrs
[i
], &ServicePtrs
[i
]->comment
, comment
);
3420 ServicePtrs
[i
]->autoloaded
= true;
3425 /***************************************************************************
3426 Have we loaded a services file yet?
3427 ***************************************************************************/
3429 bool lp_loaded(void)
3434 /***************************************************************************
3435 Unload unused services.
3436 ***************************************************************************/
3438 void lp_killunused(struct smbd_server_connection
*sconn
,
3439 bool (*snumused
) (struct smbd_server_connection
*, int))
3442 for (i
= 0; i
< iNumServices
; i
++) {
3446 /* don't kill autoloaded or usershare services */
3447 if ( ServicePtrs
[i
]->autoloaded
||
3448 ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
3452 if (!snumused
|| !snumused(sconn
, i
)) {
3453 free_service_byindex(i
);
3459 * Kill all except autoloaded and usershare services - convenience wrapper
3461 void lp_kill_all_services(void)
3463 lp_killunused(NULL
, NULL
);
3466 /***************************************************************************
3468 ***************************************************************************/
3470 void lp_killservice(int iServiceIn
)
3472 if (VALID(iServiceIn
)) {
3473 free_service_byindex(iServiceIn
);
3477 /***************************************************************************
3478 Save the curent values of all global and sDefault parameters into the
3479 defaults union. This allows testparm to show only the
3480 changed (ie. non-default) parameters.
3481 ***************************************************************************/
3483 static void lp_save_defaults(void)
3486 for (i
= 0; parm_table
[i
].label
; i
++) {
3487 if (i
> 0 && parm_table
[i
].offset
== parm_table
[i
- 1].offset
3488 && parm_table
[i
].p_class
== parm_table
[i
- 1].p_class
)
3490 switch (parm_table
[i
].type
) {
3493 parm_table
[i
].def
.lvalue
= str_list_copy(
3494 NULL
, *(const char ***)lp_parm_ptr(NULL
, &parm_table
[i
]));
3498 parm_table
[i
].def
.svalue
= talloc_strdup(Globals
.ctx
, *(char **)lp_parm_ptr(NULL
, &parm_table
[i
]));
3499 if (parm_table
[i
].def
.svalue
== NULL
) {
3500 smb_panic("talloc_strdup failed");
3505 parm_table
[i
].def
.bvalue
=
3506 *(bool *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3509 parm_table
[i
].def
.cvalue
=
3510 *(char *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3516 parm_table
[i
].def
.ivalue
=
3517 *(int *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3523 defaults_saved
= true;
3526 /***********************************************************
3527 If we should send plaintext/LANMAN passwords in the clinet
3528 ************************************************************/
3530 static void set_allowed_client_auth(void)
3532 if (Globals
.client_ntlmv2_auth
) {
3533 Globals
.client_lanman_auth
= false;
3535 if (!Globals
.client_lanman_auth
) {
3536 Globals
.client_plaintext_auth
= false;
3540 /***************************************************************************
3542 The following code allows smbd to read a user defined share file.
3543 Yes, this is my intent. Yes, I'm comfortable with that...
3545 THE FOLLOWING IS SECURITY CRITICAL CODE.
3547 It washes your clothes, it cleans your house, it guards you while you sleep...
3548 Do not f%^k with it....
3549 ***************************************************************************/
3551 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3553 /***************************************************************************
3554 Check allowed stat state of a usershare file.
3555 Ensure we print out who is dicking with us so the admin can
3556 get their sorry ass fired.
3557 ***************************************************************************/
3559 static bool check_usershare_stat(const char *fname
,
3560 const SMB_STRUCT_STAT
*psbuf
)
3562 if (!S_ISREG(psbuf
->st_ex_mode
)) {
3563 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3564 "not a regular file\n",
3565 fname
, (unsigned int)psbuf
->st_ex_uid
));
3569 /* Ensure this doesn't have the other write bit set. */
3570 if (psbuf
->st_ex_mode
& S_IWOTH
) {
3571 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3572 "public write. Refusing to allow as a usershare file.\n",
3573 fname
, (unsigned int)psbuf
->st_ex_uid
));
3577 /* Should be 10k or less. */
3578 if (psbuf
->st_ex_size
> MAX_USERSHARE_FILE_SIZE
) {
3579 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3580 "too large (%u) to be a user share file.\n",
3581 fname
, (unsigned int)psbuf
->st_ex_uid
,
3582 (unsigned int)psbuf
->st_ex_size
));
3589 /***************************************************************************
3590 Parse the contents of a usershare file.
3591 ***************************************************************************/
3593 enum usershare_err
parse_usershare_file(TALLOC_CTX
*ctx
,
3594 SMB_STRUCT_STAT
*psbuf
,
3595 const char *servicename
,
3599 char **pp_sharepath
,
3601 char **pp_cp_servicename
,
3602 struct security_descriptor
**ppsd
,
3605 const char **prefixallowlist
= lp_usershare_prefix_allow_list();
3606 const char **prefixdenylist
= lp_usershare_prefix_deny_list();
3609 SMB_STRUCT_STAT sbuf
;
3610 char *sharepath
= NULL
;
3611 char *comment
= NULL
;
3613 *pp_sharepath
= NULL
;
3616 *pallow_guest
= false;
3619 return USERSHARE_MALFORMED_FILE
;
3622 if (strcmp(lines
[0], "#VERSION 1") == 0) {
3624 } else if (strcmp(lines
[0], "#VERSION 2") == 0) {
3627 return USERSHARE_MALFORMED_FILE
;
3630 return USERSHARE_BAD_VERSION
;
3633 if (strncmp(lines
[1], "path=", 5) != 0) {
3634 return USERSHARE_MALFORMED_PATH
;
3637 sharepath
= talloc_strdup(ctx
, &lines
[1][5]);
3639 return USERSHARE_POSIX_ERR
;
3641 trim_string(sharepath
, " ", " ");
3643 if (strncmp(lines
[2], "comment=", 8) != 0) {
3644 return USERSHARE_MALFORMED_COMMENT_DEF
;
3647 comment
= talloc_strdup(ctx
, &lines
[2][8]);
3649 return USERSHARE_POSIX_ERR
;
3651 trim_string(comment
, " ", " ");
3652 trim_char(comment
, '"', '"');
3654 if (strncmp(lines
[3], "usershare_acl=", 14) != 0) {
3655 return USERSHARE_MALFORMED_ACL_DEF
;
3658 if (!parse_usershare_acl(ctx
, &lines
[3][14], ppsd
)) {
3659 return USERSHARE_ACL_ERR
;
3663 if (strncmp(lines
[4], "guest_ok=", 9) != 0) {
3664 return USERSHARE_MALFORMED_ACL_DEF
;
3666 if (lines
[4][9] == 'y') {
3667 *pallow_guest
= true;
3670 /* Backwards compatible extension to file version #2. */
3672 if (strncmp(lines
[5], "sharename=", 10) != 0) {
3673 return USERSHARE_MALFORMED_SHARENAME_DEF
;
3675 if (!strequal(&lines
[5][10], servicename
)) {
3676 return USERSHARE_BAD_SHARENAME
;
3678 *pp_cp_servicename
= talloc_strdup(ctx
, &lines
[5][10]);
3679 if (!*pp_cp_servicename
) {
3680 return USERSHARE_POSIX_ERR
;
3685 if (*pp_cp_servicename
== NULL
) {
3686 *pp_cp_servicename
= talloc_strdup(ctx
, servicename
);
3687 if (!*pp_cp_servicename
) {
3688 return USERSHARE_POSIX_ERR
;
3692 if (snum
!= -1 && (strcmp(sharepath
, ServicePtrs
[snum
]->path
) == 0)) {
3693 /* Path didn't change, no checks needed. */
3694 *pp_sharepath
= sharepath
;
3695 *pp_comment
= comment
;
3696 return USERSHARE_OK
;
3699 /* The path *must* be absolute. */
3700 if (sharepath
[0] != '/') {
3701 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3702 servicename
, sharepath
));
3703 return USERSHARE_PATH_NOT_ABSOLUTE
;
3706 /* If there is a usershare prefix deny list ensure one of these paths
3707 doesn't match the start of the user given path. */
3708 if (prefixdenylist
) {
3710 for ( i
=0; prefixdenylist
[i
]; i
++ ) {
3711 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3712 servicename
, i
, prefixdenylist
[i
], sharepath
));
3713 if (memcmp( sharepath
, prefixdenylist
[i
], strlen(prefixdenylist
[i
])) == 0) {
3714 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3715 "usershare prefix deny list entries.\n",
3716 servicename
, sharepath
));
3717 return USERSHARE_PATH_IS_DENIED
;
3722 /* If there is a usershare prefix allow list ensure one of these paths
3723 does match the start of the user given path. */
3725 if (prefixallowlist
) {
3727 for ( i
=0; prefixallowlist
[i
]; i
++ ) {
3728 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3729 servicename
, i
, prefixallowlist
[i
], sharepath
));
3730 if (memcmp( sharepath
, prefixallowlist
[i
], strlen(prefixallowlist
[i
])) == 0) {
3734 if (prefixallowlist
[i
] == NULL
) {
3735 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3736 "usershare prefix allow list entries.\n",
3737 servicename
, sharepath
));
3738 return USERSHARE_PATH_NOT_ALLOWED
;
3742 /* Ensure this is pointing to a directory. */
3743 dp
= opendir(sharepath
);
3746 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3747 servicename
, sharepath
));
3748 return USERSHARE_PATH_NOT_DIRECTORY
;
3751 /* Ensure the owner of the usershare file has permission to share
3754 if (sys_stat(sharepath
, &sbuf
, false) == -1) {
3755 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
3756 servicename
, sharepath
, strerror(errno
) ));
3758 return USERSHARE_POSIX_ERR
;
3763 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
3764 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
3765 servicename
, sharepath
));
3766 return USERSHARE_PATH_NOT_DIRECTORY
;
3769 /* Check if sharing is restricted to owner-only. */
3770 /* psbuf is the stat of the usershare definition file,
3771 sbuf is the stat of the target directory to be shared. */
3773 if (lp_usershare_owner_only()) {
3774 /* root can share anything. */
3775 if ((psbuf
->st_ex_uid
!= 0) && (sbuf
.st_ex_uid
!= psbuf
->st_ex_uid
)) {
3776 return USERSHARE_PATH_NOT_ALLOWED
;
3780 *pp_sharepath
= sharepath
;
3781 *pp_comment
= comment
;
3782 return USERSHARE_OK
;
3785 /***************************************************************************
3786 Deal with a usershare file.
3789 -1 - Bad name, invalid contents.
3790 - service name already existed and not a usershare, problem
3791 with permissions to share directory etc.
3792 ***************************************************************************/
3794 static int process_usershare_file(const char *dir_name
, const char *file_name
, int snum_template
)
3796 SMB_STRUCT_STAT sbuf
;
3797 SMB_STRUCT_STAT lsbuf
;
3799 char *sharepath
= NULL
;
3800 char *comment
= NULL
;
3801 char *cp_service_name
= NULL
;
3802 char **lines
= NULL
;
3806 TALLOC_CTX
*ctx
= talloc_stackframe();
3807 struct security_descriptor
*psd
= NULL
;
3808 bool guest_ok
= false;
3809 char *canon_name
= NULL
;
3810 bool added_service
= false;
3813 /* Ensure share name doesn't contain invalid characters. */
3814 if (!validate_net_name(file_name
, INVALID_SHARENAME_CHARS
, strlen(file_name
))) {
3815 DEBUG(0,("process_usershare_file: share name %s contains "
3816 "invalid characters (any of %s)\n",
3817 file_name
, INVALID_SHARENAME_CHARS
));
3821 canon_name
= canonicalize_servicename(ctx
, file_name
);
3826 fname
= talloc_asprintf(ctx
, "%s/%s", dir_name
, file_name
);
3831 /* Minimize the race condition by doing an lstat before we
3832 open and fstat. Ensure this isn't a symlink link. */
3834 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
3835 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
3836 fname
, strerror(errno
) ));
3840 /* This must be a regular file, not a symlink, directory or
3841 other strange filetype. */
3842 if (!check_usershare_stat(fname
, &lsbuf
)) {
3850 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
,
3855 if (NT_STATUS_IS_OK(status
) &&
3856 (data
.dptr
!= NULL
) &&
3857 (data
.dsize
== sizeof(iService
))) {
3858 memcpy(&iService
, data
.dptr
, sizeof(iService
));
3862 if (iService
!= -1 &&
3863 timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
3864 &lsbuf
.st_ex_mtime
) == 0) {
3865 /* Nothing changed - Mark valid and return. */
3866 DEBUG(10,("process_usershare_file: service %s not changed.\n",
3868 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
3873 /* Try and open the file read only - no symlinks allowed. */
3875 fd
= open(fname
, O_RDONLY
|O_NOFOLLOW
, 0);
3877 fd
= open(fname
, O_RDONLY
, 0);
3881 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
3882 fname
, strerror(errno
) ));
3886 /* Now fstat to be *SURE* it's a regular file. */
3887 if (sys_fstat(fd
, &sbuf
, false) != 0) {
3889 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
3890 fname
, strerror(errno
) ));
3894 /* Is it the same dev/inode as was lstated ? */
3895 if (!check_same_stat(&lsbuf
, &sbuf
)) {
3897 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
3898 "Symlink spoofing going on ?\n", fname
));
3902 /* This must be a regular file, not a symlink, directory or
3903 other strange filetype. */
3904 if (!check_usershare_stat(fname
, &sbuf
)) {
3909 lines
= fd_lines_load(fd
, &numlines
, MAX_USERSHARE_FILE_SIZE
, NULL
);
3912 if (lines
== NULL
) {
3913 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
3914 fname
, (unsigned int)sbuf
.st_ex_uid
));
3918 if (parse_usershare_file(ctx
, &sbuf
, file_name
,
3919 iService
, lines
, numlines
, &sharepath
,
3920 &comment
, &cp_service_name
,
3921 &psd
, &guest_ok
) != USERSHARE_OK
) {
3925 /* Everything ok - add the service possibly using a template. */
3927 const struct loadparm_service
*sp
= &sDefault
;
3928 if (snum_template
!= -1) {
3929 sp
= ServicePtrs
[snum_template
];
3932 if ((iService
= add_a_service(sp
, cp_service_name
)) < 0) {
3933 DEBUG(0, ("process_usershare_file: Failed to add "
3934 "new service %s\n", cp_service_name
));
3938 added_service
= true;
3940 /* Read only is controlled by usershare ACL below. */
3941 ServicePtrs
[iService
]->read_only
= false;
3944 /* Write the ACL of the new/modified share. */
3945 if (!set_share_security(canon_name
, psd
)) {
3946 DEBUG(0, ("process_usershare_file: Failed to set share "
3947 "security for user share %s\n",
3952 /* If from a template it may be marked invalid. */
3953 ServicePtrs
[iService
]->valid
= true;
3955 /* Set the service as a valid usershare. */
3956 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
3958 /* Set guest access. */
3959 if (lp_usershare_allow_guests()) {
3960 ServicePtrs
[iService
]->guest_ok
= guest_ok
;
3963 /* And note when it was loaded. */
3964 ServicePtrs
[iService
]->usershare_last_mod
= sbuf
.st_ex_mtime
;
3965 string_set(ServicePtrs
[iService
], &ServicePtrs
[iService
]->path
, sharepath
);
3966 string_set(ServicePtrs
[iService
], &ServicePtrs
[iService
]->comment
, comment
);
3972 if (ret
== -1 && iService
!= -1 && added_service
) {
3973 lp_remove_service(iService
);
3981 /***************************************************************************
3982 Checks if a usershare entry has been modified since last load.
3983 ***************************************************************************/
3985 static bool usershare_exists(int iService
, struct timespec
*last_mod
)
3987 SMB_STRUCT_STAT lsbuf
;
3988 const char *usersharepath
= Globals
.usershare_path
;
3991 fname
= talloc_asprintf(talloc_tos(),
3994 ServicePtrs
[iService
]->szService
);
3995 if (fname
== NULL
) {
3999 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
4004 if (!S_ISREG(lsbuf
.st_ex_mode
)) {
4010 *last_mod
= lsbuf
.st_ex_mtime
;
4014 /***************************************************************************
4015 Load a usershare service by name. Returns a valid servicenumber or -1.
4016 ***************************************************************************/
4018 int load_usershare_service(const char *servicename
)
4020 SMB_STRUCT_STAT sbuf
;
4021 const char *usersharepath
= Globals
.usershare_path
;
4022 int max_user_shares
= Globals
.usershare_max_shares
;
4023 int snum_template
= -1;
4025 if (*usersharepath
== 0 || max_user_shares
== 0) {
4029 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
4030 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4031 usersharepath
, strerror(errno
) ));
4035 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
4036 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4042 * This directory must be owned by root, and have the 't' bit set.
4043 * It also must not be writable by "other".
4047 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4049 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4051 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4052 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4057 /* Ensure the template share exists if it's set. */
4058 if (Globals
.usershare_template_share
[0]) {
4059 /* We can't use lp_servicenumber here as we are recommending that
4060 template shares have -valid=false set. */
4061 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
4062 if (ServicePtrs
[snum_template
]->szService
&&
4063 strequal(ServicePtrs
[snum_template
]->szService
,
4064 Globals
.usershare_template_share
)) {
4069 if (snum_template
== -1) {
4070 DEBUG(0,("load_usershare_service: usershare template share %s "
4071 "does not exist.\n",
4072 Globals
.usershare_template_share
));
4077 return process_usershare_file(usersharepath
, servicename
, snum_template
);
4080 /***************************************************************************
4081 Load all user defined shares from the user share directory.
4082 We only do this if we're enumerating the share list.
4083 This is the function that can delete usershares that have
4085 ***************************************************************************/
4087 int load_usershare_shares(struct smbd_server_connection
*sconn
,
4088 bool (*snumused
) (struct smbd_server_connection
*, int))
4091 SMB_STRUCT_STAT sbuf
;
4093 int num_usershares
= 0;
4094 int max_user_shares
= Globals
.usershare_max_shares
;
4095 unsigned int num_dir_entries
, num_bad_dir_entries
, num_tmp_dir_entries
;
4096 unsigned int allowed_bad_entries
= ((2*max_user_shares
)/10);
4097 unsigned int allowed_tmp_entries
= ((2*max_user_shares
)/10);
4099 int snum_template
= -1;
4100 const char *usersharepath
= Globals
.usershare_path
;
4101 int ret
= lp_numservices();
4102 TALLOC_CTX
*tmp_ctx
;
4104 if (max_user_shares
== 0 || *usersharepath
== '\0') {
4105 return lp_numservices();
4108 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
4109 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4110 usersharepath
, strerror(errno
) ));
4115 * This directory must be owned by root, and have the 't' bit set.
4116 * It also must not be writable by "other".
4120 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4122 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4124 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4125 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4130 /* Ensure the template share exists if it's set. */
4131 if (Globals
.usershare_template_share
[0]) {
4132 /* We can't use lp_servicenumber here as we are recommending that
4133 template shares have -valid=false set. */
4134 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
4135 if (ServicePtrs
[snum_template
]->szService
&&
4136 strequal(ServicePtrs
[snum_template
]->szService
,
4137 Globals
.usershare_template_share
)) {
4142 if (snum_template
== -1) {
4143 DEBUG(0,("load_usershare_shares: usershare template share %s "
4144 "does not exist.\n",
4145 Globals
.usershare_template_share
));
4150 /* Mark all existing usershares as pending delete. */
4151 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4152 if (VALID(iService
) && ServicePtrs
[iService
]->usershare
) {
4153 ServicePtrs
[iService
]->usershare
= USERSHARE_PENDING_DELETE
;
4157 dp
= opendir(usersharepath
);
4159 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4160 usersharepath
, strerror(errno
) ));
4164 for (num_dir_entries
= 0, num_bad_dir_entries
= 0, num_tmp_dir_entries
= 0;
4166 num_dir_entries
++ ) {
4168 const char *n
= de
->d_name
;
4170 /* Ignore . and .. */
4172 if ((n
[1] == '\0') || (n
[1] == '.' && n
[2] == '\0')) {
4178 /* Temporary file used when creating a share. */
4179 num_tmp_dir_entries
++;
4182 /* Allow 20% tmp entries. */
4183 if (num_tmp_dir_entries
> allowed_tmp_entries
) {
4184 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4185 "in directory %s\n",
4186 num_tmp_dir_entries
, usersharepath
));
4190 r
= process_usershare_file(usersharepath
, n
, snum_template
);
4192 /* Update the services count. */
4194 if (num_usershares
>= max_user_shares
) {
4195 DEBUG(0,("load_usershare_shares: max user shares reached "
4196 "on file %s in directory %s\n",
4197 n
, usersharepath
));
4200 } else if (r
== -1) {
4201 num_bad_dir_entries
++;
4204 /* Allow 20% bad entries. */
4205 if (num_bad_dir_entries
> allowed_bad_entries
) {
4206 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4207 "in directory %s\n",
4208 num_bad_dir_entries
, usersharepath
));
4212 /* Allow 20% bad entries. */
4213 if (num_dir_entries
> max_user_shares
+ allowed_bad_entries
) {
4214 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4215 "in directory %s\n",
4216 num_dir_entries
, usersharepath
));
4223 /* Sweep through and delete any non-refreshed usershares that are
4224 not currently in use. */
4225 tmp_ctx
= talloc_stackframe();
4226 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4227 if (VALID(iService
) && (ServicePtrs
[iService
]->usershare
== USERSHARE_PENDING_DELETE
)) {
4230 if (snumused
&& snumused(sconn
, iService
)) {
4234 servname
= lp_servicename(tmp_ctx
, iService
);
4236 /* Remove from the share ACL db. */
4237 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4239 delete_share_security(servname
);
4240 free_service_byindex(iService
);
4243 talloc_free(tmp_ctx
);
4245 return lp_numservices();
4248 /********************************************************
4249 Destroy global resources allocated in this file
4250 ********************************************************/
4252 void gfree_loadparm(void)
4258 /* Free resources allocated to services */
4260 for ( i
= 0; i
< iNumServices
; i
++ ) {
4262 free_service_byindex(i
);
4266 TALLOC_FREE( ServicePtrs
);
4269 /* Now release all resources allocated to global
4270 parameters and the default service */
4272 free_global_parameters();
4276 /***************************************************************************
4277 Allow client apps to specify that they are a client
4278 ***************************************************************************/
4279 static void lp_set_in_client(bool b
)
4285 /***************************************************************************
4286 Determine if we're running in a client app
4287 ***************************************************************************/
4288 static bool lp_is_in_client(void)
4293 /***************************************************************************
4294 Load the services array from the services file. Return true on success,
4296 ***************************************************************************/
4298 static bool lp_load_ex(const char *pszFname
,
4302 bool initialize_globals
,
4303 bool allow_include_registry
,
4304 bool load_all_shares
)
4311 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4313 bInGlobalSection
= true;
4314 bGlobalOnly
= global_only
;
4315 bAllowIncludeRegistry
= allow_include_registry
;
4317 init_globals(initialize_globals
);
4321 if (save_defaults
) {
4326 if (!initialize_globals
) {
4327 free_param_opts(&Globals
.param_opt
);
4328 apply_lp_set_cmdline();
4331 lp_do_parameter(-1, "idmap config * : backend", Globals
.szIdmapBackend
);
4333 /* We get sections first, so have to start 'behind' to make up */
4336 if (lp_config_backend_is_file()) {
4337 n2
= talloc_sub_basic(talloc_tos(), get_current_username(),
4338 current_user_info
.domain
,
4341 smb_panic("lp_load_ex: out of memory");
4344 add_to_file_list(NULL
, &file_lists
, pszFname
, n2
);
4346 bRetval
= pm_process(n2
, do_section
, do_parameter
, NULL
);
4349 /* finish up the last section */
4350 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval
)));
4352 if (iServiceIndex
>= 0) {
4353 bRetval
= service_ok(iServiceIndex
);
4357 if (lp_config_backend_is_registry()) {
4358 /* config backend changed to registry in config file */
4360 * We need to use this extra global variable here to
4361 * survive restart: init_globals uses this as a default
4362 * for config_backend. Otherwise, init_globals would
4363 * send us into an endless loop here.
4365 config_backend
= CONFIG_BACKEND_REGISTRY
;
4367 DEBUG(1, ("lp_load_ex: changing to config backend "
4370 lp_kill_all_services();
4371 return lp_load_ex(pszFname
, global_only
, save_defaults
,
4372 add_ipc
, initialize_globals
,
4373 allow_include_registry
,
4376 } else if (lp_config_backend_is_registry()) {
4377 bRetval
= process_registry_globals();
4379 DEBUG(0, ("Illegal config backend given: %d\n",
4380 lp_config_backend()));
4384 if (bRetval
&& lp_registry_shares()) {
4385 if (load_all_shares
) {
4386 bRetval
= process_registry_shares();
4388 bRetval
= reload_registry_shares();
4393 char *serv
= lp_auto_services(talloc_tos());
4394 lp_add_auto_services(serv
);
4399 /* When 'restrict anonymous = 2' guest connections to ipc$
4401 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4402 if ( lp_enable_asu_support() ) {
4403 lp_add_ipc("ADMIN$", false);
4407 set_allowed_client_auth();
4409 if (lp_security() == SEC_ADS
&& strchr(lp_password_server(), ':')) {
4410 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4411 lp_password_server()));
4416 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4417 /* if we_are_a_wins_server is true and we are in the client */
4418 if (lp_is_in_client() && Globals
.we_are_a_wins_server
) {
4419 lp_do_parameter(GLOBAL_SECTION_SNUM
, "wins server", "127.0.0.1");
4424 fault_configure(smb_panic_s3
);
4427 * We run this check once the whole smb.conf is parsed, to
4428 * force some settings for the standard way a AD DC is
4429 * operated. We may changed these as our code evolves, which
4430 * is why we force these settings.
4432 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
4433 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4435 lp_do_parameter(-1, "rpc_server:default", "external");
4436 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4437 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4438 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4439 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4440 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4441 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4442 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4443 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4446 bAllowIncludeRegistry
= true;
4451 bool lp_load(const char *pszFname
,
4455 bool initialize_globals
)
4457 return lp_load_ex(pszFname
,
4462 true, /* allow_include_registry */
4463 false); /* load_all_shares*/
4466 bool lp_load_initial_only(const char *pszFname
)
4468 return lp_load_ex(pszFname
,
4469 true, /* global only */
4470 false, /* save_defaults */
4471 false, /* add_ipc */
4472 true, /* initialize_globals */
4473 false, /* allow_include_registry */
4474 false); /* load_all_shares*/
4478 * most common lp_load wrapper, loading only the globals
4480 bool lp_load_global(const char *file_name
)
4482 return lp_load_ex(file_name
,
4483 true, /* global_only */
4484 false, /* save_defaults */
4485 false, /* add_ipc */
4486 true, /* initialize_globals */
4487 true, /* allow_include_registry */
4488 false); /* load_all_shares*/
4492 * lp_load wrapper, especially for clients
4494 bool lp_load_client(const char *file_name
)
4496 lp_set_in_client(true);
4498 return lp_load_global(file_name
);
4502 * lp_load wrapper, loading only globals, but intended
4503 * for subsequent calls, not reinitializing the globals
4506 bool lp_load_global_no_reinit(const char *file_name
)
4508 return lp_load_ex(file_name
,
4509 true, /* global_only */
4510 false, /* save_defaults */
4511 false, /* add_ipc */
4512 false, /* initialize_globals */
4513 true, /* allow_include_registry */
4514 false); /* load_all_shares*/
4518 * lp_load wrapper, especially for clients, no reinitialization
4520 bool lp_load_client_no_reinit(const char *file_name
)
4522 lp_set_in_client(true);
4524 return lp_load_global_no_reinit(file_name
);
4527 bool lp_load_with_registry_shares(const char *pszFname
,
4531 bool initialize_globals
)
4533 return lp_load_ex(pszFname
,
4538 true, /* allow_include_registry */
4539 true); /* load_all_shares*/
4542 /***************************************************************************
4543 Return the max number of services.
4544 ***************************************************************************/
4546 int lp_numservices(void)
4548 return (iNumServices
);
4551 /***************************************************************************
4552 Display the contents of the services array in human-readable form.
4553 ***************************************************************************/
4555 void lp_dump(FILE *f
, bool show_defaults
, int maxtoprint
)
4560 defaults_saved
= false;
4564 dump_a_service(&sDefault
, f
);
4566 for (iService
= 0; iService
< maxtoprint
; iService
++) {
4568 lp_dump_one(f
, show_defaults
, iService
);
4572 /***************************************************************************
4573 Display the contents of one service in human-readable form.
4574 ***************************************************************************/
4576 void lp_dump_one(FILE * f
, bool show_defaults
, int snum
)
4579 if (ServicePtrs
[snum
]->szService
[0] == '\0')
4581 dump_a_service(ServicePtrs
[snum
], f
);
4585 /***************************************************************************
4586 Return the number of the service with the given name, or -1 if it doesn't
4587 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4588 getservicebyname()! This works ONLY if all services have been loaded, and
4589 does not copy the found service.
4590 ***************************************************************************/
4592 int lp_servicenumber(const char *pszServiceName
)
4595 fstring serviceName
;
4597 if (!pszServiceName
) {
4598 return GLOBAL_SECTION_SNUM
;
4601 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4602 if (VALID(iService
) && ServicePtrs
[iService
]->szService
) {
4604 * The substitution here is used to support %U is
4607 fstrcpy(serviceName
, ServicePtrs
[iService
]->szService
);
4608 standard_sub_basic(get_current_username(),
4609 current_user_info
.domain
,
4610 serviceName
,sizeof(serviceName
));
4611 if (strequal(serviceName
, pszServiceName
)) {
4617 if (iService
>= 0 && ServicePtrs
[iService
]->usershare
== USERSHARE_VALID
) {
4618 struct timespec last_mod
;
4620 if (!usershare_exists(iService
, &last_mod
)) {
4621 /* Remove the share security tdb entry for it. */
4622 delete_share_security(lp_servicename(talloc_tos(), iService
));
4623 /* Remove it from the array. */
4624 free_service_byindex(iService
);
4625 /* Doesn't exist anymore. */
4626 return GLOBAL_SECTION_SNUM
;
4629 /* Has it been modified ? If so delete and reload. */
4630 if (timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
4632 /* Remove it from the array. */
4633 free_service_byindex(iService
);
4634 /* and now reload it. */
4635 iService
= load_usershare_service(pszServiceName
);
4640 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName
));
4641 return GLOBAL_SECTION_SNUM
;
4647 /*******************************************************************
4648 A useful volume label function.
4649 ********************************************************************/
4651 const char *volume_label(TALLOC_CTX
*ctx
, int snum
)
4654 const char *label
= lp_volume(ctx
, snum
);
4656 label
= lp_servicename(ctx
, snum
);
4659 /* This returns a 33 byte guarenteed null terminated string. */
4660 ret
= talloc_strndup(ctx
, label
, 32);
4667 /*******************************************************************
4668 Get the default server type we will announce as via nmbd.
4669 ********************************************************************/
4671 int lp_default_server_announce(void)
4673 int default_server_announce
= 0;
4674 default_server_announce
|= SV_TYPE_WORKSTATION
;
4675 default_server_announce
|= SV_TYPE_SERVER
;
4676 default_server_announce
|= SV_TYPE_SERVER_UNIX
;
4678 /* note that the flag should be set only if we have a
4679 printer service but nmbd doesn't actually load the
4680 services so we can't tell --jerry */
4682 default_server_announce
|= SV_TYPE_PRINTQ_SERVER
;
4684 default_server_announce
|= SV_TYPE_SERVER_NT
;
4685 default_server_announce
|= SV_TYPE_NT
;
4687 switch (lp_server_role()) {
4688 case ROLE_DOMAIN_MEMBER
:
4689 default_server_announce
|= SV_TYPE_DOMAIN_MEMBER
;
4691 case ROLE_DOMAIN_PDC
:
4692 default_server_announce
|= SV_TYPE_DOMAIN_CTRL
;
4694 case ROLE_DOMAIN_BDC
:
4695 default_server_announce
|= SV_TYPE_DOMAIN_BAKCTRL
;
4697 case ROLE_STANDALONE
:
4701 if (lp_time_server())
4702 default_server_announce
|= SV_TYPE_TIME_SOURCE
;
4704 if (lp_host_msdfs())
4705 default_server_announce
|= SV_TYPE_DFS_SERVER
;
4707 return default_server_announce
;
4710 /***********************************************************
4711 If we are PDC then prefer us as DMB
4712 ************************************************************/
4714 bool lp_domain_master(void)
4716 if (Globals
._domain_master
== Auto
)
4717 return (lp_server_role() == ROLE_DOMAIN_PDC
);
4719 return (bool)Globals
._domain_master
;
4722 /***********************************************************
4723 If we are PDC then prefer us as DMB
4724 ************************************************************/
4726 static bool lp_domain_master_true_or_auto(void)
4728 if (Globals
._domain_master
) /* auto or yes */
4734 /***********************************************************
4735 If we are DMB then prefer us as LMB
4736 ************************************************************/
4738 bool lp_preferred_master(void)
4740 if (Globals
.iPreferredMaster
== Auto
)
4741 return (lp_local_master() && lp_domain_master());
4743 return (bool)Globals
.iPreferredMaster
;
4746 /*******************************************************************
4748 ********************************************************************/
4750 void lp_remove_service(int snum
)
4752 ServicePtrs
[snum
]->valid
= false;
4755 const char *lp_printername(TALLOC_CTX
*ctx
, int snum
)
4757 const char *ret
= lp__printername(ctx
, snum
);
4758 if (ret
== NULL
|| *ret
== '\0') {
4759 ret
= lp_const_servicename(snum
);
4766 /***********************************************************
4767 Allow daemons such as winbindd to fix their logfile name.
4768 ************************************************************/
4770 void lp_set_logfile(const char *name
)
4772 string_set(Globals
.ctx
, &Globals
.logfile
, name
);
4773 debug_set_logfile(name
);
4776 /*******************************************************************
4777 Return the max print jobs per queue.
4778 ********************************************************************/
4780 int lp_maxprintjobs(int snum
)
4782 int maxjobs
= LP_SNUM_OK(snum
) ? ServicePtrs
[snum
]->iMaxPrintJobs
: sDefault
.iMaxPrintJobs
;
4783 if (maxjobs
<= 0 || maxjobs
>= PRINT_MAX_JOBID
)
4784 maxjobs
= PRINT_MAX_JOBID
- 1;
4789 const char *lp_printcapname(void)
4791 if ((Globals
.szPrintcapname
!= NULL
) &&
4792 (Globals
.szPrintcapname
[0] != '\0'))
4793 return Globals
.szPrintcapname
;
4795 if (sDefault
.printing
== PRINT_CUPS
) {
4799 if (sDefault
.printing
== PRINT_BSD
)
4800 return "/etc/printcap";
4802 return PRINTCAP_NAME
;
4805 static uint32 spoolss_state
;
4807 bool lp_disable_spoolss( void )
4809 if ( spoolss_state
== SVCCTL_STATE_UNKNOWN
)
4810 spoolss_state
= lp__disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
4812 return spoolss_state
== SVCCTL_STOPPED
? true : false;
4815 void lp_set_spoolss_state( uint32 state
)
4817 SMB_ASSERT( (state
== SVCCTL_STOPPED
) || (state
== SVCCTL_RUNNING
) );
4819 spoolss_state
= state
;
4822 uint32
lp_get_spoolss_state( void )
4824 return lp_disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
4827 /*******************************************************************
4828 Ensure we don't use sendfile if server smb signing is active.
4829 ********************************************************************/
4831 bool lp_use_sendfile(int snum
, struct smb_signing_state
*signing_state
)
4833 bool sign_active
= false;
4835 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
4836 if (get_Protocol() < PROTOCOL_NT1
) {
4839 if (signing_state
) {
4840 sign_active
= smb_signing_is_active(signing_state
);
4842 return (lp__use_sendfile(snum
) &&
4843 (get_remote_arch() != RA_WIN95
) &&
4847 /*******************************************************************
4848 Turn off sendfile if we find the underlying OS doesn't support it.
4849 ********************************************************************/
4851 void set_use_sendfile(int snum
, bool val
)
4853 if (LP_SNUM_OK(snum
))
4854 ServicePtrs
[snum
]->_use_sendfile
= val
;
4856 sDefault
._use_sendfile
= val
;
4859 /*******************************************************************
4860 Turn off storing DOS attributes if this share doesn't support it.
4861 ********************************************************************/
4863 void set_store_dos_attributes(int snum
, bool val
)
4865 if (!LP_SNUM_OK(snum
))
4867 ServicePtrs
[(snum
)]->store_dos_attributes
= val
;
4870 void lp_set_mangling_method(const char *new_method
)
4872 string_set(Globals
.ctx
, &Globals
.mangling_method
, new_method
);
4875 /*******************************************************************
4876 Global state for POSIX pathname processing.
4877 ********************************************************************/
4879 static bool posix_pathnames
;
4881 bool lp_posix_pathnames(void)
4883 return posix_pathnames
;
4886 /*******************************************************************
4887 Change everything needed to ensure POSIX pathname processing (currently
4889 ********************************************************************/
4891 void lp_set_posix_pathnames(void)
4893 posix_pathnames
= true;
4896 /*******************************************************************
4897 Global state for POSIX lock processing - CIFS unix extensions.
4898 ********************************************************************/
4900 bool posix_default_lock_was_set
;
4901 static enum brl_flavour posix_cifsx_locktype
; /* By default 0 == WINDOWS_LOCK */
4903 enum brl_flavour
lp_posix_cifsu_locktype(files_struct
*fsp
)
4905 if (posix_default_lock_was_set
) {
4906 return posix_cifsx_locktype
;
4908 return fsp
->posix_open
? POSIX_LOCK
: WINDOWS_LOCK
;
4912 /*******************************************************************
4913 ********************************************************************/
4915 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val
)
4917 posix_default_lock_was_set
= true;
4918 posix_cifsx_locktype
= val
;
4921 int lp_min_receive_file_size(void)
4923 if (Globals
.iminreceivefile
< 0) {
4926 return Globals
.iminreceivefile
;
4929 /*******************************************************************
4930 Safe wide links checks.
4931 This helper function always verify the validity of wide links,
4932 even after a configuration file reload.
4933 ********************************************************************/
4935 static bool lp_widelinks_internal(int snum
)
4937 return (bool)(LP_SNUM_OK(snum
)? ServicePtrs
[(snum
)]->bWidelinks
:
4938 sDefault
.bWidelinks
);
4941 void widelinks_warning(int snum
)
4943 if (lp_allow_insecure_wide_links()) {
4947 if (lp_unix_extensions() && lp_widelinks_internal(snum
)) {
4948 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
4949 "These parameters are incompatible. "
4950 "Wide links will be disabled for this share.\n",
4951 lp_servicename(talloc_tos(), snum
) ));
4955 bool lp_widelinks(int snum
)
4957 /* wide links is always incompatible with unix extensions */
4958 if (lp_unix_extensions()) {
4960 * Unless we have "allow insecure widelinks"
4963 if (!lp_allow_insecure_wide_links()) {
4968 return lp_widelinks_internal(snum
);
4971 int lp_server_role(void)
4973 return lp_find_server_role(lp__server_role(),
4975 lp__domain_logons(),
4976 lp_domain_master_true_or_auto());
4979 int lp_security(void)
4981 return lp_find_security(lp__server_role(),
4985 struct loadparm_global
* get_globals(void)