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;
260 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
262 /* prototypes for the special type handlers */
263 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
264 static bool handle_copy(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_debug_list(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
269 static bool handle_realm(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
270 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
271 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
272 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
273 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
274 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
276 /* these are parameter handlers which are not needed in the
280 #define handle_logfile NULL
282 static void set_allowed_client_auth(void);
284 static void add_to_file_list(const char *fname
, const char *subfname
);
285 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
);
286 static void free_param_opts(struct parmlist_entry
**popts
);
288 #include "lib/param/param_table.c"
290 /* this is used to prevent lots of mallocs of size 1 */
291 static const char null_string
[] = "";
294 Set a string value, allocing the space for the string
297 static bool string_init(char **dest
,const char *src
)
307 *dest
= discard_const_p(char, null_string
);
309 (*dest
) = SMB_STRDUP(src
);
310 if ((*dest
) == NULL
) {
311 DEBUG(0,("Out of memory in string_init\n"));
322 static void string_free(char **s
)
326 if (*s
== null_string
)
332 Set a string value, deallocating any existing space, and allocing the space
336 static bool string_set(char **dest
,const char *src
)
339 return(string_init(dest
,src
));
342 /***************************************************************************
343 Initialise the sDefault parameter structure for the printer values.
344 ***************************************************************************/
346 static void init_printer_values(struct loadparm_service
*pService
)
348 /* choose defaults depending on the type of printing */
349 switch (pService
->printing
) {
354 string_set(&pService
->lpq_command
, "lpq -P'%p'");
355 string_set(&pService
->lprm_command
, "lprm -P'%p' %j");
356 string_set(&pService
->print_command
, "lpr -r -P'%p' %s");
361 string_set(&pService
->lpq_command
, "lpq -P'%p'");
362 string_set(&pService
->lprm_command
, "lprm -P'%p' %j");
363 string_set(&pService
->print_command
, "lpr -r -P'%p' %s");
364 string_set(&pService
->queuepause_command
, "lpc stop '%p'");
365 string_set(&pService
->queueresume_command
, "lpc start '%p'");
366 string_set(&pService
->lppause_command
, "lpc hold '%p' %j");
367 string_set(&pService
->lpresume_command
, "lpc release '%p' %j");
372 /* set the lpq command to contain the destination printer
373 name only. This is used by cups_queue_get() */
374 string_set(&pService
->lpq_command
, "%p");
375 string_set(&pService
->lprm_command
, "");
376 string_set(&pService
->print_command
, "");
377 string_set(&pService
->lppause_command
, "");
378 string_set(&pService
->lpresume_command
, "");
379 string_set(&pService
->queuepause_command
, "");
380 string_set(&pService
->queueresume_command
, "");
385 string_set(&pService
->lpq_command
, "lpstat -o%p");
386 string_set(&pService
->lprm_command
, "cancel %p-%j");
387 string_set(&pService
->print_command
, "lp -c -d%p %s; rm %s");
388 string_set(&pService
->queuepause_command
, "disable %p");
389 string_set(&pService
->queueresume_command
, "enable %p");
391 string_set(&pService
->lppause_command
, "lp -i %p-%j -H hold");
392 string_set(&pService
->lpresume_command
, "lp -i %p-%j -H resume");
397 string_set(&pService
->lpq_command
, "lpq -P%p");
398 string_set(&pService
->lprm_command
, "lprm -P%p %j");
399 string_set(&pService
->print_command
, "lp -r -P%p %s");
402 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
407 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
410 tdbfile
= talloc_asprintf(
411 tmp_ctx
, "tdbfile=%s",
412 lp_parm_const_string(-1, "vlp", "tdbfile",
414 if (tdbfile
== NULL
) {
415 tdbfile
="tdbfile=/tmp/vlp.tdb";
418 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s print %%p %%s",
420 string_set(&pService
->print_command
,
421 tmp
? tmp
: "vlp print %p %s");
423 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpq %%p",
425 string_set(&pService
->lpq_command
,
426 tmp
? tmp
: "vlp lpq %p");
428 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lprm %%p %%j",
430 string_set(&pService
->lprm_command
,
431 tmp
? tmp
: "vlp lprm %p %j");
433 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lppause %%p %%j",
435 string_set(&pService
->lppause_command
,
436 tmp
? tmp
: "vlp lppause %p %j");
438 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpresume %%p %%j",
440 string_set(&pService
->lpresume_command
,
441 tmp
? tmp
: "vlp lpresume %p %j");
443 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queuepause %%p",
445 string_set(&pService
->queuepause_command
,
446 tmp
? tmp
: "vlp queuepause %p");
448 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queueresume %%p",
450 string_set(&pService
->queueresume_command
,
451 tmp
? tmp
: "vlp queueresume %p");
452 TALLOC_FREE(tmp_ctx
);
456 #endif /* DEVELOPER */
461 * Function to return the default value for the maximum number of open
462 * file descriptors permitted. This function tries to consult the
463 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
464 * the smaller of those.
466 static int max_open_files(void)
468 int sysctl_max
= MAX_OPEN_FILES
;
469 int rlimit_max
= MAX_OPEN_FILES
;
471 #ifdef HAVE_SYSCTLBYNAME
473 size_t size
= sizeof(sysctl_max
);
474 sysctlbyname("kern.maxfilesperproc", &sysctl_max
, &size
, NULL
,
479 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
485 if (getrlimit(RLIMIT_NOFILE
, &rl
) == 0)
486 rlimit_max
= rl
.rlim_cur
;
488 #if defined(RLIM_INFINITY)
489 if(rl
.rlim_cur
== RLIM_INFINITY
)
490 rlimit_max
= MAX_OPEN_FILES
;
495 if (sysctl_max
< MIN_OPEN_FILES_WINDOWS
) {
496 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
497 "minimum Windows limit (%d)\n",
499 MIN_OPEN_FILES_WINDOWS
));
500 sysctl_max
= MIN_OPEN_FILES_WINDOWS
;
503 if (rlimit_max
< MIN_OPEN_FILES_WINDOWS
) {
504 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
505 "minimum Windows limit (%d)\n",
507 MIN_OPEN_FILES_WINDOWS
));
508 rlimit_max
= MIN_OPEN_FILES_WINDOWS
;
511 return MIN(sysctl_max
, rlimit_max
);
515 * Common part of freeing allocated data for one parameter.
517 static void free_one_parameter_common(void *parm_ptr
,
518 struct parm_struct parm
)
520 if ((parm
.type
== P_STRING
) ||
521 (parm
.type
== P_USTRING
))
523 string_free((char**)parm_ptr
);
524 } else if (parm
.type
== P_LIST
) {
525 TALLOC_FREE(*((char***)parm_ptr
));
530 * Free the allocated data for one parameter for a share
531 * given as a service struct.
533 static void free_one_parameter(struct loadparm_service
*service
,
534 struct parm_struct parm
)
538 if (parm
.p_class
!= P_LOCAL
) {
542 parm_ptr
= lp_parm_ptr(service
, &parm
);
544 free_one_parameter_common(parm_ptr
, parm
);
548 * Free the allocated parameter data of a share given
549 * as a service struct.
551 static void free_parameters(struct loadparm_service
*service
)
555 for (i
=0; parm_table
[i
].label
; i
++) {
556 free_one_parameter(service
, parm_table
[i
]);
561 * Free the allocated data for one parameter for a given share
562 * specified by an snum.
564 static void free_one_parameter_by_snum(int snum
, struct parm_struct parm
)
569 parm_ptr
= lp_parm_ptr(NULL
, &parm
);
570 } else if (parm
.p_class
!= P_LOCAL
) {
573 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm
);
576 free_one_parameter_common(parm_ptr
, parm
);
580 * Free the allocated parameter data for a share specified
583 static void free_parameters_by_snum(int snum
)
587 for (i
=0; parm_table
[i
].label
; i
++) {
588 free_one_parameter_by_snum(snum
, parm_table
[i
]);
593 * Free the allocated global parameters.
595 static void free_global_parameters(void)
597 free_param_opts(&Globals
.param_opt
);
598 free_parameters_by_snum(GLOBAL_SECTION_SNUM
);
599 TALLOC_FREE(Globals
.ctx
);
602 struct lp_stored_option
{
603 struct lp_stored_option
*prev
, *next
;
608 static struct lp_stored_option
*stored_options
;
611 save options set by lp_set_cmdline() into a list. This list is
612 re-applied when we do a globals reset, so that cmdline set options
613 are sticky across reloads of smb.conf
615 static bool store_lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
617 struct lp_stored_option
*entry
, *entry_next
;
618 for (entry
= stored_options
; entry
!= NULL
; entry
= entry_next
) {
619 entry_next
= entry
->next
;
620 if (strcmp(pszParmName
, entry
->label
) == 0) {
621 DLIST_REMOVE(stored_options
, entry
);
627 entry
= talloc(NULL
, struct lp_stored_option
);
632 entry
->label
= talloc_strdup(entry
, pszParmName
);
638 entry
->value
= talloc_strdup(entry
, pszParmValue
);
644 DLIST_ADD_END(stored_options
, entry
, struct lp_stored_option
);
649 static bool apply_lp_set_cmdline(void)
651 struct lp_stored_option
*entry
= NULL
;
652 for (entry
= stored_options
; entry
!= NULL
; entry
= entry
->next
) {
653 if (!lp_set_cmdline_helper(entry
->label
, entry
->value
, false)) {
654 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
655 entry
->label
, entry
->value
));
662 /***************************************************************************
663 Initialise the global parameter structure.
664 ***************************************************************************/
666 static void init_globals(bool reinit_globals
)
668 static bool done_init
= false;
672 /* If requested to initialize only once and we've already done it... */
673 if (!reinit_globals
&& done_init
) {
674 /* ... then we have nothing more to do */
679 /* The logfile can be set before this is invoked. Free it if so. */
680 if (Globals
.logfile
!= NULL
) {
681 string_free(&Globals
.logfile
);
682 Globals
.logfile
= NULL
;
686 free_global_parameters();
689 /* This memset and the free_global_parameters() above will
690 * wipe out smb.conf options set with lp_set_cmdline(). The
691 * apply_lp_set_cmdline() call puts these values back in the
692 * table once the defaults are set */
693 ZERO_STRUCT(Globals
);
695 Globals
.ctx
= talloc_new(NULL
);
697 for (i
= 0; parm_table
[i
].label
; i
++) {
698 if ((parm_table
[i
].type
== P_STRING
||
699 parm_table
[i
].type
== P_USTRING
))
701 string_set((char **)lp_parm_ptr(NULL
, &parm_table
[i
]), "");
706 string_set(&sDefault
.fstype
, FSTYPE_STRING
);
707 string_set(&sDefault
.printjob_username
, "%U");
709 init_printer_values(&sDefault
);
711 sDefault
.ntvfs_handler
= (const char **)str_list_make_v3(NULL
, "unixuid default", NULL
);
713 DEBUG(3, ("Initialising global parameters\n"));
715 /* Must manually force to upper case here, as this does not go via the handler */
716 string_set(&Globals
.netbios_name
, myhostname_upper());
718 string_set(&Globals
.smb_passwd_file
, get_dyn_SMB_PASSWD_FILE());
719 string_set(&Globals
.private_dir
, get_dyn_PRIVATE_DIR());
721 /* use the new 'hash2' method by default, with a prefix of 1 */
722 string_set(&Globals
.mangling_method
, "hash2");
723 Globals
.mangle_prefix
= 1;
725 string_set(&Globals
.guest_account
, GUEST_ACCOUNT
);
727 /* using UTF8 by default allows us to support all chars */
728 string_set(&Globals
.unix_charset
, DEFAULT_UNIX_CHARSET
);
730 /* Use codepage 850 as a default for the dos character set */
731 string_set(&Globals
.dos_charset
, DEFAULT_DOS_CHARSET
);
734 * Allow the default PASSWD_CHAT to be overridden in local.h.
736 string_set(&Globals
.passwd_chat
, DEFAULT_PASSWD_CHAT
);
738 string_set(&Globals
.workgroup
, DEFAULT_WORKGROUP
);
740 string_set(&Globals
.passwd_program
, "");
741 string_set(&Globals
.lock_directory
, get_dyn_LOCKDIR());
742 string_set(&Globals
.state_directory
, get_dyn_STATEDIR());
743 string_set(&Globals
.cache_directory
, get_dyn_CACHEDIR());
744 string_set(&Globals
.pid_directory
, get_dyn_PIDDIR());
745 string_set(&Globals
.nbt_client_socket_address
, "0.0.0.0");
747 * By default support explicit binding to broadcast
750 Globals
.nmbd_bind_explicit_broadcast
= true;
752 if (asprintf(&s
, "Samba %s", samba_version_string()) < 0) {
753 smb_panic("init_globals: ENOMEM");
755 string_set(&Globals
.server_string
, s
);
758 string_set(&Globals
.panic_action
, "/bin/sleep 999999999");
761 string_set(&Globals
.socket_options
, DEFAULT_SOCKET_OPTIONS
);
763 string_set(&Globals
.logon_drive
, "");
764 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
765 string_set(&Globals
.logon_home
, "\\\\%N\\%U");
766 string_set(&Globals
.logon_path
, "\\\\%N\\%U\\profile");
768 Globals
.name_resolve_order
= (const char **)str_list_make_v3(NULL
, "lmhosts wins host bcast", NULL
);
769 string_set(&Globals
.password_server
, "*");
771 Globals
.algorithmic_rid_base
= BASE_RID
;
773 Globals
.load_printers
= true;
774 Globals
.printcap_cache_time
= 750; /* 12.5 minutes */
776 Globals
.config_backend
= config_backend
;
777 Globals
._server_role
= ROLE_AUTO
;
779 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
780 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
781 Globals
.max_xmit
= 0x4104;
782 Globals
.max_mux
= 50; /* This is *needed* for profile support. */
783 Globals
.lpq_cache_time
= 30; /* changed to handle large print servers better -- jerry */
784 Globals
._disable_spoolss
= false;
785 Globals
.max_smbd_processes
= 0;/* no limit specified */
786 Globals
.username_level
= 0;
787 Globals
.deadtime
= 0;
788 Globals
.getwd_cache
= true;
789 Globals
.large_readwrite
= true;
790 Globals
.max_log_size
= 5000;
791 Globals
.max_open_files
= max_open_files();
792 Globals
.server_max_protocol
= PROTOCOL_SMB3_00
;
793 Globals
.server_min_protocol
= PROTOCOL_LANMAN1
;
794 Globals
.client_max_protocol
= PROTOCOL_NT1
;
795 Globals
.client_min_protocol
= PROTOCOL_CORE
;
796 Globals
._security
= SEC_AUTO
;
797 Globals
.encrypt_passwords
= true;
798 Globals
.client_schannel
= Auto
;
799 Globals
.winbind_sealed_pipes
= true;
800 Globals
.require_strong_key
= true;
801 Globals
.server_schannel
= Auto
;
802 Globals
.read_raw
= true;
803 Globals
.write_raw
= true;
804 Globals
.null_passwords
= false;
805 Globals
.old_password_allowed_period
= 60;
806 Globals
.obey_pam_restrictions
= false;
808 Globals
.syslog_only
= false;
809 Globals
.timestamp_logs
= true;
810 string_set(&Globals
.log_level
, "0");
811 Globals
.debug_prefix_timestamp
= false;
812 Globals
.debug_hires_timestamp
= true;
813 Globals
.debug_pid
= false;
814 Globals
.debug_uid
= false;
815 Globals
.debug_class
= false;
816 Globals
.enable_core_files
= true;
817 Globals
.max_ttl
= 60 * 60 * 24 * 3; /* 3 days default. */
818 Globals
.max_wins_ttl
= 60 * 60 * 24 * 6; /* 6 days default. */
819 Globals
.min_wins_ttl
= 60 * 60 * 6; /* 6 hours default. */
820 Globals
.machine_password_timeout
= 60 * 60 * 24 * 7; /* 7 days default. */
821 Globals
.lm_announce
= Auto
; /* = Auto: send only if LM clients found */
822 Globals
.lm_interval
= 60;
823 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
824 Globals
.nis_homedir
= false;
825 #ifdef WITH_NISPLUS_HOME
826 string_set(&Globals
.homedir_map
, "auto_home.org_dir");
828 string_set(&Globals
.homedir_map
, "auto.home");
831 Globals
.time_server
= false;
832 Globals
.bind_interfaces_only
= false;
833 Globals
.unix_password_sync
= false;
834 Globals
.pam_password_change
= false;
835 Globals
.passwd_chat_debug
= false;
836 Globals
.passwd_chat_timeout
= 2; /* 2 second default. */
837 Globals
.nt_pipe_support
= true; /* Do NT pipes by default. */
838 Globals
.nt_status_support
= true; /* Use NT status by default. */
839 Globals
.stat_cache
= true; /* use stat cache by default */
840 Globals
.max_stat_cache_size
= 256; /* 256k by default */
841 Globals
.restrict_anonymous
= 0;
842 Globals
.client_lanman_auth
= false; /* Do NOT use the LanMan hash if it is available */
843 Globals
.client_plaintext_auth
= false; /* Do NOT use a plaintext password even if is requested by the server */
844 Globals
.lanman_auth
= false; /* Do NOT use the LanMan hash, even if it is supplied */
845 Globals
.ntlm_auth
= true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
846 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 */
847 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
849 Globals
.map_to_guest
= 0; /* By Default, "Never" */
850 Globals
.oplock_break_wait_time
= 0; /* By Default, 0 msecs. */
851 Globals
.enhanced_browsing
= true;
852 Globals
.lock_spin_time
= WINDOWS_MINIMUM_LOCK_TIMEOUT_MS
; /* msec. */
853 #ifdef MMAP_BLACKLIST
854 Globals
.use_mmap
= false;
856 Globals
.use_mmap
= true;
858 Globals
.unicode
= true;
859 Globals
.unix_extensions
= true;
860 Globals
.reset_on_zero_vc
= false;
861 Globals
.log_writeable_files_on_exit
= false;
862 Globals
.create_krb5_conf
= true;
863 Globals
.winbindMaxDomainConnections
= 1;
865 /* hostname lookups can be very expensive and are broken on
866 a large number of sites (tridge) */
867 Globals
.hostname_lookups
= false;
869 string_set(&Globals
.passdb_backend
, "tdbsam");
870 string_set(&Globals
.ldap_suffix
, "");
871 string_set(&Globals
.szLdapMachineSuffix
, "");
872 string_set(&Globals
.szLdapUserSuffix
, "");
873 string_set(&Globals
.szLdapGroupSuffix
, "");
874 string_set(&Globals
.szLdapIdmapSuffix
, "");
876 string_set(&Globals
.ldap_admin_dn
, "");
877 Globals
.ldap_ssl
= LDAP_SSL_START_TLS
;
878 Globals
.ldap_ssl_ads
= false;
879 Globals
.ldap_deref
= -1;
880 Globals
.ldap_passwd_sync
= LDAP_PASSWD_SYNC_OFF
;
881 Globals
.ldap_delete_dn
= false;
882 Globals
.ldap_replication_sleep
= 1000; /* wait 1 sec for replication */
883 Globals
.ldap_follow_referral
= Auto
;
884 Globals
.ldap_timeout
= LDAP_DEFAULT_TIMEOUT
;
885 Globals
.ldap_connection_timeout
= LDAP_CONNECTION_DEFAULT_TIMEOUT
;
886 Globals
.ldap_page_size
= LDAP_PAGE_SIZE
;
888 Globals
.ldap_debug_level
= 0;
889 Globals
.ldap_debug_threshold
= 10;
891 /* This is what we tell the afs client. in reality we set the token
892 * to never expire, though, when this runs out the afs client will
893 * forget the token. Set to 0 to get NEVERDATE.*/
894 Globals
.afs_token_lifetime
= 604800;
895 Globals
.cups_connection_timeout
= CUPS_DEFAULT_CONNECTION_TIMEOUT
;
897 /* these parameters are set to defaults that are more appropriate
898 for the increasing samba install base:
900 as a member of the workgroup, that will possibly become a
901 _local_ master browser (lm = true). this is opposed to a forced
902 local master browser startup (pm = true).
904 doesn't provide WINS server service by default (wsupp = false),
905 and doesn't provide domain master browser services by default, either.
909 Globals
.show_add_printer_wizard
= true;
910 Globals
.os_level
= 20;
911 Globals
.local_master
= true;
912 Globals
._domain_master
= Auto
; /* depending on _domain_logons */
913 Globals
._domain_logons
= false;
914 Globals
.browse_list
= true;
915 Globals
.we_are_a_wins_server
= false;
916 Globals
.wins_proxy
= false;
918 TALLOC_FREE(Globals
.init_logon_delayed_hosts
);
919 Globals
.init_logon_delay
= 100; /* 100 ms default delay */
921 Globals
.wins_dns_proxy
= true;
923 Globals
.allow_trusted_domains
= true;
924 string_set(&Globals
.szIdmapBackend
, "tdb");
926 string_set(&Globals
.template_shell
, "/bin/false");
927 string_set(&Globals
.template_homedir
, "/home/%D/%U");
928 string_set(&Globals
.winbind_separator
, "\\");
929 string_set(&Globals
.winbindd_socket_directory
, dyn_WINBINDD_SOCKET_DIR
);
931 string_set(&Globals
.cups_server
, "");
932 string_set(&Globals
.iprint_server
, "");
934 string_set(&Globals
._ctdbd_socket
, "");
936 Globals
.cluster_addresses
= NULL
;
937 Globals
.clustering
= false;
938 Globals
.ctdb_timeout
= 0;
939 Globals
.ctdb_locktime_warn_threshold
= 0;
941 Globals
.winbind_cache_time
= 300; /* 5 minutes */
942 Globals
.winbind_reconnect_delay
= 30; /* 30 seconds */
943 Globals
.winbind_max_clients
= 200;
944 Globals
.winbind_enum_users
= false;
945 Globals
.winbind_enum_groups
= false;
946 Globals
.winbind_use_default_domain
= false;
947 Globals
.winbind_trusted_domains_only
= false;
948 Globals
.winbind_nested_groups
= true;
949 Globals
.winbind_expand_groups
= 1;
950 Globals
.winbind_nss_info
= (const char **)str_list_make_v3(NULL
, "template", NULL
);
951 Globals
.winbind_refresh_tickets
= false;
952 Globals
.winbind_offline_logon
= false;
954 Globals
.idmap_cache_time
= 86400 * 7; /* a week by default */
955 Globals
.idmap_negative_cache_time
= 120; /* 2 minutes by default */
957 Globals
.passdb_expand_explicit
= false;
959 Globals
.name_cache_timeout
= 660; /* In seconds */
961 Globals
.use_spnego
= true;
962 Globals
.client_use_spnego
= true;
964 Globals
.client_signing
= SMB_SIGNING_DEFAULT
;
965 Globals
.server_signing
= SMB_SIGNING_DEFAULT
;
967 Globals
.defer_sharing_violations
= true;
968 Globals
.smb_ports
= (const char **)str_list_make_v3(NULL
, SMB_PORTS
, NULL
);
970 Globals
.enable_privileges
= true;
971 Globals
.host_msdfs
= true;
972 Globals
.enable_asu_support
= false;
974 /* User defined shares. */
975 if (asprintf(&s
, "%s/usershares", get_dyn_STATEDIR()) < 0) {
976 smb_panic("init_globals: ENOMEM");
978 string_set(&Globals
.usershare_path
, s
);
980 string_set(&Globals
.usershare_template_share
, "");
981 Globals
.usershare_max_shares
= 0;
982 /* By default disallow sharing of directories not owned by the sharer. */
983 Globals
.usershare_owner_only
= true;
984 /* By default disallow guest access to usershares. */
985 Globals
.usershare_allow_guests
= false;
987 Globals
.keepalive
= DEFAULT_KEEPALIVE
;
989 /* By default no shares out of the registry */
990 Globals
.registry_shares
= false;
992 Globals
.iminreceivefile
= 0;
994 Globals
.map_untrusted_to_domain
= false;
995 Globals
.multicast_dns_register
= true;
997 Globals
.smb2_max_read
= DEFAULT_SMB2_MAX_READ
;
998 Globals
.smb2_max_write
= DEFAULT_SMB2_MAX_WRITE
;
999 Globals
.smb2_max_trans
= DEFAULT_SMB2_MAX_TRANSACT
;
1000 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
1002 string_set(&Globals
.ncalrpc_dir
, get_dyn_NCALRPCDIR());
1004 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
);
1006 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
);
1008 Globals
.tls_enabled
= true;
1010 string_set(&Globals
._tls_keyfile
, "tls/key.pem");
1011 string_set(&Globals
._tls_certfile
, "tls/cert.pem");
1012 string_set(&Globals
._tls_cafile
, "tls/ca.pem");
1014 string_set(&Globals
.share_backend
, "classic");
1016 Globals
.iPreferredMaster
= Auto
;
1018 Globals
.allow_dns_updates
= DNS_UPDATE_SIGNED
;
1020 string_set(&Globals
.ntp_signd_socket_directory
, get_dyn_NTP_SIGND_SOCKET_DIR());
1022 string_set(&Globals
.winbindd_privileged_socket_directory
, get_dyn_WINBINDD_PRIVILEGED_SOCKET_DIR());
1024 if (asprintf(&s
, "%s/samba_kcc", get_dyn_SCRIPTSBINDIR()) < 0) {
1025 smb_panic("init_globals: ENOMEM");
1027 Globals
.samba_kcc_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1030 if (asprintf(&s
, "%s/samba_dnsupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1031 smb_panic("init_globals: ENOMEM");
1033 Globals
.dns_update_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1036 if (asprintf(&s
, "%s/samba_spnupdate", get_dyn_SCRIPTSBINDIR()) < 0) {
1037 smb_panic("init_globals: ENOMEM");
1039 Globals
.spn_update_command
= (const char **)str_list_make_v3(NULL
, s
, NULL
);
1042 Globals
.nsupdate_command
= (const char **)str_list_make_v3(NULL
, "/usr/bin/nsupdate -g", NULL
);
1044 Globals
.rndc_command
= (const char **)str_list_make_v3(NULL
, "/usr/sbin/rndc", NULL
);
1046 Globals
.cldap_port
= 389;
1048 Globals
.dgram_port
= 138;
1050 Globals
.nbt_port
= 137;
1052 Globals
.krb5_port
= 88;
1054 Globals
.kpasswd_port
= 464;
1056 Globals
.web_port
= 901;
1058 /* Now put back the settings that were set with lp_set_cmdline() */
1059 apply_lp_set_cmdline();
1062 /*******************************************************************
1063 Convenience routine to grab string parameters into talloced memory
1064 and run standard_sub_basic on them. The buffers can be written to by
1065 callers without affecting the source string.
1066 ********************************************************************/
1068 char *lp_string(TALLOC_CTX
*ctx
, const char *s
)
1072 /* The follow debug is useful for tracking down memory problems
1073 especially if you have an inner loop that is calling a lp_*()
1074 function that returns a string. Perhaps this debug should be
1075 present all the time? */
1078 DEBUG(10, ("lp_string(%s)\n", s
));
1084 ret
= talloc_sub_basic(ctx
,
1085 get_current_username(),
1086 current_user_info
.domain
,
1088 if (trim_char(ret
, '\"', '\"')) {
1089 if (strchr(ret
,'\"') != NULL
) {
1091 ret
= talloc_sub_basic(ctx
,
1092 get_current_username(),
1093 current_user_info
.domain
,
1101 In this section all the functions that are used to access the
1102 parameters from the rest of the program are defined
1105 #define FN_GLOBAL_STRING(fn_name,ptr) \
1106 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1107 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1108 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1109 #define FN_GLOBAL_LIST(fn_name,ptr) \
1110 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1111 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1112 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1113 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1114 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1115 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1116 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1118 #define FN_LOCAL_STRING(fn_name,val) \
1119 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));}
1120 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1121 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1122 #define FN_LOCAL_LIST(fn_name,val) \
1123 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1124 #define FN_LOCAL_BOOL(fn_name,val) \
1125 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1126 #define FN_LOCAL_INTEGER(fn_name,val) \
1127 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1129 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1130 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1131 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1132 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1133 #define FN_LOCAL_PARM_CHAR(fn_name,val) \
1134 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1136 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int
,
1137 winbindMaxDomainConnections
)
1139 int lp_winbind_max_domain_connections(void)
1141 if (lp_winbind_offline_logon() &&
1142 lp_winbind_max_domain_connections_int() > 1) {
1143 DEBUG(1, ("offline logons active, restricting max domain "
1144 "connections to 1\n"));
1147 return MAX(1, lp_winbind_max_domain_connections_int());
1150 int lp_smb2_max_credits(void)
1152 if (Globals
.ismb2_max_credits
== 0) {
1153 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
1155 return Globals
.ismb2_max_credits
;
1157 int lp_cups_encrypt(void)
1160 #ifdef HAVE_HTTPCONNECTENCRYPT
1161 switch (Globals
.CupsEncrypt
) {
1163 result
= HTTP_ENCRYPT_REQUIRED
;
1166 result
= HTTP_ENCRYPT_ALWAYS
;
1169 result
= HTTP_ENCRYPT_NEVER
;
1176 /* These functions remain in source3/param for now */
1178 #include "lib/param/param_functions.c"
1180 FN_LOCAL_STRING(servicename
, szService
)
1181 FN_LOCAL_CONST_STRING(const_servicename
, szService
)
1183 /* These functions cannot be auto-generated */
1184 FN_LOCAL_BOOL(autoloaded
, autoloaded
)
1186 /* local prototypes */
1188 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
);
1189 static const char *get_boolean(bool bool_value
);
1190 static int getservicebyname(const char *pszServiceName
,
1191 struct loadparm_service
*pserviceDest
);
1192 static void copy_service(struct loadparm_service
*pserviceDest
,
1193 struct loadparm_service
*pserviceSource
,
1194 struct bitmap
*pcopymapDest
);
1195 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
1197 static bool do_section(const char *pszSectionName
, void *userdata
);
1198 static void init_copymap(struct loadparm_service
*pservice
);
1199 static bool hash_a_service(const char *name
, int number
);
1200 static void free_service_byindex(int iService
);
1201 static void show_parameter(int parmIndex
);
1202 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
);
1205 * This is a helper function for parametrical options support. It returns a
1206 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1207 * parametrical functions are quite simple
1209 static struct parmlist_entry
*get_parametrics_by_service(struct loadparm_service
*service
, const char *type
,
1212 bool global_section
= false;
1214 struct parmlist_entry
*data
;
1216 if (service
== NULL
) {
1217 data
= Globals
.param_opt
;
1218 global_section
= true;
1220 data
= service
->param_opt
;
1223 if (asprintf(¶m_key
, "%s:%s", type
, option
) == -1) {
1224 DEBUG(0,("asprintf failed!\n"));
1229 if (strwicmp(data
->key
, param_key
) == 0) {
1230 string_free(¶m_key
);
1236 if (!global_section
) {
1237 /* Try to fetch the same option but from globals */
1238 /* but only if we are not already working with Globals */
1239 data
= Globals
.param_opt
;
1241 if (strwicmp(data
->key
, param_key
) == 0) {
1242 string_free(¶m_key
);
1249 string_free(¶m_key
);
1255 * This is a helper function for parametrical options support. It returns a
1256 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1257 * parametrical functions are quite simple
1259 static struct parmlist_entry
*get_parametrics(int snum
, const char *type
,
1262 if (snum
>= iNumServices
) return NULL
;
1265 return get_parametrics_by_service(NULL
, type
, option
);
1267 return get_parametrics_by_service(ServicePtrs
[snum
], type
, option
);
1272 #define MISSING_PARAMETER(name) \
1273 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1275 /*******************************************************************
1276 convenience routine to return int parameters.
1277 ********************************************************************/
1278 static int lp_int(const char *s
)
1282 MISSING_PARAMETER(lp_int
);
1286 return (int)strtol(s
, NULL
, 0);
1289 /*******************************************************************
1290 convenience routine to return unsigned long parameters.
1291 ********************************************************************/
1292 static unsigned long lp_ulong(const char *s
)
1296 MISSING_PARAMETER(lp_ulong
);
1300 return strtoul(s
, NULL
, 0);
1303 /*******************************************************************
1304 convenience routine to return boolean parameters.
1305 ********************************************************************/
1306 static bool lp_bool(const char *s
)
1311 MISSING_PARAMETER(lp_bool
);
1315 if (!set_boolean(s
, &ret
)) {
1316 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s
));
1323 /*******************************************************************
1324 convenience routine to return enum parameters.
1325 ********************************************************************/
1326 static int lp_enum(const char *s
,const struct enum_list
*_enum
)
1330 if (!s
|| !*s
|| !_enum
) {
1331 MISSING_PARAMETER(lp_enum
);
1335 for (i
=0; _enum
[i
].name
; i
++) {
1336 if (strequal(_enum
[i
].name
,s
))
1337 return _enum
[i
].value
;
1340 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s
));
1344 #undef MISSING_PARAMETER
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 char *lp_parm_talloc_string(TALLOC_CTX
*ctx
, 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
) {
1354 return lp_string(ctx
, def
);
1360 return lp_string(ctx
, data
->value
);
1363 /* Return parametric option from a given service. Type is a part of option before ':' */
1364 /* Parametric option has following syntax: 'Type: option = value' */
1365 const char *lp_parm_const_string(int snum
, const char *type
, const char *option
, const char *def
)
1367 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1369 if (data
== NULL
||data
->value
==NULL
)
1375 const char *lp_parm_const_string_service(struct loadparm_service
*service
, const char *type
, const char *option
)
1377 struct parmlist_entry
*data
= get_parametrics_by_service(service
, type
, option
);
1379 if (data
== NULL
||data
->value
==NULL
)
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 const char **lp_parm_string_list(int snum
, const char *type
, const char *option
, const char **def
)
1391 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1393 if (data
== NULL
||data
->value
==NULL
)
1394 return (const char **)def
;
1396 if (data
->list
==NULL
) {
1397 data
->list
= str_list_make_v3(NULL
, data
->value
, NULL
);
1400 return (const char **)data
->list
;
1403 /* Return parametric option from a given service. Type is a part of option before ':' */
1404 /* Parametric option has following syntax: 'Type: option = value' */
1406 int lp_parm_int(int snum
, const char *type
, const char *option
, int def
)
1408 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1410 if (data
&& data
->value
&& *data
->value
)
1411 return lp_int(data
->value
);
1416 /* Return parametric option from a given service. Type is a part of option before ':' */
1417 /* Parametric option has following syntax: 'Type: option = value' */
1419 unsigned long lp_parm_ulong(int snum
, const char *type
, const char *option
, unsigned long def
)
1421 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1423 if (data
&& data
->value
&& *data
->value
)
1424 return lp_ulong(data
->value
);
1429 /* Return parametric option from a given service. Type is a part of option before ':' */
1430 /* Parametric option has following syntax: 'Type: option = value' */
1432 bool lp_parm_bool(int snum
, const char *type
, const char *option
, bool def
)
1434 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1436 if (data
&& data
->value
&& *data
->value
)
1437 return lp_bool(data
->value
);
1442 /* Return parametric option from a given service. Type is a part of option before ':' */
1443 /* Parametric option has following syntax: 'Type: option = value' */
1445 int lp_parm_enum(int snum
, const char *type
, const char *option
,
1446 const struct enum_list
*_enum
, int def
)
1448 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1450 if (data
&& data
->value
&& *data
->value
&& _enum
)
1451 return lp_enum(data
->value
, _enum
);
1457 /***************************************************************************
1458 Initialise a service to the defaults.
1459 ***************************************************************************/
1461 static void init_service(struct loadparm_service
*pservice
)
1463 memset((char *)pservice
, '\0', sizeof(struct loadparm_service
));
1464 copy_service(pservice
, &sDefault
, NULL
);
1469 * free a param_opts structure.
1470 * param_opts handling should be moved to talloc;
1471 * then this whole functions reduces to a TALLOC_FREE().
1474 static void free_param_opts(struct parmlist_entry
**popts
)
1476 struct parmlist_entry
*opt
, *next_opt
;
1478 if (*popts
!= NULL
) {
1479 DEBUG(5, ("Freeing parametrics:\n"));
1482 while (opt
!= NULL
) {
1483 string_free(&opt
->key
);
1484 string_free(&opt
->value
);
1485 TALLOC_FREE(opt
->list
);
1486 next_opt
= opt
->next
;
1493 /***************************************************************************
1494 Free the dynamically allocated parts of a service struct.
1495 ***************************************************************************/
1497 static void free_service(struct loadparm_service
*pservice
)
1502 if (pservice
->szService
)
1503 DEBUG(5, ("free_service: Freeing service %s\n",
1504 pservice
->szService
));
1506 free_parameters(pservice
);
1508 string_free(&pservice
->szService
);
1509 TALLOC_FREE(pservice
->copymap
);
1511 free_param_opts(&pservice
->param_opt
);
1513 ZERO_STRUCTP(pservice
);
1517 /***************************************************************************
1518 remove a service indexed in the ServicePtrs array from the ServiceHash
1519 and free the dynamically allocated parts
1520 ***************************************************************************/
1522 static void free_service_byindex(int idx
)
1524 if ( !LP_SNUM_OK(idx
) )
1527 ServicePtrs
[idx
]->valid
= false;
1529 /* we have to cleanup the hash record */
1531 if (ServicePtrs
[idx
]->szService
) {
1532 char *canon_name
= canonicalize_servicename(
1534 ServicePtrs
[idx
]->szService
);
1536 dbwrap_delete_bystring(ServiceHash
, canon_name
);
1537 TALLOC_FREE(canon_name
);
1540 free_service(ServicePtrs
[idx
]);
1541 talloc_free_children(ServicePtrs
[idx
]);
1544 /***************************************************************************
1545 Add a new service to the services array initialising it with the given
1547 ***************************************************************************/
1549 static int add_a_service(const struct loadparm_service
*pservice
, const char *name
)
1552 struct loadparm_service tservice
;
1553 int num_to_alloc
= iNumServices
+ 1;
1554 struct loadparm_service
**tsp
= NULL
;
1556 tservice
= *pservice
;
1558 /* it might already exist */
1560 i
= getservicebyname(name
, NULL
);
1566 /* if not, then create one */
1568 tsp
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs
, struct loadparm_service
*, num_to_alloc
);
1570 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1574 ServicePtrs
[iNumServices
] = talloc(NULL
, struct loadparm_service
);
1575 if (!ServicePtrs
[iNumServices
]) {
1576 DEBUG(0,("add_a_service: out of memory!\n"));
1581 ServicePtrs
[i
]->valid
= true;
1583 init_service(ServicePtrs
[i
]);
1584 copy_service(ServicePtrs
[i
], &tservice
, NULL
);
1586 string_set(&ServicePtrs
[i
]->szService
, name
);
1588 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1589 i
, ServicePtrs
[i
]->szService
));
1591 if (!hash_a_service(ServicePtrs
[i
]->szService
, i
)) {
1598 /***************************************************************************
1599 Convert a string to uppercase and remove whitespaces.
1600 ***************************************************************************/
1602 char *canonicalize_servicename(TALLOC_CTX
*ctx
, const char *src
)
1607 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1611 result
= talloc_strdup(ctx
, src
);
1612 SMB_ASSERT(result
!= NULL
);
1614 if (!strlower_m(result
)) {
1615 TALLOC_FREE(result
);
1621 /***************************************************************************
1622 Add a name/index pair for the services array to the hash table.
1623 ***************************************************************************/
1625 static bool hash_a_service(const char *name
, int idx
)
1629 if ( !ServiceHash
) {
1630 DEBUG(10,("hash_a_service: creating servicehash\n"));
1631 ServiceHash
= db_open_rbt(NULL
);
1632 if ( !ServiceHash
) {
1633 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1638 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1641 canon_name
= canonicalize_servicename(talloc_tos(), name
);
1643 dbwrap_store_bystring(ServiceHash
, canon_name
,
1644 make_tdb_data((uint8
*)&idx
, sizeof(idx
)),
1647 TALLOC_FREE(canon_name
);
1652 /***************************************************************************
1653 Add a new home service, with the specified home directory, defaults coming
1655 ***************************************************************************/
1657 bool lp_add_home(const char *pszHomename
, int iDefaultService
,
1658 const char *user
, const char *pszHomedir
)
1662 if (pszHomename
== NULL
|| user
== NULL
|| pszHomedir
== NULL
||
1663 pszHomedir
[0] == '\0') {
1667 i
= add_a_service(ServicePtrs
[iDefaultService
], pszHomename
);
1672 if (!(*(ServicePtrs
[iDefaultService
]->path
))
1673 || strequal(ServicePtrs
[iDefaultService
]->path
,
1674 lp_path(talloc_tos(), GLOBAL_SECTION_SNUM
))) {
1675 string_set(&ServicePtrs
[i
]->path
, pszHomedir
);
1678 if (!(*(ServicePtrs
[i
]->comment
))) {
1679 char *comment
= NULL
;
1680 if (asprintf(&comment
, "Home directory of %s", user
) < 0) {
1683 string_set(&ServicePtrs
[i
]->comment
, comment
);
1687 /* set the browseable flag from the global default */
1689 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1690 ServicePtrs
[i
]->access_based_share_enum
= sDefault
.access_based_share_enum
;
1692 ServicePtrs
[i
]->autoloaded
= true;
1694 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename
,
1695 user
, ServicePtrs
[i
]->path
));
1700 /***************************************************************************
1701 Add a new service, based on an old one.
1702 ***************************************************************************/
1704 int lp_add_service(const char *pszService
, int iDefaultService
)
1706 if (iDefaultService
< 0) {
1707 return add_a_service(&sDefault
, pszService
);
1710 return (add_a_service(ServicePtrs
[iDefaultService
], pszService
));
1713 /***************************************************************************
1714 Add the IPC service.
1715 ***************************************************************************/
1717 static bool lp_add_ipc(const char *ipc_name
, bool guest_ok
)
1719 char *comment
= NULL
;
1720 int i
= add_a_service(&sDefault
, ipc_name
);
1725 if (asprintf(&comment
, "IPC Service (%s)",
1726 Globals
.server_string
) < 0) {
1730 string_set(&ServicePtrs
[i
]->path
, tmpdir());
1731 string_set(&ServicePtrs
[i
]->username
, "");
1732 string_set(&ServicePtrs
[i
]->comment
, comment
);
1733 string_set(&ServicePtrs
[i
]->fstype
, "IPC");
1734 ServicePtrs
[i
]->max_connections
= 0;
1735 ServicePtrs
[i
]->bAvailable
= true;
1736 ServicePtrs
[i
]->read_only
= true;
1737 ServicePtrs
[i
]->guest_only
= false;
1738 ServicePtrs
[i
]->administrative_share
= true;
1739 ServicePtrs
[i
]->guest_ok
= guest_ok
;
1740 ServicePtrs
[i
]->printable
= false;
1741 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1743 DEBUG(3, ("adding IPC service\n"));
1749 /***************************************************************************
1750 Add a new printer service, with defaults coming from service iFrom.
1751 ***************************************************************************/
1753 bool lp_add_printer(const char *pszPrintername
, int iDefaultService
)
1755 const char *comment
= "From Printcap";
1756 int i
= add_a_service(ServicePtrs
[iDefaultService
], pszPrintername
);
1761 /* note that we do NOT default the availability flag to true - */
1762 /* we take it from the default service passed. This allows all */
1763 /* dynamic printers to be disabled by disabling the [printers] */
1764 /* entry (if/when the 'available' keyword is implemented!). */
1766 /* the printer name is set to the service name. */
1767 string_set(&ServicePtrs
[i
]->_printername
, pszPrintername
);
1768 string_set(&ServicePtrs
[i
]->comment
, comment
);
1770 /* set the browseable flag from the gloabl default */
1771 ServicePtrs
[i
]->browseable
= sDefault
.browseable
;
1773 /* Printers cannot be read_only. */
1774 ServicePtrs
[i
]->read_only
= false;
1775 /* No oplocks on printer services. */
1776 ServicePtrs
[i
]->oplocks
= false;
1777 /* Printer services must be printable. */
1778 ServicePtrs
[i
]->printable
= true;
1780 DEBUG(3, ("adding printer service %s\n", pszPrintername
));
1786 /***************************************************************************
1787 Check whether the given parameter name is valid.
1788 Parametric options (names containing a colon) are considered valid.
1789 ***************************************************************************/
1791 bool lp_parameter_is_valid(const char *pszParmName
)
1793 return ((lpcfg_map_parameter(pszParmName
) != -1) ||
1794 (strchr(pszParmName
, ':') != NULL
));
1797 /***************************************************************************
1798 Check whether the given name is the name of a global parameter.
1799 Returns true for strings belonging to parameters of class
1800 P_GLOBAL, false for all other strings, also for parametric options
1801 and strings not belonging to any option.
1802 ***************************************************************************/
1804 bool lp_parameter_is_global(const char *pszParmName
)
1806 int num
= lpcfg_map_parameter(pszParmName
);
1809 return (parm_table
[num
].p_class
== P_GLOBAL
);
1815 /**************************************************************************
1816 Check whether the given name is the canonical name of a parameter.
1817 Returns false if it is not a valid parameter Name.
1818 For parametric options, true is returned.
1819 **************************************************************************/
1821 bool lp_parameter_is_canonical(const char *parm_name
)
1823 if (!lp_parameter_is_valid(parm_name
)) {
1827 return (lpcfg_map_parameter(parm_name
) ==
1828 map_parameter_canonical(parm_name
, NULL
));
1831 /**************************************************************************
1832 Determine the canonical name for a parameter.
1833 Indicate when it is an inverse (boolean) synonym instead of a
1835 **************************************************************************/
1837 bool lp_canonicalize_parameter(const char *parm_name
, const char **canon_parm
,
1842 if (!lp_parameter_is_valid(parm_name
)) {
1847 num
= map_parameter_canonical(parm_name
, inverse
);
1849 /* parametric option */
1850 *canon_parm
= parm_name
;
1852 *canon_parm
= parm_table
[num
].label
;
1859 /**************************************************************************
1860 Determine the canonical name for a parameter.
1861 Turn the value given into the inverse boolean expression when
1862 the synonym is an invers boolean synonym.
1864 Return true if parm_name is a valid parameter name and
1865 in case it is an invers boolean synonym, if the val string could
1866 successfully be converted to the reverse bool.
1867 Return false in all other cases.
1868 **************************************************************************/
1870 bool lp_canonicalize_parameter_with_value(const char *parm_name
,
1872 const char **canon_parm
,
1873 const char **canon_val
)
1878 if (!lp_parameter_is_valid(parm_name
)) {
1884 num
= map_parameter_canonical(parm_name
, &inverse
);
1886 /* parametric option */
1887 *canon_parm
= parm_name
;
1890 *canon_parm
= parm_table
[num
].label
;
1892 if (!lp_invert_boolean(val
, canon_val
)) {
1904 /***************************************************************************
1905 Map a parameter's string representation to the index of the canonical
1906 form of the parameter (it might be a synonym).
1907 Returns -1 if the parameter string is not recognised.
1908 ***************************************************************************/
1910 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
)
1912 int parm_num
, canon_num
;
1913 bool loc_inverse
= false;
1915 parm_num
= lpcfg_map_parameter(pszParmName
);
1916 if ((parm_num
< 0) || !(parm_table
[parm_num
].flags
& FLAG_HIDE
)) {
1917 /* invalid, parametric or no canidate for synonyms ... */
1921 for (canon_num
= 0; parm_table
[canon_num
].label
; canon_num
++) {
1922 if (is_synonym_of(parm_num
, canon_num
, &loc_inverse
)) {
1923 parm_num
= canon_num
;
1929 if (inverse
!= NULL
) {
1930 *inverse
= loc_inverse
;
1935 /***************************************************************************
1936 return true if parameter number parm1 is a synonym of parameter
1937 number parm2 (parm2 being the principal name).
1938 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1940 ***************************************************************************/
1942 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
)
1944 if ((parm_table
[parm1
].offset
== parm_table
[parm2
].offset
) &&
1945 (parm_table
[parm1
].p_class
== parm_table
[parm2
].p_class
) &&
1946 (parm_table
[parm1
].flags
& FLAG_HIDE
) &&
1947 !(parm_table
[parm2
].flags
& FLAG_HIDE
))
1949 if (inverse
!= NULL
) {
1950 if ((parm_table
[parm1
].type
== P_BOOLREV
) &&
1951 (parm_table
[parm2
].type
== P_BOOL
))
1963 /***************************************************************************
1964 Show one parameter's name, type, [values,] and flags.
1965 (helper functions for show_parameter_list)
1966 ***************************************************************************/
1968 static void show_parameter(int parmIndex
)
1970 int enumIndex
, flagIndex
;
1975 const char *type
[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
1976 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
1978 unsigned flags
[] = { FLAG_BASIC
, FLAG_SHARE
, FLAG_PRINT
, FLAG_GLOBAL
,
1979 FLAG_WIZARD
, FLAG_ADVANCED
, FLAG_DEVELOPER
, FLAG_DEPRECATED
,
1981 const char *flag_names
[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
1982 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
1983 "FLAG_DEPRECATED", "FLAG_HIDE", NULL
};
1985 printf("%s=%s", parm_table
[parmIndex
].label
,
1986 type
[parm_table
[parmIndex
].type
]);
1987 if (parm_table
[parmIndex
].type
== P_ENUM
) {
1990 parm_table
[parmIndex
].enum_list
[enumIndex
].name
;
1994 enumIndex
? "|" : "",
1995 parm_table
[parmIndex
].enum_list
[enumIndex
].name
);
2000 for (flagIndex
=0; flag_names
[flagIndex
]; flagIndex
++) {
2001 if (parm_table
[parmIndex
].flags
& flags
[flagIndex
]) {
2004 flag_names
[flagIndex
]);
2009 /* output synonyms */
2011 for (parmIndex2
=0; parm_table
[parmIndex2
].label
; parmIndex2
++) {
2012 if (is_synonym_of(parmIndex
, parmIndex2
, &inverse
)) {
2013 printf(" (%ssynonym of %s)", inverse
? "inverse " : "",
2014 parm_table
[parmIndex2
].label
);
2015 } else if (is_synonym_of(parmIndex2
, parmIndex
, &inverse
)) {
2017 printf(" (synonyms: ");
2022 printf("%s%s", parm_table
[parmIndex2
].label
,
2023 inverse
? "[i]" : "");
2033 /***************************************************************************
2034 Show all parameter's name, type, [values,] and flags.
2035 ***************************************************************************/
2037 void show_parameter_list(void)
2039 int classIndex
, parmIndex
;
2040 const char *section_names
[] = { "local", "global", NULL
};
2042 for (classIndex
=0; section_names
[classIndex
]; classIndex
++) {
2043 printf("[%s]\n", section_names
[classIndex
]);
2044 for (parmIndex
= 0; parm_table
[parmIndex
].label
; parmIndex
++) {
2045 if (parm_table
[parmIndex
].p_class
== classIndex
) {
2046 show_parameter(parmIndex
);
2052 /***************************************************************************
2053 Check if a given string correctly represents a boolean value.
2054 ***************************************************************************/
2056 bool lp_string_is_valid_boolean(const char *parm_value
)
2058 return set_boolean(parm_value
, NULL
);
2061 /***************************************************************************
2062 Get the standard string representation of a boolean value ("yes" or "no")
2063 ***************************************************************************/
2065 static const char *get_boolean(bool bool_value
)
2067 static const char *yes_str
= "yes";
2068 static const char *no_str
= "no";
2070 return (bool_value
? yes_str
: no_str
);
2073 /***************************************************************************
2074 Provide the string of the negated boolean value associated to the boolean
2075 given as a string. Returns false if the passed string does not correctly
2076 represent a boolean.
2077 ***************************************************************************/
2079 bool lp_invert_boolean(const char *str
, const char **inverse_str
)
2083 if (!set_boolean(str
, &val
)) {
2087 *inverse_str
= get_boolean(!val
);
2091 /***************************************************************************
2092 Provide the canonical string representation of a boolean value given
2093 as a string. Return true on success, false if the string given does
2094 not correctly represent a boolean.
2095 ***************************************************************************/
2097 bool lp_canonicalize_boolean(const char *str
, const char**canon_str
)
2101 if (!set_boolean(str
, &val
)) {
2105 *canon_str
= get_boolean(val
);
2109 /***************************************************************************
2110 Find a service by name. Otherwise works like get_service.
2111 ***************************************************************************/
2113 static int getservicebyname(const char *pszServiceName
, struct loadparm_service
*pserviceDest
)
2120 if (ServiceHash
== NULL
) {
2124 canon_name
= canonicalize_servicename(talloc_tos(), pszServiceName
);
2126 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
, canon_name
,
2129 if (NT_STATUS_IS_OK(status
) &&
2130 (data
.dptr
!= NULL
) &&
2131 (data
.dsize
== sizeof(iService
)))
2133 iService
= *(int *)data
.dptr
;
2136 TALLOC_FREE(canon_name
);
2138 if ((iService
!= -1) && (LP_SNUM_OK(iService
))
2139 && (pserviceDest
!= NULL
)) {
2140 copy_service(pserviceDest
, ServicePtrs
[iService
], NULL
);
2146 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2147 struct loadparm_service
*lp_service(const char *pszServiceName
)
2149 int iService
= getservicebyname(pszServiceName
, NULL
);
2150 if (iService
== -1 || !LP_SNUM_OK(iService
)) {
2153 return ServicePtrs
[iService
];
2156 struct loadparm_service
*lp_servicebynum(int snum
)
2158 if ((snum
== -1) || !LP_SNUM_OK(snum
)) {
2161 return ServicePtrs
[snum
];
2164 struct loadparm_service
*lp_default_loadparm_service()
2170 /***************************************************************************
2171 Copy a service structure to another.
2172 If pcopymapDest is NULL then copy all fields
2173 ***************************************************************************/
2176 * Add a parametric option to a parmlist_entry,
2177 * replacing old value, if already present.
2179 static void set_param_opt(struct parmlist_entry
**opt_list
,
2180 const char *opt_name
,
2181 const char *opt_value
,
2184 struct parmlist_entry
*new_opt
, *opt
;
2190 /* Traverse destination */
2192 /* If we already have same option, override it */
2193 if (strwicmp(opt
->key
, opt_name
) == 0) {
2194 if ((opt
->priority
& FLAG_CMDLINE
) &&
2195 !(priority
& FLAG_CMDLINE
)) {
2196 /* it's been marked as not to be
2200 string_free(&opt
->value
);
2201 TALLOC_FREE(opt
->list
);
2202 opt
->value
= SMB_STRDUP(opt_value
);
2203 opt
->priority
= priority
;
2210 new_opt
= SMB_XMALLOC_P(struct parmlist_entry
);
2211 new_opt
->key
= SMB_STRDUP(opt_name
);
2212 new_opt
->value
= SMB_STRDUP(opt_value
);
2213 new_opt
->list
= NULL
;
2214 new_opt
->priority
= priority
;
2215 DLIST_ADD(*opt_list
, new_opt
);
2219 static void copy_service(struct loadparm_service
*pserviceDest
, struct loadparm_service
*pserviceSource
,
2220 struct bitmap
*pcopymapDest
)
2223 bool bcopyall
= (pcopymapDest
== NULL
);
2224 struct parmlist_entry
*data
;
2226 for (i
= 0; parm_table
[i
].label
; i
++)
2227 if (parm_table
[i
].p_class
== P_LOCAL
&&
2228 (bcopyall
|| bitmap_query(pcopymapDest
,i
))) {
2229 void *src_ptr
= lp_parm_ptr(pserviceSource
, &parm_table
[i
]);
2230 void *dest_ptr
= lp_parm_ptr(pserviceDest
, &parm_table
[i
]);
2232 switch (parm_table
[i
].type
) {
2235 *(bool *)dest_ptr
= *(bool *)src_ptr
;
2242 *(int *)dest_ptr
= *(int *)src_ptr
;
2246 *(char *)dest_ptr
= *(char *)src_ptr
;
2250 string_set((char **)dest_ptr
,
2256 char *upper_string
= strupper_talloc(talloc_tos(),
2258 string_set((char **)dest_ptr
,
2260 TALLOC_FREE(upper_string
);
2264 TALLOC_FREE(*((char ***)dest_ptr
));
2265 *((char ***)dest_ptr
) = str_list_copy(NULL
,
2266 *(const char ***)src_ptr
);
2274 init_copymap(pserviceDest
);
2275 if (pserviceSource
->copymap
)
2276 bitmap_copy(pserviceDest
->copymap
,
2277 pserviceSource
->copymap
);
2280 data
= pserviceSource
->param_opt
;
2282 set_param_opt(&pserviceDest
->param_opt
, data
->key
, data
->value
, data
->priority
);
2287 /***************************************************************************
2288 Check a service for consistency. Return false if the service is in any way
2289 incomplete or faulty, else true.
2290 ***************************************************************************/
2292 bool service_ok(int iService
)
2297 if (ServicePtrs
[iService
]->szService
[0] == '\0') {
2298 DEBUG(0, ("The following message indicates an internal error:\n"));
2299 DEBUG(0, ("No service name in service entry.\n"));
2303 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2304 /* I can't see why you'd want a non-printable printer service... */
2305 if (strwicmp(ServicePtrs
[iService
]->szService
, PRINTERS_NAME
) == 0) {
2306 if (!ServicePtrs
[iService
]->printable
) {
2307 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2308 ServicePtrs
[iService
]->szService
));
2309 ServicePtrs
[iService
]->printable
= true;
2311 /* [printers] service must also be non-browsable. */
2312 if (ServicePtrs
[iService
]->browseable
)
2313 ServicePtrs
[iService
]->browseable
= false;
2316 if (ServicePtrs
[iService
]->path
[0] == '\0' &&
2317 strwicmp(ServicePtrs
[iService
]->szService
, HOMES_NAME
) != 0 &&
2318 ServicePtrs
[iService
]->msdfs_proxy
[0] == '\0'
2320 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2321 ServicePtrs
[iService
]->szService
));
2322 ServicePtrs
[iService
]->bAvailable
= false;
2325 /* If a service is flagged unavailable, log the fact at level 1. */
2326 if (!ServicePtrs
[iService
]->bAvailable
)
2327 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2328 ServicePtrs
[iService
]->szService
));
2333 static struct smbconf_ctx
*lp_smbconf_ctx(void)
2336 static struct smbconf_ctx
*conf_ctx
= NULL
;
2338 if (conf_ctx
== NULL
) {
2339 err
= smbconf_init(NULL
, &conf_ctx
, "registry:");
2340 if (!SBC_ERROR_IS_OK(err
)) {
2341 DEBUG(1, ("error initializing registry configuration: "
2342 "%s\n", sbcErrorString(err
)));
2350 static bool process_smbconf_service(struct smbconf_service
*service
)
2355 if (service
== NULL
) {
2359 ret
= do_section(service
->name
, NULL
);
2363 for (count
= 0; count
< service
->num_params
; count
++) {
2364 ret
= do_parameter(service
->param_names
[count
],
2365 service
->param_values
[count
],
2371 if (iServiceIndex
>= 0) {
2372 return service_ok(iServiceIndex
);
2378 * load a service from registry and activate it
2380 bool process_registry_service(const char *service_name
)
2383 struct smbconf_service
*service
= NULL
;
2384 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2385 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2388 if (conf_ctx
== NULL
) {
2392 DEBUG(5, ("process_registry_service: service name %s\n", service_name
));
2394 if (!smbconf_share_exists(conf_ctx
, service_name
)) {
2396 * Registry does not contain data for this service (yet),
2397 * but make sure lp_load doesn't return false.
2403 err
= smbconf_get_share(conf_ctx
, mem_ctx
, service_name
, &service
);
2404 if (!SBC_ERROR_IS_OK(err
)) {
2408 ret
= process_smbconf_service(service
);
2414 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2417 TALLOC_FREE(mem_ctx
);
2422 * process_registry_globals
2424 static bool process_registry_globals(void)
2428 add_to_file_list(INCLUDE_REGISTRY_NAME
, INCLUDE_REGISTRY_NAME
);
2430 ret
= do_parameter("registry shares", "yes", NULL
);
2435 return process_registry_service(GLOBAL_NAME
);
2438 bool process_registry_shares(void)
2442 struct smbconf_service
**service
= NULL
;
2443 uint32_t num_shares
= 0;
2444 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2445 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2448 if (conf_ctx
== NULL
) {
2452 err
= smbconf_get_config(conf_ctx
, mem_ctx
, &num_shares
, &service
);
2453 if (!SBC_ERROR_IS_OK(err
)) {
2459 for (count
= 0; count
< num_shares
; count
++) {
2460 if (strequal(service
[count
]->name
, GLOBAL_NAME
)) {
2463 ret
= process_smbconf_service(service
[count
]);
2470 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2473 TALLOC_FREE(mem_ctx
);
2478 * reload those shares from registry that are already
2479 * activated in the services array.
2481 static bool reload_registry_shares(void)
2486 for (i
= 0; i
< iNumServices
; i
++) {
2491 if (ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
2495 ret
= process_registry_service(ServicePtrs
[i
]->szService
);
2506 #define MAX_INCLUDE_DEPTH 100
2508 static uint8_t include_depth
;
2510 static struct file_lists
{
2511 struct file_lists
*next
;
2515 } *file_lists
= NULL
;
2517 /*******************************************************************
2518 Keep a linked list of all config files so we know when one has changed
2519 it's date and needs to be reloaded.
2520 ********************************************************************/
2522 static void add_to_file_list(const char *fname
, const char *subfname
)
2524 struct file_lists
*f
= file_lists
;
2527 if (f
->name
&& !strcmp(f
->name
, fname
))
2533 f
= SMB_MALLOC_P(struct file_lists
);
2536 f
->next
= file_lists
;
2537 f
->name
= SMB_STRDUP(fname
);
2542 f
->subfname
= SMB_STRDUP(subfname
);
2549 f
->modtime
= file_modtime(subfname
);
2551 time_t t
= file_modtime(subfname
);
2559 * Free the file lists
2561 static void free_file_list(void)
2563 struct file_lists
*f
;
2564 struct file_lists
*next
;
2569 SAFE_FREE( f
->name
);
2570 SAFE_FREE( f
->subfname
);
2579 * Utility function for outsiders to check if we're running on registry.
2581 bool lp_config_backend_is_registry(void)
2583 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY
);
2587 * Utility function to check if the config backend is FILE.
2589 bool lp_config_backend_is_file(void)
2591 return (lp_config_backend() == CONFIG_BACKEND_FILE
);
2594 /*******************************************************************
2595 Check if a config file has changed date.
2596 ********************************************************************/
2598 bool lp_file_list_changed(void)
2600 struct file_lists
*f
= file_lists
;
2602 DEBUG(6, ("lp_file_list_changed()\n"));
2607 if (strequal(f
->name
, INCLUDE_REGISTRY_NAME
)) {
2608 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2610 if (conf_ctx
== NULL
) {
2613 if (smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
,
2616 DEBUGADD(6, ("registry config changed\n"));
2621 n2
= talloc_sub_basic(talloc_tos(),
2622 get_current_username(),
2623 current_user_info
.domain
,
2628 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2629 f
->name
, n2
, ctime(&f
->modtime
)));
2631 mod_time
= file_modtime(n2
);
2634 ((f
->modtime
!= mod_time
) ||
2635 (f
->subfname
== NULL
) ||
2636 (strcmp(n2
, f
->subfname
) != 0)))
2639 ("file %s modified: %s\n", n2
,
2641 f
->modtime
= mod_time
;
2642 SAFE_FREE(f
->subfname
);
2643 f
->subfname
= SMB_STRDUP(n2
);
2656 * Initialize iconv conversion descriptors.
2658 * This is called the first time it is needed, and also called again
2659 * every time the configuration is reloaded, because the charset or
2660 * codepage might have changed.
2662 static void init_iconv(void)
2664 global_iconv_handle
= smb_iconv_handle_reinit(NULL
, lp_dos_charset(),
2666 true, global_iconv_handle
);
2669 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2671 if (strcmp(*ptr
, pszParmValue
) != 0) {
2672 string_set(ptr
, pszParmValue
);
2678 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2680 bool is_utf8
= false;
2681 size_t len
= strlen(pszParmValue
);
2683 if (len
== 4 || len
== 5) {
2684 /* Don't use StrCaseCmp here as we don't want to
2685 initialize iconv. */
2686 if ((toupper_m(pszParmValue
[0]) == 'U') &&
2687 (toupper_m(pszParmValue
[1]) == 'T') &&
2688 (toupper_m(pszParmValue
[2]) == 'F')) {
2690 if (pszParmValue
[3] == '8') {
2694 if (pszParmValue
[3] == '-' &&
2695 pszParmValue
[4] == '8') {
2702 if (strcmp(*ptr
, pszParmValue
) != 0) {
2704 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2705 "be UTF8, using (default value) %s instead.\n",
2706 DEFAULT_DOS_CHARSET
));
2707 pszParmValue
= DEFAULT_DOS_CHARSET
;
2709 string_set(ptr
, pszParmValue
);
2715 static bool handle_realm(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2718 TALLOC_CTX
*frame
= talloc_stackframe();
2719 char *realm
= strupper_talloc(frame
, pszParmValue
);
2720 char *dnsdomain
= strlower_talloc(realm
, pszParmValue
);
2722 ret
&= string_set(&Globals
.realm_original
, pszParmValue
);
2723 ret
&= string_set(&Globals
.realm
, realm
);
2724 ret
&= string_set(&Globals
.dnsdomain
, dnsdomain
);
2730 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2732 TALLOC_FREE(Globals
.netbios_aliases
);
2733 Globals
.netbios_aliases
= (const char **)str_list_make_v3(NULL
, pszParmValue
, NULL
);
2734 return set_netbios_aliases(Globals
.netbios_aliases
);
2737 /***************************************************************************
2738 Handle the include operation.
2739 ***************************************************************************/
2740 static bool bAllowIncludeRegistry
= true;
2742 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2746 if (include_depth
>= MAX_INCLUDE_DEPTH
) {
2747 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2752 if (strequal(pszParmValue
, INCLUDE_REGISTRY_NAME
)) {
2753 if (!bAllowIncludeRegistry
) {
2756 if (bInGlobalSection
) {
2759 ret
= process_registry_globals();
2763 DEBUG(1, ("\"include = registry\" only effective "
2764 "in %s section\n", GLOBAL_NAME
));
2769 fname
= talloc_sub_basic(talloc_tos(), get_current_username(),
2770 current_user_info
.domain
,
2773 add_to_file_list(pszParmValue
, fname
);
2775 string_set(ptr
, fname
);
2777 if (file_exist(fname
)) {
2780 ret
= pm_process(fname
, do_section
, do_parameter
, NULL
);
2786 DEBUG(2, ("Can't find include file %s\n", fname
));
2791 /***************************************************************************
2792 Handle the interpretation of the copy parameter.
2793 ***************************************************************************/
2795 static bool handle_copy(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2799 struct loadparm_service serviceTemp
;
2801 string_set(ptr
, pszParmValue
);
2803 init_service(&serviceTemp
);
2807 DEBUG(3, ("Copying service from service %s\n", pszParmValue
));
2809 if ((iTemp
= getservicebyname(pszParmValue
, &serviceTemp
)) >= 0) {
2810 if (iTemp
== iServiceIndex
) {
2811 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue
));
2813 copy_service(ServicePtrs
[iServiceIndex
],
2815 ServicePtrs
[iServiceIndex
]->copymap
);
2819 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue
));
2823 free_service(&serviceTemp
);
2827 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2829 Globals
.ldap_debug_level
= lp_int(pszParmValue
);
2830 init_ldap_debugging();
2835 * idmap related parameters
2838 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2840 lp_do_parameter(snum
, "idmap config * : backend", pszParmValue
);
2845 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2847 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
2852 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2854 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
2859 bool lp_idmap_range(const char *domain_name
, uint32_t *low
, uint32_t *high
)
2861 char *config_option
= NULL
;
2862 const char *range
= NULL
;
2865 SMB_ASSERT(low
!= NULL
);
2866 SMB_ASSERT(high
!= NULL
);
2868 if ((domain_name
== NULL
) || (domain_name
[0] == '\0')) {
2872 config_option
= talloc_asprintf(talloc_tos(), "idmap config %s",
2874 if (config_option
== NULL
) {
2875 DEBUG(0, ("out of memory\n"));
2879 range
= lp_parm_const_string(-1, config_option
, "range", NULL
);
2880 if (range
== NULL
) {
2881 DEBUG(1, ("idmap range not specified for domain '%s'\n", domain_name
));
2885 if (sscanf(range
, "%u - %u", low
, high
) != 2) {
2886 DEBUG(1, ("error parsing idmap range '%s' for domain '%s'\n",
2887 range
, domain_name
));
2894 talloc_free(config_option
);
2899 bool lp_idmap_default_range(uint32_t *low
, uint32_t *high
)
2901 return lp_idmap_range("*", low
, high
);
2904 const char *lp_idmap_backend(const char *domain_name
)
2906 char *config_option
= NULL
;
2907 const char *backend
= NULL
;
2909 if ((domain_name
== NULL
) || (domain_name
[0] == '\0')) {
2913 config_option
= talloc_asprintf(talloc_tos(), "idmap config %s",
2915 if (config_option
== NULL
) {
2916 DEBUG(0, ("out of memory\n"));
2920 backend
= lp_parm_const_string(-1, config_option
, "backend", NULL
);
2921 if (backend
== NULL
) {
2922 DEBUG(1, ("idmap backend not specified for domain '%s'\n", domain_name
));
2927 talloc_free(config_option
);
2931 const char *lp_idmap_default_backend(void)
2933 return lp_idmap_backend("*");
2936 /***************************************************************************
2937 Handle the DEBUG level list.
2938 ***************************************************************************/
2940 static bool handle_debug_list(struct loadparm_context
*unused
, int snum
, const char *pszParmValueIn
, char **ptr
)
2942 string_set(ptr
, pszParmValueIn
);
2943 return debug_parse_levels(pszParmValueIn
);
2946 /***************************************************************************
2947 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2948 ***************************************************************************/
2950 static const char *append_ldap_suffix(TALLOC_CTX
*ctx
, const char *str
)
2952 const char *suffix_string
;
2954 suffix_string
= talloc_asprintf(ctx
, "%s,%s", str
,
2955 Globals
.ldap_suffix
);
2956 if ( !suffix_string
) {
2957 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2961 return suffix_string
;
2964 const char *lp_ldap_machine_suffix(TALLOC_CTX
*ctx
)
2966 if (Globals
.szLdapMachineSuffix
[0])
2967 return append_ldap_suffix(ctx
, Globals
.szLdapMachineSuffix
);
2969 return lp_string(ctx
, Globals
.ldap_suffix
);
2972 const char *lp_ldap_user_suffix(TALLOC_CTX
*ctx
)
2974 if (Globals
.szLdapUserSuffix
[0])
2975 return append_ldap_suffix(ctx
, Globals
.szLdapUserSuffix
);
2977 return lp_string(ctx
, Globals
.ldap_suffix
);
2980 const char *lp_ldap_group_suffix(TALLOC_CTX
*ctx
)
2982 if (Globals
.szLdapGroupSuffix
[0])
2983 return append_ldap_suffix(ctx
, Globals
.szLdapGroupSuffix
);
2985 return lp_string(ctx
, Globals
.ldap_suffix
);
2988 const char *lp_ldap_idmap_suffix(TALLOC_CTX
*ctx
)
2990 if (Globals
.szLdapIdmapSuffix
[0])
2991 return append_ldap_suffix(ctx
, Globals
.szLdapIdmapSuffix
);
2993 return lp_string(ctx
, Globals
.ldap_suffix
);
2996 /****************************************************************************
2997 set the value for a P_ENUM
2998 ***************************************************************************/
3000 static void lp_set_enum_parm( struct parm_struct
*parm
, const char *pszParmValue
,
3005 for (i
= 0; parm
->enum_list
[i
].name
; i
++) {
3006 if ( strequal(pszParmValue
, parm
->enum_list
[i
].name
)) {
3007 *ptr
= parm
->enum_list
[i
].value
;
3011 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
3012 pszParmValue
, parm
->label
));
3015 /***************************************************************************
3016 ***************************************************************************/
3018 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
3020 static int parm_num
= -1;
3021 struct loadparm_service
*s
;
3023 if ( parm_num
== -1 )
3024 parm_num
= lpcfg_map_parameter( "printing" );
3026 lp_set_enum_parm( &parm_table
[parm_num
], pszParmValue
, (int*)ptr
);
3031 s
= ServicePtrs
[snum
];
3033 init_printer_values( s
);
3039 /***************************************************************************
3040 Initialise a copymap.
3041 ***************************************************************************/
3043 static void init_copymap(struct loadparm_service
*pservice
)
3047 TALLOC_FREE(pservice
->copymap
);
3049 pservice
->copymap
= bitmap_talloc(NULL
, NUMPARAMETERS
);
3050 if (!pservice
->copymap
)
3052 ("Couldn't allocate copymap!! (size %d)\n",
3053 (int)NUMPARAMETERS
));
3055 for (i
= 0; i
< NUMPARAMETERS
; i
++)
3056 bitmap_set(pservice
->copymap
, i
);
3060 return the parameter pointer for a parameter
3062 void *lp_parm_ptr(struct loadparm_service
*service
, struct parm_struct
*parm
)
3064 if (service
== NULL
) {
3065 if (parm
->p_class
== P_LOCAL
)
3066 return (void *)(((char *)&sDefault
)+parm
->offset
);
3067 else if (parm
->p_class
== P_GLOBAL
)
3068 return (void *)(((char *)&Globals
)+parm
->offset
);
3071 return (void *)(((char *)service
) + parm
->offset
);
3075 /***************************************************************************
3076 Return the local pointer to a parameter given the service number and parameter
3077 ***************************************************************************/
3079 void *lp_local_ptr_by_snum(int snum
, struct parm_struct
*parm
)
3081 return lp_parm_ptr(ServicePtrs
[snum
], parm
);
3084 /***************************************************************************
3085 Process a parameter for a particular service number. If snum < 0
3086 then assume we are in the globals.
3087 ***************************************************************************/
3089 bool lp_do_parameter(int snum
, const char *pszParmName
, const char *pszParmValue
)
3092 void *parm_ptr
= NULL
; /* where we are going to store the result */
3093 struct parmlist_entry
**opt_list
;
3095 parmnum
= lpcfg_map_parameter(pszParmName
);
3098 if (strchr(pszParmName
, ':') == NULL
) {
3099 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
3105 * We've got a parametric option
3108 opt_list
= (snum
< 0)
3109 ? &Globals
.param_opt
: &ServicePtrs
[snum
]->param_opt
;
3110 set_param_opt(opt_list
, pszParmName
, pszParmValue
, 0);
3115 /* if it's already been set by the command line, then we don't
3117 if (parm_table
[parmnum
].flags
& FLAG_CMDLINE
) {
3121 if (parm_table
[parmnum
].flags
& FLAG_DEPRECATED
) {
3122 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3126 /* we might point at a service, the default service or a global */
3128 parm_ptr
= lp_parm_ptr(NULL
, &parm_table
[parmnum
]);
3130 if (parm_table
[parmnum
].p_class
== P_GLOBAL
) {
3132 ("Global parameter %s found in service section!\n",
3136 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm_table
[parmnum
]);
3140 if (!ServicePtrs
[snum
]->copymap
)
3141 init_copymap(ServicePtrs
[snum
]);
3143 /* this handles the aliases - set the copymap for other entries with
3144 the same data pointer */
3145 for (i
= 0; parm_table
[i
].label
; i
++) {
3146 if ((parm_table
[i
].offset
== parm_table
[parmnum
].offset
)
3147 && (parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
)) {
3148 bitmap_clear(ServicePtrs
[snum
]->copymap
, i
);
3153 /* if it is a special case then go ahead */
3154 if (parm_table
[parmnum
].special
) {
3155 return parm_table
[parmnum
].special(NULL
, snum
, pszParmValue
,
3159 /* now switch on the type of variable it is */
3160 switch (parm_table
[parmnum
].type
)
3163 *(bool *)parm_ptr
= lp_bool(pszParmValue
);
3167 *(bool *)parm_ptr
= !lp_bool(pszParmValue
);
3171 *(int *)parm_ptr
= lp_int(pszParmValue
);
3175 *(char *)parm_ptr
= *pszParmValue
;
3179 i
= sscanf(pszParmValue
, "%o", (int *)parm_ptr
);
3181 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName
));
3188 if (conv_str_size_error(pszParmValue
, &val
)) {
3189 if (val
<= INT_MAX
) {
3190 *(int *)parm_ptr
= (int)val
;
3195 DEBUG(0,("lp_do_parameter(%s): value is not "
3196 "a valid size specifier!\n", pszParmValue
));
3202 TALLOC_FREE(*((char ***)parm_ptr
));
3203 *(char ***)parm_ptr
= str_list_make_v3(
3204 NULL
, pszParmValue
, NULL
);
3208 string_set((char **)parm_ptr
, pszParmValue
);
3213 char *upper_string
= strupper_talloc(talloc_tos(),
3215 string_set((char **)parm_ptr
, upper_string
);
3216 TALLOC_FREE(upper_string
);
3220 lp_set_enum_parm( &parm_table
[parmnum
], pszParmValue
, (int*)parm_ptr
);
3229 /***************************************************************************
3230 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3231 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3232 ***************************************************************************/
3234 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
)
3237 parmnum
= lpcfg_map_parameter(pszParmName
);
3239 parm_table
[parmnum
].flags
&= ~FLAG_CMDLINE
;
3240 if (!lp_do_parameter(-1, pszParmName
, pszParmValue
)) {
3243 parm_table
[parmnum
].flags
|= FLAG_CMDLINE
;
3245 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
3246 * be grouped in the table, so we don't have to search the
3249 i
>=0 && parm_table
[i
].offset
== parm_table
[parmnum
].offset
3250 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;
3252 parm_table
[i
].flags
|= FLAG_CMDLINE
;
3254 for (i
=parmnum
+1;i
<NUMPARAMETERS
&& parm_table
[i
].offset
== parm_table
[parmnum
].offset
3255 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;i
++) {
3256 parm_table
[i
].flags
|= FLAG_CMDLINE
;
3260 store_lp_set_cmdline(pszParmName
, pszParmValue
);
3265 /* it might be parametric */
3266 if (strchr(pszParmName
, ':') != NULL
) {
3267 set_param_opt(&Globals
.param_opt
, pszParmName
, pszParmValue
, FLAG_CMDLINE
);
3269 store_lp_set_cmdline(pszParmName
, pszParmValue
);
3274 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName
));
3278 bool lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
3280 return lp_set_cmdline_helper(pszParmName
, pszParmValue
, true);
3283 /***************************************************************************
3284 Process a parameter.
3285 ***************************************************************************/
3287 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
3290 if (!bInGlobalSection
&& bGlobalOnly
)
3293 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName
, pszParmValue
));
3295 return (lp_do_parameter(bInGlobalSection
? -2 : iServiceIndex
,
3296 pszParmName
, pszParmValue
));
3300 set a option from the commandline in 'a=b' format. Use to support --option
3302 bool lp_set_option(const char *option
)
3307 s
= talloc_strdup(NULL
, option
);
3320 /* skip white spaces after the = sign */
3323 } while (*p
== ' ');
3325 ret
= lp_set_cmdline(s
, p
);
3330 /***************************************************************************
3331 Initialize any local variables in the sDefault table, after parsing a
3333 ***************************************************************************/
3335 static void init_locals(void)
3338 * We run this check once the [globals] is parsed, to force
3339 * the VFS objects and other per-share settings we need for
3340 * the standard way a AD DC is operated. We may change these
3341 * as our code evolves, which is why we force these settings.
3343 * We can't do this at the end of lp_load_ex(), as by that
3344 * point the services have been loaded and they will already
3345 * have "" as their vfs objects.
3347 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
3348 const char **vfs_objects
= lp_vfs_objects(-1);
3349 if (!vfs_objects
|| !vfs_objects
[0]) {
3350 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL
)) {
3351 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3352 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL
)) {
3353 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3355 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3359 lp_do_parameter(-1, "map hidden", "no");
3360 lp_do_parameter(-1, "map system", "no");
3361 lp_do_parameter(-1, "map readonly", "no");
3362 lp_do_parameter(-1, "map archive", "no");
3363 lp_do_parameter(-1, "store dos attributes", "yes");
3367 /***************************************************************************
3368 Process a new section (service). At this stage all sections are services.
3369 Later we'll have special sections that permit server parameters to be set.
3370 Returns true on success, false on failure.
3371 ***************************************************************************/
3373 static bool do_section(const char *pszSectionName
, void *userdata
)
3376 bool isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
3377 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
3380 /* if we were in a global section then do the local inits */
3381 if (bInGlobalSection
&& !isglobal
)
3384 /* if we've just struck a global section, note the fact. */
3385 bInGlobalSection
= isglobal
;
3387 /* check for multiple global sections */
3388 if (bInGlobalSection
) {
3389 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName
));
3393 if (!bInGlobalSection
&& bGlobalOnly
)
3396 /* if we have a current service, tidy it up before moving on */
3399 if (iServiceIndex
>= 0)
3400 bRetval
= service_ok(iServiceIndex
);
3402 /* if all is still well, move to the next record in the services array */
3404 /* We put this here to avoid an odd message order if messages are */
3405 /* issued by the post-processing of a previous section. */
3406 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName
));
3408 iServiceIndex
= add_a_service(&sDefault
, pszSectionName
);
3409 if (iServiceIndex
< 0) {
3410 DEBUG(0, ("Failed to add a new service\n"));
3413 /* Clean all parametric options for service */
3414 /* They will be added during parsing again */
3415 free_param_opts(&ServicePtrs
[iServiceIndex
]->param_opt
);
3422 /***************************************************************************
3423 Determine if a partcular base parameter is currentl set to the default value.
3424 ***************************************************************************/
3426 static bool is_default(int i
)
3428 switch (parm_table
[i
].type
) {
3431 return str_list_equal((const char **)parm_table
[i
].def
.lvalue
,
3432 *(const char ***)lp_parm_ptr(NULL
,
3436 return strequal(parm_table
[i
].def
.svalue
,
3437 *(char **)lp_parm_ptr(NULL
,
3441 return parm_table
[i
].def
.bvalue
==
3442 *(bool *)lp_parm_ptr(NULL
,
3445 return parm_table
[i
].def
.cvalue
==
3446 *(char *)lp_parm_ptr(NULL
,
3452 return parm_table
[i
].def
.ivalue
==
3453 *(int *)lp_parm_ptr(NULL
,
3461 /***************************************************************************
3462 Display the contents of the global structure.
3463 ***************************************************************************/
3465 static void dump_globals(FILE *f
)
3468 struct parmlist_entry
*data
;
3470 fprintf(f
, "[global]\n");
3472 for (i
= 0; parm_table
[i
].label
; i
++)
3473 if (parm_table
[i
].p_class
== P_GLOBAL
&&
3474 !(parm_table
[i
].flags
& FLAG_META
) &&
3475 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
))) {
3476 if (defaults_saved
&& is_default(i
))
3478 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
3479 lpcfg_print_parameter(&parm_table
[i
], lp_parm_ptr(NULL
,
3484 if (Globals
.param_opt
!= NULL
) {
3485 data
= Globals
.param_opt
;
3487 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
3494 /***************************************************************************
3495 Display the contents of a single services record.
3496 ***************************************************************************/
3498 static void dump_a_service(struct loadparm_service
*pService
, FILE * f
)
3501 struct parmlist_entry
*data
;
3503 if (pService
!= &sDefault
)
3504 fprintf(f
, "[%s]\n", pService
->szService
);
3506 for (i
= 0; parm_table
[i
].label
; i
++) {
3508 if (parm_table
[i
].p_class
== P_LOCAL
&&
3509 !(parm_table
[i
].flags
& FLAG_META
) &&
3510 (*parm_table
[i
].label
!= '-') &&
3511 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
)))
3513 if (pService
== &sDefault
) {
3514 if (defaults_saved
&& is_default(i
))
3517 if (lpcfg_equal_parameter(parm_table
[i
].type
,
3518 lp_parm_ptr(pService
, &parm_table
[i
]),
3519 lp_parm_ptr(NULL
, &parm_table
[i
])))
3523 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
3524 lpcfg_print_parameter(&parm_table
[i
],
3525 lp_parm_ptr(pService
, &parm_table
[i
]),
3531 if (pService
->param_opt
!= NULL
) {
3532 data
= pService
->param_opt
;
3534 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
3540 /***************************************************************************
3541 Display the contents of a parameter of a single services record.
3542 ***************************************************************************/
3544 bool dump_a_parameter(int snum
, char *parm_name
, FILE * f
, bool isGlobal
)
3546 bool result
= false;
3547 fstring local_parm_name
;
3549 const char *parm_opt_value
;
3551 struct loadparm_context
*lp_ctx
;
3553 /* check for parametrical option */
3554 fstrcpy( local_parm_name
, parm_name
);
3555 parm_opt
= strchr( local_parm_name
, ':');
3560 if (strlen(parm_opt
)) {
3561 parm_opt_value
= lp_parm_const_string( snum
,
3562 local_parm_name
, parm_opt
, NULL
);
3563 if (parm_opt_value
) {
3564 printf( "%s\n", parm_opt_value
);
3571 lp_ctx
= loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
3572 if (lp_ctx
== NULL
) {
3577 result
= lpcfg_dump_a_parameter(lp_ctx
, NULL
, parm_name
, f
);
3579 result
= lpcfg_dump_a_parameter(lp_ctx
, ServicePtrs
[snum
], parm_name
, f
);
3581 TALLOC_FREE(lp_ctx
);
3585 /***************************************************************************
3586 Return info about the requested parameter (given as a string).
3587 Return NULL when the string is not a valid parameter name.
3588 ***************************************************************************/
3590 struct parm_struct
*lp_get_parameter(const char *param_name
)
3592 int num
= lpcfg_map_parameter(param_name
);
3598 return &parm_table
[num
];
3602 /***************************************************************************
3603 Display the contents of a single copy structure.
3604 ***************************************************************************/
3605 static void dump_copy_map(bool *pcopymap
)
3611 printf("\n\tNon-Copied parameters:\n");
3613 for (i
= 0; parm_table
[i
].label
; i
++)
3614 if (parm_table
[i
].p_class
== P_LOCAL
&&
3615 parm_table
[i
].ptr
&& !pcopymap
[i
] &&
3616 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
- 1].ptr
)))
3618 printf("\t\t%s\n", parm_table
[i
].label
);
3623 /***************************************************************************
3624 Return TRUE if the passed service number is within range.
3625 ***************************************************************************/
3627 bool lp_snum_ok(int iService
)
3629 return (LP_SNUM_OK(iService
) && ServicePtrs
[iService
]->bAvailable
);
3632 /***************************************************************************
3633 Auto-load some home services.
3634 ***************************************************************************/
3636 static void lp_add_auto_services(char *str
)
3646 s
= SMB_STRDUP(str
);
3650 homes
= lp_servicenumber(HOMES_NAME
);
3652 for (p
= strtok_r(s
, LIST_SEP
, &saveptr
); p
;
3653 p
= strtok_r(NULL
, LIST_SEP
, &saveptr
)) {
3656 if (lp_servicenumber(p
) >= 0)
3659 home
= get_user_home_dir(talloc_tos(), p
);
3661 if (home
&& home
[0] && homes
>= 0)
3662 lp_add_home(p
, homes
, p
, home
);
3669 /***************************************************************************
3670 Auto-load one printer.
3671 ***************************************************************************/
3673 void lp_add_one_printer(const char *name
, const char *comment
,
3674 const char *location
, void *pdata
)
3676 int printers
= lp_servicenumber(PRINTERS_NAME
);
3679 if (lp_servicenumber(name
) < 0) {
3680 lp_add_printer(name
, printers
);
3681 if ((i
= lp_servicenumber(name
)) >= 0) {
3682 string_set(&ServicePtrs
[i
]->comment
, comment
);
3683 ServicePtrs
[i
]->autoloaded
= true;
3688 /***************************************************************************
3689 Have we loaded a services file yet?
3690 ***************************************************************************/
3692 bool lp_loaded(void)
3697 /***************************************************************************
3698 Unload unused services.
3699 ***************************************************************************/
3701 void lp_killunused(struct smbd_server_connection
*sconn
,
3702 bool (*snumused
) (struct smbd_server_connection
*, int))
3705 for (i
= 0; i
< iNumServices
; i
++) {
3709 /* don't kill autoloaded or usershare services */
3710 if ( ServicePtrs
[i
]->autoloaded
||
3711 ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
3715 if (!snumused
|| !snumused(sconn
, i
)) {
3716 free_service_byindex(i
);
3722 * Kill all except autoloaded and usershare services - convenience wrapper
3724 void lp_kill_all_services(void)
3726 lp_killunused(NULL
, NULL
);
3729 /***************************************************************************
3731 ***************************************************************************/
3733 void lp_killservice(int iServiceIn
)
3735 if (VALID(iServiceIn
)) {
3736 free_service_byindex(iServiceIn
);
3740 /***************************************************************************
3741 Save the curent values of all global and sDefault parameters into the
3742 defaults union. This allows testparm to show only the
3743 changed (ie. non-default) parameters.
3744 ***************************************************************************/
3746 static void lp_save_defaults(void)
3749 for (i
= 0; parm_table
[i
].label
; i
++) {
3750 if (i
> 0 && parm_table
[i
].offset
== parm_table
[i
- 1].offset
3751 && parm_table
[i
].p_class
== parm_table
[i
- 1].p_class
)
3753 switch (parm_table
[i
].type
) {
3756 parm_table
[i
].def
.lvalue
= str_list_copy(
3757 NULL
, *(const char ***)lp_parm_ptr(NULL
, &parm_table
[i
]));
3761 parm_table
[i
].def
.svalue
= SMB_STRDUP(*(char **)lp_parm_ptr(NULL
, &parm_table
[i
]));
3765 parm_table
[i
].def
.bvalue
=
3766 *(bool *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3769 parm_table
[i
].def
.cvalue
=
3770 *(char *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3776 parm_table
[i
].def
.ivalue
=
3777 *(int *)lp_parm_ptr(NULL
, &parm_table
[i
]);
3783 defaults_saved
= true;
3786 /***********************************************************
3787 If we should send plaintext/LANMAN passwords in the clinet
3788 ************************************************************/
3790 static void set_allowed_client_auth(void)
3792 if (Globals
.client_ntlmv2_auth
) {
3793 Globals
.client_lanman_auth
= false;
3795 if (!Globals
.client_lanman_auth
) {
3796 Globals
.client_plaintext_auth
= false;
3800 /***************************************************************************
3802 The following code allows smbd to read a user defined share file.
3803 Yes, this is my intent. Yes, I'm comfortable with that...
3805 THE FOLLOWING IS SECURITY CRITICAL CODE.
3807 It washes your clothes, it cleans your house, it guards you while you sleep...
3808 Do not f%^k with it....
3809 ***************************************************************************/
3811 #define MAX_USERSHARE_FILE_SIZE (10*1024)
3813 /***************************************************************************
3814 Check allowed stat state of a usershare file.
3815 Ensure we print out who is dicking with us so the admin can
3816 get their sorry ass fired.
3817 ***************************************************************************/
3819 static bool check_usershare_stat(const char *fname
,
3820 const SMB_STRUCT_STAT
*psbuf
)
3822 if (!S_ISREG(psbuf
->st_ex_mode
)) {
3823 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3824 "not a regular file\n",
3825 fname
, (unsigned int)psbuf
->st_ex_uid
));
3829 /* Ensure this doesn't have the other write bit set. */
3830 if (psbuf
->st_ex_mode
& S_IWOTH
) {
3831 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
3832 "public write. Refusing to allow as a usershare file.\n",
3833 fname
, (unsigned int)psbuf
->st_ex_uid
));
3837 /* Should be 10k or less. */
3838 if (psbuf
->st_ex_size
> MAX_USERSHARE_FILE_SIZE
) {
3839 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
3840 "too large (%u) to be a user share file.\n",
3841 fname
, (unsigned int)psbuf
->st_ex_uid
,
3842 (unsigned int)psbuf
->st_ex_size
));
3849 /***************************************************************************
3850 Parse the contents of a usershare file.
3851 ***************************************************************************/
3853 enum usershare_err
parse_usershare_file(TALLOC_CTX
*ctx
,
3854 SMB_STRUCT_STAT
*psbuf
,
3855 const char *servicename
,
3859 char **pp_sharepath
,
3861 char **pp_cp_servicename
,
3862 struct security_descriptor
**ppsd
,
3865 const char **prefixallowlist
= lp_usershare_prefix_allow_list();
3866 const char **prefixdenylist
= lp_usershare_prefix_deny_list();
3869 SMB_STRUCT_STAT sbuf
;
3870 char *sharepath
= NULL
;
3871 char *comment
= NULL
;
3873 *pp_sharepath
= NULL
;
3876 *pallow_guest
= false;
3879 return USERSHARE_MALFORMED_FILE
;
3882 if (strcmp(lines
[0], "#VERSION 1") == 0) {
3884 } else if (strcmp(lines
[0], "#VERSION 2") == 0) {
3887 return USERSHARE_MALFORMED_FILE
;
3890 return USERSHARE_BAD_VERSION
;
3893 if (strncmp(lines
[1], "path=", 5) != 0) {
3894 return USERSHARE_MALFORMED_PATH
;
3897 sharepath
= talloc_strdup(ctx
, &lines
[1][5]);
3899 return USERSHARE_POSIX_ERR
;
3901 trim_string(sharepath
, " ", " ");
3903 if (strncmp(lines
[2], "comment=", 8) != 0) {
3904 return USERSHARE_MALFORMED_COMMENT_DEF
;
3907 comment
= talloc_strdup(ctx
, &lines
[2][8]);
3909 return USERSHARE_POSIX_ERR
;
3911 trim_string(comment
, " ", " ");
3912 trim_char(comment
, '"', '"');
3914 if (strncmp(lines
[3], "usershare_acl=", 14) != 0) {
3915 return USERSHARE_MALFORMED_ACL_DEF
;
3918 if (!parse_usershare_acl(ctx
, &lines
[3][14], ppsd
)) {
3919 return USERSHARE_ACL_ERR
;
3923 if (strncmp(lines
[4], "guest_ok=", 9) != 0) {
3924 return USERSHARE_MALFORMED_ACL_DEF
;
3926 if (lines
[4][9] == 'y') {
3927 *pallow_guest
= true;
3930 /* Backwards compatible extension to file version #2. */
3932 if (strncmp(lines
[5], "sharename=", 10) != 0) {
3933 return USERSHARE_MALFORMED_SHARENAME_DEF
;
3935 if (!strequal(&lines
[5][10], servicename
)) {
3936 return USERSHARE_BAD_SHARENAME
;
3938 *pp_cp_servicename
= talloc_strdup(ctx
, &lines
[5][10]);
3939 if (!*pp_cp_servicename
) {
3940 return USERSHARE_POSIX_ERR
;
3945 if (*pp_cp_servicename
== NULL
) {
3946 *pp_cp_servicename
= talloc_strdup(ctx
, servicename
);
3947 if (!*pp_cp_servicename
) {
3948 return USERSHARE_POSIX_ERR
;
3952 if (snum
!= -1 && (strcmp(sharepath
, ServicePtrs
[snum
]->path
) == 0)) {
3953 /* Path didn't change, no checks needed. */
3954 *pp_sharepath
= sharepath
;
3955 *pp_comment
= comment
;
3956 return USERSHARE_OK
;
3959 /* The path *must* be absolute. */
3960 if (sharepath
[0] != '/') {
3961 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
3962 servicename
, sharepath
));
3963 return USERSHARE_PATH_NOT_ABSOLUTE
;
3966 /* If there is a usershare prefix deny list ensure one of these paths
3967 doesn't match the start of the user given path. */
3968 if (prefixdenylist
) {
3970 for ( i
=0; prefixdenylist
[i
]; i
++ ) {
3971 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
3972 servicename
, i
, prefixdenylist
[i
], sharepath
));
3973 if (memcmp( sharepath
, prefixdenylist
[i
], strlen(prefixdenylist
[i
])) == 0) {
3974 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
3975 "usershare prefix deny list entries.\n",
3976 servicename
, sharepath
));
3977 return USERSHARE_PATH_IS_DENIED
;
3982 /* If there is a usershare prefix allow list ensure one of these paths
3983 does match the start of the user given path. */
3985 if (prefixallowlist
) {
3987 for ( i
=0; prefixallowlist
[i
]; i
++ ) {
3988 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
3989 servicename
, i
, prefixallowlist
[i
], sharepath
));
3990 if (memcmp( sharepath
, prefixallowlist
[i
], strlen(prefixallowlist
[i
])) == 0) {
3994 if (prefixallowlist
[i
] == NULL
) {
3995 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
3996 "usershare prefix allow list entries.\n",
3997 servicename
, sharepath
));
3998 return USERSHARE_PATH_NOT_ALLOWED
;
4002 /* Ensure this is pointing to a directory. */
4003 dp
= opendir(sharepath
);
4006 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4007 servicename
, sharepath
));
4008 return USERSHARE_PATH_NOT_DIRECTORY
;
4011 /* Ensure the owner of the usershare file has permission to share
4014 if (sys_stat(sharepath
, &sbuf
, false) == -1) {
4015 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4016 servicename
, sharepath
, strerror(errno
) ));
4018 return USERSHARE_POSIX_ERR
;
4023 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
4024 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4025 servicename
, sharepath
));
4026 return USERSHARE_PATH_NOT_DIRECTORY
;
4029 /* Check if sharing is restricted to owner-only. */
4030 /* psbuf is the stat of the usershare definition file,
4031 sbuf is the stat of the target directory to be shared. */
4033 if (lp_usershare_owner_only()) {
4034 /* root can share anything. */
4035 if ((psbuf
->st_ex_uid
!= 0) && (sbuf
.st_ex_uid
!= psbuf
->st_ex_uid
)) {
4036 return USERSHARE_PATH_NOT_ALLOWED
;
4040 *pp_sharepath
= sharepath
;
4041 *pp_comment
= comment
;
4042 return USERSHARE_OK
;
4045 /***************************************************************************
4046 Deal with a usershare file.
4049 -1 - Bad name, invalid contents.
4050 - service name already existed and not a usershare, problem
4051 with permissions to share directory etc.
4052 ***************************************************************************/
4054 static int process_usershare_file(const char *dir_name
, const char *file_name
, int snum_template
)
4056 SMB_STRUCT_STAT sbuf
;
4057 SMB_STRUCT_STAT lsbuf
;
4059 char *sharepath
= NULL
;
4060 char *comment
= NULL
;
4061 char *cp_service_name
= NULL
;
4062 char **lines
= NULL
;
4066 TALLOC_CTX
*ctx
= talloc_stackframe();
4067 struct security_descriptor
*psd
= NULL
;
4068 bool guest_ok
= false;
4069 char *canon_name
= NULL
;
4070 bool added_service
= false;
4073 /* Ensure share name doesn't contain invalid characters. */
4074 if (!validate_net_name(file_name
, INVALID_SHARENAME_CHARS
, strlen(file_name
))) {
4075 DEBUG(0,("process_usershare_file: share name %s contains "
4076 "invalid characters (any of %s)\n",
4077 file_name
, INVALID_SHARENAME_CHARS
));
4081 canon_name
= canonicalize_servicename(ctx
, file_name
);
4086 fname
= talloc_asprintf(ctx
, "%s/%s", dir_name
, file_name
);
4091 /* Minimize the race condition by doing an lstat before we
4092 open and fstat. Ensure this isn't a symlink link. */
4094 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
4095 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4096 fname
, strerror(errno
) ));
4100 /* This must be a regular file, not a symlink, directory or
4101 other strange filetype. */
4102 if (!check_usershare_stat(fname
, &lsbuf
)) {
4110 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
,
4115 if (NT_STATUS_IS_OK(status
) &&
4116 (data
.dptr
!= NULL
) &&
4117 (data
.dsize
== sizeof(iService
))) {
4118 memcpy(&iService
, data
.dptr
, sizeof(iService
));
4122 if (iService
!= -1 &&
4123 timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
4124 &lsbuf
.st_ex_mtime
) == 0) {
4125 /* Nothing changed - Mark valid and return. */
4126 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4128 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
4133 /* Try and open the file read only - no symlinks allowed. */
4135 fd
= open(fname
, O_RDONLY
|O_NOFOLLOW
, 0);
4137 fd
= open(fname
, O_RDONLY
, 0);
4141 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4142 fname
, strerror(errno
) ));
4146 /* Now fstat to be *SURE* it's a regular file. */
4147 if (sys_fstat(fd
, &sbuf
, false) != 0) {
4149 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4150 fname
, strerror(errno
) ));
4154 /* Is it the same dev/inode as was lstated ? */
4155 if (!check_same_stat(&lsbuf
, &sbuf
)) {
4157 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4158 "Symlink spoofing going on ?\n", fname
));
4162 /* This must be a regular file, not a symlink, directory or
4163 other strange filetype. */
4164 if (!check_usershare_stat(fname
, &sbuf
)) {
4169 lines
= fd_lines_load(fd
, &numlines
, MAX_USERSHARE_FILE_SIZE
, NULL
);
4172 if (lines
== NULL
) {
4173 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4174 fname
, (unsigned int)sbuf
.st_ex_uid
));
4178 if (parse_usershare_file(ctx
, &sbuf
, file_name
,
4179 iService
, lines
, numlines
, &sharepath
,
4180 &comment
, &cp_service_name
,
4181 &psd
, &guest_ok
) != USERSHARE_OK
) {
4185 /* Everything ok - add the service possibly using a template. */
4187 const struct loadparm_service
*sp
= &sDefault
;
4188 if (snum_template
!= -1) {
4189 sp
= ServicePtrs
[snum_template
];
4192 if ((iService
= add_a_service(sp
, cp_service_name
)) < 0) {
4193 DEBUG(0, ("process_usershare_file: Failed to add "
4194 "new service %s\n", cp_service_name
));
4198 added_service
= true;
4200 /* Read only is controlled by usershare ACL below. */
4201 ServicePtrs
[iService
]->read_only
= false;
4204 /* Write the ACL of the new/modified share. */
4205 if (!set_share_security(canon_name
, psd
)) {
4206 DEBUG(0, ("process_usershare_file: Failed to set share "
4207 "security for user share %s\n",
4212 /* If from a template it may be marked invalid. */
4213 ServicePtrs
[iService
]->valid
= true;
4215 /* Set the service as a valid usershare. */
4216 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
4218 /* Set guest access. */
4219 if (lp_usershare_allow_guests()) {
4220 ServicePtrs
[iService
]->guest_ok
= guest_ok
;
4223 /* And note when it was loaded. */
4224 ServicePtrs
[iService
]->usershare_last_mod
= sbuf
.st_ex_mtime
;
4225 string_set(&ServicePtrs
[iService
]->path
, sharepath
);
4226 string_set(&ServicePtrs
[iService
]->comment
, comment
);
4232 if (ret
== -1 && iService
!= -1 && added_service
) {
4233 lp_remove_service(iService
);
4241 /***************************************************************************
4242 Checks if a usershare entry has been modified since last load.
4243 ***************************************************************************/
4245 static bool usershare_exists(int iService
, struct timespec
*last_mod
)
4247 SMB_STRUCT_STAT lsbuf
;
4248 const char *usersharepath
= Globals
.usershare_path
;
4251 if (asprintf(&fname
, "%s/%s",
4253 ServicePtrs
[iService
]->szService
) < 0) {
4257 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
4262 if (!S_ISREG(lsbuf
.st_ex_mode
)) {
4268 *last_mod
= lsbuf
.st_ex_mtime
;
4272 /***************************************************************************
4273 Load a usershare service by name. Returns a valid servicenumber or -1.
4274 ***************************************************************************/
4276 int load_usershare_service(const char *servicename
)
4278 SMB_STRUCT_STAT sbuf
;
4279 const char *usersharepath
= Globals
.usershare_path
;
4280 int max_user_shares
= Globals
.usershare_max_shares
;
4281 int snum_template
= -1;
4283 if (*usersharepath
== 0 || max_user_shares
== 0) {
4287 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
4288 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4289 usersharepath
, strerror(errno
) ));
4293 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
4294 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4300 * This directory must be owned by root, and have the 't' bit set.
4301 * It also must not be writable by "other".
4305 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4307 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4309 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4310 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4315 /* Ensure the template share exists if it's set. */
4316 if (Globals
.usershare_template_share
[0]) {
4317 /* We can't use lp_servicenumber here as we are recommending that
4318 template shares have -valid=false set. */
4319 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
4320 if (ServicePtrs
[snum_template
]->szService
&&
4321 strequal(ServicePtrs
[snum_template
]->szService
,
4322 Globals
.usershare_template_share
)) {
4327 if (snum_template
== -1) {
4328 DEBUG(0,("load_usershare_service: usershare template share %s "
4329 "does not exist.\n",
4330 Globals
.usershare_template_share
));
4335 return process_usershare_file(usersharepath
, servicename
, snum_template
);
4338 /***************************************************************************
4339 Load all user defined shares from the user share directory.
4340 We only do this if we're enumerating the share list.
4341 This is the function that can delete usershares that have
4343 ***************************************************************************/
4345 int load_usershare_shares(struct smbd_server_connection
*sconn
,
4346 bool (*snumused
) (struct smbd_server_connection
*, int))
4349 SMB_STRUCT_STAT sbuf
;
4351 int num_usershares
= 0;
4352 int max_user_shares
= Globals
.usershare_max_shares
;
4353 unsigned int num_dir_entries
, num_bad_dir_entries
, num_tmp_dir_entries
;
4354 unsigned int allowed_bad_entries
= ((2*max_user_shares
)/10);
4355 unsigned int allowed_tmp_entries
= ((2*max_user_shares
)/10);
4357 int snum_template
= -1;
4358 const char *usersharepath
= Globals
.usershare_path
;
4359 int ret
= lp_numservices();
4360 TALLOC_CTX
*tmp_ctx
;
4362 if (max_user_shares
== 0 || *usersharepath
== '\0') {
4363 return lp_numservices();
4366 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
4367 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4368 usersharepath
, strerror(errno
) ));
4373 * This directory must be owned by root, and have the 't' bit set.
4374 * It also must not be writable by "other".
4378 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4380 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4382 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4383 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4388 /* Ensure the template share exists if it's set. */
4389 if (Globals
.usershare_template_share
[0]) {
4390 /* We can't use lp_servicenumber here as we are recommending that
4391 template shares have -valid=false set. */
4392 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
4393 if (ServicePtrs
[snum_template
]->szService
&&
4394 strequal(ServicePtrs
[snum_template
]->szService
,
4395 Globals
.usershare_template_share
)) {
4400 if (snum_template
== -1) {
4401 DEBUG(0,("load_usershare_shares: usershare template share %s "
4402 "does not exist.\n",
4403 Globals
.usershare_template_share
));
4408 /* Mark all existing usershares as pending delete. */
4409 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4410 if (VALID(iService
) && ServicePtrs
[iService
]->usershare
) {
4411 ServicePtrs
[iService
]->usershare
= USERSHARE_PENDING_DELETE
;
4415 dp
= opendir(usersharepath
);
4417 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4418 usersharepath
, strerror(errno
) ));
4422 for (num_dir_entries
= 0, num_bad_dir_entries
= 0, num_tmp_dir_entries
= 0;
4424 num_dir_entries
++ ) {
4426 const char *n
= de
->d_name
;
4428 /* Ignore . and .. */
4430 if ((n
[1] == '\0') || (n
[1] == '.' && n
[2] == '\0')) {
4436 /* Temporary file used when creating a share. */
4437 num_tmp_dir_entries
++;
4440 /* Allow 20% tmp entries. */
4441 if (num_tmp_dir_entries
> allowed_tmp_entries
) {
4442 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4443 "in directory %s\n",
4444 num_tmp_dir_entries
, usersharepath
));
4448 r
= process_usershare_file(usersharepath
, n
, snum_template
);
4450 /* Update the services count. */
4452 if (num_usershares
>= max_user_shares
) {
4453 DEBUG(0,("load_usershare_shares: max user shares reached "
4454 "on file %s in directory %s\n",
4455 n
, usersharepath
));
4458 } else if (r
== -1) {
4459 num_bad_dir_entries
++;
4462 /* Allow 20% bad entries. */
4463 if (num_bad_dir_entries
> allowed_bad_entries
) {
4464 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4465 "in directory %s\n",
4466 num_bad_dir_entries
, usersharepath
));
4470 /* Allow 20% bad entries. */
4471 if (num_dir_entries
> max_user_shares
+ allowed_bad_entries
) {
4472 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4473 "in directory %s\n",
4474 num_dir_entries
, usersharepath
));
4481 /* Sweep through and delete any non-refreshed usershares that are
4482 not currently in use. */
4483 tmp_ctx
= talloc_stackframe();
4484 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4485 if (VALID(iService
) && (ServicePtrs
[iService
]->usershare
== USERSHARE_PENDING_DELETE
)) {
4488 if (snumused
&& snumused(sconn
, iService
)) {
4492 servname
= lp_servicename(tmp_ctx
, iService
);
4494 /* Remove from the share ACL db. */
4495 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4497 delete_share_security(servname
);
4498 free_service_byindex(iService
);
4501 talloc_free(tmp_ctx
);
4503 return lp_numservices();
4506 /********************************************************
4507 Destroy global resources allocated in this file
4508 ********************************************************/
4510 void gfree_loadparm(void)
4516 /* Free resources allocated to services */
4518 for ( i
= 0; i
< iNumServices
; i
++ ) {
4520 free_service_byindex(i
);
4524 SAFE_FREE( ServicePtrs
);
4527 /* Now release all resources allocated to global
4528 parameters and the default service */
4530 free_global_parameters();
4534 /***************************************************************************
4535 Allow client apps to specify that they are a client
4536 ***************************************************************************/
4537 static void lp_set_in_client(bool b
)
4543 /***************************************************************************
4544 Determine if we're running in a client app
4545 ***************************************************************************/
4546 static bool lp_is_in_client(void)
4551 /***************************************************************************
4552 Load the services array from the services file. Return true on success,
4554 ***************************************************************************/
4556 static bool lp_load_ex(const char *pszFname
,
4560 bool initialize_globals
,
4561 bool allow_include_registry
,
4562 bool load_all_shares
)
4569 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4571 bInGlobalSection
= true;
4572 bGlobalOnly
= global_only
;
4573 bAllowIncludeRegistry
= allow_include_registry
;
4575 init_globals(initialize_globals
);
4579 if (save_defaults
) {
4584 if (!initialize_globals
) {
4585 free_param_opts(&Globals
.param_opt
);
4586 apply_lp_set_cmdline();
4589 lp_do_parameter(-1, "idmap config * : backend", Globals
.szIdmapBackend
);
4591 /* We get sections first, so have to start 'behind' to make up */
4594 if (lp_config_backend_is_file()) {
4595 n2
= talloc_sub_basic(talloc_tos(), get_current_username(),
4596 current_user_info
.domain
,
4599 smb_panic("lp_load_ex: out of memory");
4602 add_to_file_list(pszFname
, n2
);
4604 bRetval
= pm_process(n2
, do_section
, do_parameter
, NULL
);
4607 /* finish up the last section */
4608 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval
)));
4610 if (iServiceIndex
>= 0) {
4611 bRetval
= service_ok(iServiceIndex
);
4615 if (lp_config_backend_is_registry()) {
4616 /* config backend changed to registry in config file */
4618 * We need to use this extra global variable here to
4619 * survive restart: init_globals uses this as a default
4620 * for config_backend. Otherwise, init_globals would
4621 * send us into an endless loop here.
4623 config_backend
= CONFIG_BACKEND_REGISTRY
;
4625 DEBUG(1, ("lp_load_ex: changing to config backend "
4628 lp_kill_all_services();
4629 return lp_load_ex(pszFname
, global_only
, save_defaults
,
4630 add_ipc
, initialize_globals
,
4631 allow_include_registry
,
4634 } else if (lp_config_backend_is_registry()) {
4635 bRetval
= process_registry_globals();
4637 DEBUG(0, ("Illegal config backend given: %d\n",
4638 lp_config_backend()));
4642 if (bRetval
&& lp_registry_shares()) {
4643 if (load_all_shares
) {
4644 bRetval
= process_registry_shares();
4646 bRetval
= reload_registry_shares();
4651 char *serv
= lp_auto_services(talloc_tos());
4652 lp_add_auto_services(serv
);
4657 /* When 'restrict anonymous = 2' guest connections to ipc$
4659 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4660 if ( lp_enable_asu_support() ) {
4661 lp_add_ipc("ADMIN$", false);
4665 set_allowed_client_auth();
4667 if (lp_security() == SEC_ADS
&& strchr(lp_password_server(), ':')) {
4668 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4669 lp_password_server()));
4674 /* Now we check we_are_a_wins_server and set szWINSserver to 127.0.0.1 */
4675 /* if we_are_a_wins_server is true and we are in the client */
4676 if (lp_is_in_client() && Globals
.we_are_a_wins_server
) {
4677 lp_do_parameter(GLOBAL_SECTION_SNUM
, "wins server", "127.0.0.1");
4682 fault_configure(smb_panic_s3
);
4685 * We run this check once the whole smb.conf is parsed, to
4686 * force some settings for the standard way a AD DC is
4687 * operated. We may changed these as our code evolves, which
4688 * is why we force these settings.
4690 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
4691 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4693 lp_do_parameter(-1, "rpc_server:default", "external");
4694 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4695 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4696 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4697 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4698 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4699 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4700 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4701 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4704 bAllowIncludeRegistry
= true;
4709 bool lp_load(const char *pszFname
,
4713 bool initialize_globals
)
4715 return lp_load_ex(pszFname
,
4720 true, /* allow_include_registry */
4721 false); /* load_all_shares*/
4724 bool lp_load_initial_only(const char *pszFname
)
4726 return lp_load_ex(pszFname
,
4727 true, /* global only */
4728 false, /* save_defaults */
4729 false, /* add_ipc */
4730 true, /* initialize_globals */
4731 false, /* allow_include_registry */
4732 false); /* load_all_shares*/
4736 * most common lp_load wrapper, loading only the globals
4738 bool lp_load_global(const char *file_name
)
4740 return lp_load_ex(file_name
,
4741 true, /* global_only */
4742 false, /* save_defaults */
4743 false, /* add_ipc */
4744 true, /* initialize_globals */
4745 true, /* allow_include_registry */
4746 false); /* load_all_shares*/
4750 * lp_load wrapper, especially for clients
4752 bool lp_load_client(const char *file_name
)
4754 lp_set_in_client(true);
4756 return lp_load_global(file_name
);
4760 * lp_load wrapper, loading only globals, but intended
4761 * for subsequent calls, not reinitializing the globals
4764 bool lp_load_global_no_reinit(const char *file_name
)
4766 return lp_load_ex(file_name
,
4767 true, /* global_only */
4768 false, /* save_defaults */
4769 false, /* add_ipc */
4770 false, /* initialize_globals */
4771 true, /* allow_include_registry */
4772 false); /* load_all_shares*/
4776 * lp_load wrapper, especially for clients, no reinitialization
4778 bool lp_load_client_no_reinit(const char *file_name
)
4780 lp_set_in_client(true);
4782 return lp_load_global_no_reinit(file_name
);
4785 bool lp_load_with_registry_shares(const char *pszFname
,
4789 bool initialize_globals
)
4791 return lp_load_ex(pszFname
,
4796 true, /* allow_include_registry */
4797 true); /* load_all_shares*/
4800 /***************************************************************************
4801 Return the max number of services.
4802 ***************************************************************************/
4804 int lp_numservices(void)
4806 return (iNumServices
);
4809 /***************************************************************************
4810 Display the contents of the services array in human-readable form.
4811 ***************************************************************************/
4813 void lp_dump(FILE *f
, bool show_defaults
, int maxtoprint
)
4818 defaults_saved
= false;
4822 dump_a_service(&sDefault
, f
);
4824 for (iService
= 0; iService
< maxtoprint
; iService
++) {
4826 lp_dump_one(f
, show_defaults
, iService
);
4830 /***************************************************************************
4831 Display the contents of one service in human-readable form.
4832 ***************************************************************************/
4834 void lp_dump_one(FILE * f
, bool show_defaults
, int snum
)
4837 if (ServicePtrs
[snum
]->szService
[0] == '\0')
4839 dump_a_service(ServicePtrs
[snum
], f
);
4843 /***************************************************************************
4844 Return the number of the service with the given name, or -1 if it doesn't
4845 exist. Note that this is a DIFFERENT ANIMAL from the internal function
4846 getservicebyname()! This works ONLY if all services have been loaded, and
4847 does not copy the found service.
4848 ***************************************************************************/
4850 int lp_servicenumber(const char *pszServiceName
)
4853 fstring serviceName
;
4855 if (!pszServiceName
) {
4856 return GLOBAL_SECTION_SNUM
;
4859 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4860 if (VALID(iService
) && ServicePtrs
[iService
]->szService
) {
4862 * The substitution here is used to support %U is
4865 fstrcpy(serviceName
, ServicePtrs
[iService
]->szService
);
4866 standard_sub_basic(get_current_username(),
4867 current_user_info
.domain
,
4868 serviceName
,sizeof(serviceName
));
4869 if (strequal(serviceName
, pszServiceName
)) {
4875 if (iService
>= 0 && ServicePtrs
[iService
]->usershare
== USERSHARE_VALID
) {
4876 struct timespec last_mod
;
4878 if (!usershare_exists(iService
, &last_mod
)) {
4879 /* Remove the share security tdb entry for it. */
4880 delete_share_security(lp_servicename(talloc_tos(), iService
));
4881 /* Remove it from the array. */
4882 free_service_byindex(iService
);
4883 /* Doesn't exist anymore. */
4884 return GLOBAL_SECTION_SNUM
;
4887 /* Has it been modified ? If so delete and reload. */
4888 if (timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
4890 /* Remove it from the array. */
4891 free_service_byindex(iService
);
4892 /* and now reload it. */
4893 iService
= load_usershare_service(pszServiceName
);
4898 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName
));
4899 return GLOBAL_SECTION_SNUM
;
4905 /*******************************************************************
4906 A useful volume label function.
4907 ********************************************************************/
4909 const char *volume_label(TALLOC_CTX
*ctx
, int snum
)
4912 const char *label
= lp_volume(ctx
, snum
);
4914 label
= lp_servicename(ctx
, snum
);
4917 /* This returns a 33 byte guarenteed null terminated string. */
4918 ret
= talloc_strndup(ctx
, label
, 32);
4925 /*******************************************************************
4926 Get the default server type we will announce as via nmbd.
4927 ********************************************************************/
4929 int lp_default_server_announce(void)
4931 int default_server_announce
= 0;
4932 default_server_announce
|= SV_TYPE_WORKSTATION
;
4933 default_server_announce
|= SV_TYPE_SERVER
;
4934 default_server_announce
|= SV_TYPE_SERVER_UNIX
;
4936 /* note that the flag should be set only if we have a
4937 printer service but nmbd doesn't actually load the
4938 services so we can't tell --jerry */
4940 default_server_announce
|= SV_TYPE_PRINTQ_SERVER
;
4942 default_server_announce
|= SV_TYPE_SERVER_NT
;
4943 default_server_announce
|= SV_TYPE_NT
;
4945 switch (lp_server_role()) {
4946 case ROLE_DOMAIN_MEMBER
:
4947 default_server_announce
|= SV_TYPE_DOMAIN_MEMBER
;
4949 case ROLE_DOMAIN_PDC
:
4950 default_server_announce
|= SV_TYPE_DOMAIN_CTRL
;
4952 case ROLE_DOMAIN_BDC
:
4953 default_server_announce
|= SV_TYPE_DOMAIN_BAKCTRL
;
4955 case ROLE_STANDALONE
:
4959 if (lp_time_server())
4960 default_server_announce
|= SV_TYPE_TIME_SOURCE
;
4962 if (lp_host_msdfs())
4963 default_server_announce
|= SV_TYPE_DFS_SERVER
;
4965 return default_server_announce
;
4968 /***********************************************************
4969 If we are PDC then prefer us as DMB
4970 ************************************************************/
4972 bool lp_domain_master(void)
4974 if (Globals
._domain_master
== Auto
)
4975 return (lp_server_role() == ROLE_DOMAIN_PDC
);
4977 return (bool)Globals
._domain_master
;
4980 /***********************************************************
4981 If we are PDC then prefer us as DMB
4982 ************************************************************/
4984 static bool lp_domain_master_true_or_auto(void)
4986 if (Globals
._domain_master
) /* auto or yes */
4992 /***********************************************************
4993 If we are DMB then prefer us as LMB
4994 ************************************************************/
4996 bool lp_preferred_master(void)
4998 if (Globals
.iPreferredMaster
== Auto
)
4999 return (lp_local_master() && lp_domain_master());
5001 return (bool)Globals
.iPreferredMaster
;
5004 /*******************************************************************
5006 ********************************************************************/
5008 void lp_remove_service(int snum
)
5010 ServicePtrs
[snum
]->valid
= false;
5013 /*******************************************************************
5015 ********************************************************************/
5017 void lp_copy_service(int snum
, const char *new_name
)
5019 do_section(new_name
, NULL
);
5021 snum
= lp_servicenumber(new_name
);
5023 char *name
= lp_servicename(talloc_tos(), snum
);
5024 lp_do_parameter(snum
, "copy", name
);
5029 const char *lp_printername(TALLOC_CTX
*ctx
, int snum
)
5031 const char *ret
= lp__printername(ctx
, snum
);
5032 if (ret
== NULL
|| *ret
== '\0') {
5033 ret
= lp_const_servicename(snum
);
5040 /***********************************************************
5041 Allow daemons such as winbindd to fix their logfile name.
5042 ************************************************************/
5044 void lp_set_logfile(const char *name
)
5046 string_set(&Globals
.logfile
, name
);
5047 debug_set_logfile(name
);
5050 /*******************************************************************
5051 Return the max print jobs per queue.
5052 ********************************************************************/
5054 int lp_maxprintjobs(int snum
)
5056 int maxjobs
= LP_SNUM_OK(snum
) ? ServicePtrs
[snum
]->iMaxPrintJobs
: sDefault
.iMaxPrintJobs
;
5057 if (maxjobs
<= 0 || maxjobs
>= PRINT_MAX_JOBID
)
5058 maxjobs
= PRINT_MAX_JOBID
- 1;
5063 const char *lp_printcapname(void)
5065 if ((Globals
.szPrintcapname
!= NULL
) &&
5066 (Globals
.szPrintcapname
[0] != '\0'))
5067 return Globals
.szPrintcapname
;
5069 if (sDefault
.printing
== PRINT_CUPS
) {
5073 if (sDefault
.printing
== PRINT_BSD
)
5074 return "/etc/printcap";
5076 return PRINTCAP_NAME
;
5079 static uint32 spoolss_state
;
5081 bool lp_disable_spoolss( void )
5083 if ( spoolss_state
== SVCCTL_STATE_UNKNOWN
)
5084 spoolss_state
= lp__disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
5086 return spoolss_state
== SVCCTL_STOPPED
? true : false;
5089 void lp_set_spoolss_state( uint32 state
)
5091 SMB_ASSERT( (state
== SVCCTL_STOPPED
) || (state
== SVCCTL_RUNNING
) );
5093 spoolss_state
= state
;
5096 uint32
lp_get_spoolss_state( void )
5098 return lp_disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
5101 /*******************************************************************
5102 Ensure we don't use sendfile if server smb signing is active.
5103 ********************************************************************/
5105 bool lp_use_sendfile(int snum
, struct smb_signing_state
*signing_state
)
5107 bool sign_active
= false;
5109 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5110 if (get_Protocol() < PROTOCOL_NT1
) {
5113 if (signing_state
) {
5114 sign_active
= smb_signing_is_active(signing_state
);
5116 return (lp__use_sendfile(snum
) &&
5117 (get_remote_arch() != RA_WIN95
) &&
5121 /*******************************************************************
5122 Turn off sendfile if we find the underlying OS doesn't support it.
5123 ********************************************************************/
5125 void set_use_sendfile(int snum
, bool val
)
5127 if (LP_SNUM_OK(snum
))
5128 ServicePtrs
[snum
]->_use_sendfile
= val
;
5130 sDefault
._use_sendfile
= val
;
5133 /*******************************************************************
5134 Turn off storing DOS attributes if this share doesn't support it.
5135 ********************************************************************/
5137 void set_store_dos_attributes(int snum
, bool val
)
5139 if (!LP_SNUM_OK(snum
))
5141 ServicePtrs
[(snum
)]->store_dos_attributes
= val
;
5144 void lp_set_mangling_method(const char *new_method
)
5146 string_set(&Globals
.mangling_method
, new_method
);
5149 /*******************************************************************
5150 Global state for POSIX pathname processing.
5151 ********************************************************************/
5153 static bool posix_pathnames
;
5155 bool lp_posix_pathnames(void)
5157 return posix_pathnames
;
5160 /*******************************************************************
5161 Change everything needed to ensure POSIX pathname processing (currently
5163 ********************************************************************/
5165 void lp_set_posix_pathnames(void)
5167 posix_pathnames
= true;
5170 /*******************************************************************
5171 Global state for POSIX lock processing - CIFS unix extensions.
5172 ********************************************************************/
5174 bool posix_default_lock_was_set
;
5175 static enum brl_flavour posix_cifsx_locktype
; /* By default 0 == WINDOWS_LOCK */
5177 enum brl_flavour
lp_posix_cifsu_locktype(files_struct
*fsp
)
5179 if (posix_default_lock_was_set
) {
5180 return posix_cifsx_locktype
;
5182 return fsp
->posix_open
? POSIX_LOCK
: WINDOWS_LOCK
;
5186 /*******************************************************************
5187 ********************************************************************/
5189 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val
)
5191 posix_default_lock_was_set
= true;
5192 posix_cifsx_locktype
= val
;
5195 int lp_min_receive_file_size(void)
5197 if (Globals
.iminreceivefile
< 0) {
5200 return Globals
.iminreceivefile
;
5203 /*******************************************************************
5204 Safe wide links checks.
5205 This helper function always verify the validity of wide links,
5206 even after a configuration file reload.
5207 ********************************************************************/
5209 static bool lp_widelinks_internal(int snum
)
5211 return (bool)(LP_SNUM_OK(snum
)? ServicePtrs
[(snum
)]->bWidelinks
:
5212 sDefault
.bWidelinks
);
5215 void widelinks_warning(int snum
)
5217 if (lp_allow_insecure_wide_links()) {
5221 if (lp_unix_extensions() && lp_widelinks_internal(snum
)) {
5222 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5223 "These parameters are incompatible. "
5224 "Wide links will be disabled for this share.\n",
5225 lp_servicename(talloc_tos(), snum
) ));
5229 bool lp_widelinks(int snum
)
5231 /* wide links is always incompatible with unix extensions */
5232 if (lp_unix_extensions()) {
5234 * Unless we have "allow insecure widelinks"
5237 if (!lp_allow_insecure_wide_links()) {
5242 return lp_widelinks_internal(snum
);
5245 int lp_server_role(void)
5247 return lp_find_server_role(lp__server_role(),
5249 lp__domain_logons(),
5250 lp_domain_master_true_or_auto());
5253 int lp_security(void)
5255 return lp_find_security(lp__server_role(),
5259 struct loadparm_global
* get_globals(void)