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"
61 #include "lib/smbconf/smbconf.h"
62 #include "lib/smbconf/smbconf_init.h"
65 #include "../librpc/gen_ndr/svcctl.h"
67 #include "../libcli/smb/smb_signing.h"
68 #include "dbwrap/dbwrap.h"
69 #include "dbwrap/dbwrap_rbt.h"
70 #include "../lib/util/bitmap.h"
72 #ifdef HAVE_SYS_SYSCTL_H
73 #include <sys/sysctl.h>
76 #ifdef HAVE_HTTPCONNECTENCRYPT
77 #include <cups/http.h>
80 #ifdef CLUSTER_SUPPORT
81 #include "ctdb_private.h"
86 extern userdom_struct current_user_info
;
88 /* the special value for the include parameter
89 * to be interpreted not as a file name but to
90 * trigger loading of the global smb.conf options
92 #ifndef INCLUDE_REGISTRY_NAME
93 #define INCLUDE_REGISTRY_NAME "registry"
96 static bool in_client
= false; /* Not in the client by default */
97 static struct smbconf_csn conf_last_csn
;
99 static int config_backend
= CONFIG_BACKEND_FILE
;
101 /* some helpful bits */
102 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
103 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
105 #define USERSHARE_VALID 1
106 #define USERSHARE_PENDING_DELETE 2
108 static bool defaults_saved
= false;
110 #define LOADPARM_EXTRA_GLOBALS \
111 struct parmlist_entry *param_opt; \
114 int iminreceivefile; \
115 char *szPrintcapname; \
117 int iPreferredMaster; \
118 char *szLdapMachineSuffix; \
119 char *szLdapUserSuffix; \
120 char *szLdapIdmapSuffix; \
121 char *szLdapGroupSuffix; \
124 char *szUsershareTemplateShare; \
127 int winbindMaxDomainConnections; \
128 int ismb2_max_credits; \
130 char *tls_certfile; \
134 int bPreferredMaster;
136 #include "param/param_global.h"
138 static struct loadparm_global Globals
;
140 /* This is a default service used to prime a services structure */
141 static struct loadparm_service sDefault
=
146 .usershare_last_mod
= {0, 0},
150 .szInvalidUsers
= NULL
,
151 .szValidUsers
= NULL
,
152 .szAdminUsers
= NULL
,
157 .szRootPreExec
= NULL
,
158 .szRootPostExec
= NULL
,
159 .szCupsOptions
= NULL
,
160 .szPrintcommand
= NULL
,
161 .szLpqcommand
= NULL
,
162 .szLprmcommand
= NULL
,
163 .szLppausecommand
= NULL
,
164 .szLpresumecommand
= NULL
,
165 .szQueuepausecommand
= NULL
,
166 .szQueueresumecommand
= NULL
,
167 .szPrintername
= NULL
,
168 .szPrintjobUsername
= NULL
,
169 .szDontdescend
= NULL
,
170 .szHostsallow
= NULL
,
172 .szMagicScript
= NULL
,
173 .szMagicOutput
= NULL
,
176 .szVetoOplockFiles
= NULL
,
184 .szVfsObjects
= NULL
,
185 .szMSDfsProxy
= NULL
,
186 .szAioWriteBehind
= NULL
,
189 .iMaxPrintJobs
= 1000,
190 .iMaxReportedPrintJobs
= 0,
191 .iWriteCacheSize
= 0,
192 .iCreate_mask
= 0744,
193 .iCreate_force_mode
= 0,
195 .iDir_force_mode
= 0,
196 .iMaxConnections
= 0,
197 .iDefaultCase
= CASE_LOWER
,
198 .iPrinting
= DEFAULT_PRINTING
,
199 .iOplockContentionLimit
= 2,
202 .iDfreeCacheTime
= 0,
203 .bPreexecClose
= false,
204 .bRootpreexecClose
= false,
205 .iCaseSensitive
= Auto
,
206 .bCasePreserve
= true,
207 .bShortCasePreserve
= true,
208 .bHideDotFiles
= true,
209 .bHideSpecialFiles
= false,
210 .bHideUnReadable
= false,
211 .bHideUnWriteableFiles
= false,
213 .bAccessBasedShareEnum
= false,
217 .bGuest_only
= false,
218 .bAdministrative_share
= false,
221 .bPrintNotifyBackchannel
= true,
222 .bMap_system
= false,
223 .bMap_hidden
= false,
224 .bMap_archive
= true,
225 .bStoreDosAttributes
= false,
226 .bDmapiSupport
= false,
228 .iStrictLocking
= Auto
,
229 .bPosixLocking
= true,
231 .bKernelOplocks
= false,
232 .bLevel2OpLocks
= true,
234 .bMangledNames
= true,
237 .bSyncAlways
= false,
238 .bStrictAllocate
= false,
239 .bStrictSync
= false,
242 .bDeleteReadonly
= false,
243 .bFakeOplocks
= false,
244 .bDeleteVetoFiles
= false,
245 .bDosFilemode
= false,
246 .bDosFiletimes
= true,
247 .bDosFiletimeResolution
= false,
248 .bFakeDirCreateTimes
= false,
249 .bBlockingLocks
= true,
250 .bInheritPerms
= false,
251 .bInheritACLS
= false,
252 .bInheritOwner
= false,
254 .bUseClientDriver
= false,
255 .bDefaultDevmode
= true,
256 .bForcePrintername
= false,
257 .bNTAclSupport
= true,
258 .bForceUnknownAclUser
= false,
259 .bUseSendfile
= false,
260 .bProfileAcls
= false,
261 .bMap_acl_inherit
= false,
264 .bAclCheckPermissions
= true,
265 .bAclMapFullControl
= true,
266 .bAclGroupControl
= false,
267 .bAclAllowExecuteAlways
= false,
268 .bChangeNotify
= true,
269 .bKernelChangeNotify
= true,
270 .iallocation_roundup_size
= SMB_ROUNDUP_ALLOCATION_SIZE
,
273 .iMap_readonly
= MAP_READONLY_YES
,
274 #ifdef BROKEN_DIRECTORY_HANDLING
275 .iDirectoryNameCacheSize
= 0,
277 .iDirectoryNameCacheSize
= 100,
279 .ismb_encrypt
= SMB_SIGNING_DEFAULT
,
280 .bKernelShareModes
= true,
281 .bDurableHandles
= true,
286 /* local variables */
287 static struct loadparm_service
**ServicePtrs
= NULL
;
288 static int iNumServices
= 0;
289 static int iServiceIndex
= 0;
290 static struct db_context
*ServiceHash
;
291 static int *invalid_services
= NULL
;
292 static int num_invalid_services
= 0;
293 static bool bInGlobalSection
= true;
294 static bool bGlobalOnly
= false;
296 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
298 /* prototypes for the special type handlers */
299 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
300 static bool handle_copy(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
301 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
302 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
303 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
304 static bool handle_debug_list(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
305 static bool handle_realm(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
306 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
307 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
308 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
309 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
310 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
);
312 /* these are parameter handlers which are not needed in the
316 #define handle_logfile NULL
318 static void set_allowed_client_auth(void);
320 static void add_to_file_list(const char *fname
, const char *subfname
);
321 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
);
322 static void free_param_opts(struct parmlist_entry
**popts
);
324 #include "lib/param/param_table.c"
326 /* this is used to prevent lots of mallocs of size 1 */
327 static const char null_string
[] = "";
330 Set a string value, allocing the space for the string
333 static bool string_init(char **dest
,const char *src
)
343 *dest
= discard_const_p(char, null_string
);
345 (*dest
) = SMB_STRDUP(src
);
346 if ((*dest
) == NULL
) {
347 DEBUG(0,("Out of memory in string_init\n"));
358 static void string_free(char **s
)
362 if (*s
== null_string
)
368 Set a string value, deallocating any existing space, and allocing the space
372 static bool string_set(char **dest
,const char *src
)
375 return(string_init(dest
,src
));
378 /***************************************************************************
379 Initialise the sDefault parameter structure for the printer values.
380 ***************************************************************************/
382 static void init_printer_values(struct loadparm_service
*pService
)
384 /* choose defaults depending on the type of printing */
385 switch (pService
->iPrinting
) {
390 string_set(&pService
->szLpqcommand
, "lpq -P'%p'");
391 string_set(&pService
->szLprmcommand
, "lprm -P'%p' %j");
392 string_set(&pService
->szPrintcommand
, "lpr -r -P'%p' %s");
397 string_set(&pService
->szLpqcommand
, "lpq -P'%p'");
398 string_set(&pService
->szLprmcommand
, "lprm -P'%p' %j");
399 string_set(&pService
->szPrintcommand
, "lpr -r -P'%p' %s");
400 string_set(&pService
->szQueuepausecommand
, "lpc stop '%p'");
401 string_set(&pService
->szQueueresumecommand
, "lpc start '%p'");
402 string_set(&pService
->szLppausecommand
, "lpc hold '%p' %j");
403 string_set(&pService
->szLpresumecommand
, "lpc release '%p' %j");
408 /* set the lpq command to contain the destination printer
409 name only. This is used by cups_queue_get() */
410 string_set(&pService
->szLpqcommand
, "%p");
411 string_set(&pService
->szLprmcommand
, "");
412 string_set(&pService
->szPrintcommand
, "");
413 string_set(&pService
->szLppausecommand
, "");
414 string_set(&pService
->szLpresumecommand
, "");
415 string_set(&pService
->szQueuepausecommand
, "");
416 string_set(&pService
->szQueueresumecommand
, "");
421 string_set(&pService
->szLpqcommand
, "lpstat -o%p");
422 string_set(&pService
->szLprmcommand
, "cancel %p-%j");
423 string_set(&pService
->szPrintcommand
, "lp -c -d%p %s; rm %s");
424 string_set(&pService
->szQueuepausecommand
, "disable %p");
425 string_set(&pService
->szQueueresumecommand
, "enable %p");
427 string_set(&pService
->szLppausecommand
, "lp -i %p-%j -H hold");
428 string_set(&pService
->szLpresumecommand
, "lp -i %p-%j -H resume");
433 string_set(&pService
->szLpqcommand
, "lpq -P%p");
434 string_set(&pService
->szLprmcommand
, "lprm -P%p %j");
435 string_set(&pService
->szPrintcommand
, "lp -r -P%p %s");
438 #if defined(DEVELOPER) || defined(ENABLE_SELFTEST)
443 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
446 tdbfile
= talloc_asprintf(
447 tmp_ctx
, "tdbfile=%s",
448 lp_parm_const_string(-1, "vlp", "tdbfile",
450 if (tdbfile
== NULL
) {
451 tdbfile
="tdbfile=/tmp/vlp.tdb";
454 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s print %%p %%s",
456 string_set(&pService
->szPrintcommand
,
457 tmp
? tmp
: "vlp print %p %s");
459 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpq %%p",
461 string_set(&pService
->szLpqcommand
,
462 tmp
? tmp
: "vlp lpq %p");
464 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lprm %%p %%j",
466 string_set(&pService
->szLprmcommand
,
467 tmp
? tmp
: "vlp lprm %p %j");
469 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lppause %%p %%j",
471 string_set(&pService
->szLppausecommand
,
472 tmp
? tmp
: "vlp lppause %p %j");
474 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s lpresume %%p %%j",
476 string_set(&pService
->szLpresumecommand
,
477 tmp
? tmp
: "vlp lpresume %p %j");
479 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queuepause %%p",
481 string_set(&pService
->szQueuepausecommand
,
482 tmp
? tmp
: "vlp queuepause %p");
484 tmp
= talloc_asprintf(tmp_ctx
, "vlp %s queueresume %%p",
486 string_set(&pService
->szQueueresumecommand
,
487 tmp
? tmp
: "vlp queueresume %p");
488 TALLOC_FREE(tmp_ctx
);
492 #endif /* DEVELOPER */
497 * Function to return the default value for the maximum number of open
498 * file descriptors permitted. This function tries to consult the
499 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
500 * the smaller of those.
502 static int max_open_files(void)
504 int sysctl_max
= MAX_OPEN_FILES
;
505 int rlimit_max
= MAX_OPEN_FILES
;
507 #ifdef HAVE_SYSCTLBYNAME
509 size_t size
= sizeof(sysctl_max
);
510 sysctlbyname("kern.maxfilesperproc", &sysctl_max
, &size
, NULL
,
515 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
521 if (getrlimit(RLIMIT_NOFILE
, &rl
) == 0)
522 rlimit_max
= rl
.rlim_cur
;
524 #if defined(RLIM_INFINITY)
525 if(rl
.rlim_cur
== RLIM_INFINITY
)
526 rlimit_max
= MAX_OPEN_FILES
;
531 if (sysctl_max
< MIN_OPEN_FILES_WINDOWS
) {
532 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
533 "minimum Windows limit (%d)\n",
535 MIN_OPEN_FILES_WINDOWS
));
536 sysctl_max
= MIN_OPEN_FILES_WINDOWS
;
539 if (rlimit_max
< MIN_OPEN_FILES_WINDOWS
) {
540 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
541 "minimum Windows limit (%d)\n",
543 MIN_OPEN_FILES_WINDOWS
));
544 rlimit_max
= MIN_OPEN_FILES_WINDOWS
;
547 return MIN(sysctl_max
, rlimit_max
);
551 * Common part of freeing allocated data for one parameter.
553 static void free_one_parameter_common(void *parm_ptr
,
554 struct parm_struct parm
)
556 if ((parm
.type
== P_STRING
) ||
557 (parm
.type
== P_USTRING
))
559 string_free((char**)parm_ptr
);
560 } else if (parm
.type
== P_LIST
) {
561 TALLOC_FREE(*((char***)parm_ptr
));
566 * Free the allocated data for one parameter for a share
567 * given as a service struct.
569 static void free_one_parameter(struct loadparm_service
*service
,
570 struct parm_struct parm
)
574 if (parm
.p_class
!= P_LOCAL
) {
578 parm_ptr
= lp_parm_ptr(service
, &parm
);
580 free_one_parameter_common(parm_ptr
, parm
);
584 * Free the allocated parameter data of a share given
585 * as a service struct.
587 static void free_parameters(struct loadparm_service
*service
)
591 for (i
=0; parm_table
[i
].label
; i
++) {
592 free_one_parameter(service
, parm_table
[i
]);
597 * Free the allocated data for one parameter for a given share
598 * specified by an snum.
600 static void free_one_parameter_by_snum(int snum
, struct parm_struct parm
)
605 parm_ptr
= lp_parm_ptr(NULL
, &parm
);
606 } else if (parm
.p_class
!= P_LOCAL
) {
609 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm
);
612 free_one_parameter_common(parm_ptr
, parm
);
616 * Free the allocated parameter data for a share specified
619 static void free_parameters_by_snum(int snum
)
623 for (i
=0; parm_table
[i
].label
; i
++) {
624 free_one_parameter_by_snum(snum
, parm_table
[i
]);
629 * Free the allocated global parameters.
631 static void free_global_parameters(void)
633 free_param_opts(&Globals
.param_opt
);
634 free_parameters_by_snum(GLOBAL_SECTION_SNUM
);
635 TALLOC_FREE(Globals
.ctx
);
638 static int map_parameter(const char *pszParmName
);
640 struct lp_stored_option
{
641 struct lp_stored_option
*prev
, *next
;
646 static struct lp_stored_option
*stored_options
;
649 save options set by lp_set_cmdline() into a list. This list is
650 re-applied when we do a globals reset, so that cmdline set options
651 are sticky across reloads of smb.conf
653 static bool store_lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
655 struct lp_stored_option
*entry
, *entry_next
;
656 for (entry
= stored_options
; entry
!= NULL
; entry
= entry_next
) {
657 entry_next
= entry
->next
;
658 if (strcmp(pszParmName
, entry
->label
) == 0) {
659 DLIST_REMOVE(stored_options
, entry
);
665 entry
= talloc(NULL
, struct lp_stored_option
);
670 entry
->label
= talloc_strdup(entry
, pszParmName
);
676 entry
->value
= talloc_strdup(entry
, pszParmValue
);
682 DLIST_ADD_END(stored_options
, entry
, struct lp_stored_option
);
687 static bool apply_lp_set_cmdline(void)
689 struct lp_stored_option
*entry
= NULL
;
690 for (entry
= stored_options
; entry
!= NULL
; entry
= entry
->next
) {
691 if (!lp_set_cmdline_helper(entry
->label
, entry
->value
, false)) {
692 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
693 entry
->label
, entry
->value
));
700 /***************************************************************************
701 Initialise the global parameter structure.
702 ***************************************************************************/
704 static void init_globals(bool reinit_globals
)
706 static bool done_init
= false;
710 /* If requested to initialize only once and we've already done it... */
711 if (!reinit_globals
&& done_init
) {
712 /* ... then we have nothing more to do */
717 /* The logfile can be set before this is invoked. Free it if so. */
718 if (Globals
.logfile
!= NULL
) {
719 string_free(&Globals
.logfile
);
720 Globals
.logfile
= NULL
;
724 free_global_parameters();
727 /* This memset and the free_global_parameters() above will
728 * wipe out smb.conf options set with lp_set_cmdline(). The
729 * apply_lp_set_cmdline() call puts these values back in the
730 * table once the defaults are set */
731 ZERO_STRUCT(Globals
);
733 Globals
.ctx
= talloc_new(NULL
);
735 for (i
= 0; parm_table
[i
].label
; i
++) {
736 if ((parm_table
[i
].type
== P_STRING
||
737 parm_table
[i
].type
== P_USTRING
))
739 string_set((char **)lp_parm_ptr(NULL
, &parm_table
[i
]), "");
744 string_set(&sDefault
.fstype
, FSTYPE_STRING
);
745 string_set(&sDefault
.szPrintjobUsername
, "%U");
747 init_printer_values(&sDefault
);
750 DEBUG(3, ("Initialising global parameters\n"));
752 /* Must manually force to upper case here, as this does not go via the handler */
753 string_set(&Globals
.szNetbiosName
, myhostname_upper());
755 string_set(&Globals
.szSMBPasswdFile
, get_dyn_SMB_PASSWD_FILE());
756 string_set(&Globals
.szPrivateDir
, get_dyn_PRIVATE_DIR());
758 /* use the new 'hash2' method by default, with a prefix of 1 */
759 string_set(&Globals
.szManglingMethod
, "hash2");
760 Globals
.mangle_prefix
= 1;
762 string_set(&Globals
.szGuestaccount
, GUEST_ACCOUNT
);
764 /* using UTF8 by default allows us to support all chars */
765 string_set(&Globals
.unix_charset
, DEFAULT_UNIX_CHARSET
);
767 /* Use codepage 850 as a default for the dos character set */
768 string_set(&Globals
.dos_charset
, DEFAULT_DOS_CHARSET
);
771 * Allow the default PASSWD_CHAT to be overridden in local.h.
773 string_set(&Globals
.szPasswdChat
, DEFAULT_PASSWD_CHAT
);
775 string_set(&Globals
.szWorkgroup
, DEFAULT_WORKGROUP
);
777 string_set(&Globals
.szPasswdProgram
, "");
778 string_set(&Globals
.szLockDir
, get_dyn_LOCKDIR());
779 string_set(&Globals
.szStateDir
, get_dyn_STATEDIR());
780 string_set(&Globals
.szCacheDir
, get_dyn_CACHEDIR());
781 string_set(&Globals
.szPidDir
, get_dyn_PIDDIR());
782 string_set(&Globals
.nbt_client_socket_address
, "0.0.0.0");
784 * By default support explicit binding to broadcast
787 Globals
.bNmbdBindExplicitBroadcast
= true;
789 if (asprintf(&s
, "Samba %s", samba_version_string()) < 0) {
790 smb_panic("init_globals: ENOMEM");
792 string_set(&Globals
.szServerString
, s
);
795 string_set(&Globals
.szPanicAction
, "/bin/sleep 999999999");
798 string_set(&Globals
.socket_options
, DEFAULT_SOCKET_OPTIONS
);
800 string_set(&Globals
.szLogonDrive
, "");
801 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
802 string_set(&Globals
.szLogonHome
, "\\\\%N\\%U");
803 string_set(&Globals
.szLogonPath
, "\\\\%N\\%U\\profile");
805 Globals
.szNameResolveOrder
= (const char **)str_list_make_v3(NULL
, "lmhosts wins host bcast", NULL
);
806 string_set(&Globals
.szPasswordServer
, "*");
808 Globals
.AlgorithmicRidBase
= BASE_RID
;
810 Globals
.bLoadPrinters
= true;
811 Globals
.PrintcapCacheTime
= 750; /* 12.5 minutes */
813 Globals
.ConfigBackend
= config_backend
;
814 Globals
.server_role
= ROLE_AUTO
;
816 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
817 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
818 Globals
.max_xmit
= 0x4104;
819 Globals
.max_mux
= 50; /* This is *needed* for profile support. */
820 Globals
.lpqcachetime
= 30; /* changed to handle large print servers better -- jerry */
821 Globals
.bDisableSpoolss
= false;
822 Globals
.iMaxSmbdProcesses
= 0;/* no limit specified */
823 Globals
.pwordlevel
= 0;
824 Globals
.unamelevel
= 0;
825 Globals
.deadtime
= 0;
826 Globals
.getwd_cache
= true;
827 Globals
.bLargeReadwrite
= true;
828 Globals
.max_log_size
= 5000;
829 Globals
.max_open_files
= max_open_files();
830 Globals
.open_files_db_hash_size
= SMB_OPEN_DATABASE_TDB_HASH_SIZE
;
831 Globals
.srv_maxprotocol
= PROTOCOL_SMB3_00
;
832 Globals
.srv_minprotocol
= PROTOCOL_LANMAN1
;
833 Globals
.security
= SEC_USER
;
834 Globals
.bEncryptPasswords
= true;
835 Globals
.clientSchannel
= Auto
;
836 Globals
.serverSchannel
= Auto
;
837 Globals
.bReadRaw
= true;
838 Globals
.bWriteRaw
= true;
839 Globals
.bNullPasswords
= false;
840 Globals
.bObeyPamRestrictions
= false;
842 Globals
.bSyslogOnly
= false;
843 Globals
.bTimestampLogs
= true;
844 string_set(&Globals
.loglevel
, "0");
845 Globals
.bDebugPrefixTimestamp
= false;
846 Globals
.bDebugHiresTimestamp
= true;
847 Globals
.bDebugPid
= false;
848 Globals
.bDebugUid
= false;
849 Globals
.bDebugClass
= false;
850 Globals
.bEnableCoreFiles
= true;
851 Globals
.max_ttl
= 60 * 60 * 24 * 3; /* 3 days default. */
852 Globals
.max_wins_ttl
= 60 * 60 * 24 * 6; /* 6 days default. */
853 Globals
.min_wins_ttl
= 60 * 60 * 6; /* 6 hours default. */
854 Globals
.machine_password_timeout
= 60 * 60 * 24 * 7; /* 7 days default. */
855 Globals
.lm_announce
= Auto
; /* = Auto: send only if LM clients found */
856 Globals
.lm_interval
= 60;
857 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
858 Globals
.bNISHomeMap
= false;
859 #ifdef WITH_NISPLUS_HOME
860 string_set(&Globals
.szNISHomeMapName
, "auto_home.org_dir");
862 string_set(&Globals
.szNISHomeMapName
, "auto.home");
865 Globals
.bTimeServer
= false;
866 Globals
.bBindInterfacesOnly
= false;
867 Globals
.bUnixPasswdSync
= false;
868 Globals
.bPamPasswordChange
= false;
869 Globals
.bPasswdChatDebug
= false;
870 Globals
.iPasswdChatTimeout
= 2; /* 2 second default. */
871 Globals
.bNTPipeSupport
= true; /* Do NT pipes by default. */
872 Globals
.bNTStatusSupport
= true; /* Use NT status by default. */
873 Globals
.bStatCache
= true; /* use stat cache by default */
874 Globals
.iMaxStatCacheSize
= 256; /* 256k by default */
875 Globals
.restrict_anonymous
= 0;
876 Globals
.bClientLanManAuth
= false; /* Do NOT use the LanMan hash if it is available */
877 Globals
.bClientPlaintextAuth
= false; /* Do NOT use a plaintext password even if is requested by the server */
878 Globals
.bLanmanAuth
= false; /* Do NOT use the LanMan hash, even if it is supplied */
879 Globals
.bNTLMAuth
= true; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
880 Globals
.bClientNTLMv2Auth
= true; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
881 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
883 Globals
.map_to_guest
= 0; /* By Default, "Never" */
884 Globals
.oplock_break_wait_time
= 0; /* By Default, 0 msecs. */
885 Globals
.enhanced_browsing
= true;
886 Globals
.iLockSpinTime
= WINDOWS_MINIMUM_LOCK_TIMEOUT_MS
; /* msec. */
887 #ifdef MMAP_BLACKLIST
888 Globals
.bUseMmap
= false;
890 Globals
.bUseMmap
= true;
892 Globals
.bUnicode
= true;
893 Globals
.bUnixExtensions
= true;
894 Globals
.bResetOnZeroVC
= false;
895 Globals
.bLogWriteableFilesOnExit
= false;
896 Globals
.bCreateKrb5Conf
= true;
897 Globals
.winbindMaxDomainConnections
= 1;
899 /* hostname lookups can be very expensive and are broken on
900 a large number of sites (tridge) */
901 Globals
.bHostnameLookups
= false;
903 string_set(&Globals
.passdb_backend
, "tdbsam");
904 string_set(&Globals
.szLdapSuffix
, "");
905 string_set(&Globals
.szLdapMachineSuffix
, "");
906 string_set(&Globals
.szLdapUserSuffix
, "");
907 string_set(&Globals
.szLdapGroupSuffix
, "");
908 string_set(&Globals
.szLdapIdmapSuffix
, "");
910 string_set(&Globals
.szLdapAdminDn
, "");
911 Globals
.ldap_ssl
= LDAP_SSL_START_TLS
;
912 Globals
.ldap_ssl_ads
= false;
913 Globals
.ldap_deref
= -1;
914 Globals
.ldap_passwd_sync
= LDAP_PASSWD_SYNC_OFF
;
915 Globals
.ldap_delete_dn
= false;
916 Globals
.ldap_replication_sleep
= 1000; /* wait 1 sec for replication */
917 Globals
.ldap_follow_referral
= Auto
;
918 Globals
.ldap_timeout
= LDAP_DEFAULT_TIMEOUT
;
919 Globals
.ldap_connection_timeout
= LDAP_CONNECTION_DEFAULT_TIMEOUT
;
920 Globals
.ldap_page_size
= LDAP_PAGE_SIZE
;
922 Globals
.ldap_debug_level
= 0;
923 Globals
.ldap_debug_threshold
= 10;
925 /* This is what we tell the afs client. in reality we set the token
926 * to never expire, though, when this runs out the afs client will
927 * forget the token. Set to 0 to get NEVERDATE.*/
928 Globals
.iAfsTokenLifetime
= 604800;
929 Globals
.cups_connection_timeout
= CUPS_DEFAULT_CONNECTION_TIMEOUT
;
931 /* these parameters are set to defaults that are more appropriate
932 for the increasing samba install base:
934 as a member of the workgroup, that will possibly become a
935 _local_ master browser (lm = true). this is opposed to a forced
936 local master browser startup (pm = true).
938 doesn't provide WINS server service by default (wsupp = false),
939 and doesn't provide domain master browser services by default, either.
943 Globals
.bMsAddPrinterWizard
= true;
944 Globals
.os_level
= 20;
945 Globals
.bLocalMaster
= true;
946 Globals
.domain_master
= Auto
; /* depending on bDomainLogons */
947 Globals
.bDomainLogons
= false;
948 Globals
.bBrowseList
= true;
949 Globals
.bWINSsupport
= false;
950 Globals
.bWINSproxy
= false;
952 TALLOC_FREE(Globals
.szInitLogonDelayedHosts
);
953 Globals
.InitLogonDelay
= 100; /* 100 ms default delay */
955 Globals
.bWINSdnsProxy
= true;
957 Globals
.bAllowTrustedDomains
= true;
958 string_set(&Globals
.szIdmapBackend
, "tdb");
960 string_set(&Globals
.szTemplateShell
, "/bin/false");
961 string_set(&Globals
.szTemplateHomedir
, "/home/%D/%U");
962 string_set(&Globals
.szWinbindSeparator
, "\\");
964 string_set(&Globals
.szCupsServer
, "");
965 string_set(&Globals
.szIPrintServer
, "");
967 #ifdef CLUSTER_SUPPORT
968 string_set(&Globals
.ctdbdSocket
, CTDB_PATH
);
970 string_set(&Globals
.ctdbdSocket
, "");
973 Globals
.szClusterAddresses
= NULL
;
974 Globals
.clustering
= false;
975 Globals
.ctdb_timeout
= 0;
976 Globals
.ctdb_locktime_warn_threshold
= 0;
978 Globals
.winbind_cache_time
= 300; /* 5 minutes */
979 Globals
.winbind_reconnect_delay
= 30; /* 30 seconds */
980 Globals
.winbind_request_timeout
= 60; /* 60 seconds */
981 Globals
.winbind_max_clients
= 200;
982 Globals
.bWinbindEnumUsers
= false;
983 Globals
.bWinbindEnumGroups
= false;
984 Globals
.bWinbindUseDefaultDomain
= false;
985 Globals
.bWinbindTrustedDomainsOnly
= false;
986 Globals
.bWinbindNestedGroups
= true;
987 Globals
.winbind_expand_groups
= 1;
988 Globals
.szWinbindNssInfo
= (const char **)str_list_make_v3(NULL
, "template", NULL
);
989 Globals
.bWinbindRefreshTickets
= false;
990 Globals
.bWinbindOfflineLogon
= false;
992 Globals
.iIdmapCacheTime
= 86400 * 7; /* a week by default */
993 Globals
.iIdmapNegativeCacheTime
= 120; /* 2 minutes by default */
995 Globals
.bPassdbExpandExplicit
= false;
997 Globals
.name_cache_timeout
= 660; /* In seconds */
999 Globals
.bUseSpnego
= true;
1000 Globals
.bClientUseSpnego
= true;
1002 Globals
.client_signing
= SMB_SIGNING_DEFAULT
;
1003 Globals
.server_signing
= SMB_SIGNING_DEFAULT
;
1005 Globals
.bDeferSharingViolations
= true;
1006 Globals
.smb_ports
= (const char **)str_list_make_v3(NULL
, SMB_PORTS
, NULL
);
1008 Globals
.bEnablePrivileges
= true;
1009 Globals
.bHostMSDfs
= true;
1010 Globals
.bASUSupport
= false;
1012 /* User defined shares. */
1013 if (asprintf(&s
, "%s/usershares", get_dyn_STATEDIR()) < 0) {
1014 smb_panic("init_globals: ENOMEM");
1016 string_set(&Globals
.szUsersharePath
, s
);
1018 string_set(&Globals
.szUsershareTemplateShare
, "");
1019 Globals
.iUsershareMaxShares
= 0;
1020 /* By default disallow sharing of directories not owned by the sharer. */
1021 Globals
.bUsershareOwnerOnly
= true;
1022 /* By default disallow guest access to usershares. */
1023 Globals
.bUsershareAllowGuests
= false;
1025 Globals
.iKeepalive
= DEFAULT_KEEPALIVE
;
1027 /* By default no shares out of the registry */
1028 Globals
.bRegistryShares
= false;
1030 Globals
.iminreceivefile
= 0;
1032 Globals
.bMapUntrustedToDomain
= false;
1033 Globals
.bMulticastDnsRegister
= true;
1035 Globals
.ismb2_max_read
= DEFAULT_SMB2_MAX_READ
;
1036 Globals
.ismb2_max_write
= DEFAULT_SMB2_MAX_WRITE
;
1037 Globals
.ismb2_max_trans
= DEFAULT_SMB2_MAX_TRANSACT
;
1038 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
1040 string_set(&Globals
.ncalrpc_dir
, get_dyn_NCALRPCDIR());
1042 /* Now put back the settings that were set with lp_set_cmdline() */
1043 apply_lp_set_cmdline();
1046 /*******************************************************************
1047 Convenience routine to grab string parameters into talloced memory
1048 and run standard_sub_basic on them. The buffers can be written to by
1049 callers without affecting the source string.
1050 ********************************************************************/
1052 static char *lp_string(TALLOC_CTX
*ctx
, const char *s
)
1056 /* The follow debug is useful for tracking down memory problems
1057 especially if you have an inner loop that is calling a lp_*()
1058 function that returns a string. Perhaps this debug should be
1059 present all the time? */
1062 DEBUG(10, ("lp_string(%s)\n", s
));
1068 ret
= talloc_sub_basic(ctx
,
1069 get_current_username(),
1070 current_user_info
.domain
,
1072 if (trim_char(ret
, '\"', '\"')) {
1073 if (strchr(ret
,'\"') != NULL
) {
1075 ret
= talloc_sub_basic(ctx
,
1076 get_current_username(),
1077 current_user_info
.domain
,
1085 In this section all the functions that are used to access the
1086 parameters from the rest of the program are defined
1089 #define FN_GLOBAL_STRING(fn_name,ptr) \
1090 char *lp_ ## fn_name(TALLOC_CTX *ctx) {return(lp_string((ctx), *(char **)(&Globals.ptr) ? *(char **)(&Globals.ptr) : ""));}
1091 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1092 const char *lp_ ## fn_name(void) {return(*(const char * const *)(&Globals.ptr) ? *(const char * const *)(&Globals.ptr) : "");}
1093 #define FN_GLOBAL_LIST(fn_name,ptr) \
1094 const char **lp_ ## fn_name(void) {return(*(const char ***)(&Globals.ptr));}
1095 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1096 bool lp_ ## fn_name(void) {return(*(bool *)(&Globals.ptr));}
1097 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1098 char lp_ ## fn_name(void) {return(*(char *)(&Globals.ptr));}
1099 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1100 int lp_ ## fn_name(void) {return(*(int *)(&Globals.ptr));}
1102 #define FN_LOCAL_STRING(fn_name,val) \
1103 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));}
1104 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1105 const char *lp_ ## fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1106 #define FN_LOCAL_LIST(fn_name,val) \
1107 const char **lp_ ## fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1108 #define FN_LOCAL_BOOL(fn_name,val) \
1109 bool lp_ ## fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1110 #define FN_LOCAL_INTEGER(fn_name,val) \
1111 int lp_ ## fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1113 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1114 bool lp_ ## fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1115 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1116 int lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1117 #define FN_LOCAL_CHAR(fn_name,val) \
1118 char lp_ ## fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1121 static FN_GLOBAL_BOOL(_readraw
, bReadRaw
)
1122 static FN_GLOBAL_BOOL(_writeraw
, bWriteRaw
)
1124 /* If lp_statedir() and lp_cachedir() are explicitely set during the
1125 * build process or in smb.conf, we use that value. Otherwise they
1126 * default to the value of lp_lockdir(). */
1127 const char *lp_statedir(void) {
1128 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
1129 (strcmp(get_dyn_STATEDIR(), Globals
.szStateDir
) != 0))
1130 return(*(char **)(&Globals
.szStateDir
) ?
1131 *(char **)(&Globals
.szStateDir
) : "");
1133 return(*(char **)(&Globals
.szLockDir
) ?
1134 *(char **)(&Globals
.szLockDir
) : "");
1136 const char *lp_cachedir(void) {
1137 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
1138 (strcmp(get_dyn_CACHEDIR(), Globals
.szCacheDir
) != 0))
1139 return(*(char **)(&Globals
.szCacheDir
) ?
1140 *(char **)(&Globals
.szCacheDir
) : "");
1142 return(*(char **)(&Globals
.szLockDir
) ?
1143 *(char **)(&Globals
.szLockDir
) : "");
1145 static FN_GLOBAL_INTEGER(winbind_max_domain_connections_int
,
1146 winbindMaxDomainConnections
)
1148 int lp_winbind_max_domain_connections(void)
1150 if (lp_winbind_offline_logon() &&
1151 lp_winbind_max_domain_connections_int() > 1) {
1152 DEBUG(1, ("offline logons active, restricting max domain "
1153 "connections to 1\n"));
1156 return MAX(1, lp_winbind_max_domain_connections_int());
1159 int lp_smb2_max_credits(void)
1161 if (Globals
.ismb2_max_credits
== 0) {
1162 Globals
.ismb2_max_credits
= DEFAULT_SMB2_MAX_CREDITS
;
1164 return Globals
.ismb2_max_credits
;
1166 int lp_cups_encrypt(void)
1169 #ifdef HAVE_HTTPCONNECTENCRYPT
1170 switch (Globals
.CupsEncrypt
) {
1172 result
= HTTP_ENCRYPT_REQUIRED
;
1175 result
= HTTP_ENCRYPT_ALWAYS
;
1178 result
= HTTP_ENCRYPT_NEVER
;
1185 /* These functions remain in source3/param for now */
1187 FN_GLOBAL_STRING(configfile
, szConfigFile
)
1189 #include "lib/param/param_functions.c"
1191 FN_LOCAL_STRING(servicename
, szService
)
1192 FN_LOCAL_CONST_STRING(const_servicename
, szService
)
1194 /* local prototypes */
1196 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
);
1197 static const char *get_boolean(bool bool_value
);
1198 static int getservicebyname(const char *pszServiceName
,
1199 struct loadparm_service
*pserviceDest
);
1200 static void copy_service(struct loadparm_service
*pserviceDest
,
1201 struct loadparm_service
*pserviceSource
,
1202 struct bitmap
*pcopymapDest
);
1203 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
1205 static bool do_section(const char *pszSectionName
, void *userdata
);
1206 static void init_copymap(struct loadparm_service
*pservice
);
1207 static bool hash_a_service(const char *name
, int number
);
1208 static void free_service_byindex(int iService
);
1209 static void show_parameter(int parmIndex
);
1210 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
);
1213 * This is a helper function for parametrical options support. It returns a
1214 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1215 * parametrical functions are quite simple
1217 static struct parmlist_entry
*get_parametrics_by_service(struct loadparm_service
*service
, const char *type
,
1220 bool global_section
= false;
1222 struct parmlist_entry
*data
;
1224 if (service
== NULL
) {
1225 data
= Globals
.param_opt
;
1226 global_section
= true;
1228 data
= service
->param_opt
;
1231 if (asprintf(¶m_key
, "%s:%s", type
, option
) == -1) {
1232 DEBUG(0,("asprintf failed!\n"));
1237 if (strwicmp(data
->key
, param_key
) == 0) {
1238 string_free(¶m_key
);
1244 if (!global_section
) {
1245 /* Try to fetch the same option but from globals */
1246 /* but only if we are not already working with Globals */
1247 data
= Globals
.param_opt
;
1249 if (strwicmp(data
->key
, param_key
) == 0) {
1250 string_free(¶m_key
);
1257 string_free(¶m_key
);
1263 * This is a helper function for parametrical options support. It returns a
1264 * pointer to parametrical option value if it exists or NULL otherwise. Actual
1265 * parametrical functions are quite simple
1267 static struct parmlist_entry
*get_parametrics(int snum
, const char *type
,
1270 if (snum
>= iNumServices
) return NULL
;
1273 return get_parametrics_by_service(NULL
, type
, option
);
1275 return get_parametrics_by_service(ServicePtrs
[snum
], type
, option
);
1280 #define MISSING_PARAMETER(name) \
1281 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
1283 /*******************************************************************
1284 convenience routine to return int parameters.
1285 ********************************************************************/
1286 static int lp_int(const char *s
)
1290 MISSING_PARAMETER(lp_int
);
1294 return (int)strtol(s
, NULL
, 0);
1297 /*******************************************************************
1298 convenience routine to return unsigned long parameters.
1299 ********************************************************************/
1300 static unsigned long lp_ulong(const char *s
)
1304 MISSING_PARAMETER(lp_ulong
);
1308 return strtoul(s
, NULL
, 0);
1311 /*******************************************************************
1312 convenience routine to return boolean parameters.
1313 ********************************************************************/
1314 static bool lp_bool(const char *s
)
1319 MISSING_PARAMETER(lp_bool
);
1323 if (!set_boolean(s
, &ret
)) {
1324 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s
));
1331 /*******************************************************************
1332 convenience routine to return enum parameters.
1333 ********************************************************************/
1334 static int lp_enum(const char *s
,const struct enum_list
*_enum
)
1338 if (!s
|| !*s
|| !_enum
) {
1339 MISSING_PARAMETER(lp_enum
);
1343 for (i
=0; _enum
[i
].name
; i
++) {
1344 if (strequal(_enum
[i
].name
,s
))
1345 return _enum
[i
].value
;
1348 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s
));
1352 #undef MISSING_PARAMETER
1354 /* Return parametric option from a given service. Type is a part of option before ':' */
1355 /* Parametric option has following syntax: 'Type: option = value' */
1356 char *lp_parm_talloc_string(TALLOC_CTX
*ctx
, int snum
, const char *type
, const char *option
, const char *def
)
1358 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1360 if (data
== NULL
||data
->value
==NULL
) {
1362 return lp_string(ctx
, def
);
1368 return lp_string(ctx
, data
->value
);
1371 /* Return parametric option from a given service. Type is a part of option before ':' */
1372 /* Parametric option has following syntax: 'Type: option = value' */
1373 const char *lp_parm_const_string(int snum
, const char *type
, const char *option
, const char *def
)
1375 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1377 if (data
== NULL
||data
->value
==NULL
)
1383 const char *lp_parm_const_string_service(struct loadparm_service
*service
, const char *type
, const char *option
)
1385 struct parmlist_entry
*data
= get_parametrics_by_service(service
, type
, option
);
1387 if (data
== NULL
||data
->value
==NULL
)
1394 /* Return parametric option from a given service. Type is a part of option before ':' */
1395 /* Parametric option has following syntax: 'Type: option = value' */
1397 const char **lp_parm_string_list(int snum
, const char *type
, const char *option
, const char **def
)
1399 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1401 if (data
== NULL
||data
->value
==NULL
)
1402 return (const char **)def
;
1404 if (data
->list
==NULL
) {
1405 data
->list
= str_list_make_v3(NULL
, data
->value
, NULL
);
1408 return (const char **)data
->list
;
1411 /* Return parametric option from a given service. Type is a part of option before ':' */
1412 /* Parametric option has following syntax: 'Type: option = value' */
1414 int lp_parm_int(int snum
, const char *type
, const char *option
, int def
)
1416 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1418 if (data
&& data
->value
&& *data
->value
)
1419 return lp_int(data
->value
);
1424 /* Return parametric option from a given service. Type is a part of option before ':' */
1425 /* Parametric option has following syntax: 'Type: option = value' */
1427 unsigned long lp_parm_ulong(int snum
, const char *type
, const char *option
, unsigned long def
)
1429 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1431 if (data
&& data
->value
&& *data
->value
)
1432 return lp_ulong(data
->value
);
1437 /* Return parametric option from a given service. Type is a part of option before ':' */
1438 /* Parametric option has following syntax: 'Type: option = value' */
1440 bool lp_parm_bool(int snum
, const char *type
, const char *option
, bool def
)
1442 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1444 if (data
&& data
->value
&& *data
->value
)
1445 return lp_bool(data
->value
);
1450 /* Return parametric option from a given service. Type is a part of option before ':' */
1451 /* Parametric option has following syntax: 'Type: option = value' */
1453 int lp_parm_enum(int snum
, const char *type
, const char *option
,
1454 const struct enum_list
*_enum
, int def
)
1456 struct parmlist_entry
*data
= get_parametrics(snum
, type
, option
);
1458 if (data
&& data
->value
&& *data
->value
&& _enum
)
1459 return lp_enum(data
->value
, _enum
);
1465 /***************************************************************************
1466 Initialise a service to the defaults.
1467 ***************************************************************************/
1469 static void init_service(struct loadparm_service
*pservice
)
1471 memset((char *)pservice
, '\0', sizeof(struct loadparm_service
));
1472 copy_service(pservice
, &sDefault
, NULL
);
1477 * free a param_opts structure.
1478 * param_opts handling should be moved to talloc;
1479 * then this whole functions reduces to a TALLOC_FREE().
1482 static void free_param_opts(struct parmlist_entry
**popts
)
1484 struct parmlist_entry
*opt
, *next_opt
;
1486 if (*popts
!= NULL
) {
1487 DEBUG(5, ("Freeing parametrics:\n"));
1490 while (opt
!= NULL
) {
1491 string_free(&opt
->key
);
1492 string_free(&opt
->value
);
1493 TALLOC_FREE(opt
->list
);
1494 next_opt
= opt
->next
;
1501 /***************************************************************************
1502 Free the dynamically allocated parts of a service struct.
1503 ***************************************************************************/
1505 static void free_service(struct loadparm_service
*pservice
)
1510 if (pservice
->szService
)
1511 DEBUG(5, ("free_service: Freeing service %s\n",
1512 pservice
->szService
));
1514 free_parameters(pservice
);
1516 string_free(&pservice
->szService
);
1517 TALLOC_FREE(pservice
->copymap
);
1519 free_param_opts(&pservice
->param_opt
);
1521 ZERO_STRUCTP(pservice
);
1525 /***************************************************************************
1526 remove a service indexed in the ServicePtrs array from the ServiceHash
1527 and free the dynamically allocated parts
1528 ***************************************************************************/
1530 static void free_service_byindex(int idx
)
1532 if ( !LP_SNUM_OK(idx
) )
1535 ServicePtrs
[idx
]->valid
= false;
1536 invalid_services
[num_invalid_services
++] = idx
;
1538 /* we have to cleanup the hash record */
1540 if (ServicePtrs
[idx
]->szService
) {
1541 char *canon_name
= canonicalize_servicename(
1543 ServicePtrs
[idx
]->szService
);
1545 dbwrap_delete_bystring(ServiceHash
, canon_name
);
1546 TALLOC_FREE(canon_name
);
1549 free_service(ServicePtrs
[idx
]);
1550 talloc_free_children(ServicePtrs
[idx
]);
1553 /***************************************************************************
1554 Add a new service to the services array initialising it with the given
1556 ***************************************************************************/
1558 static int add_a_service(const struct loadparm_service
*pservice
, const char *name
)
1561 struct loadparm_service tservice
;
1562 int num_to_alloc
= iNumServices
+ 1;
1564 tservice
= *pservice
;
1566 /* it might already exist */
1568 i
= getservicebyname(name
, NULL
);
1574 /* find an invalid one */
1576 if (num_invalid_services
> 0) {
1577 i
= invalid_services
[--num_invalid_services
];
1580 /* if not, then create one */
1581 if (i
== iNumServices
) {
1582 struct loadparm_service
**tsp
;
1585 tsp
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs
, struct loadparm_service
*, num_to_alloc
);
1587 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1591 ServicePtrs
[iNumServices
] = talloc(NULL
, struct loadparm_service
);
1592 if (!ServicePtrs
[iNumServices
]) {
1593 DEBUG(0,("add_a_service: out of memory!\n"));
1598 /* enlarge invalid_services here for now... */
1599 tinvalid
= SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services
, int,
1601 if (tinvalid
== NULL
) {
1602 DEBUG(0,("add_a_service: failed to enlarge "
1603 "invalid_services!\n"));
1606 invalid_services
= tinvalid
;
1608 free_service_byindex(i
);
1611 ServicePtrs
[i
]->valid
= true;
1613 init_service(ServicePtrs
[i
]);
1614 copy_service(ServicePtrs
[i
], &tservice
, NULL
);
1616 string_set(&ServicePtrs
[i
]->szService
, name
);
1618 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
1619 i
, ServicePtrs
[i
]->szService
));
1621 if (!hash_a_service(ServicePtrs
[i
]->szService
, i
)) {
1628 /***************************************************************************
1629 Convert a string to uppercase and remove whitespaces.
1630 ***************************************************************************/
1632 char *canonicalize_servicename(TALLOC_CTX
*ctx
, const char *src
)
1637 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
1641 result
= talloc_strdup(ctx
, src
);
1642 SMB_ASSERT(result
!= NULL
);
1644 if (!strlower_m(result
)) {
1645 TALLOC_FREE(result
);
1651 /***************************************************************************
1652 Add a name/index pair for the services array to the hash table.
1653 ***************************************************************************/
1655 static bool hash_a_service(const char *name
, int idx
)
1659 if ( !ServiceHash
) {
1660 DEBUG(10,("hash_a_service: creating servicehash\n"));
1661 ServiceHash
= db_open_rbt(NULL
);
1662 if ( !ServiceHash
) {
1663 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
1668 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
1671 canon_name
= canonicalize_servicename(talloc_tos(), name
);
1673 dbwrap_store_bystring(ServiceHash
, canon_name
,
1674 make_tdb_data((uint8
*)&idx
, sizeof(idx
)),
1677 TALLOC_FREE(canon_name
);
1682 /***************************************************************************
1683 Add a new home service, with the specified home directory, defaults coming
1685 ***************************************************************************/
1687 bool lp_add_home(const char *pszHomename
, int iDefaultService
,
1688 const char *user
, const char *pszHomedir
)
1692 if (pszHomename
== NULL
|| user
== NULL
|| pszHomedir
== NULL
||
1693 pszHomedir
[0] == '\0') {
1697 i
= add_a_service(ServicePtrs
[iDefaultService
], pszHomename
);
1702 if (!(*(ServicePtrs
[iDefaultService
]->szPath
))
1703 || strequal(ServicePtrs
[iDefaultService
]->szPath
,
1704 lp_pathname(talloc_tos(), GLOBAL_SECTION_SNUM
))) {
1705 string_set(&ServicePtrs
[i
]->szPath
, pszHomedir
);
1708 if (!(*(ServicePtrs
[i
]->comment
))) {
1709 char *comment
= NULL
;
1710 if (asprintf(&comment
, "Home directory of %s", user
) < 0) {
1713 string_set(&ServicePtrs
[i
]->comment
, comment
);
1717 /* set the browseable flag from the global default */
1719 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
1720 ServicePtrs
[i
]->bAccessBasedShareEnum
= sDefault
.bAccessBasedShareEnum
;
1722 ServicePtrs
[i
]->autoloaded
= true;
1724 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename
,
1725 user
, ServicePtrs
[i
]->szPath
));
1730 /***************************************************************************
1731 Add a new service, based on an old one.
1732 ***************************************************************************/
1734 int lp_add_service(const char *pszService
, int iDefaultService
)
1736 if (iDefaultService
< 0) {
1737 return add_a_service(&sDefault
, pszService
);
1740 return (add_a_service(ServicePtrs
[iDefaultService
], pszService
));
1743 /***************************************************************************
1744 Add the IPC service.
1745 ***************************************************************************/
1747 static bool lp_add_ipc(const char *ipc_name
, bool guest_ok
)
1749 char *comment
= NULL
;
1750 int i
= add_a_service(&sDefault
, ipc_name
);
1755 if (asprintf(&comment
, "IPC Service (%s)",
1756 Globals
.szServerString
) < 0) {
1760 string_set(&ServicePtrs
[i
]->szPath
, tmpdir());
1761 string_set(&ServicePtrs
[i
]->szUsername
, "");
1762 string_set(&ServicePtrs
[i
]->comment
, comment
);
1763 string_set(&ServicePtrs
[i
]->fstype
, "IPC");
1764 ServicePtrs
[i
]->iMaxConnections
= 0;
1765 ServicePtrs
[i
]->bAvailable
= true;
1766 ServicePtrs
[i
]->bRead_only
= true;
1767 ServicePtrs
[i
]->bGuest_only
= false;
1768 ServicePtrs
[i
]->bAdministrative_share
= true;
1769 ServicePtrs
[i
]->bGuest_ok
= guest_ok
;
1770 ServicePtrs
[i
]->bPrint_ok
= false;
1771 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
1773 DEBUG(3, ("adding IPC service\n"));
1779 /***************************************************************************
1780 Add a new printer service, with defaults coming from service iFrom.
1781 ***************************************************************************/
1783 bool lp_add_printer(const char *pszPrintername
, int iDefaultService
)
1785 const char *comment
= "From Printcap";
1786 int i
= add_a_service(ServicePtrs
[iDefaultService
], pszPrintername
);
1791 /* note that we do NOT default the availability flag to true - */
1792 /* we take it from the default service passed. This allows all */
1793 /* dynamic printers to be disabled by disabling the [printers] */
1794 /* entry (if/when the 'available' keyword is implemented!). */
1796 /* the printer name is set to the service name. */
1797 string_set(&ServicePtrs
[i
]->szPrintername
, pszPrintername
);
1798 string_set(&ServicePtrs
[i
]->comment
, comment
);
1800 /* set the browseable flag from the gloabl default */
1801 ServicePtrs
[i
]->bBrowseable
= sDefault
.bBrowseable
;
1803 /* Printers cannot be read_only. */
1804 ServicePtrs
[i
]->bRead_only
= false;
1805 /* No oplocks on printer services. */
1806 ServicePtrs
[i
]->bOpLocks
= false;
1807 /* Printer services must be printable. */
1808 ServicePtrs
[i
]->bPrint_ok
= true;
1810 DEBUG(3, ("adding printer service %s\n", pszPrintername
));
1816 /***************************************************************************
1817 Check whether the given parameter name is valid.
1818 Parametric options (names containing a colon) are considered valid.
1819 ***************************************************************************/
1821 bool lp_parameter_is_valid(const char *pszParmName
)
1823 return ((map_parameter(pszParmName
) != -1) ||
1824 (strchr(pszParmName
, ':') != NULL
));
1827 /***************************************************************************
1828 Check whether the given name is the name of a global parameter.
1829 Returns true for strings belonging to parameters of class
1830 P_GLOBAL, false for all other strings, also for parametric options
1831 and strings not belonging to any option.
1832 ***************************************************************************/
1834 bool lp_parameter_is_global(const char *pszParmName
)
1836 int num
= map_parameter(pszParmName
);
1839 return (parm_table
[num
].p_class
== P_GLOBAL
);
1845 /**************************************************************************
1846 Check whether the given name is the canonical name of a parameter.
1847 Returns false if it is not a valid parameter Name.
1848 For parametric options, true is returned.
1849 **************************************************************************/
1851 bool lp_parameter_is_canonical(const char *parm_name
)
1853 if (!lp_parameter_is_valid(parm_name
)) {
1857 return (map_parameter(parm_name
) ==
1858 map_parameter_canonical(parm_name
, NULL
));
1861 /**************************************************************************
1862 Determine the canonical name for a parameter.
1863 Indicate when it is an inverse (boolean) synonym instead of a
1865 **************************************************************************/
1867 bool lp_canonicalize_parameter(const char *parm_name
, const char **canon_parm
,
1872 if (!lp_parameter_is_valid(parm_name
)) {
1877 num
= map_parameter_canonical(parm_name
, inverse
);
1879 /* parametric option */
1880 *canon_parm
= parm_name
;
1882 *canon_parm
= parm_table
[num
].label
;
1889 /**************************************************************************
1890 Determine the canonical name for a parameter.
1891 Turn the value given into the inverse boolean expression when
1892 the synonym is an invers boolean synonym.
1894 Return true if parm_name is a valid parameter name and
1895 in case it is an invers boolean synonym, if the val string could
1896 successfully be converted to the reverse bool.
1897 Return false in all other cases.
1898 **************************************************************************/
1900 bool lp_canonicalize_parameter_with_value(const char *parm_name
,
1902 const char **canon_parm
,
1903 const char **canon_val
)
1908 if (!lp_parameter_is_valid(parm_name
)) {
1914 num
= map_parameter_canonical(parm_name
, &inverse
);
1916 /* parametric option */
1917 *canon_parm
= parm_name
;
1920 *canon_parm
= parm_table
[num
].label
;
1922 if (!lp_invert_boolean(val
, canon_val
)) {
1934 /***************************************************************************
1935 Map a parameter's string representation to something we can use.
1936 Returns false if the parameter string is not recognised, else TRUE.
1937 ***************************************************************************/
1939 static int map_parameter(const char *pszParmName
)
1943 if (*pszParmName
== '-' && !strequal(pszParmName
, "-valid"))
1946 for (iIndex
= 0; parm_table
[iIndex
].label
; iIndex
++)
1947 if (strwicmp(parm_table
[iIndex
].label
, pszParmName
) == 0)
1950 /* Warn only if it isn't parametric option */
1951 if (strchr(pszParmName
, ':') == NULL
)
1952 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName
));
1953 /* We do return 'fail' for parametric options as well because they are
1954 stored in different storage
1959 /***************************************************************************
1960 Map a parameter's string representation to the index of the canonical
1961 form of the parameter (it might be a synonym).
1962 Returns -1 if the parameter string is not recognised.
1963 ***************************************************************************/
1965 static int map_parameter_canonical(const char *pszParmName
, bool *inverse
)
1967 int parm_num
, canon_num
;
1968 bool loc_inverse
= false;
1970 parm_num
= map_parameter(pszParmName
);
1971 if ((parm_num
< 0) || !(parm_table
[parm_num
].flags
& FLAG_HIDE
)) {
1972 /* invalid, parametric or no canidate for synonyms ... */
1976 for (canon_num
= 0; parm_table
[canon_num
].label
; canon_num
++) {
1977 if (is_synonym_of(parm_num
, canon_num
, &loc_inverse
)) {
1978 parm_num
= canon_num
;
1984 if (inverse
!= NULL
) {
1985 *inverse
= loc_inverse
;
1990 /***************************************************************************
1991 return true if parameter number parm1 is a synonym of parameter
1992 number parm2 (parm2 being the principal name).
1993 set inverse to true if parm1 is P_BOOLREV and parm2 is P_BOOL,
1995 ***************************************************************************/
1997 static bool is_synonym_of(int parm1
, int parm2
, bool *inverse
)
1999 if ((parm_table
[parm1
].offset
== parm_table
[parm2
].offset
) &&
2000 (parm_table
[parm1
].p_class
== parm_table
[parm2
].p_class
) &&
2001 (parm_table
[parm1
].flags
& FLAG_HIDE
) &&
2002 !(parm_table
[parm2
].flags
& FLAG_HIDE
))
2004 if (inverse
!= NULL
) {
2005 if ((parm_table
[parm1
].type
== P_BOOLREV
) &&
2006 (parm_table
[parm2
].type
== P_BOOL
))
2018 /***************************************************************************
2019 Show one parameter's name, type, [values,] and flags.
2020 (helper functions for show_parameter_list)
2021 ***************************************************************************/
2023 static void show_parameter(int parmIndex
)
2025 int enumIndex
, flagIndex
;
2030 const char *type
[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2031 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
2033 unsigned flags
[] = { FLAG_BASIC
, FLAG_SHARE
, FLAG_PRINT
, FLAG_GLOBAL
,
2034 FLAG_WIZARD
, FLAG_ADVANCED
, FLAG_DEVELOPER
, FLAG_DEPRECATED
,
2036 const char *flag_names
[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2037 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2038 "FLAG_DEPRECATED", "FLAG_HIDE", NULL
};
2040 printf("%s=%s", parm_table
[parmIndex
].label
,
2041 type
[parm_table
[parmIndex
].type
]);
2042 if (parm_table
[parmIndex
].type
== P_ENUM
) {
2045 parm_table
[parmIndex
].enum_list
[enumIndex
].name
;
2049 enumIndex
? "|" : "",
2050 parm_table
[parmIndex
].enum_list
[enumIndex
].name
);
2055 for (flagIndex
=0; flag_names
[flagIndex
]; flagIndex
++) {
2056 if (parm_table
[parmIndex
].flags
& flags
[flagIndex
]) {
2059 flag_names
[flagIndex
]);
2064 /* output synonyms */
2066 for (parmIndex2
=0; parm_table
[parmIndex2
].label
; parmIndex2
++) {
2067 if (is_synonym_of(parmIndex
, parmIndex2
, &inverse
)) {
2068 printf(" (%ssynonym of %s)", inverse
? "inverse " : "",
2069 parm_table
[parmIndex2
].label
);
2070 } else if (is_synonym_of(parmIndex2
, parmIndex
, &inverse
)) {
2072 printf(" (synonyms: ");
2077 printf("%s%s", parm_table
[parmIndex2
].label
,
2078 inverse
? "[i]" : "");
2088 /***************************************************************************
2089 Show all parameter's name, type, [values,] and flags.
2090 ***************************************************************************/
2092 void show_parameter_list(void)
2094 int classIndex
, parmIndex
;
2095 const char *section_names
[] = { "local", "global", NULL
};
2097 for (classIndex
=0; section_names
[classIndex
]; classIndex
++) {
2098 printf("[%s]\n", section_names
[classIndex
]);
2099 for (parmIndex
= 0; parm_table
[parmIndex
].label
; parmIndex
++) {
2100 if (parm_table
[parmIndex
].p_class
== classIndex
) {
2101 show_parameter(parmIndex
);
2107 /***************************************************************************
2108 Check if a given string correctly represents a boolean value.
2109 ***************************************************************************/
2111 bool lp_string_is_valid_boolean(const char *parm_value
)
2113 return set_boolean(parm_value
, NULL
);
2116 /***************************************************************************
2117 Get the standard string representation of a boolean value ("yes" or "no")
2118 ***************************************************************************/
2120 static const char *get_boolean(bool bool_value
)
2122 static const char *yes_str
= "yes";
2123 static const char *no_str
= "no";
2125 return (bool_value
? yes_str
: no_str
);
2128 /***************************************************************************
2129 Provide the string of the negated boolean value associated to the boolean
2130 given as a string. Returns false if the passed string does not correctly
2131 represent a boolean.
2132 ***************************************************************************/
2134 bool lp_invert_boolean(const char *str
, const char **inverse_str
)
2138 if (!set_boolean(str
, &val
)) {
2142 *inverse_str
= get_boolean(!val
);
2146 /***************************************************************************
2147 Provide the canonical string representation of a boolean value given
2148 as a string. Return true on success, false if the string given does
2149 not correctly represent a boolean.
2150 ***************************************************************************/
2152 bool lp_canonicalize_boolean(const char *str
, const char**canon_str
)
2156 if (!set_boolean(str
, &val
)) {
2160 *canon_str
= get_boolean(val
);
2164 /***************************************************************************
2165 Find a service by name. Otherwise works like get_service.
2166 ***************************************************************************/
2168 static int getservicebyname(const char *pszServiceName
, struct loadparm_service
*pserviceDest
)
2175 if (ServiceHash
== NULL
) {
2179 canon_name
= canonicalize_servicename(talloc_tos(), pszServiceName
);
2181 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
, canon_name
,
2184 if (NT_STATUS_IS_OK(status
) &&
2185 (data
.dptr
!= NULL
) &&
2186 (data
.dsize
== sizeof(iService
)))
2188 iService
= *(int *)data
.dptr
;
2191 TALLOC_FREE(canon_name
);
2193 if ((iService
!= -1) && (LP_SNUM_OK(iService
))
2194 && (pserviceDest
!= NULL
)) {
2195 copy_service(pserviceDest
, ServicePtrs
[iService
], NULL
);
2201 /* Return a pointer to a service by name. Unlike getservicebyname, it does not copy the service */
2202 struct loadparm_service
*lp_service(const char *pszServiceName
)
2204 int iService
= getservicebyname(pszServiceName
, NULL
);
2205 if (iService
== -1 || !LP_SNUM_OK(iService
)) {
2208 return ServicePtrs
[iService
];
2211 struct loadparm_service
*lp_servicebynum(int snum
)
2213 if ((snum
== -1) || !LP_SNUM_OK(snum
)) {
2216 return ServicePtrs
[snum
];
2219 struct loadparm_service
*lp_default_loadparm_service()
2225 /***************************************************************************
2226 Copy a service structure to another.
2227 If pcopymapDest is NULL then copy all fields
2228 ***************************************************************************/
2231 * Add a parametric option to a parmlist_entry,
2232 * replacing old value, if already present.
2234 static void set_param_opt(struct parmlist_entry
**opt_list
,
2235 const char *opt_name
,
2236 const char *opt_value
,
2239 struct parmlist_entry
*new_opt
, *opt
;
2245 /* Traverse destination */
2247 /* If we already have same option, override it */
2248 if (strwicmp(opt
->key
, opt_name
) == 0) {
2249 if ((opt
->priority
& FLAG_CMDLINE
) &&
2250 !(priority
& FLAG_CMDLINE
)) {
2251 /* it's been marked as not to be
2255 string_free(&opt
->value
);
2256 TALLOC_FREE(opt
->list
);
2257 opt
->value
= SMB_STRDUP(opt_value
);
2258 opt
->priority
= priority
;
2265 new_opt
= SMB_XMALLOC_P(struct parmlist_entry
);
2266 new_opt
->key
= SMB_STRDUP(opt_name
);
2267 new_opt
->value
= SMB_STRDUP(opt_value
);
2268 new_opt
->list
= NULL
;
2269 new_opt
->priority
= priority
;
2270 DLIST_ADD(*opt_list
, new_opt
);
2274 static void copy_service(struct loadparm_service
*pserviceDest
, struct loadparm_service
*pserviceSource
,
2275 struct bitmap
*pcopymapDest
)
2278 bool bcopyall
= (pcopymapDest
== NULL
);
2279 struct parmlist_entry
*data
;
2281 for (i
= 0; parm_table
[i
].label
; i
++)
2282 if (parm_table
[i
].p_class
== P_LOCAL
&&
2283 (bcopyall
|| bitmap_query(pcopymapDest
,i
))) {
2284 void *src_ptr
= lp_parm_ptr(pserviceSource
, &parm_table
[i
]);
2285 void *dest_ptr
= lp_parm_ptr(pserviceDest
, &parm_table
[i
]);
2287 switch (parm_table
[i
].type
) {
2290 *(bool *)dest_ptr
= *(bool *)src_ptr
;
2297 *(int *)dest_ptr
= *(int *)src_ptr
;
2301 *(char *)dest_ptr
= *(char *)src_ptr
;
2305 string_set((char **)dest_ptr
,
2311 char *upper_string
= strupper_talloc(talloc_tos(),
2313 string_set((char **)dest_ptr
,
2315 TALLOC_FREE(upper_string
);
2319 TALLOC_FREE(*((char ***)dest_ptr
));
2320 *((char ***)dest_ptr
) = str_list_copy(NULL
,
2321 *(const char ***)src_ptr
);
2329 init_copymap(pserviceDest
);
2330 if (pserviceSource
->copymap
)
2331 bitmap_copy(pserviceDest
->copymap
,
2332 pserviceSource
->copymap
);
2335 data
= pserviceSource
->param_opt
;
2337 set_param_opt(&pserviceDest
->param_opt
, data
->key
, data
->value
, data
->priority
);
2342 /***************************************************************************
2343 Check a service for consistency. Return false if the service is in any way
2344 incomplete or faulty, else true.
2345 ***************************************************************************/
2347 bool service_ok(int iService
)
2352 if (ServicePtrs
[iService
]->szService
[0] == '\0') {
2353 DEBUG(0, ("The following message indicates an internal error:\n"));
2354 DEBUG(0, ("No service name in service entry.\n"));
2358 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2359 /* I can't see why you'd want a non-printable printer service... */
2360 if (strwicmp(ServicePtrs
[iService
]->szService
, PRINTERS_NAME
) == 0) {
2361 if (!ServicePtrs
[iService
]->bPrint_ok
) {
2362 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2363 ServicePtrs
[iService
]->szService
));
2364 ServicePtrs
[iService
]->bPrint_ok
= true;
2366 /* [printers] service must also be non-browsable. */
2367 if (ServicePtrs
[iService
]->bBrowseable
)
2368 ServicePtrs
[iService
]->bBrowseable
= false;
2371 if (ServicePtrs
[iService
]->szPath
[0] == '\0' &&
2372 strwicmp(ServicePtrs
[iService
]->szService
, HOMES_NAME
) != 0 &&
2373 ServicePtrs
[iService
]->szMSDfsProxy
[0] == '\0'
2375 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2376 ServicePtrs
[iService
]->szService
));
2377 ServicePtrs
[iService
]->bAvailable
= false;
2380 /* If a service is flagged unavailable, log the fact at level 1. */
2381 if (!ServicePtrs
[iService
]->bAvailable
)
2382 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2383 ServicePtrs
[iService
]->szService
));
2388 static struct smbconf_ctx
*lp_smbconf_ctx(void)
2391 static struct smbconf_ctx
*conf_ctx
= NULL
;
2393 if (conf_ctx
== NULL
) {
2394 err
= smbconf_init(NULL
, &conf_ctx
, "registry:");
2395 if (!SBC_ERROR_IS_OK(err
)) {
2396 DEBUG(1, ("error initializing registry configuration: "
2397 "%s\n", sbcErrorString(err
)));
2405 static bool process_smbconf_service(struct smbconf_service
*service
)
2410 if (service
== NULL
) {
2414 ret
= do_section(service
->name
, NULL
);
2418 for (count
= 0; count
< service
->num_params
; count
++) {
2419 ret
= do_parameter(service
->param_names
[count
],
2420 service
->param_values
[count
],
2426 if (iServiceIndex
>= 0) {
2427 return service_ok(iServiceIndex
);
2433 * load a service from registry and activate it
2435 bool process_registry_service(const char *service_name
)
2438 struct smbconf_service
*service
= NULL
;
2439 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2440 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2443 if (conf_ctx
== NULL
) {
2447 DEBUG(5, ("process_registry_service: service name %s\n", service_name
));
2449 if (!smbconf_share_exists(conf_ctx
, service_name
)) {
2451 * Registry does not contain data for this service (yet),
2452 * but make sure lp_load doesn't return false.
2458 err
= smbconf_get_share(conf_ctx
, mem_ctx
, service_name
, &service
);
2459 if (!SBC_ERROR_IS_OK(err
)) {
2463 ret
= process_smbconf_service(service
);
2469 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2472 TALLOC_FREE(mem_ctx
);
2477 * process_registry_globals
2479 static bool process_registry_globals(void)
2483 add_to_file_list(INCLUDE_REGISTRY_NAME
, INCLUDE_REGISTRY_NAME
);
2485 ret
= do_parameter("registry shares", "yes", NULL
);
2490 return process_registry_service(GLOBAL_NAME
);
2493 bool process_registry_shares(void)
2497 struct smbconf_service
**service
= NULL
;
2498 uint32_t num_shares
= 0;
2499 TALLOC_CTX
*mem_ctx
= talloc_stackframe();
2500 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2503 if (conf_ctx
== NULL
) {
2507 err
= smbconf_get_config(conf_ctx
, mem_ctx
, &num_shares
, &service
);
2508 if (!SBC_ERROR_IS_OK(err
)) {
2514 for (count
= 0; count
< num_shares
; count
++) {
2515 if (strequal(service
[count
]->name
, GLOBAL_NAME
)) {
2518 ret
= process_smbconf_service(service
[count
]);
2525 smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
, NULL
);
2528 TALLOC_FREE(mem_ctx
);
2533 * reload those shares from registry that are already
2534 * activated in the services array.
2536 static bool reload_registry_shares(void)
2541 for (i
= 0; i
< iNumServices
; i
++) {
2546 if (ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
2550 ret
= process_registry_service(ServicePtrs
[i
]->szService
);
2561 #define MAX_INCLUDE_DEPTH 100
2563 static uint8_t include_depth
;
2565 static struct file_lists
{
2566 struct file_lists
*next
;
2570 } *file_lists
= NULL
;
2572 /*******************************************************************
2573 Keep a linked list of all config files so we know when one has changed
2574 it's date and needs to be reloaded.
2575 ********************************************************************/
2577 static void add_to_file_list(const char *fname
, const char *subfname
)
2579 struct file_lists
*f
= file_lists
;
2582 if (f
->name
&& !strcmp(f
->name
, fname
))
2588 f
= SMB_MALLOC_P(struct file_lists
);
2591 f
->next
= file_lists
;
2592 f
->name
= SMB_STRDUP(fname
);
2597 f
->subfname
= SMB_STRDUP(subfname
);
2604 f
->modtime
= file_modtime(subfname
);
2606 time_t t
= file_modtime(subfname
);
2614 * Free the file lists
2616 static void free_file_list(void)
2618 struct file_lists
*f
;
2619 struct file_lists
*next
;
2624 SAFE_FREE( f
->name
);
2625 SAFE_FREE( f
->subfname
);
2634 * Utility function for outsiders to check if we're running on registry.
2636 bool lp_config_backend_is_registry(void)
2638 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY
);
2642 * Utility function to check if the config backend is FILE.
2644 bool lp_config_backend_is_file(void)
2646 return (lp_config_backend() == CONFIG_BACKEND_FILE
);
2649 /*******************************************************************
2650 Check if a config file has changed date.
2651 ********************************************************************/
2653 bool lp_file_list_changed(void)
2655 struct file_lists
*f
= file_lists
;
2657 DEBUG(6, ("lp_file_list_changed()\n"));
2662 if (strequal(f
->name
, INCLUDE_REGISTRY_NAME
)) {
2663 struct smbconf_ctx
*conf_ctx
= lp_smbconf_ctx();
2665 if (conf_ctx
== NULL
) {
2668 if (smbconf_changed(conf_ctx
, &conf_last_csn
, NULL
,
2671 DEBUGADD(6, ("registry config changed\n"));
2676 n2
= talloc_sub_basic(talloc_tos(),
2677 get_current_username(),
2678 current_user_info
.domain
,
2683 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2684 f
->name
, n2
, ctime(&f
->modtime
)));
2686 mod_time
= file_modtime(n2
);
2689 ((f
->modtime
!= mod_time
) ||
2690 (f
->subfname
== NULL
) ||
2691 (strcmp(n2
, f
->subfname
) != 0)))
2694 ("file %s modified: %s\n", n2
,
2696 f
->modtime
= mod_time
;
2697 SAFE_FREE(f
->subfname
);
2698 f
->subfname
= SMB_STRDUP(n2
);
2711 * Initialize iconv conversion descriptors.
2713 * This is called the first time it is needed, and also called again
2714 * every time the configuration is reloaded, because the charset or
2715 * codepage might have changed.
2717 static void init_iconv(void)
2719 global_iconv_handle
= smb_iconv_handle_reinit(NULL
, lp_dos_charset(),
2721 true, global_iconv_handle
);
2724 static bool handle_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2726 if (strcmp(*ptr
, pszParmValue
) != 0) {
2727 string_set(ptr
, pszParmValue
);
2733 static bool handle_dos_charset(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2735 bool is_utf8
= false;
2736 size_t len
= strlen(pszParmValue
);
2738 if (len
== 4 || len
== 5) {
2739 /* Don't use StrCaseCmp here as we don't want to
2740 initialize iconv. */
2741 if ((toupper_m(pszParmValue
[0]) == 'U') &&
2742 (toupper_m(pszParmValue
[1]) == 'T') &&
2743 (toupper_m(pszParmValue
[2]) == 'F')) {
2745 if (pszParmValue
[3] == '8') {
2749 if (pszParmValue
[3] == '-' &&
2750 pszParmValue
[4] == '8') {
2757 if (strcmp(*ptr
, pszParmValue
) != 0) {
2759 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
2760 "be UTF8, using (default value) %s instead.\n",
2761 DEFAULT_DOS_CHARSET
));
2762 pszParmValue
= DEFAULT_DOS_CHARSET
;
2764 string_set(ptr
, pszParmValue
);
2770 static bool handle_realm(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2773 TALLOC_CTX
*frame
= talloc_stackframe();
2774 char *realm
= strupper_talloc(frame
, pszParmValue
);
2775 char *dnsdomain
= strlower_talloc(realm
, pszParmValue
);
2777 ret
&= string_set(&Globals
.szRealm
, pszParmValue
);
2778 ret
&= string_set(&Globals
.szRealm_upper
, realm
);
2779 ret
&= string_set(&Globals
.szRealm_lower
, dnsdomain
);
2785 static bool handle_netbios_aliases(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2787 TALLOC_FREE(Globals
.szNetbiosAliases
);
2788 Globals
.szNetbiosAliases
= (const char **)str_list_make_v3(NULL
, pszParmValue
, NULL
);
2789 return set_netbios_aliases(Globals
.szNetbiosAliases
);
2792 /***************************************************************************
2793 Handle the include operation.
2794 ***************************************************************************/
2795 static bool bAllowIncludeRegistry
= true;
2797 static bool handle_include(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2801 if (include_depth
>= MAX_INCLUDE_DEPTH
) {
2802 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
2807 if (strequal(pszParmValue
, INCLUDE_REGISTRY_NAME
)) {
2808 if (!bAllowIncludeRegistry
) {
2811 if (bInGlobalSection
) {
2814 ret
= process_registry_globals();
2818 DEBUG(1, ("\"include = registry\" only effective "
2819 "in %s section\n", GLOBAL_NAME
));
2824 fname
= talloc_sub_basic(talloc_tos(), get_current_username(),
2825 current_user_info
.domain
,
2828 add_to_file_list(pszParmValue
, fname
);
2830 string_set(ptr
, fname
);
2832 if (file_exist(fname
)) {
2835 ret
= pm_process(fname
, do_section
, do_parameter
, NULL
);
2841 DEBUG(2, ("Can't find include file %s\n", fname
));
2846 /***************************************************************************
2847 Handle the interpretation of the copy parameter.
2848 ***************************************************************************/
2850 static bool handle_copy(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2854 struct loadparm_service serviceTemp
;
2856 string_set(ptr
, pszParmValue
);
2858 init_service(&serviceTemp
);
2862 DEBUG(3, ("Copying service from service %s\n", pszParmValue
));
2864 if ((iTemp
= getservicebyname(pszParmValue
, &serviceTemp
)) >= 0) {
2865 if (iTemp
== iServiceIndex
) {
2866 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue
));
2868 copy_service(ServicePtrs
[iServiceIndex
],
2870 ServicePtrs
[iServiceIndex
]->copymap
);
2874 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue
));
2878 free_service(&serviceTemp
);
2882 static bool handle_ldap_debug_level(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2884 Globals
.ldap_debug_level
= lp_int(pszParmValue
);
2885 init_ldap_debugging();
2889 /***************************************************************************
2890 Handle idmap/non unix account uid and gid allocation parameters. The format of these
2895 idmap uid = 1000-1999
2898 We only do simple parsing checks here. The strings are parsed into useful
2899 structures in the idmap daemon code.
2901 ***************************************************************************/
2903 /* Some lp_ routines to return idmap [ug]id information */
2905 static uid_t idmap_uid_low
, idmap_uid_high
;
2906 static gid_t idmap_gid_low
, idmap_gid_high
;
2908 bool lp_idmap_uid(uid_t
*low
, uid_t
*high
)
2910 if (idmap_uid_low
== 0 || idmap_uid_high
== 0)
2914 *low
= idmap_uid_low
;
2917 *high
= idmap_uid_high
;
2922 bool lp_idmap_gid(gid_t
*low
, gid_t
*high
)
2924 if (idmap_gid_low
== 0 || idmap_gid_high
== 0)
2928 *low
= idmap_gid_low
;
2931 *high
= idmap_gid_high
;
2936 static bool handle_idmap_backend(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2938 lp_do_parameter(snum
, "idmap config * : backend", pszParmValue
);
2943 /* Do some simple checks on "idmap [ug]id" parameter values */
2945 static bool handle_idmap_uid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2947 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
2952 static bool handle_idmap_gid(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
2954 lp_do_parameter(snum
, "idmap config * : range", pszParmValue
);
2959 /***************************************************************************
2960 Handle the DEBUG level list.
2961 ***************************************************************************/
2963 static bool handle_debug_list(struct loadparm_context
*unused
, int snum
, const char *pszParmValueIn
, char **ptr
)
2965 string_set(ptr
, pszParmValueIn
);
2966 return debug_parse_levels(pszParmValueIn
);
2969 /***************************************************************************
2970 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
2971 ***************************************************************************/
2973 static const char *append_ldap_suffix(TALLOC_CTX
*ctx
, const char *str
)
2975 const char *suffix_string
;
2977 suffix_string
= talloc_asprintf(ctx
, "%s,%s", str
,
2978 Globals
.szLdapSuffix
);
2979 if ( !suffix_string
) {
2980 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
2984 return suffix_string
;
2987 const char *lp_ldap_machine_suffix(TALLOC_CTX
*ctx
)
2989 if (Globals
.szLdapMachineSuffix
[0])
2990 return append_ldap_suffix(ctx
, Globals
.szLdapMachineSuffix
);
2992 return lp_string(ctx
, Globals
.szLdapSuffix
);
2995 const char *lp_ldap_user_suffix(TALLOC_CTX
*ctx
)
2997 if (Globals
.szLdapUserSuffix
[0])
2998 return append_ldap_suffix(ctx
, Globals
.szLdapUserSuffix
);
3000 return lp_string(ctx
, Globals
.szLdapSuffix
);
3003 const char *lp_ldap_group_suffix(TALLOC_CTX
*ctx
)
3005 if (Globals
.szLdapGroupSuffix
[0])
3006 return append_ldap_suffix(ctx
, Globals
.szLdapGroupSuffix
);
3008 return lp_string(ctx
, Globals
.szLdapSuffix
);
3011 const char *lp_ldap_idmap_suffix(TALLOC_CTX
*ctx
)
3013 if (Globals
.szLdapIdmapSuffix
[0])
3014 return append_ldap_suffix(ctx
, Globals
.szLdapIdmapSuffix
);
3016 return lp_string(ctx
, Globals
.szLdapSuffix
);
3019 /****************************************************************************
3020 set the value for a P_ENUM
3021 ***************************************************************************/
3023 static void lp_set_enum_parm( struct parm_struct
*parm
, const char *pszParmValue
,
3028 for (i
= 0; parm
->enum_list
[i
].name
; i
++) {
3029 if ( strequal(pszParmValue
, parm
->enum_list
[i
].name
)) {
3030 *ptr
= parm
->enum_list
[i
].value
;
3034 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
3035 pszParmValue
, parm
->label
));
3038 /***************************************************************************
3039 ***************************************************************************/
3041 static bool handle_printing(struct loadparm_context
*unused
, int snum
, const char *pszParmValue
, char **ptr
)
3043 static int parm_num
= -1;
3044 struct loadparm_service
*s
;
3046 if ( parm_num
== -1 )
3047 parm_num
= map_parameter( "printing" );
3049 lp_set_enum_parm( &parm_table
[parm_num
], pszParmValue
, (int*)ptr
);
3054 s
= ServicePtrs
[snum
];
3056 init_printer_values( s
);
3062 /***************************************************************************
3063 Initialise a copymap.
3064 ***************************************************************************/
3066 static void init_copymap(struct loadparm_service
*pservice
)
3070 TALLOC_FREE(pservice
->copymap
);
3072 pservice
->copymap
= bitmap_talloc(NULL
, NUMPARAMETERS
);
3073 if (!pservice
->copymap
)
3075 ("Couldn't allocate copymap!! (size %d)\n",
3076 (int)NUMPARAMETERS
));
3078 for (i
= 0; i
< NUMPARAMETERS
; i
++)
3079 bitmap_set(pservice
->copymap
, i
);
3083 return the parameter pointer for a parameter
3085 void *lp_parm_ptr(struct loadparm_service
*service
, struct parm_struct
*parm
)
3087 if (service
== NULL
) {
3088 if (parm
->p_class
== P_LOCAL
)
3089 return (void *)(((char *)&sDefault
)+parm
->offset
);
3090 else if (parm
->p_class
== P_GLOBAL
)
3091 return (void *)(((char *)&Globals
)+parm
->offset
);
3094 return (void *)(((char *)service
) + parm
->offset
);
3098 /***************************************************************************
3099 Return the local pointer to a parameter given the service number and parameter
3100 ***************************************************************************/
3102 void *lp_local_ptr_by_snum(int snum
, struct parm_struct
*parm
)
3104 return lp_parm_ptr(ServicePtrs
[snum
], parm
);
3107 /***************************************************************************
3108 Process a parameter for a particular service number. If snum < 0
3109 then assume we are in the globals.
3110 ***************************************************************************/
3112 bool lp_do_parameter(int snum
, const char *pszParmName
, const char *pszParmValue
)
3115 void *parm_ptr
= NULL
; /* where we are going to store the result */
3116 struct parmlist_entry
**opt_list
;
3118 parmnum
= map_parameter(pszParmName
);
3121 if (strchr(pszParmName
, ':') == NULL
) {
3122 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
3128 * We've got a parametric option
3131 opt_list
= (snum
< 0)
3132 ? &Globals
.param_opt
: &ServicePtrs
[snum
]->param_opt
;
3133 set_param_opt(opt_list
, pszParmName
, pszParmValue
, 0);
3138 /* if it's already been set by the command line, then we don't
3140 if (parm_table
[parmnum
].flags
& FLAG_CMDLINE
) {
3144 if (parm_table
[parmnum
].flags
& FLAG_DEPRECATED
) {
3145 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3149 /* we might point at a service, the default service or a global */
3151 parm_ptr
= lp_parm_ptr(NULL
, &parm_table
[parmnum
]);
3153 if (parm_table
[parmnum
].p_class
== P_GLOBAL
) {
3155 ("Global parameter %s found in service section!\n",
3159 parm_ptr
= lp_local_ptr_by_snum(snum
, &parm_table
[parmnum
]);
3163 if (!ServicePtrs
[snum
]->copymap
)
3164 init_copymap(ServicePtrs
[snum
]);
3166 /* this handles the aliases - set the copymap for other entries with
3167 the same data pointer */
3168 for (i
= 0; parm_table
[i
].label
; i
++) {
3169 if ((parm_table
[i
].offset
== parm_table
[parmnum
].offset
)
3170 && (parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
)) {
3171 bitmap_clear(ServicePtrs
[snum
]->copymap
, i
);
3176 /* if it is a special case then go ahead */
3177 if (parm_table
[parmnum
].special
) {
3178 return parm_table
[parmnum
].special(NULL
, snum
, pszParmValue
,
3182 /* now switch on the type of variable it is */
3183 switch (parm_table
[parmnum
].type
)
3186 *(bool *)parm_ptr
= lp_bool(pszParmValue
);
3190 *(bool *)parm_ptr
= !lp_bool(pszParmValue
);
3194 *(int *)parm_ptr
= lp_int(pszParmValue
);
3198 *(char *)parm_ptr
= *pszParmValue
;
3202 i
= sscanf(pszParmValue
, "%o", (int *)parm_ptr
);
3204 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName
));
3211 if (conv_str_size_error(pszParmValue
, &val
)) {
3212 if (val
<= INT_MAX
) {
3213 *(int *)parm_ptr
= (int)val
;
3218 DEBUG(0,("lp_do_parameter(%s): value is not "
3219 "a valid size specifier!\n", pszParmValue
));
3225 TALLOC_FREE(*((char ***)parm_ptr
));
3226 *(char ***)parm_ptr
= str_list_make_v3(
3227 NULL
, pszParmValue
, NULL
);
3231 string_set((char **)parm_ptr
, pszParmValue
);
3236 char *upper_string
= strupper_talloc(talloc_tos(),
3238 string_set((char **)parm_ptr
, upper_string
);
3239 TALLOC_FREE(upper_string
);
3243 lp_set_enum_parm( &parm_table
[parmnum
], pszParmValue
, (int*)parm_ptr
);
3252 /***************************************************************************
3253 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
3254 FLAG_CMDLINE won't be overridden by loads from smb.conf.
3255 ***************************************************************************/
3257 static bool lp_set_cmdline_helper(const char *pszParmName
, const char *pszParmValue
, bool store_values
)
3260 parmnum
= map_parameter(pszParmName
);
3262 parm_table
[parmnum
].flags
&= ~FLAG_CMDLINE
;
3263 if (!lp_do_parameter(-1, pszParmName
, pszParmValue
)) {
3266 parm_table
[parmnum
].flags
|= FLAG_CMDLINE
;
3268 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
3269 * be grouped in the table, so we don't have to search the
3272 i
>=0 && parm_table
[i
].offset
== parm_table
[parmnum
].offset
3273 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;
3275 parm_table
[i
].flags
|= FLAG_CMDLINE
;
3277 for (i
=parmnum
+1;i
<NUMPARAMETERS
&& parm_table
[i
].offset
== parm_table
[parmnum
].offset
3278 && parm_table
[i
].p_class
== parm_table
[parmnum
].p_class
;i
++) {
3279 parm_table
[i
].flags
|= FLAG_CMDLINE
;
3283 store_lp_set_cmdline(pszParmName
, pszParmValue
);
3288 /* it might be parametric */
3289 if (strchr(pszParmName
, ':') != NULL
) {
3290 set_param_opt(&Globals
.param_opt
, pszParmName
, pszParmValue
, FLAG_CMDLINE
);
3292 store_lp_set_cmdline(pszParmName
, pszParmValue
);
3297 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName
));
3301 bool lp_set_cmdline(const char *pszParmName
, const char *pszParmValue
)
3303 return lp_set_cmdline_helper(pszParmName
, pszParmValue
, true);
3306 /***************************************************************************
3307 Process a parameter.
3308 ***************************************************************************/
3310 static bool do_parameter(const char *pszParmName
, const char *pszParmValue
,
3313 if (!bInGlobalSection
&& bGlobalOnly
)
3316 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName
, pszParmValue
));
3318 return (lp_do_parameter(bInGlobalSection
? -2 : iServiceIndex
,
3319 pszParmName
, pszParmValue
));
3323 set a option from the commandline in 'a=b' format. Use to support --option
3325 bool lp_set_option(const char *option
)
3330 s
= talloc_strdup(NULL
, option
);
3343 /* skip white spaces after the = sign */
3346 } while (*p
== ' ');
3348 ret
= lp_set_cmdline(s
, p
);
3353 /**************************************************************************
3354 Print a parameter of the specified type.
3355 ***************************************************************************/
3357 static void print_parameter(struct parm_struct
*p
, void *ptr
, FILE * f
)
3359 /* For the seperation of lists values that we print below */
3360 const char *list_sep
= ", ";
3365 for (i
= 0; p
->enum_list
[i
].name
; i
++) {
3366 if (*(int *)ptr
== p
->enum_list
[i
].value
) {
3368 p
->enum_list
[i
].name
);
3375 fprintf(f
, "%s", BOOLSTR(*(bool *)ptr
));
3379 fprintf(f
, "%s", BOOLSTR(!*(bool *)ptr
));
3384 fprintf(f
, "%d", *(int *)ptr
);
3388 fprintf(f
, "%c", *(char *)ptr
);
3392 int val
= *(int *)ptr
;
3396 fprintf(f
, "0%o", val
);
3405 if ((char ***)ptr
&& *(char ***)ptr
) {
3406 char **list
= *(char ***)ptr
;
3407 for (; *list
; list
++) {
3408 /* surround strings with whitespace in double quotes */
3409 if (*(list
+1) == NULL
) {
3410 /* last item, no extra separator */
3413 if ( strchr_m( *list
, ' ' ) ) {
3414 fprintf(f
, "\"%s\"%s", *list
, list_sep
);
3416 fprintf(f
, "%s%s", *list
, list_sep
);
3424 if (*(char **)ptr
) {
3425 fprintf(f
, "%s", *(char **)ptr
);
3433 /***************************************************************************
3434 Check if two parameters are equal.
3435 ***************************************************************************/
3437 static bool equal_parameter(parm_type type
, void *ptr1
, void *ptr2
)
3442 return (*((bool *)ptr1
) == *((bool *)ptr2
));
3448 return (*((int *)ptr1
) == *((int *)ptr2
));
3451 return (*((char *)ptr1
) == *((char *)ptr2
));
3455 return str_list_equal(*(const char ***)ptr1
, *(const char ***)ptr2
);
3460 char *p1
= *(char **)ptr1
, *p2
= *(char **)ptr2
;
3465 return (p1
== p2
|| strequal(p1
, p2
));
3473 /***************************************************************************
3474 Initialize any local variables in the sDefault table, after parsing a
3476 ***************************************************************************/
3478 static void init_locals(void)
3481 * We run this check once the [globals] is parsed, to force
3482 * the VFS objects and other per-share settings we need for
3483 * the standard way a AD DC is operated. We may change these
3484 * as our code evolves, which is why we force these settings.
3486 * We can't do this at the end of lp_load_ex(), as by that
3487 * point the services have been loaded and they will already
3488 * have "" as their vfs objects.
3490 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
3491 const char **vfs_objects
= lp_vfs_objects(-1);
3492 if (!vfs_objects
|| !vfs_objects
[0]) {
3493 if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL
)) {
3494 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb");
3495 } else if (lp_parm_const_string(-1, "posix", "eadb", NULL
)) {
3496 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb");
3498 lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr");
3502 lp_do_parameter(-1, "map hidden", "no");
3503 lp_do_parameter(-1, "map system", "no");
3504 lp_do_parameter(-1, "map readonly", "no");
3505 lp_do_parameter(-1, "map archive", "no");
3506 lp_do_parameter(-1, "store dos attributes", "yes");
3510 /***************************************************************************
3511 Process a new section (service). At this stage all sections are services.
3512 Later we'll have special sections that permit server parameters to be set.
3513 Returns true on success, false on failure.
3514 ***************************************************************************/
3516 static bool do_section(const char *pszSectionName
, void *userdata
)
3519 bool isglobal
= ((strwicmp(pszSectionName
, GLOBAL_NAME
) == 0) ||
3520 (strwicmp(pszSectionName
, GLOBAL_NAME2
) == 0));
3523 /* if we were in a global section then do the local inits */
3524 if (bInGlobalSection
&& !isglobal
)
3527 /* if we've just struck a global section, note the fact. */
3528 bInGlobalSection
= isglobal
;
3530 /* check for multiple global sections */
3531 if (bInGlobalSection
) {
3532 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName
));
3536 if (!bInGlobalSection
&& bGlobalOnly
)
3539 /* if we have a current service, tidy it up before moving on */
3542 if (iServiceIndex
>= 0)
3543 bRetval
= service_ok(iServiceIndex
);
3545 /* if all is still well, move to the next record in the services array */
3547 /* We put this here to avoid an odd message order if messages are */
3548 /* issued by the post-processing of a previous section. */
3549 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName
));
3551 iServiceIndex
= add_a_service(&sDefault
, pszSectionName
);
3552 if (iServiceIndex
< 0) {
3553 DEBUG(0, ("Failed to add a new service\n"));
3556 /* Clean all parametric options for service */
3557 /* They will be added during parsing again */
3558 free_param_opts(&ServicePtrs
[iServiceIndex
]->param_opt
);
3565 /***************************************************************************
3566 Determine if a partcular base parameter is currentl set to the default value.
3567 ***************************************************************************/
3569 static bool is_default(int i
)
3571 if (!defaults_saved
)
3573 switch (parm_table
[i
].type
) {
3576 return str_list_equal((const char **)parm_table
[i
].def
.lvalue
,
3577 *(const char ***)lp_parm_ptr(NULL
,
3581 return strequal(parm_table
[i
].def
.svalue
,
3582 *(char **)lp_parm_ptr(NULL
,
3586 return parm_table
[i
].def
.bvalue
==
3587 *(bool *)lp_parm_ptr(NULL
,
3590 return parm_table
[i
].def
.cvalue
==
3591 *(char *)lp_parm_ptr(NULL
,
3597 return parm_table
[i
].def
.ivalue
==
3598 *(int *)lp_parm_ptr(NULL
,
3606 /***************************************************************************
3607 Display the contents of the global structure.
3608 ***************************************************************************/
3610 static void dump_globals(FILE *f
)
3613 struct parmlist_entry
*data
;
3615 fprintf(f
, "[global]\n");
3617 for (i
= 0; parm_table
[i
].label
; i
++)
3618 if (parm_table
[i
].p_class
== P_GLOBAL
&&
3619 !(parm_table
[i
].flags
& FLAG_META
) &&
3620 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
))) {
3621 if (defaults_saved
&& is_default(i
))
3623 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
3624 print_parameter(&parm_table
[i
], lp_parm_ptr(NULL
,
3629 if (Globals
.param_opt
!= NULL
) {
3630 data
= Globals
.param_opt
;
3632 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
3639 /***************************************************************************
3640 Return true if a local parameter is currently set to the global default.
3641 ***************************************************************************/
3643 bool lp_is_default(int snum
, struct parm_struct
*parm
)
3645 return equal_parameter(parm
->type
,
3646 lp_parm_ptr(ServicePtrs
[snum
], parm
),
3647 lp_parm_ptr(NULL
, parm
));
3650 /***************************************************************************
3651 Display the contents of a single services record.
3652 ***************************************************************************/
3654 static void dump_a_service(struct loadparm_service
*pService
, FILE * f
)
3657 struct parmlist_entry
*data
;
3659 if (pService
!= &sDefault
)
3660 fprintf(f
, "[%s]\n", pService
->szService
);
3662 for (i
= 0; parm_table
[i
].label
; i
++) {
3664 if (parm_table
[i
].p_class
== P_LOCAL
&&
3665 !(parm_table
[i
].flags
& FLAG_META
) &&
3666 (*parm_table
[i
].label
!= '-') &&
3667 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
)))
3669 if (pService
== &sDefault
) {
3670 if (defaults_saved
&& is_default(i
))
3673 if (equal_parameter(parm_table
[i
].type
,
3674 lp_parm_ptr(pService
, &parm_table
[i
]),
3675 lp_parm_ptr(NULL
, &parm_table
[i
])))
3679 fprintf(f
, "\t%s = ", parm_table
[i
].label
);
3680 print_parameter(&parm_table
[i
],
3681 lp_parm_ptr(pService
, &parm_table
[i
]),
3687 if (pService
->param_opt
!= NULL
) {
3688 data
= pService
->param_opt
;
3690 fprintf(f
, "\t%s = %s\n", data
->key
, data
->value
);
3696 /***************************************************************************
3697 Display the contents of a parameter of a single services record.
3698 ***************************************************************************/
3700 bool dump_a_parameter(int snum
, char *parm_name
, FILE * f
, bool isGlobal
)
3703 bool result
= false;
3706 fstring local_parm_name
;
3708 const char *parm_opt_value
;
3710 /* check for parametrical option */
3711 fstrcpy( local_parm_name
, parm_name
);
3712 parm_opt
= strchr( local_parm_name
, ':');
3717 if (strlen(parm_opt
)) {
3718 parm_opt_value
= lp_parm_const_string( snum
,
3719 local_parm_name
, parm_opt
, NULL
);
3720 if (parm_opt_value
) {
3721 printf( "%s\n", parm_opt_value
);
3728 /* check for a key and print the value */
3735 for (i
= 0; parm_table
[i
].label
; i
++) {
3736 if (strwicmp(parm_table
[i
].label
, parm_name
) == 0 &&
3737 !(parm_table
[i
].flags
& FLAG_META
) &&
3738 (parm_table
[i
].p_class
== p_class
|| parm_table
[i
].flags
& flag
) &&
3739 (*parm_table
[i
].label
!= '-') &&
3740 (i
== 0 || (parm_table
[i
].offset
!= parm_table
[i
- 1].offset
)))
3745 ptr
= lp_parm_ptr(NULL
,
3748 ptr
= lp_parm_ptr(ServicePtrs
[snum
],
3752 print_parameter(&parm_table
[i
],
3763 /***************************************************************************
3764 Return info about the requested parameter (given as a string).
3765 Return NULL when the string is not a valid parameter name.
3766 ***************************************************************************/
3768 struct parm_struct
*lp_get_parameter(const char *param_name
)
3770 int num
= map_parameter(param_name
);
3776 return &parm_table
[num
];
3779 /***************************************************************************
3780 Return info about the next parameter in a service.
3781 snum==GLOBAL_SECTION_SNUM gives the globals.
3782 Return NULL when out of parameters.
3783 ***************************************************************************/
3785 struct parm_struct
*lp_next_parameter(int snum
, int *i
, int allparameters
)
3788 /* do the globals */
3789 for (; parm_table
[*i
].label
; (*i
)++) {
3790 if (parm_table
[*i
].p_class
== P_SEPARATOR
)
3791 return &parm_table
[(*i
)++];
3793 if ((*parm_table
[*i
].label
== '-'))
3797 && (parm_table
[*i
].offset
==
3798 parm_table
[(*i
) - 1].offset
)
3799 && (parm_table
[*i
].p_class
==
3800 parm_table
[(*i
) - 1].p_class
))
3803 if (is_default(*i
) && !allparameters
)
3806 return &parm_table
[(*i
)++];
3809 struct loadparm_service
*pService
= ServicePtrs
[snum
];
3811 for (; parm_table
[*i
].label
; (*i
)++) {
3812 if (parm_table
[*i
].p_class
== P_SEPARATOR
)
3813 return &parm_table
[(*i
)++];
3815 if (parm_table
[*i
].p_class
== P_LOCAL
&&
3816 (*parm_table
[*i
].label
!= '-') &&
3818 (parm_table
[*i
].offset
!=
3819 parm_table
[(*i
) - 1].offset
)))
3821 if (allparameters
||
3822 !equal_parameter(parm_table
[*i
].type
,
3823 lp_parm_ptr(pService
,
3828 return &parm_table
[(*i
)++];
3839 /***************************************************************************
3840 Display the contents of a single copy structure.
3841 ***************************************************************************/
3842 static void dump_copy_map(bool *pcopymap
)
3848 printf("\n\tNon-Copied parameters:\n");
3850 for (i
= 0; parm_table
[i
].label
; i
++)
3851 if (parm_table
[i
].p_class
== P_LOCAL
&&
3852 parm_table
[i
].ptr
&& !pcopymap
[i
] &&
3853 (i
== 0 || (parm_table
[i
].ptr
!= parm_table
[i
- 1].ptr
)))
3855 printf("\t\t%s\n", parm_table
[i
].label
);
3860 /***************************************************************************
3861 Return TRUE if the passed service number is within range.
3862 ***************************************************************************/
3864 bool lp_snum_ok(int iService
)
3866 return (LP_SNUM_OK(iService
) && ServicePtrs
[iService
]->bAvailable
);
3869 /***************************************************************************
3870 Auto-load some home services.
3871 ***************************************************************************/
3873 static void lp_add_auto_services(char *str
)
3883 s
= SMB_STRDUP(str
);
3887 homes
= lp_servicenumber(HOMES_NAME
);
3889 for (p
= strtok_r(s
, LIST_SEP
, &saveptr
); p
;
3890 p
= strtok_r(NULL
, LIST_SEP
, &saveptr
)) {
3893 if (lp_servicenumber(p
) >= 0)
3896 home
= get_user_home_dir(talloc_tos(), p
);
3898 if (home
&& home
[0] && homes
>= 0)
3899 lp_add_home(p
, homes
, p
, home
);
3906 /***************************************************************************
3907 Auto-load one printer.
3908 ***************************************************************************/
3910 void lp_add_one_printer(const char *name
, const char *comment
,
3911 const char *location
, void *pdata
)
3913 int printers
= lp_servicenumber(PRINTERS_NAME
);
3916 if (lp_servicenumber(name
) < 0) {
3917 lp_add_printer(name
, printers
);
3918 if ((i
= lp_servicenumber(name
)) >= 0) {
3919 string_set(&ServicePtrs
[i
]->comment
, comment
);
3920 ServicePtrs
[i
]->autoloaded
= true;
3925 /***************************************************************************
3926 Have we loaded a services file yet?
3927 ***************************************************************************/
3929 bool lp_loaded(void)
3934 /***************************************************************************
3935 Unload unused services.
3936 ***************************************************************************/
3938 void lp_killunused(struct smbd_server_connection
*sconn
,
3939 bool (*snumused
) (struct smbd_server_connection
*, int))
3942 for (i
= 0; i
< iNumServices
; i
++) {
3946 /* don't kill autoloaded or usershare services */
3947 if ( ServicePtrs
[i
]->autoloaded
||
3948 ServicePtrs
[i
]->usershare
== USERSHARE_VALID
) {
3952 if (!snumused
|| !snumused(sconn
, i
)) {
3953 free_service_byindex(i
);
3959 * Kill all except autoloaded and usershare services - convenience wrapper
3961 void lp_kill_all_services(void)
3963 lp_killunused(NULL
, NULL
);
3966 /***************************************************************************
3968 ***************************************************************************/
3970 void lp_killservice(int iServiceIn
)
3972 if (VALID(iServiceIn
)) {
3973 free_service_byindex(iServiceIn
);
3977 /***************************************************************************
3978 Save the curent values of all global and sDefault parameters into the
3979 defaults union. This allows swat and testparm to show only the
3980 changed (ie. non-default) parameters.
3981 ***************************************************************************/
3983 static void lp_save_defaults(void)
3986 for (i
= 0; parm_table
[i
].label
; i
++) {
3987 if (i
> 0 && parm_table
[i
].offset
== parm_table
[i
- 1].offset
3988 && parm_table
[i
].p_class
== parm_table
[i
- 1].p_class
)
3990 switch (parm_table
[i
].type
) {
3993 parm_table
[i
].def
.lvalue
= str_list_copy(
3994 NULL
, *(const char ***)lp_parm_ptr(NULL
, &parm_table
[i
]));
3998 parm_table
[i
].def
.svalue
= SMB_STRDUP(*(char **)lp_parm_ptr(NULL
, &parm_table
[i
]));
4002 parm_table
[i
].def
.bvalue
=
4003 *(bool *)lp_parm_ptr(NULL
, &parm_table
[i
]);
4006 parm_table
[i
].def
.cvalue
=
4007 *(char *)lp_parm_ptr(NULL
, &parm_table
[i
]);
4013 parm_table
[i
].def
.ivalue
=
4014 *(int *)lp_parm_ptr(NULL
, &parm_table
[i
]);
4020 defaults_saved
= true;
4023 /***********************************************************
4024 If we should send plaintext/LANMAN passwords in the clinet
4025 ************************************************************/
4027 static void set_allowed_client_auth(void)
4029 if (Globals
.bClientNTLMv2Auth
) {
4030 Globals
.bClientLanManAuth
= false;
4032 if (!Globals
.bClientLanManAuth
) {
4033 Globals
.bClientPlaintextAuth
= false;
4037 /***************************************************************************
4039 The following code allows smbd to read a user defined share file.
4040 Yes, this is my intent. Yes, I'm comfortable with that...
4042 THE FOLLOWING IS SECURITY CRITICAL CODE.
4044 It washes your clothes, it cleans your house, it guards you while you sleep...
4045 Do not f%^k with it....
4046 ***************************************************************************/
4048 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4050 /***************************************************************************
4051 Check allowed stat state of a usershare file.
4052 Ensure we print out who is dicking with us so the admin can
4053 get their sorry ass fired.
4054 ***************************************************************************/
4056 static bool check_usershare_stat(const char *fname
,
4057 const SMB_STRUCT_STAT
*psbuf
)
4059 if (!S_ISREG(psbuf
->st_ex_mode
)) {
4060 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4061 "not a regular file\n",
4062 fname
, (unsigned int)psbuf
->st_ex_uid
));
4066 /* Ensure this doesn't have the other write bit set. */
4067 if (psbuf
->st_ex_mode
& S_IWOTH
) {
4068 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4069 "public write. Refusing to allow as a usershare file.\n",
4070 fname
, (unsigned int)psbuf
->st_ex_uid
));
4074 /* Should be 10k or less. */
4075 if (psbuf
->st_ex_size
> MAX_USERSHARE_FILE_SIZE
) {
4076 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4077 "too large (%u) to be a user share file.\n",
4078 fname
, (unsigned int)psbuf
->st_ex_uid
,
4079 (unsigned int)psbuf
->st_ex_size
));
4086 /***************************************************************************
4087 Parse the contents of a usershare file.
4088 ***************************************************************************/
4090 enum usershare_err
parse_usershare_file(TALLOC_CTX
*ctx
,
4091 SMB_STRUCT_STAT
*psbuf
,
4092 const char *servicename
,
4096 char **pp_sharepath
,
4098 char **pp_cp_servicename
,
4099 struct security_descriptor
**ppsd
,
4102 const char **prefixallowlist
= lp_usershare_prefix_allow_list();
4103 const char **prefixdenylist
= lp_usershare_prefix_deny_list();
4106 SMB_STRUCT_STAT sbuf
;
4107 char *sharepath
= NULL
;
4108 char *comment
= NULL
;
4110 *pp_sharepath
= NULL
;
4113 *pallow_guest
= false;
4116 return USERSHARE_MALFORMED_FILE
;
4119 if (strcmp(lines
[0], "#VERSION 1") == 0) {
4121 } else if (strcmp(lines
[0], "#VERSION 2") == 0) {
4124 return USERSHARE_MALFORMED_FILE
;
4127 return USERSHARE_BAD_VERSION
;
4130 if (strncmp(lines
[1], "path=", 5) != 0) {
4131 return USERSHARE_MALFORMED_PATH
;
4134 sharepath
= talloc_strdup(ctx
, &lines
[1][5]);
4136 return USERSHARE_POSIX_ERR
;
4138 trim_string(sharepath
, " ", " ");
4140 if (strncmp(lines
[2], "comment=", 8) != 0) {
4141 return USERSHARE_MALFORMED_COMMENT_DEF
;
4144 comment
= talloc_strdup(ctx
, &lines
[2][8]);
4146 return USERSHARE_POSIX_ERR
;
4148 trim_string(comment
, " ", " ");
4149 trim_char(comment
, '"', '"');
4151 if (strncmp(lines
[3], "usershare_acl=", 14) != 0) {
4152 return USERSHARE_MALFORMED_ACL_DEF
;
4155 if (!parse_usershare_acl(ctx
, &lines
[3][14], ppsd
)) {
4156 return USERSHARE_ACL_ERR
;
4160 if (strncmp(lines
[4], "guest_ok=", 9) != 0) {
4161 return USERSHARE_MALFORMED_ACL_DEF
;
4163 if (lines
[4][9] == 'y') {
4164 *pallow_guest
= true;
4167 /* Backwards compatible extension to file version #2. */
4169 if (strncmp(lines
[5], "sharename=", 10) != 0) {
4170 return USERSHARE_MALFORMED_SHARENAME_DEF
;
4172 if (!strequal(&lines
[5][10], servicename
)) {
4173 return USERSHARE_BAD_SHARENAME
;
4175 *pp_cp_servicename
= talloc_strdup(ctx
, &lines
[5][10]);
4176 if (!*pp_cp_servicename
) {
4177 return USERSHARE_POSIX_ERR
;
4182 if (*pp_cp_servicename
== NULL
) {
4183 *pp_cp_servicename
= talloc_strdup(ctx
, servicename
);
4184 if (!*pp_cp_servicename
) {
4185 return USERSHARE_POSIX_ERR
;
4189 if (snum
!= -1 && (strcmp(sharepath
, ServicePtrs
[snum
]->szPath
) == 0)) {
4190 /* Path didn't change, no checks needed. */
4191 *pp_sharepath
= sharepath
;
4192 *pp_comment
= comment
;
4193 return USERSHARE_OK
;
4196 /* The path *must* be absolute. */
4197 if (sharepath
[0] != '/') {
4198 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4199 servicename
, sharepath
));
4200 return USERSHARE_PATH_NOT_ABSOLUTE
;
4203 /* If there is a usershare prefix deny list ensure one of these paths
4204 doesn't match the start of the user given path. */
4205 if (prefixdenylist
) {
4207 for ( i
=0; prefixdenylist
[i
]; i
++ ) {
4208 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4209 servicename
, i
, prefixdenylist
[i
], sharepath
));
4210 if (memcmp( sharepath
, prefixdenylist
[i
], strlen(prefixdenylist
[i
])) == 0) {
4211 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4212 "usershare prefix deny list entries.\n",
4213 servicename
, sharepath
));
4214 return USERSHARE_PATH_IS_DENIED
;
4219 /* If there is a usershare prefix allow list ensure one of these paths
4220 does match the start of the user given path. */
4222 if (prefixallowlist
) {
4224 for ( i
=0; prefixallowlist
[i
]; i
++ ) {
4225 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4226 servicename
, i
, prefixallowlist
[i
], sharepath
));
4227 if (memcmp( sharepath
, prefixallowlist
[i
], strlen(prefixallowlist
[i
])) == 0) {
4231 if (prefixallowlist
[i
] == NULL
) {
4232 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4233 "usershare prefix allow list entries.\n",
4234 servicename
, sharepath
));
4235 return USERSHARE_PATH_NOT_ALLOWED
;
4239 /* Ensure this is pointing to a directory. */
4240 dp
= opendir(sharepath
);
4243 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4244 servicename
, sharepath
));
4245 return USERSHARE_PATH_NOT_DIRECTORY
;
4248 /* Ensure the owner of the usershare file has permission to share
4251 if (sys_stat(sharepath
, &sbuf
, false) == -1) {
4252 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4253 servicename
, sharepath
, strerror(errno
) ));
4255 return USERSHARE_POSIX_ERR
;
4260 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
4261 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4262 servicename
, sharepath
));
4263 return USERSHARE_PATH_NOT_DIRECTORY
;
4266 /* Check if sharing is restricted to owner-only. */
4267 /* psbuf is the stat of the usershare definition file,
4268 sbuf is the stat of the target directory to be shared. */
4270 if (lp_usershare_owner_only()) {
4271 /* root can share anything. */
4272 if ((psbuf
->st_ex_uid
!= 0) && (sbuf
.st_ex_uid
!= psbuf
->st_ex_uid
)) {
4273 return USERSHARE_PATH_NOT_ALLOWED
;
4277 *pp_sharepath
= sharepath
;
4278 *pp_comment
= comment
;
4279 return USERSHARE_OK
;
4282 /***************************************************************************
4283 Deal with a usershare file.
4286 -1 - Bad name, invalid contents.
4287 - service name already existed and not a usershare, problem
4288 with permissions to share directory etc.
4289 ***************************************************************************/
4291 static int process_usershare_file(const char *dir_name
, const char *file_name
, int snum_template
)
4293 SMB_STRUCT_STAT sbuf
;
4294 SMB_STRUCT_STAT lsbuf
;
4296 char *sharepath
= NULL
;
4297 char *comment
= NULL
;
4298 char *cp_service_name
= NULL
;
4299 char **lines
= NULL
;
4303 TALLOC_CTX
*ctx
= talloc_stackframe();
4304 struct security_descriptor
*psd
= NULL
;
4305 bool guest_ok
= false;
4306 char *canon_name
= NULL
;
4307 bool added_service
= false;
4310 /* Ensure share name doesn't contain invalid characters. */
4311 if (!validate_net_name(file_name
, INVALID_SHARENAME_CHARS
, strlen(file_name
))) {
4312 DEBUG(0,("process_usershare_file: share name %s contains "
4313 "invalid characters (any of %s)\n",
4314 file_name
, INVALID_SHARENAME_CHARS
));
4318 canon_name
= canonicalize_servicename(ctx
, file_name
);
4323 fname
= talloc_asprintf(ctx
, "%s/%s", dir_name
, file_name
);
4328 /* Minimize the race condition by doing an lstat before we
4329 open and fstat. Ensure this isn't a symlink link. */
4331 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
4332 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4333 fname
, strerror(errno
) ));
4337 /* This must be a regular file, not a symlink, directory or
4338 other strange filetype. */
4339 if (!check_usershare_stat(fname
, &lsbuf
)) {
4347 status
= dbwrap_fetch_bystring(ServiceHash
, canon_name
,
4352 if (NT_STATUS_IS_OK(status
) &&
4353 (data
.dptr
!= NULL
) &&
4354 (data
.dsize
== sizeof(iService
))) {
4355 memcpy(&iService
, data
.dptr
, sizeof(iService
));
4359 if (iService
!= -1 &&
4360 timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
4361 &lsbuf
.st_ex_mtime
) == 0) {
4362 /* Nothing changed - Mark valid and return. */
4363 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4365 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
4370 /* Try and open the file read only - no symlinks allowed. */
4372 fd
= open(fname
, O_RDONLY
|O_NOFOLLOW
, 0);
4374 fd
= open(fname
, O_RDONLY
, 0);
4378 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4379 fname
, strerror(errno
) ));
4383 /* Now fstat to be *SURE* it's a regular file. */
4384 if (sys_fstat(fd
, &sbuf
, false) != 0) {
4386 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4387 fname
, strerror(errno
) ));
4391 /* Is it the same dev/inode as was lstated ? */
4392 if (!check_same_stat(&lsbuf
, &sbuf
)) {
4394 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4395 "Symlink spoofing going on ?\n", fname
));
4399 /* This must be a regular file, not a symlink, directory or
4400 other strange filetype. */
4401 if (!check_usershare_stat(fname
, &sbuf
)) {
4406 lines
= fd_lines_load(fd
, &numlines
, MAX_USERSHARE_FILE_SIZE
, NULL
);
4409 if (lines
== NULL
) {
4410 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4411 fname
, (unsigned int)sbuf
.st_ex_uid
));
4415 if (parse_usershare_file(ctx
, &sbuf
, file_name
,
4416 iService
, lines
, numlines
, &sharepath
,
4417 &comment
, &cp_service_name
,
4418 &psd
, &guest_ok
) != USERSHARE_OK
) {
4422 /* Everything ok - add the service possibly using a template. */
4424 const struct loadparm_service
*sp
= &sDefault
;
4425 if (snum_template
!= -1) {
4426 sp
= ServicePtrs
[snum_template
];
4429 if ((iService
= add_a_service(sp
, cp_service_name
)) < 0) {
4430 DEBUG(0, ("process_usershare_file: Failed to add "
4431 "new service %s\n", cp_service_name
));
4435 added_service
= true;
4437 /* Read only is controlled by usershare ACL below. */
4438 ServicePtrs
[iService
]->bRead_only
= false;
4441 /* Write the ACL of the new/modified share. */
4442 if (!set_share_security(canon_name
, psd
)) {
4443 DEBUG(0, ("process_usershare_file: Failed to set share "
4444 "security for user share %s\n",
4449 /* If from a template it may be marked invalid. */
4450 ServicePtrs
[iService
]->valid
= true;
4452 /* Set the service as a valid usershare. */
4453 ServicePtrs
[iService
]->usershare
= USERSHARE_VALID
;
4455 /* Set guest access. */
4456 if (lp_usershare_allow_guests()) {
4457 ServicePtrs
[iService
]->bGuest_ok
= guest_ok
;
4460 /* And note when it was loaded. */
4461 ServicePtrs
[iService
]->usershare_last_mod
= sbuf
.st_ex_mtime
;
4462 string_set(&ServicePtrs
[iService
]->szPath
, sharepath
);
4463 string_set(&ServicePtrs
[iService
]->comment
, comment
);
4469 if (ret
== -1 && iService
!= -1 && added_service
) {
4470 lp_remove_service(iService
);
4478 /***************************************************************************
4479 Checks if a usershare entry has been modified since last load.
4480 ***************************************************************************/
4482 static bool usershare_exists(int iService
, struct timespec
*last_mod
)
4484 SMB_STRUCT_STAT lsbuf
;
4485 const char *usersharepath
= Globals
.szUsersharePath
;
4488 if (asprintf(&fname
, "%s/%s",
4490 ServicePtrs
[iService
]->szService
) < 0) {
4494 if (sys_lstat(fname
, &lsbuf
, false) != 0) {
4499 if (!S_ISREG(lsbuf
.st_ex_mode
)) {
4505 *last_mod
= lsbuf
.st_ex_mtime
;
4509 /***************************************************************************
4510 Load a usershare service by name. Returns a valid servicenumber or -1.
4511 ***************************************************************************/
4513 int load_usershare_service(const char *servicename
)
4515 SMB_STRUCT_STAT sbuf
;
4516 const char *usersharepath
= Globals
.szUsersharePath
;
4517 int max_user_shares
= Globals
.iUsershareMaxShares
;
4518 int snum_template
= -1;
4520 if (*usersharepath
== 0 || max_user_shares
== 0) {
4524 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
4525 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4526 usersharepath
, strerror(errno
) ));
4530 if (!S_ISDIR(sbuf
.st_ex_mode
)) {
4531 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4537 * This directory must be owned by root, and have the 't' bit set.
4538 * It also must not be writable by "other".
4542 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4544 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4546 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4547 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4552 /* Ensure the template share exists if it's set. */
4553 if (Globals
.szUsershareTemplateShare
[0]) {
4554 /* We can't use lp_servicenumber here as we are recommending that
4555 template shares have -valid=false set. */
4556 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
4557 if (ServicePtrs
[snum_template
]->szService
&&
4558 strequal(ServicePtrs
[snum_template
]->szService
,
4559 Globals
.szUsershareTemplateShare
)) {
4564 if (snum_template
== -1) {
4565 DEBUG(0,("load_usershare_service: usershare template share %s "
4566 "does not exist.\n",
4567 Globals
.szUsershareTemplateShare
));
4572 return process_usershare_file(usersharepath
, servicename
, snum_template
);
4575 /***************************************************************************
4576 Load all user defined shares from the user share directory.
4577 We only do this if we're enumerating the share list.
4578 This is the function that can delete usershares that have
4580 ***************************************************************************/
4582 int load_usershare_shares(struct smbd_server_connection
*sconn
,
4583 bool (*snumused
) (struct smbd_server_connection
*, int))
4586 SMB_STRUCT_STAT sbuf
;
4588 int num_usershares
= 0;
4589 int max_user_shares
= Globals
.iUsershareMaxShares
;
4590 unsigned int num_dir_entries
, num_bad_dir_entries
, num_tmp_dir_entries
;
4591 unsigned int allowed_bad_entries
= ((2*max_user_shares
)/10);
4592 unsigned int allowed_tmp_entries
= ((2*max_user_shares
)/10);
4594 int snum_template
= -1;
4595 const char *usersharepath
= Globals
.szUsersharePath
;
4596 int ret
= lp_numservices();
4597 TALLOC_CTX
*tmp_ctx
;
4599 if (max_user_shares
== 0 || *usersharepath
== '\0') {
4600 return lp_numservices();
4603 if (sys_stat(usersharepath
, &sbuf
, false) != 0) {
4604 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4605 usersharepath
, strerror(errno
) ));
4610 * This directory must be owned by root, and have the 't' bit set.
4611 * It also must not be writable by "other".
4615 if (sbuf
.st_ex_uid
!= 0 || !(sbuf
.st_ex_mode
& S_ISVTX
) || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4617 if (sbuf
.st_ex_uid
!= 0 || (sbuf
.st_ex_mode
& S_IWOTH
)) {
4619 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4620 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4625 /* Ensure the template share exists if it's set. */
4626 if (Globals
.szUsershareTemplateShare
[0]) {
4627 /* We can't use lp_servicenumber here as we are recommending that
4628 template shares have -valid=false set. */
4629 for (snum_template
= iNumServices
- 1; snum_template
>= 0; snum_template
--) {
4630 if (ServicePtrs
[snum_template
]->szService
&&
4631 strequal(ServicePtrs
[snum_template
]->szService
,
4632 Globals
.szUsershareTemplateShare
)) {
4637 if (snum_template
== -1) {
4638 DEBUG(0,("load_usershare_shares: usershare template share %s "
4639 "does not exist.\n",
4640 Globals
.szUsershareTemplateShare
));
4645 /* Mark all existing usershares as pending delete. */
4646 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4647 if (VALID(iService
) && ServicePtrs
[iService
]->usershare
) {
4648 ServicePtrs
[iService
]->usershare
= USERSHARE_PENDING_DELETE
;
4652 dp
= opendir(usersharepath
);
4654 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4655 usersharepath
, strerror(errno
) ));
4659 for (num_dir_entries
= 0, num_bad_dir_entries
= 0, num_tmp_dir_entries
= 0;
4661 num_dir_entries
++ ) {
4663 const char *n
= de
->d_name
;
4665 /* Ignore . and .. */
4667 if ((n
[1] == '\0') || (n
[1] == '.' && n
[2] == '\0')) {
4673 /* Temporary file used when creating a share. */
4674 num_tmp_dir_entries
++;
4677 /* Allow 20% tmp entries. */
4678 if (num_tmp_dir_entries
> allowed_tmp_entries
) {
4679 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4680 "in directory %s\n",
4681 num_tmp_dir_entries
, usersharepath
));
4685 r
= process_usershare_file(usersharepath
, n
, snum_template
);
4687 /* Update the services count. */
4689 if (num_usershares
>= max_user_shares
) {
4690 DEBUG(0,("load_usershare_shares: max user shares reached "
4691 "on file %s in directory %s\n",
4692 n
, usersharepath
));
4695 } else if (r
== -1) {
4696 num_bad_dir_entries
++;
4699 /* Allow 20% bad entries. */
4700 if (num_bad_dir_entries
> allowed_bad_entries
) {
4701 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4702 "in directory %s\n",
4703 num_bad_dir_entries
, usersharepath
));
4707 /* Allow 20% bad entries. */
4708 if (num_dir_entries
> max_user_shares
+ allowed_bad_entries
) {
4709 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4710 "in directory %s\n",
4711 num_dir_entries
, usersharepath
));
4718 /* Sweep through and delete any non-refreshed usershares that are
4719 not currently in use. */
4720 tmp_ctx
= talloc_stackframe();
4721 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
4722 if (VALID(iService
) && (ServicePtrs
[iService
]->usershare
== USERSHARE_PENDING_DELETE
)) {
4725 if (snumused
&& snumused(sconn
, iService
)) {
4729 servname
= lp_servicename(tmp_ctx
, iService
);
4731 /* Remove from the share ACL db. */
4732 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4734 delete_share_security(servname
);
4735 free_service_byindex(iService
);
4738 talloc_free(tmp_ctx
);
4740 return lp_numservices();
4743 /********************************************************
4744 Destroy global resources allocated in this file
4745 ********************************************************/
4747 void gfree_loadparm(void)
4753 /* Free resources allocated to services */
4755 for ( i
= 0; i
< iNumServices
; i
++ ) {
4757 free_service_byindex(i
);
4761 SAFE_FREE( ServicePtrs
);
4764 /* Now release all resources allocated to global
4765 parameters and the default service */
4767 free_global_parameters();
4771 /***************************************************************************
4772 Allow client apps to specify that they are a client
4773 ***************************************************************************/
4774 static void lp_set_in_client(bool b
)
4780 /***************************************************************************
4781 Determine if we're running in a client app
4782 ***************************************************************************/
4783 static bool lp_is_in_client(void)
4788 /***************************************************************************
4789 Load the services array from the services file. Return true on success,
4791 ***************************************************************************/
4793 static bool lp_load_ex(const char *pszFname
,
4797 bool initialize_globals
,
4798 bool allow_include_registry
,
4799 bool load_all_shares
)
4806 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
4808 bInGlobalSection
= true;
4809 bGlobalOnly
= global_only
;
4810 bAllowIncludeRegistry
= allow_include_registry
;
4812 init_globals(initialize_globals
);
4816 if (save_defaults
) {
4821 if (!initialize_globals
) {
4822 free_param_opts(&Globals
.param_opt
);
4823 apply_lp_set_cmdline();
4826 lp_do_parameter(-1, "idmap config * : backend", Globals
.szIdmapBackend
);
4828 /* We get sections first, so have to start 'behind' to make up */
4831 if (lp_config_backend_is_file()) {
4832 n2
= talloc_sub_basic(talloc_tos(), get_current_username(),
4833 current_user_info
.domain
,
4836 smb_panic("lp_load_ex: out of memory");
4839 add_to_file_list(pszFname
, n2
);
4841 bRetval
= pm_process(n2
, do_section
, do_parameter
, NULL
);
4844 /* finish up the last section */
4845 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval
)));
4847 if (iServiceIndex
>= 0) {
4848 bRetval
= service_ok(iServiceIndex
);
4852 if (lp_config_backend_is_registry()) {
4853 /* config backend changed to registry in config file */
4855 * We need to use this extra global variable here to
4856 * survive restart: init_globals uses this as a default
4857 * for ConfigBackend. Otherwise, init_globals would
4858 * send us into an endless loop here.
4860 config_backend
= CONFIG_BACKEND_REGISTRY
;
4862 DEBUG(1, ("lp_load_ex: changing to config backend "
4865 lp_kill_all_services();
4866 return lp_load_ex(pszFname
, global_only
, save_defaults
,
4867 add_ipc
, initialize_globals
,
4868 allow_include_registry
,
4871 } else if (lp_config_backend_is_registry()) {
4872 bRetval
= process_registry_globals();
4874 DEBUG(0, ("Illegal config backend given: %d\n",
4875 lp_config_backend()));
4879 if (bRetval
&& lp_registry_shares()) {
4880 if (load_all_shares
) {
4881 bRetval
= process_registry_shares();
4883 bRetval
= reload_registry_shares();
4888 char *serv
= lp_auto_services(talloc_tos());
4889 lp_add_auto_services(serv
);
4894 /* When 'restrict anonymous = 2' guest connections to ipc$
4896 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4897 if ( lp_enable_asu_support() ) {
4898 lp_add_ipc("ADMIN$", false);
4902 set_allowed_client_auth();
4904 if (lp_security() == SEC_ADS
&& strchr(lp_passwordserver(), ':')) {
4905 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
4906 lp_passwordserver()));
4911 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
4912 /* if bWINSsupport is true and we are in the client */
4913 if (lp_is_in_client() && Globals
.bWINSsupport
) {
4914 lp_do_parameter(GLOBAL_SECTION_SNUM
, "wins server", "127.0.0.1");
4919 fault_configure(smb_panic_s3
);
4922 * We run this check once the whole smb.conf is parsed, to
4923 * force some settings for the standard way a AD DC is
4924 * operated. We may changed these as our code evolves, which
4925 * is why we force these settings.
4927 if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
4928 lp_do_parameter(-1, "passdb backend", "samba_dsdb");
4930 lp_do_parameter(-1, "rpc_server:default", "external");
4931 lp_do_parameter(-1, "rpc_server:svcctl", "embedded");
4932 lp_do_parameter(-1, "rpc_server:srvsvc", "embedded");
4933 lp_do_parameter(-1, "rpc_server:eventlog", "embedded");
4934 lp_do_parameter(-1, "rpc_server:ntsvcs", "embedded");
4935 lp_do_parameter(-1, "rpc_server:winreg", "embedded");
4936 lp_do_parameter(-1, "rpc_server:spoolss", "embedded");
4937 lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded");
4938 lp_do_parameter(-1, "rpc_server:tcpip", "no");
4941 bAllowIncludeRegistry
= true;
4946 bool lp_load(const char *pszFname
,
4950 bool initialize_globals
)
4952 return lp_load_ex(pszFname
,
4957 true, /* allow_include_registry */
4958 false); /* load_all_shares*/
4961 bool lp_load_initial_only(const char *pszFname
)
4963 return lp_load_ex(pszFname
,
4964 true, /* global only */
4965 false, /* save_defaults */
4966 false, /* add_ipc */
4967 true, /* initialize_globals */
4968 false, /* allow_include_registry */
4969 false); /* load_all_shares*/
4973 * most common lp_load wrapper, loading only the globals
4975 bool lp_load_global(const char *file_name
)
4977 return lp_load_ex(file_name
,
4978 true, /* global_only */
4979 false, /* save_defaults */
4980 false, /* add_ipc */
4981 true, /* initialize_globals */
4982 true, /* allow_include_registry */
4983 false); /* load_all_shares*/
4987 * lp_load wrapper, especially for clients
4989 bool lp_load_client(const char *file_name
)
4991 lp_set_in_client(true);
4993 return lp_load_global(file_name
);
4997 * lp_load wrapper, loading only globals, but intended
4998 * for subsequent calls, not reinitializing the globals
5001 bool lp_load_global_no_reinit(const char *file_name
)
5003 return lp_load_ex(file_name
,
5004 true, /* global_only */
5005 false, /* save_defaults */
5006 false, /* add_ipc */
5007 false, /* initialize_globals */
5008 true, /* allow_include_registry */
5009 false); /* load_all_shares*/
5013 * lp_load wrapper, especially for clients, no reinitialization
5015 bool lp_load_client_no_reinit(const char *file_name
)
5017 lp_set_in_client(true);
5019 return lp_load_global_no_reinit(file_name
);
5022 bool lp_load_with_registry_shares(const char *pszFname
,
5026 bool initialize_globals
)
5028 return lp_load_ex(pszFname
,
5033 true, /* allow_include_registry */
5034 true); /* load_all_shares*/
5037 /***************************************************************************
5038 Return the max number of services.
5039 ***************************************************************************/
5041 int lp_numservices(void)
5043 return (iNumServices
);
5046 /***************************************************************************
5047 Display the contents of the services array in human-readable form.
5048 ***************************************************************************/
5050 void lp_dump(FILE *f
, bool show_defaults
, int maxtoprint
)
5055 defaults_saved
= false;
5059 dump_a_service(&sDefault
, f
);
5061 for (iService
= 0; iService
< maxtoprint
; iService
++) {
5063 lp_dump_one(f
, show_defaults
, iService
);
5067 /***************************************************************************
5068 Display the contents of one service in human-readable form.
5069 ***************************************************************************/
5071 void lp_dump_one(FILE * f
, bool show_defaults
, int snum
)
5074 if (ServicePtrs
[snum
]->szService
[0] == '\0')
5076 dump_a_service(ServicePtrs
[snum
], f
);
5080 /***************************************************************************
5081 Return the number of the service with the given name, or -1 if it doesn't
5082 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5083 getservicebyname()! This works ONLY if all services have been loaded, and
5084 does not copy the found service.
5085 ***************************************************************************/
5087 int lp_servicenumber(const char *pszServiceName
)
5090 fstring serviceName
;
5092 if (!pszServiceName
) {
5093 return GLOBAL_SECTION_SNUM
;
5096 for (iService
= iNumServices
- 1; iService
>= 0; iService
--) {
5097 if (VALID(iService
) && ServicePtrs
[iService
]->szService
) {
5099 * The substitution here is used to support %U is
5102 fstrcpy(serviceName
, ServicePtrs
[iService
]->szService
);
5103 standard_sub_basic(get_current_username(),
5104 current_user_info
.domain
,
5105 serviceName
,sizeof(serviceName
));
5106 if (strequal(serviceName
, pszServiceName
)) {
5112 if (iService
>= 0 && ServicePtrs
[iService
]->usershare
== USERSHARE_VALID
) {
5113 struct timespec last_mod
;
5115 if (!usershare_exists(iService
, &last_mod
)) {
5116 /* Remove the share security tdb entry for it. */
5117 delete_share_security(lp_servicename(talloc_tos(), iService
));
5118 /* Remove it from the array. */
5119 free_service_byindex(iService
);
5120 /* Doesn't exist anymore. */
5121 return GLOBAL_SECTION_SNUM
;
5124 /* Has it been modified ? If so delete and reload. */
5125 if (timespec_compare(&ServicePtrs
[iService
]->usershare_last_mod
,
5127 /* Remove it from the array. */
5128 free_service_byindex(iService
);
5129 /* and now reload it. */
5130 iService
= load_usershare_service(pszServiceName
);
5135 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName
));
5136 return GLOBAL_SECTION_SNUM
;
5142 /*******************************************************************
5143 A useful volume label function.
5144 ********************************************************************/
5146 const char *volume_label(TALLOC_CTX
*ctx
, int snum
)
5149 const char *label
= lp_volume(ctx
, snum
);
5151 label
= lp_servicename(ctx
, snum
);
5154 /* This returns a 33 byte guarenteed null terminated string. */
5155 ret
= talloc_strndup(ctx
, label
, 32);
5162 /*******************************************************************
5163 Get the default server type we will announce as via nmbd.
5164 ********************************************************************/
5166 int lp_default_server_announce(void)
5168 int default_server_announce
= 0;
5169 default_server_announce
|= SV_TYPE_WORKSTATION
;
5170 default_server_announce
|= SV_TYPE_SERVER
;
5171 default_server_announce
|= SV_TYPE_SERVER_UNIX
;
5173 /* note that the flag should be set only if we have a
5174 printer service but nmbd doesn't actually load the
5175 services so we can't tell --jerry */
5177 default_server_announce
|= SV_TYPE_PRINTQ_SERVER
;
5179 default_server_announce
|= SV_TYPE_SERVER_NT
;
5180 default_server_announce
|= SV_TYPE_NT
;
5182 switch (lp_server_role()) {
5183 case ROLE_DOMAIN_MEMBER
:
5184 default_server_announce
|= SV_TYPE_DOMAIN_MEMBER
;
5186 case ROLE_DOMAIN_PDC
:
5187 default_server_announce
|= SV_TYPE_DOMAIN_CTRL
;
5189 case ROLE_DOMAIN_BDC
:
5190 default_server_announce
|= SV_TYPE_DOMAIN_BAKCTRL
;
5192 case ROLE_STANDALONE
:
5196 if (lp_time_server())
5197 default_server_announce
|= SV_TYPE_TIME_SOURCE
;
5199 if (lp_host_msdfs())
5200 default_server_announce
|= SV_TYPE_DFS_SERVER
;
5202 return default_server_announce
;
5205 /***********************************************************
5206 If we are PDC then prefer us as DMB
5207 ************************************************************/
5209 bool lp_domain_master(void)
5211 if (Globals
.domain_master
== Auto
)
5212 return (lp_server_role() == ROLE_DOMAIN_PDC
);
5214 return (bool)Globals
.domain_master
;
5217 /***********************************************************
5218 If we are PDC then prefer us as DMB
5219 ************************************************************/
5221 static bool lp_domain_master_true_or_auto(void)
5223 if (Globals
.domain_master
) /* auto or yes */
5229 /***********************************************************
5230 If we are DMB then prefer us as LMB
5231 ************************************************************/
5233 bool lp_preferred_master(void)
5235 if (Globals
.iPreferredMaster
== Auto
)
5236 return (lp_local_master() && lp_domain_master());
5238 return (bool)Globals
.iPreferredMaster
;
5241 /*******************************************************************
5243 ********************************************************************/
5245 void lp_remove_service(int snum
)
5247 ServicePtrs
[snum
]->valid
= false;
5248 invalid_services
[num_invalid_services
++] = snum
;
5251 /*******************************************************************
5253 ********************************************************************/
5255 void lp_copy_service(int snum
, const char *new_name
)
5257 do_section(new_name
, NULL
);
5259 snum
= lp_servicenumber(new_name
);
5261 char *name
= lp_servicename(talloc_tos(), snum
);
5262 lp_do_parameter(snum
, "copy", name
);
5267 const char *lp_printername(TALLOC_CTX
*ctx
, int snum
)
5269 const char *ret
= lp__printername(talloc_tos(), snum
);
5270 if (ret
== NULL
|| *ret
== '\0') {
5271 ret
= lp_const_servicename(snum
);
5278 /***********************************************************
5279 Allow daemons such as winbindd to fix their logfile name.
5280 ************************************************************/
5282 void lp_set_logfile(const char *name
)
5284 string_set(&Globals
.logfile
, name
);
5285 debug_set_logfile(name
);
5288 /*******************************************************************
5289 Return the max print jobs per queue.
5290 ********************************************************************/
5292 int lp_maxprintjobs(int snum
)
5294 int maxjobs
= LP_SNUM_OK(snum
) ? ServicePtrs
[snum
]->iMaxPrintJobs
: sDefault
.iMaxPrintJobs
;
5295 if (maxjobs
<= 0 || maxjobs
>= PRINT_MAX_JOBID
)
5296 maxjobs
= PRINT_MAX_JOBID
- 1;
5301 const char *lp_printcapname(void)
5303 if ((Globals
.szPrintcapname
!= NULL
) &&
5304 (Globals
.szPrintcapname
[0] != '\0'))
5305 return Globals
.szPrintcapname
;
5307 if (sDefault
.iPrinting
== PRINT_CUPS
) {
5311 if (sDefault
.iPrinting
== PRINT_BSD
)
5312 return "/etc/printcap";
5314 return PRINTCAP_NAME
;
5317 static uint32 spoolss_state
;
5319 bool lp_disable_spoolss( void )
5321 if ( spoolss_state
== SVCCTL_STATE_UNKNOWN
)
5322 spoolss_state
= lp__disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
5324 return spoolss_state
== SVCCTL_STOPPED
? true : false;
5327 void lp_set_spoolss_state( uint32 state
)
5329 SMB_ASSERT( (state
== SVCCTL_STOPPED
) || (state
== SVCCTL_RUNNING
) );
5331 spoolss_state
= state
;
5334 uint32
lp_get_spoolss_state( void )
5336 return lp_disable_spoolss() ? SVCCTL_STOPPED
: SVCCTL_RUNNING
;
5339 /*******************************************************************
5340 Ensure we don't use sendfile if server smb signing is active.
5341 ********************************************************************/
5343 bool lp_use_sendfile(int snum
, struct smb_signing_state
*signing_state
)
5345 bool sign_active
= false;
5347 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5348 if (get_Protocol() < PROTOCOL_NT1
) {
5351 if (signing_state
) {
5352 sign_active
= smb_signing_is_active(signing_state
);
5354 return (lp__use_sendfile(snum
) &&
5355 (get_remote_arch() != RA_WIN95
) &&
5359 /*******************************************************************
5360 Turn off sendfile if we find the underlying OS doesn't support it.
5361 ********************************************************************/
5363 void set_use_sendfile(int snum
, bool val
)
5365 if (LP_SNUM_OK(snum
))
5366 ServicePtrs
[snum
]->bUseSendfile
= val
;
5368 sDefault
.bUseSendfile
= val
;
5371 /*******************************************************************
5372 Turn off storing DOS attributes if this share doesn't support it.
5373 ********************************************************************/
5375 void set_store_dos_attributes(int snum
, bool val
)
5377 if (!LP_SNUM_OK(snum
))
5379 ServicePtrs
[(snum
)]->bStoreDosAttributes
= val
;
5382 void lp_set_mangling_method(const char *new_method
)
5384 string_set(&Globals
.szManglingMethod
, new_method
);
5387 /*******************************************************************
5388 Global state for POSIX pathname processing.
5389 ********************************************************************/
5391 static bool posix_pathnames
;
5393 bool lp_posix_pathnames(void)
5395 return posix_pathnames
;
5398 /*******************************************************************
5399 Change everything needed to ensure POSIX pathname processing (currently
5401 ********************************************************************/
5403 void lp_set_posix_pathnames(void)
5405 posix_pathnames
= true;
5408 /*******************************************************************
5409 Global state for POSIX lock processing - CIFS unix extensions.
5410 ********************************************************************/
5412 bool posix_default_lock_was_set
;
5413 static enum brl_flavour posix_cifsx_locktype
; /* By default 0 == WINDOWS_LOCK */
5415 enum brl_flavour
lp_posix_cifsu_locktype(files_struct
*fsp
)
5417 if (posix_default_lock_was_set
) {
5418 return posix_cifsx_locktype
;
5420 return fsp
->posix_open
? POSIX_LOCK
: WINDOWS_LOCK
;
5424 /*******************************************************************
5425 ********************************************************************/
5427 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val
)
5429 posix_default_lock_was_set
= true;
5430 posix_cifsx_locktype
= val
;
5433 int lp_min_receive_file_size(void)
5435 if (Globals
.iminreceivefile
< 0) {
5438 return Globals
.iminreceivefile
;
5441 /*******************************************************************
5442 Safe wide links checks.
5443 This helper function always verify the validity of wide links,
5444 even after a configuration file reload.
5445 ********************************************************************/
5447 static bool lp_widelinks_internal(int snum
)
5449 return (bool)(LP_SNUM_OK(snum
)? ServicePtrs
[(snum
)]->bWidelinks
:
5450 sDefault
.bWidelinks
);
5453 void widelinks_warning(int snum
)
5455 if (lp_allow_insecure_widelinks()) {
5459 if (lp_unix_extensions() && lp_widelinks_internal(snum
)) {
5460 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
5461 "These parameters are incompatible. "
5462 "Wide links will be disabled for this share.\n",
5463 lp_servicename(talloc_tos(), snum
) ));
5467 bool lp_widelinks(int snum
)
5469 /* wide links is always incompatible with unix extensions */
5470 if (lp_unix_extensions()) {
5472 * Unless we have "allow insecure widelinks"
5475 if (!lp_allow_insecure_widelinks()) {
5480 return lp_widelinks_internal(snum
);
5483 bool lp_writeraw(void)
5485 if (lp_async_smb_echo_handler()) {
5488 return lp__writeraw();
5491 bool lp_readraw(void)
5493 if (lp_async_smb_echo_handler()) {
5496 return lp__readraw();
5499 int lp_server_role(void)
5501 return lp_find_server_role(lp__server_role(),
5503 lp__domain_logons(),
5504 lp_domain_master_true_or_auto());
5507 int lp_security(void)
5509 return lp_find_security(lp__server_role(),