s3:loadparm: fix the reload of the configuration: also reload activated registry...
[Samba.git] / source3 / param / loadparm.c
blobbec525e59a80fffae253a9e054711d34090b3ce3
1 /*
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
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 3 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
29 * Load parameters.
31 * This module provides suitable callback functions for the params
32 * module. It builds the internal table of service details which is
33 * then used by the rest of the server.
35 * To add a parameter:
37 * 1) add it to the global or service structure definition
38 * 2) add it to the parm_table
39 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40 * 4) If it's a global then initialise it in init_globals. If a local
41 * (ie. service) parameter then initialise it in the sDefault structure
44 * Notes:
45 * The configuration file is processed sequentially for speed. It is NOT
46 * accessed randomly as happens in 'real' Windows. For this reason, there
47 * is a fair bit of sequence-dependent code here - ie., code which assumes
48 * that certain things happen before others. In particular, the code which
49 * happens at the boundary between sections is delicately poised, so be
50 * careful!
54 #include "includes.h"
55 #include "system/filesys.h"
56 #include "util_tdb.h"
57 #include "printing.h"
58 #include "lib/smbconf/smbconf.h"
59 #include "lib/smbconf/smbconf_init.h"
61 #include "ads.h"
62 #include "../librpc/gen_ndr/svcctl.h"
63 #include "intl.h"
64 #include "smb_signing.h"
65 #include "dbwrap.h"
66 #include "smbldap.h"
68 #ifdef HAVE_SYS_SYSCTL_H
69 #include <sys/sysctl.h>
70 #endif
72 #ifdef HAVE_HTTPCONNECTENCRYPT
73 #include <cups/http.h>
74 #endif
76 bool bLoaded = False;
78 extern userdom_struct current_user_info;
80 #ifndef GLOBAL_NAME
81 #define GLOBAL_NAME "global"
82 #endif
84 #ifndef PRINTERS_NAME
85 #define PRINTERS_NAME "printers"
86 #endif
88 #ifndef HOMES_NAME
89 #define HOMES_NAME "homes"
90 #endif
92 /* the special value for the include parameter
93 * to be interpreted not as a file name but to
94 * trigger loading of the global smb.conf options
95 * from registry. */
96 #ifndef INCLUDE_REGISTRY_NAME
97 #define INCLUDE_REGISTRY_NAME "registry"
98 #endif
100 static bool in_client = False; /* Not in the client by default */
101 static struct smbconf_csn conf_last_csn;
103 #define CONFIG_BACKEND_FILE 0
104 #define CONFIG_BACKEND_REGISTRY 1
106 static int config_backend = CONFIG_BACKEND_FILE;
108 /* some helpful bits */
109 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
110 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
112 #define USERSHARE_VALID 1
113 #define USERSHARE_PENDING_DELETE 2
115 static bool defaults_saved = False;
117 struct param_opt_struct {
118 struct param_opt_struct *prev, *next;
119 char *key;
120 char *value;
121 char **list;
122 unsigned flags;
126 * This structure describes global (ie., server-wide) parameters.
128 struct global {
129 int ConfigBackend;
130 char *smb_ports;
131 char *dos_charset;
132 char *unix_charset;
133 char *display_charset;
134 char *szPrintcapname;
135 char *szAddPortCommand;
136 char *szEnumPortsCommand;
137 char *szAddPrinterCommand;
138 char *szDeletePrinterCommand;
139 char *szOs2DriverMap;
140 char *szLockDir;
141 char *szStateDir;
142 char *szCacheDir;
143 char *szPidDir;
144 char *szRootdir;
145 char *szDefaultService;
146 char *szGetQuota;
147 char *szSetQuota;
148 char *szMsgCommand;
149 char *szServerString;
150 char *szAutoServices;
151 char *szPasswdProgram;
152 char *szPasswdChat;
153 char *szLogFile;
154 char *szConfigFile;
155 char *szSMBPasswdFile;
156 char *szPrivateDir;
157 char *szPassdbBackend;
158 char **szPreloadModules;
159 char *szPasswordServer;
160 char *szSocketOptions;
161 char *szRealm;
162 char *szAfsUsernameMap;
163 int iAfsTokenLifetime;
164 char *szLogNtTokenCommand;
165 char *szUsernameMap;
166 char *szLogonScript;
167 char *szLogonPath;
168 char *szLogonDrive;
169 char *szLogonHome;
170 char **szWINSservers;
171 char **szInterfaces;
172 char *szRemoteAnnounce;
173 char *szRemoteBrowseSync;
174 char *szSocketAddress;
175 bool bNmbdBindExplicitBroadcast;
176 char *szNISHomeMapName;
177 char *szAnnounceVersion; /* This is initialised in init_globals */
178 char *szWorkgroup;
179 char *szNetbiosName;
180 char **szNetbiosAliases;
181 char *szNetbiosScope;
182 char *szNameResolveOrder;
183 char *szPanicAction;
184 char *szAddUserScript;
185 char *szRenameUserScript;
186 char *szDelUserScript;
187 char *szAddGroupScript;
188 char *szDelGroupScript;
189 char *szAddUserToGroupScript;
190 char *szDelUserFromGroupScript;
191 char *szSetPrimaryGroupScript;
192 char *szAddMachineScript;
193 char *szShutdownScript;
194 char *szAbortShutdownScript;
195 char *szUsernameMapScript;
196 int iUsernameMapCacheTime;
197 char *szCheckPasswordScript;
198 char *szWINSHook;
199 char *szUtmpDir;
200 char *szWtmpDir;
201 bool bUtmp;
202 char *szIdmapUID;
203 char *szIdmapGID;
204 bool bPassdbExpandExplicit;
205 int AlgorithmicRidBase;
206 char *szTemplateHomedir;
207 char *szTemplateShell;
208 char *szWinbindSeparator;
209 bool bWinbindEnumUsers;
210 bool bWinbindEnumGroups;
211 bool bWinbindUseDefaultDomain;
212 bool bWinbindTrustedDomainsOnly;
213 bool bWinbindNestedGroups;
214 int winbind_expand_groups;
215 bool bWinbindRefreshTickets;
216 bool bWinbindOfflineLogon;
217 bool bWinbindNormalizeNames;
218 bool bWinbindRpcOnly;
219 bool bCreateKrb5Conf;
220 int winbindMaxDomainConnections;
221 char *szIdmapBackend;
222 bool bIdmapReadOnly;
223 char *szAddShareCommand;
224 char *szChangeShareCommand;
225 char *szDeleteShareCommand;
226 char **szEventLogs;
227 char *szGuestaccount;
228 char *szManglingMethod;
229 char **szServicesList;
230 char *szUsersharePath;
231 char *szUsershareTemplateShare;
232 char **szUsersharePrefixAllowList;
233 char **szUsersharePrefixDenyList;
234 int mangle_prefix;
235 int max_log_size;
236 char *szLogLevel;
237 int max_xmit;
238 int max_mux;
239 int max_open_files;
240 int open_files_db_hash_size;
241 int pwordlevel;
242 int unamelevel;
243 int deadtime;
244 bool getwd_cache;
245 int maxprotocol;
246 int minprotocol;
247 int security;
248 char **AuthMethods;
249 bool paranoid_server_security;
250 int maxdisksize;
251 int lpqcachetime;
252 int iMaxSmbdProcesses;
253 bool bDisableSpoolss;
254 int syslog;
255 int os_level;
256 bool enhanced_browsing;
257 int max_ttl;
258 int max_wins_ttl;
259 int min_wins_ttl;
260 int lm_announce;
261 int lm_interval;
262 int announce_as; /* This is initialised in init_globals */
263 int machine_password_timeout;
264 int map_to_guest;
265 int oplock_break_wait_time;
266 int winbind_cache_time;
267 int winbind_reconnect_delay;
268 int winbind_max_clients;
269 char **szWinbindNssInfo;
270 int iLockSpinTime;
271 char *szLdapMachineSuffix;
272 char *szLdapUserSuffix;
273 char *szLdapIdmapSuffix;
274 char *szLdapGroupSuffix;
275 int ldap_ssl;
276 bool ldap_ssl_ads;
277 int ldap_deref;
278 int ldap_follow_referral;
279 char *szLdapSuffix;
280 char *szLdapAdminDn;
281 int ldap_debug_level;
282 int ldap_debug_threshold;
283 int iAclCompat;
284 char *szCupsServer;
285 int CupsEncrypt;
286 char *szIPrintServer;
287 char *ctdbdSocket;
288 char **szClusterAddresses;
289 bool clustering;
290 int ctdb_timeout;
291 int ctdb_locktime_warn_threshold;
292 int ldap_passwd_sync;
293 int ldap_replication_sleep;
294 int ldap_timeout; /* This is initialised in init_globals */
295 int ldap_connection_timeout;
296 int ldap_page_size;
297 bool ldap_delete_dn;
298 bool bMsAddPrinterWizard;
299 bool bDNSproxy;
300 bool bWINSsupport;
301 bool bWINSproxy;
302 bool bLocalMaster;
303 int iPreferredMaster;
304 int iDomainMaster;
305 bool bDomainLogons;
306 char **szInitLogonDelayedHosts;
307 int InitLogonDelay;
308 bool bEncryptPasswords;
309 bool bUpdateEncrypt;
310 int clientSchannel;
311 int serverSchannel;
312 bool bNullPasswords;
313 bool bObeyPamRestrictions;
314 bool bLoadPrinters;
315 int PrintcapCacheTime;
316 bool bLargeReadwrite;
317 bool bReadRaw;
318 bool bWriteRaw;
319 bool bSyslogOnly;
320 bool bBrowseList;
321 bool bNISHomeMap;
322 bool bTimeServer;
323 bool bBindInterfacesOnly;
324 bool bPamPasswordChange;
325 bool bUnixPasswdSync;
326 bool bPasswdChatDebug;
327 int iPasswdChatTimeout;
328 bool bTimestampLogs;
329 bool bNTSmbSupport;
330 bool bNTPipeSupport;
331 bool bNTStatusSupport;
332 bool bStatCache;
333 int iMaxStatCacheSize;
334 bool bKernelOplocks;
335 bool bAllowTrustedDomains;
336 bool bLanmanAuth;
337 bool bNTLMAuth;
338 bool bUseSpnego;
339 bool bClientLanManAuth;
340 bool bClientNTLMv2Auth;
341 bool bClientPlaintextAuth;
342 bool bClientUseSpnego;
343 bool client_use_spnego_principal;
344 bool send_spnego_principal;
345 bool bDebugPrefixTimestamp;
346 bool bDebugHiresTimestamp;
347 bool bDebugPid;
348 bool bDebugUid;
349 bool bDebugClass;
350 bool bEnableCoreFiles;
351 bool bHostMSDfs;
352 bool bUseMmap;
353 bool bHostnameLookups;
354 bool bUnixExtensions;
355 bool bDisableNetbios;
356 char * szDedicatedKeytabFile;
357 int iKerberosMethod;
358 bool bDeferSharingViolations;
359 bool bEnablePrivileges;
360 bool bASUSupport;
361 bool bUsershareOwnerOnly;
362 bool bUsershareAllowGuests;
363 bool bRegistryShares;
364 int restrict_anonymous;
365 int name_cache_timeout;
366 int client_signing;
367 int server_signing;
368 int client_ldap_sasl_wrapping;
369 int iUsershareMaxShares;
370 int iIdmapCacheTime;
371 int iIdmapNegativeCacheTime;
372 bool bResetOnZeroVC;
373 bool bLogWriteableFilesOnExit;
374 int iKeepalive;
375 int iminreceivefile;
376 struct param_opt_struct *param_opt;
377 int cups_connection_timeout;
378 char *szSMBPerfcountModule;
379 bool bMapUntrustedToDomain;
380 bool bAsyncSMBEchoHandler;
381 bool bMulticastDnsRegister;
382 int ismb2_max_read;
383 int ismb2_max_write;
384 int ismb2_max_trans;
385 int ismb2_max_credits;
386 char *ncalrpc_dir;
389 static struct global Globals;
392 * This structure describes a single service.
394 struct service {
395 bool valid;
396 bool autoloaded;
397 int usershare;
398 struct timespec usershare_last_mod;
399 char *szService;
400 char *szPath;
401 char *szUsername;
402 char **szInvalidUsers;
403 char **szValidUsers;
404 char **szAdminUsers;
405 char *szCopy;
406 char *szInclude;
407 char *szPreExec;
408 char *szPostExec;
409 char *szRootPreExec;
410 char *szRootPostExec;
411 char *szCupsOptions;
412 char *szPrintcommand;
413 char *szLpqcommand;
414 char *szLprmcommand;
415 char *szLppausecommand;
416 char *szLpresumecommand;
417 char *szQueuepausecommand;
418 char *szQueueresumecommand;
419 char *szPrintername;
420 char *szPrintjobUsername;
421 char *szDontdescend;
422 char **szHostsallow;
423 char **szHostsdeny;
424 char *szMagicScript;
425 char *szMagicOutput;
426 char *szVetoFiles;
427 char *szHideFiles;
428 char *szVetoOplockFiles;
429 char *comment;
430 char *force_user;
431 char *force_group;
432 char **readlist;
433 char **writelist;
434 char **printer_admin;
435 char *volume;
436 char *fstype;
437 char **szVfsObjects;
438 char *szMSDfsProxy;
439 char *szAioWriteBehind;
440 char *szDfree;
441 int iMinPrintSpace;
442 int iMaxPrintJobs;
443 int iMaxReportedPrintJobs;
444 int iWriteCacheSize;
445 int iCreate_mask;
446 int iCreate_force_mode;
447 int iSecurity_mask;
448 int iSecurity_force_mode;
449 int iDir_mask;
450 int iDir_force_mode;
451 int iDir_Security_mask;
452 int iDir_Security_force_mode;
453 int iMaxConnections;
454 int iDefaultCase;
455 int iPrinting;
456 int iOplockContentionLimit;
457 int iCSCPolicy;
458 int iBlock_size;
459 int iDfreeCacheTime;
460 bool bPreexecClose;
461 bool bRootpreexecClose;
462 int iCaseSensitive;
463 bool bCasePreserve;
464 bool bShortCasePreserve;
465 bool bHideDotFiles;
466 bool bHideSpecialFiles;
467 bool bHideUnReadable;
468 bool bHideUnWriteableFiles;
469 bool bBrowseable;
470 bool bAccessBasedShareEnum;
471 bool bAvailable;
472 bool bRead_only;
473 bool bNo_set_dir;
474 bool bGuest_only;
475 bool bAdministrative_share;
476 bool bGuest_ok;
477 bool bPrint_ok;
478 bool bPrintNotifyBackchannel;
479 bool bMap_system;
480 bool bMap_hidden;
481 bool bMap_archive;
482 bool bStoreDosAttributes;
483 bool bDmapiSupport;
484 bool bLocking;
485 int iStrictLocking;
486 bool bPosixLocking;
487 bool bShareModes;
488 bool bOpLocks;
489 bool bLevel2OpLocks;
490 bool bOnlyUser;
491 bool bMangledNames;
492 bool bWidelinks;
493 bool bSymlinks;
494 bool bSyncAlways;
495 bool bStrictAllocate;
496 bool bStrictSync;
497 char magic_char;
498 struct bitmap *copymap;
499 bool bDeleteReadonly;
500 bool bFakeOplocks;
501 bool bDeleteVetoFiles;
502 bool bDosFilemode;
503 bool bDosFiletimes;
504 bool bDosFiletimeResolution;
505 bool bFakeDirCreateTimes;
506 bool bBlockingLocks;
507 bool bInheritPerms;
508 bool bInheritACLS;
509 bool bInheritOwner;
510 bool bMSDfsRoot;
511 bool bUseClientDriver;
512 bool bDefaultDevmode;
513 bool bForcePrintername;
514 bool bNTAclSupport;
515 bool bForceUnknownAclUser;
516 bool bUseSendfile;
517 bool bProfileAcls;
518 bool bMap_acl_inherit;
519 bool bAfs_Share;
520 bool bEASupport;
521 bool bAclCheckPermissions;
522 bool bAclMapFullControl;
523 bool bAclGroupControl;
524 bool bChangeNotify;
525 bool bKernelChangeNotify;
526 int iallocation_roundup_size;
527 int iAioReadSize;
528 int iAioWriteSize;
529 int iMap_readonly;
530 int iDirectoryNameCacheSize;
531 int ismb_encrypt;
532 struct param_opt_struct *param_opt;
534 char dummy[3]; /* for alignment */
538 /* This is a default service used to prime a services structure */
539 static struct service sDefault = {
540 True, /* valid */
541 False, /* not autoloaded */
542 0, /* not a usershare */
543 {0, }, /* No last mod time */
544 NULL, /* szService */
545 NULL, /* szPath */
546 NULL, /* szUsername */
547 NULL, /* szInvalidUsers */
548 NULL, /* szValidUsers */
549 NULL, /* szAdminUsers */
550 NULL, /* szCopy */
551 NULL, /* szInclude */
552 NULL, /* szPreExec */
553 NULL, /* szPostExec */
554 NULL, /* szRootPreExec */
555 NULL, /* szRootPostExec */
556 NULL, /* szCupsOptions */
557 NULL, /* szPrintcommand */
558 NULL, /* szLpqcommand */
559 NULL, /* szLprmcommand */
560 NULL, /* szLppausecommand */
561 NULL, /* szLpresumecommand */
562 NULL, /* szQueuepausecommand */
563 NULL, /* szQueueresumecommand */
564 NULL, /* szPrintername */
565 NULL, /* szPrintjobUsername */
566 NULL, /* szDontdescend */
567 NULL, /* szHostsallow */
568 NULL, /* szHostsdeny */
569 NULL, /* szMagicScript */
570 NULL, /* szMagicOutput */
571 NULL, /* szVetoFiles */
572 NULL, /* szHideFiles */
573 NULL, /* szVetoOplockFiles */
574 NULL, /* comment */
575 NULL, /* force user */
576 NULL, /* force group */
577 NULL, /* readlist */
578 NULL, /* writelist */
579 NULL, /* printer admin */
580 NULL, /* volume */
581 NULL, /* fstype */
582 NULL, /* vfs objects */
583 NULL, /* szMSDfsProxy */
584 NULL, /* szAioWriteBehind */
585 NULL, /* szDfree */
586 0, /* iMinPrintSpace */
587 1000, /* iMaxPrintJobs */
588 0, /* iMaxReportedPrintJobs */
589 0, /* iWriteCacheSize */
590 0744, /* iCreate_mask */
591 0000, /* iCreate_force_mode */
592 0777, /* iSecurity_mask */
593 0, /* iSecurity_force_mode */
594 0755, /* iDir_mask */
595 0000, /* iDir_force_mode */
596 0777, /* iDir_Security_mask */
597 0, /* iDir_Security_force_mode */
598 0, /* iMaxConnections */
599 CASE_LOWER, /* iDefaultCase */
600 DEFAULT_PRINTING, /* iPrinting */
601 2, /* iOplockContentionLimit */
602 0, /* iCSCPolicy */
603 1024, /* iBlock_size */
604 0, /* iDfreeCacheTime */
605 False, /* bPreexecClose */
606 False, /* bRootpreexecClose */
607 Auto, /* case sensitive */
608 True, /* case preserve */
609 True, /* short case preserve */
610 True, /* bHideDotFiles */
611 False, /* bHideSpecialFiles */
612 False, /* bHideUnReadable */
613 False, /* bHideUnWriteableFiles */
614 True, /* bBrowseable */
615 False, /* bAccessBasedShareEnum */
616 True, /* bAvailable */
617 True, /* bRead_only */
618 True, /* bNo_set_dir */
619 False, /* bGuest_only */
620 False, /* bAdministrative_share */
621 False, /* bGuest_ok */
622 False, /* bPrint_ok */
623 True, /* bPrintNotifyBackchannel */
624 False, /* bMap_system */
625 False, /* bMap_hidden */
626 True, /* bMap_archive */
627 False, /* bStoreDosAttributes */
628 False, /* bDmapiSupport */
629 True, /* bLocking */
630 Auto, /* iStrictLocking */
631 True, /* bPosixLocking */
632 True, /* bShareModes */
633 True, /* bOpLocks */
634 True, /* bLevel2OpLocks */
635 False, /* bOnlyUser */
636 True, /* bMangledNames */
637 false, /* bWidelinks */
638 True, /* bSymlinks */
639 False, /* bSyncAlways */
640 False, /* bStrictAllocate */
641 False, /* bStrictSync */
642 '~', /* magic char */
643 NULL, /* copymap */
644 False, /* bDeleteReadonly */
645 False, /* bFakeOplocks */
646 False, /* bDeleteVetoFiles */
647 False, /* bDosFilemode */
648 True, /* bDosFiletimes */
649 False, /* bDosFiletimeResolution */
650 False, /* bFakeDirCreateTimes */
651 True, /* bBlockingLocks */
652 False, /* bInheritPerms */
653 False, /* bInheritACLS */
654 False, /* bInheritOwner */
655 False, /* bMSDfsRoot */
656 False, /* bUseClientDriver */
657 True, /* bDefaultDevmode */
658 False, /* bForcePrintername */
659 True, /* bNTAclSupport */
660 False, /* bForceUnknownAclUser */
661 False, /* bUseSendfile */
662 False, /* bProfileAcls */
663 False, /* bMap_acl_inherit */
664 False, /* bAfs_Share */
665 False, /* bEASupport */
666 True, /* bAclCheckPermissions */
667 True, /* bAclMapFullControl */
668 False, /* bAclGroupControl */
669 True, /* bChangeNotify */
670 True, /* bKernelChangeNotify */
671 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
672 0, /* iAioReadSize */
673 0, /* iAioWriteSize */
674 MAP_READONLY_YES, /* iMap_readonly */
675 #ifdef BROKEN_DIRECTORY_HANDLING
676 0, /* iDirectoryNameCacheSize */
677 #else
678 100, /* iDirectoryNameCacheSize */
679 #endif
680 Auto, /* ismb_encrypt */
681 NULL, /* Parametric options */
683 "" /* dummy */
686 /* local variables */
687 static struct service **ServicePtrs = NULL;
688 static int iNumServices = 0;
689 static int iServiceIndex = 0;
690 static struct db_context *ServiceHash;
691 static int *invalid_services = NULL;
692 static int num_invalid_services = 0;
693 static bool bInGlobalSection = True;
694 static bool bGlobalOnly = False;
695 static int default_server_announce;
697 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
699 /* prototypes for the special type handlers */
700 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
701 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
702 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
703 static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr);
704 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
705 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
706 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
707 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
708 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
709 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
710 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
711 static bool handle_dos_charset( int snum, const char *pszParmValue, char **ptr );
712 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
713 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
715 static void set_default_server_announce_type(void);
716 static void set_allowed_client_auth(void);
718 static void *lp_local_ptr(struct service *service, void *ptr);
720 static void add_to_file_list(const char *fname, const char *subfname);
721 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
723 static const struct enum_list enum_protocol[] = {
724 {PROTOCOL_SMB2, "SMB2"},
725 {PROTOCOL_NT1, "NT1"},
726 {PROTOCOL_LANMAN2, "LANMAN2"},
727 {PROTOCOL_LANMAN1, "LANMAN1"},
728 {PROTOCOL_CORE, "CORE"},
729 {PROTOCOL_COREPLUS, "COREPLUS"},
730 {PROTOCOL_COREPLUS, "CORE+"},
731 {-1, NULL}
734 static const struct enum_list enum_security[] = {
735 {SEC_SHARE, "SHARE"},
736 {SEC_USER, "USER"},
737 {SEC_SERVER, "SERVER"},
738 {SEC_DOMAIN, "DOMAIN"},
739 #ifdef HAVE_ADS
740 {SEC_ADS, "ADS"},
741 #endif
742 {-1, NULL}
745 static const struct enum_list enum_printing[] = {
746 {PRINT_SYSV, "sysv"},
747 {PRINT_AIX, "aix"},
748 {PRINT_HPUX, "hpux"},
749 {PRINT_BSD, "bsd"},
750 {PRINT_QNX, "qnx"},
751 {PRINT_PLP, "plp"},
752 {PRINT_LPRNG, "lprng"},
753 {PRINT_CUPS, "cups"},
754 {PRINT_IPRINT, "iprint"},
755 {PRINT_LPRNT, "nt"},
756 {PRINT_LPROS2, "os2"},
757 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
758 {PRINT_TEST, "test"},
759 {PRINT_VLP, "vlp"},
760 #endif /* DEVELOPER */
761 {-1, NULL}
764 static const struct enum_list enum_ldap_sasl_wrapping[] = {
765 {0, "plain"},
766 {ADS_AUTH_SASL_SIGN, "sign"},
767 {ADS_AUTH_SASL_SEAL, "seal"},
768 {-1, NULL}
771 static const struct enum_list enum_ldap_ssl[] = {
772 {LDAP_SSL_OFF, "no"},
773 {LDAP_SSL_OFF, "off"},
774 {LDAP_SSL_START_TLS, "start tls"},
775 {LDAP_SSL_START_TLS, "start_tls"},
776 {-1, NULL}
779 /* LDAP Dereferencing Alias types */
780 #define SAMBA_LDAP_DEREF_NEVER 0
781 #define SAMBA_LDAP_DEREF_SEARCHING 1
782 #define SAMBA_LDAP_DEREF_FINDING 2
783 #define SAMBA_LDAP_DEREF_ALWAYS 3
785 static const struct enum_list enum_ldap_deref[] = {
786 {SAMBA_LDAP_DEREF_NEVER, "never"},
787 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
788 {SAMBA_LDAP_DEREF_FINDING, "finding"},
789 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
790 {-1, "auto"}
793 static const struct enum_list enum_ldap_passwd_sync[] = {
794 {LDAP_PASSWD_SYNC_OFF, "no"},
795 {LDAP_PASSWD_SYNC_OFF, "off"},
796 {LDAP_PASSWD_SYNC_ON, "yes"},
797 {LDAP_PASSWD_SYNC_ON, "on"},
798 {LDAP_PASSWD_SYNC_ONLY, "only"},
799 {-1, NULL}
802 /* Types of machine we can announce as. */
803 #define ANNOUNCE_AS_NT_SERVER 1
804 #define ANNOUNCE_AS_WIN95 2
805 #define ANNOUNCE_AS_WFW 3
806 #define ANNOUNCE_AS_NT_WORKSTATION 4
808 static const struct enum_list enum_announce_as[] = {
809 {ANNOUNCE_AS_NT_SERVER, "NT"},
810 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
811 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
812 {ANNOUNCE_AS_WIN95, "win95"},
813 {ANNOUNCE_AS_WFW, "WfW"},
814 {-1, NULL}
817 static const struct enum_list enum_map_readonly[] = {
818 {MAP_READONLY_NO, "no"},
819 {MAP_READONLY_NO, "false"},
820 {MAP_READONLY_NO, "0"},
821 {MAP_READONLY_YES, "yes"},
822 {MAP_READONLY_YES, "true"},
823 {MAP_READONLY_YES, "1"},
824 {MAP_READONLY_PERMISSIONS, "permissions"},
825 {MAP_READONLY_PERMISSIONS, "perms"},
826 {-1, NULL}
829 static const struct enum_list enum_case[] = {
830 {CASE_LOWER, "lower"},
831 {CASE_UPPER, "upper"},
832 {-1, NULL}
837 static const struct enum_list enum_bool_auto[] = {
838 {False, "No"},
839 {False, "False"},
840 {False, "0"},
841 {True, "Yes"},
842 {True, "True"},
843 {True, "1"},
844 {Auto, "Auto"},
845 {-1, NULL}
848 static const struct enum_list enum_csc_policy[] = {
849 {CSC_POLICY_MANUAL, "manual"},
850 {CSC_POLICY_DOCUMENTS, "documents"},
851 {CSC_POLICY_PROGRAMS, "programs"},
852 {CSC_POLICY_DISABLE, "disable"},
853 {-1, NULL}
856 /* SMB signing types. */
857 static const struct enum_list enum_smb_signing_vals[] = {
858 {False, "No"},
859 {False, "False"},
860 {False, "0"},
861 {False, "Off"},
862 {False, "disabled"},
863 {True, "Yes"},
864 {True, "True"},
865 {True, "1"},
866 {True, "On"},
867 {True, "enabled"},
868 {Auto, "auto"},
869 {Required, "required"},
870 {Required, "mandatory"},
871 {Required, "force"},
872 {Required, "forced"},
873 {Required, "enforced"},
874 {-1, NULL}
877 /* ACL compatibility options. */
878 static const struct enum_list enum_acl_compat_vals[] = {
879 { ACL_COMPAT_AUTO, "auto" },
880 { ACL_COMPAT_WINNT, "winnt" },
881 { ACL_COMPAT_WIN2K, "win2k" },
882 { -1, NULL}
886 Do you want session setups at user level security with a invalid
887 password to be rejected or allowed in as guest? WinNT rejects them
888 but it can be a pain as it means "net view" needs to use a password
890 You have 3 choices in the setting of map_to_guest:
892 "Never" means session setups with an invalid password
893 are rejected. This is the default.
895 "Bad User" means session setups with an invalid password
896 are rejected, unless the username does not exist, in which case it
897 is treated as a guest login
899 "Bad Password" means session setups with an invalid password
900 are treated as a guest login
902 Note that map_to_guest only has an effect in user or server
903 level security.
906 static const struct enum_list enum_map_to_guest[] = {
907 {NEVER_MAP_TO_GUEST, "Never"},
908 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
909 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
910 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
911 {-1, NULL}
914 /* Config backend options */
916 static const struct enum_list enum_config_backend[] = {
917 {CONFIG_BACKEND_FILE, "file"},
918 {CONFIG_BACKEND_REGISTRY, "registry"},
919 {-1, NULL}
922 /* ADS kerberos ticket verification options */
924 static const struct enum_list enum_kerberos_method[] = {
925 {KERBEROS_VERIFY_SECRETS, "default"},
926 {KERBEROS_VERIFY_SECRETS, "secrets only"},
927 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
928 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
929 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
930 {-1, NULL}
933 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
935 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
936 * screen in SWAT. This is used to exclude parameters as well as to squash all
937 * parameters that have been duplicated by pseudonyms.
939 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
940 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
941 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
942 * respective views.
944 * NOTE2: Handling of duplicated (synonym) parameters:
945 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
946 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
947 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
948 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
951 static struct parm_struct parm_table[] = {
952 {N_("Base Options"), P_SEP, P_SEPARATOR},
955 .label = "dos charset",
956 .type = P_STRING,
957 .p_class = P_GLOBAL,
958 .ptr = &Globals.dos_charset,
959 .special = handle_dos_charset,
960 .enum_list = NULL,
961 .flags = FLAG_ADVANCED
964 .label = "unix charset",
965 .type = P_STRING,
966 .p_class = P_GLOBAL,
967 .ptr = &Globals.unix_charset,
968 .special = handle_charset,
969 .enum_list = NULL,
970 .flags = FLAG_ADVANCED
973 .label = "display charset",
974 .type = P_STRING,
975 .p_class = P_GLOBAL,
976 .ptr = &Globals.display_charset,
977 .special = handle_charset,
978 .enum_list = NULL,
979 .flags = FLAG_ADVANCED
982 .label = "comment",
983 .type = P_STRING,
984 .p_class = P_LOCAL,
985 .ptr = &sDefault.comment,
986 .special = NULL,
987 .enum_list = NULL,
988 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
991 .label = "path",
992 .type = P_STRING,
993 .p_class = P_LOCAL,
994 .ptr = &sDefault.szPath,
995 .special = NULL,
996 .enum_list = NULL,
997 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1000 .label = "directory",
1001 .type = P_STRING,
1002 .p_class = P_LOCAL,
1003 .ptr = &sDefault.szPath,
1004 .special = NULL,
1005 .enum_list = NULL,
1006 .flags = FLAG_HIDE,
1009 .label = "workgroup",
1010 .type = P_USTRING,
1011 .p_class = P_GLOBAL,
1012 .ptr = &Globals.szWorkgroup,
1013 .special = handle_workgroup,
1014 .enum_list = NULL,
1015 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1017 #ifdef WITH_ADS
1019 .label = "realm",
1020 .type = P_USTRING,
1021 .p_class = P_GLOBAL,
1022 .ptr = &Globals.szRealm,
1023 .special = NULL,
1024 .enum_list = NULL,
1025 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1027 #endif
1029 .label = "netbios name",
1030 .type = P_USTRING,
1031 .p_class = P_GLOBAL,
1032 .ptr = &Globals.szNetbiosName,
1033 .special = handle_netbios_name,
1034 .enum_list = NULL,
1035 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1038 .label = "netbios aliases",
1039 .type = P_LIST,
1040 .p_class = P_GLOBAL,
1041 .ptr = &Globals.szNetbiosAliases,
1042 .special = handle_netbios_aliases,
1043 .enum_list = NULL,
1044 .flags = FLAG_ADVANCED,
1047 .label = "netbios scope",
1048 .type = P_USTRING,
1049 .p_class = P_GLOBAL,
1050 .ptr = &Globals.szNetbiosScope,
1051 .special = handle_netbios_scope,
1052 .enum_list = NULL,
1053 .flags = FLAG_ADVANCED,
1056 .label = "server string",
1057 .type = P_STRING,
1058 .p_class = P_GLOBAL,
1059 .ptr = &Globals.szServerString,
1060 .special = NULL,
1061 .enum_list = NULL,
1062 .flags = FLAG_BASIC | FLAG_ADVANCED,
1065 .label = "interfaces",
1066 .type = P_LIST,
1067 .p_class = P_GLOBAL,
1068 .ptr = &Globals.szInterfaces,
1069 .special = NULL,
1070 .enum_list = NULL,
1071 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1074 .label = "bind interfaces only",
1075 .type = P_BOOL,
1076 .p_class = P_GLOBAL,
1077 .ptr = &Globals.bBindInterfacesOnly,
1078 .special = NULL,
1079 .enum_list = NULL,
1080 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1083 .label = "config backend",
1084 .type = P_ENUM,
1085 .p_class = P_GLOBAL,
1086 .ptr = &Globals.ConfigBackend,
1087 .special = NULL,
1088 .enum_list = enum_config_backend,
1089 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1092 {N_("Security Options"), P_SEP, P_SEPARATOR},
1095 .label = "security",
1096 .type = P_ENUM,
1097 .p_class = P_GLOBAL,
1098 .ptr = &Globals.security,
1099 .special = NULL,
1100 .enum_list = enum_security,
1101 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1104 .label = "auth methods",
1105 .type = P_LIST,
1106 .p_class = P_GLOBAL,
1107 .ptr = &Globals.AuthMethods,
1108 .special = NULL,
1109 .enum_list = NULL,
1110 .flags = FLAG_ADVANCED,
1113 .label = "encrypt passwords",
1114 .type = P_BOOL,
1115 .p_class = P_GLOBAL,
1116 .ptr = &Globals.bEncryptPasswords,
1117 .special = NULL,
1118 .enum_list = NULL,
1119 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1122 .label = "client schannel",
1123 .type = P_ENUM,
1124 .p_class = P_GLOBAL,
1125 .ptr = &Globals.clientSchannel,
1126 .special = NULL,
1127 .enum_list = enum_bool_auto,
1128 .flags = FLAG_BASIC | FLAG_ADVANCED,
1131 .label = "server schannel",
1132 .type = P_ENUM,
1133 .p_class = P_GLOBAL,
1134 .ptr = &Globals.serverSchannel,
1135 .special = NULL,
1136 .enum_list = enum_bool_auto,
1137 .flags = FLAG_BASIC | FLAG_ADVANCED,
1140 .label = "allow trusted domains",
1141 .type = P_BOOL,
1142 .p_class = P_GLOBAL,
1143 .ptr = &Globals.bAllowTrustedDomains,
1144 .special = NULL,
1145 .enum_list = NULL,
1146 .flags = FLAG_ADVANCED,
1149 .label = "map to guest",
1150 .type = P_ENUM,
1151 .p_class = P_GLOBAL,
1152 .ptr = &Globals.map_to_guest,
1153 .special = NULL,
1154 .enum_list = enum_map_to_guest,
1155 .flags = FLAG_ADVANCED,
1158 .label = "null passwords",
1159 .type = P_BOOL,
1160 .p_class = P_GLOBAL,
1161 .ptr = &Globals.bNullPasswords,
1162 .special = NULL,
1163 .enum_list = NULL,
1164 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1167 .label = "obey pam restrictions",
1168 .type = P_BOOL,
1169 .p_class = P_GLOBAL,
1170 .ptr = &Globals.bObeyPamRestrictions,
1171 .special = NULL,
1172 .enum_list = NULL,
1173 .flags = FLAG_ADVANCED,
1176 .label = "password server",
1177 .type = P_STRING,
1178 .p_class = P_GLOBAL,
1179 .ptr = &Globals.szPasswordServer,
1180 .special = NULL,
1181 .enum_list = NULL,
1182 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1185 .label = "smb passwd file",
1186 .type = P_STRING,
1187 .p_class = P_GLOBAL,
1188 .ptr = &Globals.szSMBPasswdFile,
1189 .special = NULL,
1190 .enum_list = NULL,
1191 .flags = FLAG_ADVANCED,
1194 .label = "private dir",
1195 .type = P_STRING,
1196 .p_class = P_GLOBAL,
1197 .ptr = &Globals.szPrivateDir,
1198 .special = NULL,
1199 .enum_list = NULL,
1200 .flags = FLAG_ADVANCED,
1203 .label = "passdb backend",
1204 .type = P_STRING,
1205 .p_class = P_GLOBAL,
1206 .ptr = &Globals.szPassdbBackend,
1207 .special = NULL,
1208 .enum_list = NULL,
1209 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1212 .label = "algorithmic rid base",
1213 .type = P_INTEGER,
1214 .p_class = P_GLOBAL,
1215 .ptr = &Globals.AlgorithmicRidBase,
1216 .special = NULL,
1217 .enum_list = NULL,
1218 .flags = FLAG_ADVANCED,
1221 .label = "root directory",
1222 .type = P_STRING,
1223 .p_class = P_GLOBAL,
1224 .ptr = &Globals.szRootdir,
1225 .special = NULL,
1226 .enum_list = NULL,
1227 .flags = FLAG_ADVANCED,
1230 .label = "root dir",
1231 .type = P_STRING,
1232 .p_class = P_GLOBAL,
1233 .ptr = &Globals.szRootdir,
1234 .special = NULL,
1235 .enum_list = NULL,
1236 .flags = FLAG_HIDE,
1239 .label = "root",
1240 .type = P_STRING,
1241 .p_class = P_GLOBAL,
1242 .ptr = &Globals.szRootdir,
1243 .special = NULL,
1244 .enum_list = NULL,
1245 .flags = FLAG_HIDE,
1248 .label = "guest account",
1249 .type = P_STRING,
1250 .p_class = P_GLOBAL,
1251 .ptr = &Globals.szGuestaccount,
1252 .special = NULL,
1253 .enum_list = NULL,
1254 .flags = FLAG_BASIC | FLAG_ADVANCED,
1257 .label = "enable privileges",
1258 .type = P_BOOL,
1259 .p_class = P_GLOBAL,
1260 .ptr = &Globals.bEnablePrivileges,
1261 .special = NULL,
1262 .enum_list = NULL,
1263 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1267 .label = "pam password change",
1268 .type = P_BOOL,
1269 .p_class = P_GLOBAL,
1270 .ptr = &Globals.bPamPasswordChange,
1271 .special = NULL,
1272 .enum_list = NULL,
1273 .flags = FLAG_ADVANCED,
1276 .label = "passwd program",
1277 .type = P_STRING,
1278 .p_class = P_GLOBAL,
1279 .ptr = &Globals.szPasswdProgram,
1280 .special = NULL,
1281 .enum_list = NULL,
1282 .flags = FLAG_ADVANCED,
1285 .label = "passwd chat",
1286 .type = P_STRING,
1287 .p_class = P_GLOBAL,
1288 .ptr = &Globals.szPasswdChat,
1289 .special = NULL,
1290 .enum_list = NULL,
1291 .flags = FLAG_ADVANCED,
1294 .label = "passwd chat debug",
1295 .type = P_BOOL,
1296 .p_class = P_GLOBAL,
1297 .ptr = &Globals.bPasswdChatDebug,
1298 .special = NULL,
1299 .enum_list = NULL,
1300 .flags = FLAG_ADVANCED,
1303 .label = "passwd chat timeout",
1304 .type = P_INTEGER,
1305 .p_class = P_GLOBAL,
1306 .ptr = &Globals.iPasswdChatTimeout,
1307 .special = NULL,
1308 .enum_list = NULL,
1309 .flags = FLAG_ADVANCED,
1312 .label = "check password script",
1313 .type = P_STRING,
1314 .p_class = P_GLOBAL,
1315 .ptr = &Globals.szCheckPasswordScript,
1316 .special = NULL,
1317 .enum_list = NULL,
1318 .flags = FLAG_ADVANCED,
1321 .label = "username map",
1322 .type = P_STRING,
1323 .p_class = P_GLOBAL,
1324 .ptr = &Globals.szUsernameMap,
1325 .special = NULL,
1326 .enum_list = NULL,
1327 .flags = FLAG_ADVANCED,
1330 .label = "password level",
1331 .type = P_INTEGER,
1332 .p_class = P_GLOBAL,
1333 .ptr = &Globals.pwordlevel,
1334 .special = NULL,
1335 .enum_list = NULL,
1336 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
1339 .label = "username level",
1340 .type = P_INTEGER,
1341 .p_class = P_GLOBAL,
1342 .ptr = &Globals.unamelevel,
1343 .special = NULL,
1344 .enum_list = NULL,
1345 .flags = FLAG_ADVANCED,
1348 .label = "unix password sync",
1349 .type = P_BOOL,
1350 .p_class = P_GLOBAL,
1351 .ptr = &Globals.bUnixPasswdSync,
1352 .special = NULL,
1353 .enum_list = NULL,
1354 .flags = FLAG_ADVANCED,
1357 .label = "restrict anonymous",
1358 .type = P_INTEGER,
1359 .p_class = P_GLOBAL,
1360 .ptr = &Globals.restrict_anonymous,
1361 .special = NULL,
1362 .enum_list = NULL,
1363 .flags = FLAG_ADVANCED,
1366 .label = "lanman auth",
1367 .type = P_BOOL,
1368 .p_class = P_GLOBAL,
1369 .ptr = &Globals.bLanmanAuth,
1370 .special = NULL,
1371 .enum_list = NULL,
1372 .flags = FLAG_ADVANCED,
1375 .label = "ntlm auth",
1376 .type = P_BOOL,
1377 .p_class = P_GLOBAL,
1378 .ptr = &Globals.bNTLMAuth,
1379 .special = NULL,
1380 .enum_list = NULL,
1381 .flags = FLAG_ADVANCED,
1384 .label = "client NTLMv2 auth",
1385 .type = P_BOOL,
1386 .p_class = P_GLOBAL,
1387 .ptr = &Globals.bClientNTLMv2Auth,
1388 .special = NULL,
1389 .enum_list = NULL,
1390 .flags = FLAG_ADVANCED,
1393 .label = "client lanman auth",
1394 .type = P_BOOL,
1395 .p_class = P_GLOBAL,
1396 .ptr = &Globals.bClientLanManAuth,
1397 .special = NULL,
1398 .enum_list = NULL,
1399 .flags = FLAG_ADVANCED,
1402 .label = "client plaintext auth",
1403 .type = P_BOOL,
1404 .p_class = P_GLOBAL,
1405 .ptr = &Globals.bClientPlaintextAuth,
1406 .special = NULL,
1407 .enum_list = NULL,
1408 .flags = FLAG_ADVANCED,
1411 .label = "client use spnego principal",
1412 .type = P_BOOL,
1413 .p_class = P_GLOBAL,
1414 .ptr = &Globals.client_use_spnego_principal,
1415 .special = NULL,
1416 .enum_list = NULL,
1417 .flags = FLAG_ADVANCED,
1420 .label = "send spnego principal",
1421 .type = P_BOOL,
1422 .p_class = P_GLOBAL,
1423 .ptr = &Globals.send_spnego_principal,
1424 .special = NULL,
1425 .enum_list = NULL,
1426 .flags = FLAG_ADVANCED,
1429 .label = "username",
1430 .type = P_STRING,
1431 .p_class = P_LOCAL,
1432 .ptr = &sDefault.szUsername,
1433 .special = NULL,
1434 .enum_list = NULL,
1435 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED,
1438 .label = "user",
1439 .type = P_STRING,
1440 .p_class = P_LOCAL,
1441 .ptr = &sDefault.szUsername,
1442 .special = NULL,
1443 .enum_list = NULL,
1444 .flags = FLAG_HIDE,
1447 .label = "users",
1448 .type = P_STRING,
1449 .p_class = P_LOCAL,
1450 .ptr = &sDefault.szUsername,
1451 .special = NULL,
1452 .enum_list = NULL,
1453 .flags = FLAG_HIDE,
1456 .label = "invalid users",
1457 .type = P_LIST,
1458 .p_class = P_LOCAL,
1459 .ptr = &sDefault.szInvalidUsers,
1460 .special = NULL,
1461 .enum_list = NULL,
1462 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1465 .label = "valid users",
1466 .type = P_LIST,
1467 .p_class = P_LOCAL,
1468 .ptr = &sDefault.szValidUsers,
1469 .special = NULL,
1470 .enum_list = NULL,
1471 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1474 .label = "admin users",
1475 .type = P_LIST,
1476 .p_class = P_LOCAL,
1477 .ptr = &sDefault.szAdminUsers,
1478 .special = NULL,
1479 .enum_list = NULL,
1480 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1483 .label = "read list",
1484 .type = P_LIST,
1485 .p_class = P_LOCAL,
1486 .ptr = &sDefault.readlist,
1487 .special = NULL,
1488 .enum_list = NULL,
1489 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1492 .label = "write list",
1493 .type = P_LIST,
1494 .p_class = P_LOCAL,
1495 .ptr = &sDefault.writelist,
1496 .special = NULL,
1497 .enum_list = NULL,
1498 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1501 .label = "printer admin",
1502 .type = P_LIST,
1503 .p_class = P_LOCAL,
1504 .ptr = &sDefault.printer_admin,
1505 .special = NULL,
1506 .enum_list = NULL,
1507 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1510 .label = "force user",
1511 .type = P_STRING,
1512 .p_class = P_LOCAL,
1513 .ptr = &sDefault.force_user,
1514 .special = NULL,
1515 .enum_list = NULL,
1516 .flags = FLAG_ADVANCED | FLAG_SHARE,
1519 .label = "force group",
1520 .type = P_STRING,
1521 .p_class = P_LOCAL,
1522 .ptr = &sDefault.force_group,
1523 .special = NULL,
1524 .enum_list = NULL,
1525 .flags = FLAG_ADVANCED | FLAG_SHARE,
1528 .label = "group",
1529 .type = P_STRING,
1530 .p_class = P_LOCAL,
1531 .ptr = &sDefault.force_group,
1532 .special = NULL,
1533 .enum_list = NULL,
1534 .flags = FLAG_ADVANCED,
1537 .label = "read only",
1538 .type = P_BOOL,
1539 .p_class = P_LOCAL,
1540 .ptr = &sDefault.bRead_only,
1541 .special = NULL,
1542 .enum_list = NULL,
1543 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1546 .label = "write ok",
1547 .type = P_BOOLREV,
1548 .p_class = P_LOCAL,
1549 .ptr = &sDefault.bRead_only,
1550 .special = NULL,
1551 .enum_list = NULL,
1552 .flags = FLAG_HIDE,
1555 .label = "writeable",
1556 .type = P_BOOLREV,
1557 .p_class = P_LOCAL,
1558 .ptr = &sDefault.bRead_only,
1559 .special = NULL,
1560 .enum_list = NULL,
1561 .flags = FLAG_HIDE,
1564 .label = "writable",
1565 .type = P_BOOLREV,
1566 .p_class = P_LOCAL,
1567 .ptr = &sDefault.bRead_only,
1568 .special = NULL,
1569 .enum_list = NULL,
1570 .flags = FLAG_HIDE,
1573 .label = "acl check permissions",
1574 .type = P_BOOL,
1575 .p_class = P_LOCAL,
1576 .ptr = &sDefault.bAclCheckPermissions,
1577 .special = NULL,
1578 .enum_list = NULL,
1579 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1582 .label = "acl group control",
1583 .type = P_BOOL,
1584 .p_class = P_LOCAL,
1585 .ptr = &sDefault.bAclGroupControl,
1586 .special = NULL,
1587 .enum_list = NULL,
1588 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1591 .label = "acl map full control",
1592 .type = P_BOOL,
1593 .p_class = P_LOCAL,
1594 .ptr = &sDefault.bAclMapFullControl,
1595 .special = NULL,
1596 .enum_list = NULL,
1597 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1600 .label = "create mask",
1601 .type = P_OCTAL,
1602 .p_class = P_LOCAL,
1603 .ptr = &sDefault.iCreate_mask,
1604 .special = NULL,
1605 .enum_list = NULL,
1606 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1609 .label = "create mode",
1610 .type = P_OCTAL,
1611 .p_class = P_LOCAL,
1612 .ptr = &sDefault.iCreate_mask,
1613 .special = NULL,
1614 .enum_list = NULL,
1615 .flags = FLAG_HIDE,
1618 .label = "force create mode",
1619 .type = P_OCTAL,
1620 .p_class = P_LOCAL,
1621 .ptr = &sDefault.iCreate_force_mode,
1622 .special = NULL,
1623 .enum_list = NULL,
1624 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1627 .label = "security mask",
1628 .type = P_OCTAL,
1629 .p_class = P_LOCAL,
1630 .ptr = &sDefault.iSecurity_mask,
1631 .special = NULL,
1632 .enum_list = NULL,
1633 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1636 .label = "force security mode",
1637 .type = P_OCTAL,
1638 .p_class = P_LOCAL,
1639 .ptr = &sDefault.iSecurity_force_mode,
1640 .special = NULL,
1641 .enum_list = NULL,
1642 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1645 .label = "directory mask",
1646 .type = P_OCTAL,
1647 .p_class = P_LOCAL,
1648 .ptr = &sDefault.iDir_mask,
1649 .special = NULL,
1650 .enum_list = NULL,
1651 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1654 .label = "directory mode",
1655 .type = P_OCTAL,
1656 .p_class = P_LOCAL,
1657 .ptr = &sDefault.iDir_mask,
1658 .special = NULL,
1659 .enum_list = NULL,
1660 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1663 .label = "force directory mode",
1664 .type = P_OCTAL,
1665 .p_class = P_LOCAL,
1666 .ptr = &sDefault.iDir_force_mode,
1667 .special = NULL,
1668 .enum_list = NULL,
1669 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1672 .label = "directory security mask",
1673 .type = P_OCTAL,
1674 .p_class = P_LOCAL,
1675 .ptr = &sDefault.iDir_Security_mask,
1676 .special = NULL,
1677 .enum_list = NULL,
1678 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1681 .label = "force directory security mode",
1682 .type = P_OCTAL,
1683 .p_class = P_LOCAL,
1684 .ptr = &sDefault.iDir_Security_force_mode,
1685 .special = NULL,
1686 .enum_list = NULL,
1687 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1690 .label = "force unknown acl user",
1691 .type = P_BOOL,
1692 .p_class = P_LOCAL,
1693 .ptr = &sDefault.bForceUnknownAclUser,
1694 .special = NULL,
1695 .enum_list = NULL,
1696 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1699 .label = "inherit permissions",
1700 .type = P_BOOL,
1701 .p_class = P_LOCAL,
1702 .ptr = &sDefault.bInheritPerms,
1703 .special = NULL,
1704 .enum_list = NULL,
1705 .flags = FLAG_ADVANCED | FLAG_SHARE,
1708 .label = "inherit acls",
1709 .type = P_BOOL,
1710 .p_class = P_LOCAL,
1711 .ptr = &sDefault.bInheritACLS,
1712 .special = NULL,
1713 .enum_list = NULL,
1714 .flags = FLAG_ADVANCED | FLAG_SHARE,
1717 .label = "inherit owner",
1718 .type = P_BOOL,
1719 .p_class = P_LOCAL,
1720 .ptr = &sDefault.bInheritOwner,
1721 .special = NULL,
1722 .enum_list = NULL,
1723 .flags = FLAG_ADVANCED | FLAG_SHARE,
1726 .label = "guest only",
1727 .type = P_BOOL,
1728 .p_class = P_LOCAL,
1729 .ptr = &sDefault.bGuest_only,
1730 .special = NULL,
1731 .enum_list = NULL,
1732 .flags = FLAG_ADVANCED | FLAG_SHARE,
1735 .label = "only guest",
1736 .type = P_BOOL,
1737 .p_class = P_LOCAL,
1738 .ptr = &sDefault.bGuest_only,
1739 .special = NULL,
1740 .enum_list = NULL,
1741 .flags = FLAG_HIDE,
1744 .label = "administrative share",
1745 .type = P_BOOL,
1746 .p_class = P_LOCAL,
1747 .ptr = &sDefault.bAdministrative_share,
1748 .special = NULL,
1749 .enum_list = NULL,
1750 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1754 .label = "guest ok",
1755 .type = P_BOOL,
1756 .p_class = P_LOCAL,
1757 .ptr = &sDefault.bGuest_ok,
1758 .special = NULL,
1759 .enum_list = NULL,
1760 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1763 .label = "public",
1764 .type = P_BOOL,
1765 .p_class = P_LOCAL,
1766 .ptr = &sDefault.bGuest_ok,
1767 .special = NULL,
1768 .enum_list = NULL,
1769 .flags = FLAG_HIDE,
1772 .label = "only user",
1773 .type = P_BOOL,
1774 .p_class = P_LOCAL,
1775 .ptr = &sDefault.bOnlyUser,
1776 .special = NULL,
1777 .enum_list = NULL,
1778 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1781 .label = "hosts allow",
1782 .type = P_LIST,
1783 .p_class = P_LOCAL,
1784 .ptr = &sDefault.szHostsallow,
1785 .special = NULL,
1786 .enum_list = NULL,
1787 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1790 .label = "allow hosts",
1791 .type = P_LIST,
1792 .p_class = P_LOCAL,
1793 .ptr = &sDefault.szHostsallow,
1794 .special = NULL,
1795 .enum_list = NULL,
1796 .flags = FLAG_HIDE,
1799 .label = "hosts deny",
1800 .type = P_LIST,
1801 .p_class = P_LOCAL,
1802 .ptr = &sDefault.szHostsdeny,
1803 .special = NULL,
1804 .enum_list = NULL,
1805 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1808 .label = "deny hosts",
1809 .type = P_LIST,
1810 .p_class = P_LOCAL,
1811 .ptr = &sDefault.szHostsdeny,
1812 .special = NULL,
1813 .enum_list = NULL,
1814 .flags = FLAG_HIDE,
1817 .label = "preload modules",
1818 .type = P_LIST,
1819 .p_class = P_GLOBAL,
1820 .ptr = &Globals.szPreloadModules,
1821 .special = NULL,
1822 .enum_list = NULL,
1823 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1826 .label = "dedicated keytab file",
1827 .type = P_STRING,
1828 .p_class = P_GLOBAL,
1829 .ptr = &Globals.szDedicatedKeytabFile,
1830 .special = NULL,
1831 .enum_list = NULL,
1832 .flags = FLAG_ADVANCED,
1835 .label = "kerberos method",
1836 .type = P_ENUM,
1837 .p_class = P_GLOBAL,
1838 .ptr = &Globals.iKerberosMethod,
1839 .special = NULL,
1840 .enum_list = enum_kerberos_method,
1841 .flags = FLAG_ADVANCED,
1844 .label = "map untrusted to domain",
1845 .type = P_BOOL,
1846 .p_class = P_GLOBAL,
1847 .ptr = &Globals.bMapUntrustedToDomain,
1848 .special = NULL,
1849 .enum_list = NULL,
1850 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1854 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1857 .label = "log level",
1858 .type = P_STRING,
1859 .p_class = P_GLOBAL,
1860 .ptr = &Globals.szLogLevel,
1861 .special = handle_debug_list,
1862 .enum_list = NULL,
1863 .flags = FLAG_ADVANCED,
1866 .label = "debuglevel",
1867 .type = P_STRING,
1868 .p_class = P_GLOBAL,
1869 .ptr = &Globals.szLogLevel,
1870 .special = handle_debug_list,
1871 .enum_list = NULL,
1872 .flags = FLAG_HIDE,
1875 .label = "syslog",
1876 .type = P_INTEGER,
1877 .p_class = P_GLOBAL,
1878 .ptr = &Globals.syslog,
1879 .special = NULL,
1880 .enum_list = NULL,
1881 .flags = FLAG_ADVANCED,
1884 .label = "syslog only",
1885 .type = P_BOOL,
1886 .p_class = P_GLOBAL,
1887 .ptr = &Globals.bSyslogOnly,
1888 .special = NULL,
1889 .enum_list = NULL,
1890 .flags = FLAG_ADVANCED,
1893 .label = "log file",
1894 .type = P_STRING,
1895 .p_class = P_GLOBAL,
1896 .ptr = &Globals.szLogFile,
1897 .special = NULL,
1898 .enum_list = NULL,
1899 .flags = FLAG_ADVANCED,
1902 .label = "max log size",
1903 .type = P_INTEGER,
1904 .p_class = P_GLOBAL,
1905 .ptr = &Globals.max_log_size,
1906 .special = NULL,
1907 .enum_list = NULL,
1908 .flags = FLAG_ADVANCED,
1911 .label = "debug timestamp",
1912 .type = P_BOOL,
1913 .p_class = P_GLOBAL,
1914 .ptr = &Globals.bTimestampLogs,
1915 .special = NULL,
1916 .enum_list = NULL,
1917 .flags = FLAG_ADVANCED,
1920 .label = "timestamp logs",
1921 .type = P_BOOL,
1922 .p_class = P_GLOBAL,
1923 .ptr = &Globals.bTimestampLogs,
1924 .special = NULL,
1925 .enum_list = NULL,
1926 .flags = FLAG_ADVANCED,
1929 .label = "debug prefix timestamp",
1930 .type = P_BOOL,
1931 .p_class = P_GLOBAL,
1932 .ptr = &Globals.bDebugPrefixTimestamp,
1933 .special = NULL,
1934 .enum_list = NULL,
1935 .flags = FLAG_ADVANCED,
1938 .label = "debug hires timestamp",
1939 .type = P_BOOL,
1940 .p_class = P_GLOBAL,
1941 .ptr = &Globals.bDebugHiresTimestamp,
1942 .special = NULL,
1943 .enum_list = NULL,
1944 .flags = FLAG_ADVANCED,
1947 .label = "debug pid",
1948 .type = P_BOOL,
1949 .p_class = P_GLOBAL,
1950 .ptr = &Globals.bDebugPid,
1951 .special = NULL,
1952 .enum_list = NULL,
1953 .flags = FLAG_ADVANCED,
1956 .label = "debug uid",
1957 .type = P_BOOL,
1958 .p_class = P_GLOBAL,
1959 .ptr = &Globals.bDebugUid,
1960 .special = NULL,
1961 .enum_list = NULL,
1962 .flags = FLAG_ADVANCED,
1965 .label = "debug class",
1966 .type = P_BOOL,
1967 .p_class = P_GLOBAL,
1968 .ptr = &Globals.bDebugClass,
1969 .special = NULL,
1970 .enum_list = NULL,
1971 .flags = FLAG_ADVANCED,
1974 .label = "enable core files",
1975 .type = P_BOOL,
1976 .p_class = P_GLOBAL,
1977 .ptr = &Globals.bEnableCoreFiles,
1978 .special = NULL,
1979 .enum_list = NULL,
1980 .flags = FLAG_ADVANCED,
1983 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1986 .label = "allocation roundup size",
1987 .type = P_INTEGER,
1988 .p_class = P_LOCAL,
1989 .ptr = &sDefault.iallocation_roundup_size,
1990 .special = NULL,
1991 .enum_list = NULL,
1992 .flags = FLAG_ADVANCED,
1995 .label = "aio read size",
1996 .type = P_INTEGER,
1997 .p_class = P_LOCAL,
1998 .ptr = &sDefault.iAioReadSize,
1999 .special = NULL,
2000 .enum_list = NULL,
2001 .flags = FLAG_ADVANCED,
2004 .label = "aio write size",
2005 .type = P_INTEGER,
2006 .p_class = P_LOCAL,
2007 .ptr = &sDefault.iAioWriteSize,
2008 .special = NULL,
2009 .enum_list = NULL,
2010 .flags = FLAG_ADVANCED,
2013 .label = "aio write behind",
2014 .type = P_STRING,
2015 .p_class = P_LOCAL,
2016 .ptr = &sDefault.szAioWriteBehind,
2017 .special = NULL,
2018 .enum_list = NULL,
2019 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2022 .label = "smb ports",
2023 .type = P_STRING,
2024 .p_class = P_GLOBAL,
2025 .ptr = &Globals.smb_ports,
2026 .special = NULL,
2027 .enum_list = NULL,
2028 .flags = FLAG_ADVANCED,
2031 .label = "large readwrite",
2032 .type = P_BOOL,
2033 .p_class = P_GLOBAL,
2034 .ptr = &Globals.bLargeReadwrite,
2035 .special = NULL,
2036 .enum_list = NULL,
2037 .flags = FLAG_ADVANCED,
2040 .label = "max protocol",
2041 .type = P_ENUM,
2042 .p_class = P_GLOBAL,
2043 .ptr = &Globals.maxprotocol,
2044 .special = NULL,
2045 .enum_list = enum_protocol,
2046 .flags = FLAG_ADVANCED,
2049 .label = "protocol",
2050 .type = P_ENUM,
2051 .p_class = P_GLOBAL,
2052 .ptr = &Globals.maxprotocol,
2053 .special = NULL,
2054 .enum_list = enum_protocol,
2055 .flags = FLAG_ADVANCED,
2058 .label = "min protocol",
2059 .type = P_ENUM,
2060 .p_class = P_GLOBAL,
2061 .ptr = &Globals.minprotocol,
2062 .special = NULL,
2063 .enum_list = enum_protocol,
2064 .flags = FLAG_ADVANCED,
2067 .label = "min receivefile size",
2068 .type = P_INTEGER,
2069 .p_class = P_GLOBAL,
2070 .ptr = &Globals.iminreceivefile,
2071 .special = NULL,
2072 .enum_list = NULL,
2073 .flags = FLAG_ADVANCED,
2076 .label = "read raw",
2077 .type = P_BOOL,
2078 .p_class = P_GLOBAL,
2079 .ptr = &Globals.bReadRaw,
2080 .special = NULL,
2081 .enum_list = NULL,
2082 .flags = FLAG_ADVANCED,
2085 .label = "write raw",
2086 .type = P_BOOL,
2087 .p_class = P_GLOBAL,
2088 .ptr = &Globals.bWriteRaw,
2089 .special = NULL,
2090 .enum_list = NULL,
2091 .flags = FLAG_ADVANCED,
2094 .label = "disable netbios",
2095 .type = P_BOOL,
2096 .p_class = P_GLOBAL,
2097 .ptr = &Globals.bDisableNetbios,
2098 .special = NULL,
2099 .enum_list = NULL,
2100 .flags = FLAG_ADVANCED,
2103 .label = "reset on zero vc",
2104 .type = P_BOOL,
2105 .p_class = P_GLOBAL,
2106 .ptr = &Globals.bResetOnZeroVC,
2107 .special = NULL,
2108 .enum_list = NULL,
2109 .flags = FLAG_ADVANCED,
2112 .label = "log writeable files on exit",
2113 .type = P_BOOL,
2114 .p_class = P_GLOBAL,
2115 .ptr = &Globals.bLogWriteableFilesOnExit,
2116 .special = NULL,
2117 .enum_list = NULL,
2118 .flags = FLAG_ADVANCED,
2121 .label = "acl compatibility",
2122 .type = P_ENUM,
2123 .p_class = P_GLOBAL,
2124 .ptr = &Globals.iAclCompat,
2125 .special = NULL,
2126 .enum_list = enum_acl_compat_vals,
2127 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2130 .label = "defer sharing violations",
2131 .type = P_BOOL,
2132 .p_class = P_GLOBAL,
2133 .ptr = &Globals.bDeferSharingViolations,
2134 .special = NULL,
2135 .enum_list = NULL,
2136 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2139 .label = "ea support",
2140 .type = P_BOOL,
2141 .p_class = P_LOCAL,
2142 .ptr = &sDefault.bEASupport,
2143 .special = NULL,
2144 .enum_list = NULL,
2145 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2148 .label = "nt acl support",
2149 .type = P_BOOL,
2150 .p_class = P_LOCAL,
2151 .ptr = &sDefault.bNTAclSupport,
2152 .special = NULL,
2153 .enum_list = NULL,
2154 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2157 .label = "nt pipe support",
2158 .type = P_BOOL,
2159 .p_class = P_GLOBAL,
2160 .ptr = &Globals.bNTPipeSupport,
2161 .special = NULL,
2162 .enum_list = NULL,
2163 .flags = FLAG_ADVANCED,
2166 .label = "nt status support",
2167 .type = P_BOOL,
2168 .p_class = P_GLOBAL,
2169 .ptr = &Globals.bNTStatusSupport,
2170 .special = NULL,
2171 .enum_list = NULL,
2172 .flags = FLAG_ADVANCED,
2175 .label = "profile acls",
2176 .type = P_BOOL,
2177 .p_class = P_LOCAL,
2178 .ptr = &sDefault.bProfileAcls,
2179 .special = NULL,
2180 .enum_list = NULL,
2181 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2184 .label = "announce version",
2185 .type = P_STRING,
2186 .p_class = P_GLOBAL,
2187 .ptr = &Globals.szAnnounceVersion,
2188 .special = NULL,
2189 .enum_list = NULL,
2190 .flags = FLAG_ADVANCED,
2193 .label = "announce as",
2194 .type = P_ENUM,
2195 .p_class = P_GLOBAL,
2196 .ptr = &Globals.announce_as,
2197 .special = NULL,
2198 .enum_list = enum_announce_as,
2199 .flags = FLAG_ADVANCED,
2202 .label = "map acl inherit",
2203 .type = P_BOOL,
2204 .p_class = P_LOCAL,
2205 .ptr = &sDefault.bMap_acl_inherit,
2206 .special = NULL,
2207 .enum_list = NULL,
2208 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2211 .label = "afs share",
2212 .type = P_BOOL,
2213 .p_class = P_LOCAL,
2214 .ptr = &sDefault.bAfs_Share,
2215 .special = NULL,
2216 .enum_list = NULL,
2217 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2220 .label = "max mux",
2221 .type = P_INTEGER,
2222 .p_class = P_GLOBAL,
2223 .ptr = &Globals.max_mux,
2224 .special = NULL,
2225 .enum_list = NULL,
2226 .flags = FLAG_ADVANCED,
2229 .label = "max xmit",
2230 .type = P_INTEGER,
2231 .p_class = P_GLOBAL,
2232 .ptr = &Globals.max_xmit,
2233 .special = NULL,
2234 .enum_list = NULL,
2235 .flags = FLAG_ADVANCED,
2238 .label = "name resolve order",
2239 .type = P_STRING,
2240 .p_class = P_GLOBAL,
2241 .ptr = &Globals.szNameResolveOrder,
2242 .special = NULL,
2243 .enum_list = NULL,
2244 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2247 .label = "max ttl",
2248 .type = P_INTEGER,
2249 .p_class = P_GLOBAL,
2250 .ptr = &Globals.max_ttl,
2251 .special = NULL,
2252 .enum_list = NULL,
2253 .flags = FLAG_ADVANCED,
2256 .label = "max wins ttl",
2257 .type = P_INTEGER,
2258 .p_class = P_GLOBAL,
2259 .ptr = &Globals.max_wins_ttl,
2260 .special = NULL,
2261 .enum_list = NULL,
2262 .flags = FLAG_ADVANCED,
2265 .label = "min wins ttl",
2266 .type = P_INTEGER,
2267 .p_class = P_GLOBAL,
2268 .ptr = &Globals.min_wins_ttl,
2269 .special = NULL,
2270 .enum_list = NULL,
2271 .flags = FLAG_ADVANCED,
2274 .label = "time server",
2275 .type = P_BOOL,
2276 .p_class = P_GLOBAL,
2277 .ptr = &Globals.bTimeServer,
2278 .special = NULL,
2279 .enum_list = NULL,
2280 .flags = FLAG_ADVANCED,
2283 .label = "unix extensions",
2284 .type = P_BOOL,
2285 .p_class = P_GLOBAL,
2286 .ptr = &Globals.bUnixExtensions,
2287 .special = NULL,
2288 .enum_list = NULL,
2289 .flags = FLAG_ADVANCED,
2292 .label = "use spnego",
2293 .type = P_BOOL,
2294 .p_class = P_GLOBAL,
2295 .ptr = &Globals.bUseSpnego,
2296 .special = NULL,
2297 .enum_list = NULL,
2298 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
2301 .label = "client signing",
2302 .type = P_ENUM,
2303 .p_class = P_GLOBAL,
2304 .ptr = &Globals.client_signing,
2305 .special = NULL,
2306 .enum_list = enum_smb_signing_vals,
2307 .flags = FLAG_ADVANCED,
2310 .label = "server signing",
2311 .type = P_ENUM,
2312 .p_class = P_GLOBAL,
2313 .ptr = &Globals.server_signing,
2314 .special = NULL,
2315 .enum_list = enum_smb_signing_vals,
2316 .flags = FLAG_ADVANCED,
2319 .label = "smb encrypt",
2320 .type = P_ENUM,
2321 .p_class = P_LOCAL,
2322 .ptr = &sDefault.ismb_encrypt,
2323 .special = NULL,
2324 .enum_list = enum_smb_signing_vals,
2325 .flags = FLAG_ADVANCED,
2328 .label = "client use spnego",
2329 .type = P_BOOL,
2330 .p_class = P_GLOBAL,
2331 .ptr = &Globals.bClientUseSpnego,
2332 .special = NULL,
2333 .enum_list = NULL,
2334 .flags = FLAG_ADVANCED,
2337 .label = "client ldap sasl wrapping",
2338 .type = P_ENUM,
2339 .p_class = P_GLOBAL,
2340 .ptr = &Globals.client_ldap_sasl_wrapping,
2341 .special = NULL,
2342 .enum_list = enum_ldap_sasl_wrapping,
2343 .flags = FLAG_ADVANCED,
2346 .label = "enable asu support",
2347 .type = P_BOOL,
2348 .p_class = P_GLOBAL,
2349 .ptr = &Globals.bASUSupport,
2350 .special = NULL,
2351 .enum_list = NULL,
2352 .flags = FLAG_ADVANCED,
2355 .label = "svcctl list",
2356 .type = P_LIST,
2357 .p_class = P_GLOBAL,
2358 .ptr = &Globals.szServicesList,
2359 .special = NULL,
2360 .enum_list = NULL,
2361 .flags = FLAG_ADVANCED,
2364 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2367 .label = "block size",
2368 .type = P_INTEGER,
2369 .p_class = P_LOCAL,
2370 .ptr = &sDefault.iBlock_size,
2371 .special = NULL,
2372 .enum_list = NULL,
2373 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2376 .label = "deadtime",
2377 .type = P_INTEGER,
2378 .p_class = P_GLOBAL,
2379 .ptr = &Globals.deadtime,
2380 .special = NULL,
2381 .enum_list = NULL,
2382 .flags = FLAG_ADVANCED,
2385 .label = "getwd cache",
2386 .type = P_BOOL,
2387 .p_class = P_GLOBAL,
2388 .ptr = &Globals.getwd_cache,
2389 .special = NULL,
2390 .enum_list = NULL,
2391 .flags = FLAG_ADVANCED,
2394 .label = "keepalive",
2395 .type = P_INTEGER,
2396 .p_class = P_GLOBAL,
2397 .ptr = &Globals.iKeepalive,
2398 .special = NULL,
2399 .enum_list = NULL,
2400 .flags = FLAG_ADVANCED,
2403 .label = "change notify",
2404 .type = P_BOOL,
2405 .p_class = P_LOCAL,
2406 .ptr = &sDefault.bChangeNotify,
2407 .special = NULL,
2408 .enum_list = NULL,
2409 .flags = FLAG_ADVANCED | FLAG_SHARE,
2412 .label = "directory name cache size",
2413 .type = P_INTEGER,
2414 .p_class = P_LOCAL,
2415 .ptr = &sDefault.iDirectoryNameCacheSize,
2416 .special = NULL,
2417 .enum_list = NULL,
2418 .flags = FLAG_ADVANCED | FLAG_SHARE,
2421 .label = "kernel change notify",
2422 .type = P_BOOL,
2423 .p_class = P_LOCAL,
2424 .ptr = &sDefault.bKernelChangeNotify,
2425 .special = NULL,
2426 .enum_list = NULL,
2427 .flags = FLAG_ADVANCED | FLAG_SHARE,
2430 .label = "lpq cache time",
2431 .type = P_INTEGER,
2432 .p_class = P_GLOBAL,
2433 .ptr = &Globals.lpqcachetime,
2434 .special = NULL,
2435 .enum_list = NULL,
2436 .flags = FLAG_ADVANCED,
2439 .label = "max smbd processes",
2440 .type = P_INTEGER,
2441 .p_class = P_GLOBAL,
2442 .ptr = &Globals.iMaxSmbdProcesses,
2443 .special = NULL,
2444 .enum_list = NULL,
2445 .flags = FLAG_ADVANCED,
2448 .label = "max connections",
2449 .type = P_INTEGER,
2450 .p_class = P_LOCAL,
2451 .ptr = &sDefault.iMaxConnections,
2452 .special = NULL,
2453 .enum_list = NULL,
2454 .flags = FLAG_ADVANCED | FLAG_SHARE,
2457 .label = "paranoid server security",
2458 .type = P_BOOL,
2459 .p_class = P_GLOBAL,
2460 .ptr = &Globals.paranoid_server_security,
2461 .special = NULL,
2462 .enum_list = NULL,
2463 .flags = FLAG_ADVANCED,
2466 .label = "max disk size",
2467 .type = P_INTEGER,
2468 .p_class = P_GLOBAL,
2469 .ptr = &Globals.maxdisksize,
2470 .special = NULL,
2471 .enum_list = NULL,
2472 .flags = FLAG_ADVANCED,
2475 .label = "max open files",
2476 .type = P_INTEGER,
2477 .p_class = P_GLOBAL,
2478 .ptr = &Globals.max_open_files,
2479 .special = NULL,
2480 .enum_list = NULL,
2481 .flags = FLAG_ADVANCED,
2484 .label = "min print space",
2485 .type = P_INTEGER,
2486 .p_class = P_LOCAL,
2487 .ptr = &sDefault.iMinPrintSpace,
2488 .special = NULL,
2489 .enum_list = NULL,
2490 .flags = FLAG_ADVANCED | FLAG_PRINT,
2493 .label = "socket options",
2494 .type = P_STRING,
2495 .p_class = P_GLOBAL,
2496 .ptr = &Globals.szSocketOptions,
2497 .special = NULL,
2498 .enum_list = NULL,
2499 .flags = FLAG_ADVANCED,
2502 .label = "strict allocate",
2503 .type = P_BOOL,
2504 .p_class = P_LOCAL,
2505 .ptr = &sDefault.bStrictAllocate,
2506 .special = NULL,
2507 .enum_list = NULL,
2508 .flags = FLAG_ADVANCED | FLAG_SHARE,
2511 .label = "strict sync",
2512 .type = P_BOOL,
2513 .p_class = P_LOCAL,
2514 .ptr = &sDefault.bStrictSync,
2515 .special = NULL,
2516 .enum_list = NULL,
2517 .flags = FLAG_ADVANCED | FLAG_SHARE,
2520 .label = "sync always",
2521 .type = P_BOOL,
2522 .p_class = P_LOCAL,
2523 .ptr = &sDefault.bSyncAlways,
2524 .special = NULL,
2525 .enum_list = NULL,
2526 .flags = FLAG_ADVANCED | FLAG_SHARE,
2529 .label = "use mmap",
2530 .type = P_BOOL,
2531 .p_class = P_GLOBAL,
2532 .ptr = &Globals.bUseMmap,
2533 .special = NULL,
2534 .enum_list = NULL,
2535 .flags = FLAG_ADVANCED,
2538 .label = "use sendfile",
2539 .type = P_BOOL,
2540 .p_class = P_LOCAL,
2541 .ptr = &sDefault.bUseSendfile,
2542 .special = NULL,
2543 .enum_list = NULL,
2544 .flags = FLAG_ADVANCED | FLAG_SHARE,
2547 .label = "hostname lookups",
2548 .type = P_BOOL,
2549 .p_class = P_GLOBAL,
2550 .ptr = &Globals.bHostnameLookups,
2551 .special = NULL,
2552 .enum_list = NULL,
2553 .flags = FLAG_ADVANCED,
2556 .label = "write cache size",
2557 .type = P_INTEGER,
2558 .p_class = P_LOCAL,
2559 .ptr = &sDefault.iWriteCacheSize,
2560 .special = NULL,
2561 .enum_list = NULL,
2562 .flags = FLAG_ADVANCED | FLAG_SHARE,
2565 .label = "name cache timeout",
2566 .type = P_INTEGER,
2567 .p_class = P_GLOBAL,
2568 .ptr = &Globals.name_cache_timeout,
2569 .special = NULL,
2570 .enum_list = NULL,
2571 .flags = FLAG_ADVANCED,
2574 .label = "ctdbd socket",
2575 .type = P_STRING,
2576 .p_class = P_GLOBAL,
2577 .ptr = &Globals.ctdbdSocket,
2578 .special = NULL,
2579 .enum_list = NULL,
2580 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2583 .label = "cluster addresses",
2584 .type = P_LIST,
2585 .p_class = P_GLOBAL,
2586 .ptr = &Globals.szClusterAddresses,
2587 .special = NULL,
2588 .enum_list = NULL,
2589 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2592 .label = "clustering",
2593 .type = P_BOOL,
2594 .p_class = P_GLOBAL,
2595 .ptr = &Globals.clustering,
2596 .special = NULL,
2597 .enum_list = NULL,
2598 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2601 .label = "ctdb timeout",
2602 .type = P_INTEGER,
2603 .p_class = P_GLOBAL,
2604 .ptr = &Globals.ctdb_timeout,
2605 .special = NULL,
2606 .enum_list = NULL,
2607 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2610 .label = "ctdb locktime warn threshold",
2611 .type = P_INTEGER,
2612 .p_class = P_GLOBAL,
2613 .ptr = &Globals.ctdb_locktime_warn_threshold,
2614 .special = NULL,
2615 .enum_list = NULL,
2616 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2619 .label = "smb2 max read",
2620 .type = P_INTEGER,
2621 .p_class = P_GLOBAL,
2622 .ptr = &Globals.ismb2_max_read,
2623 .special = NULL,
2624 .enum_list = NULL,
2625 .flags = FLAG_ADVANCED,
2628 .label = "smb2 max write",
2629 .type = P_INTEGER,
2630 .p_class = P_GLOBAL,
2631 .ptr = &Globals.ismb2_max_write,
2632 .special = NULL,
2633 .enum_list = NULL,
2634 .flags = FLAG_ADVANCED,
2637 .label = "smb2 max trans",
2638 .type = P_INTEGER,
2639 .p_class = P_GLOBAL,
2640 .ptr = &Globals.ismb2_max_trans,
2641 .special = NULL,
2642 .enum_list = NULL,
2643 .flags = FLAG_ADVANCED,
2646 .label = "smb2 max credits",
2647 .type = P_INTEGER,
2648 .p_class = P_GLOBAL,
2649 .ptr = &Globals.ismb2_max_credits,
2650 .special = NULL,
2651 .enum_list = NULL,
2652 .flags = FLAG_ADVANCED,
2655 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2658 .label = "max reported print jobs",
2659 .type = P_INTEGER,
2660 .p_class = P_LOCAL,
2661 .ptr = &sDefault.iMaxReportedPrintJobs,
2662 .special = NULL,
2663 .enum_list = NULL,
2664 .flags = FLAG_ADVANCED | FLAG_PRINT,
2667 .label = "max print jobs",
2668 .type = P_INTEGER,
2669 .p_class = P_LOCAL,
2670 .ptr = &sDefault.iMaxPrintJobs,
2671 .special = NULL,
2672 .enum_list = NULL,
2673 .flags = FLAG_ADVANCED | FLAG_PRINT,
2676 .label = "load printers",
2677 .type = P_BOOL,
2678 .p_class = P_GLOBAL,
2679 .ptr = &Globals.bLoadPrinters,
2680 .special = NULL,
2681 .enum_list = NULL,
2682 .flags = FLAG_ADVANCED | FLAG_PRINT,
2685 .label = "printcap cache time",
2686 .type = P_INTEGER,
2687 .p_class = P_GLOBAL,
2688 .ptr = &Globals.PrintcapCacheTime,
2689 .special = NULL,
2690 .enum_list = NULL,
2691 .flags = FLAG_ADVANCED | FLAG_PRINT,
2694 .label = "printcap name",
2695 .type = P_STRING,
2696 .p_class = P_GLOBAL,
2697 .ptr = &Globals.szPrintcapname,
2698 .special = NULL,
2699 .enum_list = NULL,
2700 .flags = FLAG_ADVANCED | FLAG_PRINT,
2703 .label = "printcap",
2704 .type = P_STRING,
2705 .p_class = P_GLOBAL,
2706 .ptr = &Globals.szPrintcapname,
2707 .special = NULL,
2708 .enum_list = NULL,
2709 .flags = FLAG_HIDE,
2712 .label = "printable",
2713 .type = P_BOOL,
2714 .p_class = P_LOCAL,
2715 .ptr = &sDefault.bPrint_ok,
2716 .special = NULL,
2717 .enum_list = NULL,
2718 .flags = FLAG_ADVANCED | FLAG_PRINT,
2721 .label = "print notify backchannel",
2722 .type = P_BOOL,
2723 .p_class = P_LOCAL,
2724 .ptr = &sDefault.bPrintNotifyBackchannel,
2725 .special = NULL,
2726 .enum_list = NULL,
2727 .flags = FLAG_ADVANCED,
2730 .label = "print ok",
2731 .type = P_BOOL,
2732 .p_class = P_LOCAL,
2733 .ptr = &sDefault.bPrint_ok,
2734 .special = NULL,
2735 .enum_list = NULL,
2736 .flags = FLAG_HIDE,
2739 .label = "printing",
2740 .type = P_ENUM,
2741 .p_class = P_LOCAL,
2742 .ptr = &sDefault.iPrinting,
2743 .special = handle_printing,
2744 .enum_list = enum_printing,
2745 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2748 .label = "cups options",
2749 .type = P_STRING,
2750 .p_class = P_LOCAL,
2751 .ptr = &sDefault.szCupsOptions,
2752 .special = NULL,
2753 .enum_list = NULL,
2754 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2757 .label = "cups server",
2758 .type = P_STRING,
2759 .p_class = P_GLOBAL,
2760 .ptr = &Globals.szCupsServer,
2761 .special = NULL,
2762 .enum_list = NULL,
2763 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2766 .label = "cups encrypt",
2767 .type = P_ENUM,
2768 .p_class = P_GLOBAL,
2769 .ptr = &Globals.CupsEncrypt,
2770 .special = NULL,
2771 .enum_list = enum_bool_auto,
2772 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2776 .label = "cups connection timeout",
2777 .type = P_INTEGER,
2778 .p_class = P_GLOBAL,
2779 .ptr = &Globals.cups_connection_timeout,
2780 .special = NULL,
2781 .enum_list = NULL,
2782 .flags = FLAG_ADVANCED,
2785 .label = "iprint server",
2786 .type = P_STRING,
2787 .p_class = P_GLOBAL,
2788 .ptr = &Globals.szIPrintServer,
2789 .special = NULL,
2790 .enum_list = NULL,
2791 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2794 .label = "print command",
2795 .type = P_STRING,
2796 .p_class = P_LOCAL,
2797 .ptr = &sDefault.szPrintcommand,
2798 .special = NULL,
2799 .enum_list = NULL,
2800 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2803 .label = "disable spoolss",
2804 .type = P_BOOL,
2805 .p_class = P_GLOBAL,
2806 .ptr = &Globals.bDisableSpoolss,
2807 .special = NULL,
2808 .enum_list = NULL,
2809 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2812 .label = "enable spoolss",
2813 .type = P_BOOLREV,
2814 .p_class = P_GLOBAL,
2815 .ptr = &Globals.bDisableSpoolss,
2816 .special = NULL,
2817 .enum_list = NULL,
2818 .flags = FLAG_HIDE,
2821 .label = "lpq command",
2822 .type = P_STRING,
2823 .p_class = P_LOCAL,
2824 .ptr = &sDefault.szLpqcommand,
2825 .special = NULL,
2826 .enum_list = NULL,
2827 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2830 .label = "lprm command",
2831 .type = P_STRING,
2832 .p_class = P_LOCAL,
2833 .ptr = &sDefault.szLprmcommand,
2834 .special = NULL,
2835 .enum_list = NULL,
2836 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2839 .label = "lppause command",
2840 .type = P_STRING,
2841 .p_class = P_LOCAL,
2842 .ptr = &sDefault.szLppausecommand,
2843 .special = NULL,
2844 .enum_list = NULL,
2845 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2848 .label = "lpresume command",
2849 .type = P_STRING,
2850 .p_class = P_LOCAL,
2851 .ptr = &sDefault.szLpresumecommand,
2852 .special = NULL,
2853 .enum_list = NULL,
2854 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2857 .label = "queuepause command",
2858 .type = P_STRING,
2859 .p_class = P_LOCAL,
2860 .ptr = &sDefault.szQueuepausecommand,
2861 .special = NULL,
2862 .enum_list = NULL,
2863 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2866 .label = "queueresume command",
2867 .type = P_STRING,
2868 .p_class = P_LOCAL,
2869 .ptr = &sDefault.szQueueresumecommand,
2870 .special = NULL,
2871 .enum_list = NULL,
2872 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2875 .label = "addport command",
2876 .type = P_STRING,
2877 .p_class = P_GLOBAL,
2878 .ptr = &Globals.szAddPortCommand,
2879 .special = NULL,
2880 .enum_list = NULL,
2881 .flags = FLAG_ADVANCED,
2884 .label = "enumports command",
2885 .type = P_STRING,
2886 .p_class = P_GLOBAL,
2887 .ptr = &Globals.szEnumPortsCommand,
2888 .special = NULL,
2889 .enum_list = NULL,
2890 .flags = FLAG_ADVANCED,
2893 .label = "addprinter command",
2894 .type = P_STRING,
2895 .p_class = P_GLOBAL,
2896 .ptr = &Globals.szAddPrinterCommand,
2897 .special = NULL,
2898 .enum_list = NULL,
2899 .flags = FLAG_ADVANCED,
2902 .label = "deleteprinter command",
2903 .type = P_STRING,
2904 .p_class = P_GLOBAL,
2905 .ptr = &Globals.szDeletePrinterCommand,
2906 .special = NULL,
2907 .enum_list = NULL,
2908 .flags = FLAG_ADVANCED,
2911 .label = "show add printer wizard",
2912 .type = P_BOOL,
2913 .p_class = P_GLOBAL,
2914 .ptr = &Globals.bMsAddPrinterWizard,
2915 .special = NULL,
2916 .enum_list = NULL,
2917 .flags = FLAG_ADVANCED,
2920 .label = "os2 driver map",
2921 .type = P_STRING,
2922 .p_class = P_GLOBAL,
2923 .ptr = &Globals.szOs2DriverMap,
2924 .special = NULL,
2925 .enum_list = NULL,
2926 .flags = FLAG_ADVANCED,
2930 .label = "printer name",
2931 .type = P_STRING,
2932 .p_class = P_LOCAL,
2933 .ptr = &sDefault.szPrintername,
2934 .special = NULL,
2935 .enum_list = NULL,
2936 .flags = FLAG_ADVANCED | FLAG_PRINT,
2939 .label = "printer",
2940 .type = P_STRING,
2941 .p_class = P_LOCAL,
2942 .ptr = &sDefault.szPrintername,
2943 .special = NULL,
2944 .enum_list = NULL,
2945 .flags = FLAG_HIDE,
2948 .label = "use client driver",
2949 .type = P_BOOL,
2950 .p_class = P_LOCAL,
2951 .ptr = &sDefault.bUseClientDriver,
2952 .special = NULL,
2953 .enum_list = NULL,
2954 .flags = FLAG_ADVANCED | FLAG_PRINT,
2957 .label = "default devmode",
2958 .type = P_BOOL,
2959 .p_class = P_LOCAL,
2960 .ptr = &sDefault.bDefaultDevmode,
2961 .special = NULL,
2962 .enum_list = NULL,
2963 .flags = FLAG_ADVANCED | FLAG_PRINT,
2966 .label = "force printername",
2967 .type = P_BOOL,
2968 .p_class = P_LOCAL,
2969 .ptr = &sDefault.bForcePrintername,
2970 .special = NULL,
2971 .enum_list = NULL,
2972 .flags = FLAG_ADVANCED | FLAG_PRINT,
2975 .label = "printjob username",
2976 .type = P_STRING,
2977 .p_class = P_LOCAL,
2978 .ptr = &sDefault.szPrintjobUsername,
2979 .special = NULL,
2980 .enum_list = NULL,
2981 .flags = FLAG_ADVANCED | FLAG_PRINT,
2984 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2987 .label = "mangling method",
2988 .type = P_STRING,
2989 .p_class = P_GLOBAL,
2990 .ptr = &Globals.szManglingMethod,
2991 .special = NULL,
2992 .enum_list = NULL,
2993 .flags = FLAG_ADVANCED,
2996 .label = "mangle prefix",
2997 .type = P_INTEGER,
2998 .p_class = P_GLOBAL,
2999 .ptr = &Globals.mangle_prefix,
3000 .special = NULL,
3001 .enum_list = NULL,
3002 .flags = FLAG_ADVANCED,
3006 .label = "default case",
3007 .type = P_ENUM,
3008 .p_class = P_LOCAL,
3009 .ptr = &sDefault.iDefaultCase,
3010 .special = NULL,
3011 .enum_list = enum_case,
3012 .flags = FLAG_ADVANCED | FLAG_SHARE,
3015 .label = "case sensitive",
3016 .type = P_ENUM,
3017 .p_class = P_LOCAL,
3018 .ptr = &sDefault.iCaseSensitive,
3019 .special = NULL,
3020 .enum_list = enum_bool_auto,
3021 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3024 .label = "casesignames",
3025 .type = P_ENUM,
3026 .p_class = P_LOCAL,
3027 .ptr = &sDefault.iCaseSensitive,
3028 .special = NULL,
3029 .enum_list = enum_bool_auto,
3030 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
3033 .label = "preserve case",
3034 .type = P_BOOL,
3035 .p_class = P_LOCAL,
3036 .ptr = &sDefault.bCasePreserve,
3037 .special = NULL,
3038 .enum_list = NULL,
3039 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3042 .label = "short preserve case",
3043 .type = P_BOOL,
3044 .p_class = P_LOCAL,
3045 .ptr = &sDefault.bShortCasePreserve,
3046 .special = NULL,
3047 .enum_list = NULL,
3048 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3051 .label = "mangling char",
3052 .type = P_CHAR,
3053 .p_class = P_LOCAL,
3054 .ptr = &sDefault.magic_char,
3055 .special = NULL,
3056 .enum_list = NULL,
3057 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3060 .label = "hide dot files",
3061 .type = P_BOOL,
3062 .p_class = P_LOCAL,
3063 .ptr = &sDefault.bHideDotFiles,
3064 .special = NULL,
3065 .enum_list = NULL,
3066 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3069 .label = "hide special files",
3070 .type = P_BOOL,
3071 .p_class = P_LOCAL,
3072 .ptr = &sDefault.bHideSpecialFiles,
3073 .special = NULL,
3074 .enum_list = NULL,
3075 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3078 .label = "hide unreadable",
3079 .type = P_BOOL,
3080 .p_class = P_LOCAL,
3081 .ptr = &sDefault.bHideUnReadable,
3082 .special = NULL,
3083 .enum_list = NULL,
3084 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3087 .label = "hide unwriteable files",
3088 .type = P_BOOL,
3089 .p_class = P_LOCAL,
3090 .ptr = &sDefault.bHideUnWriteableFiles,
3091 .special = NULL,
3092 .enum_list = NULL,
3093 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3096 .label = "delete veto files",
3097 .type = P_BOOL,
3098 .p_class = P_LOCAL,
3099 .ptr = &sDefault.bDeleteVetoFiles,
3100 .special = NULL,
3101 .enum_list = NULL,
3102 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3105 .label = "veto files",
3106 .type = P_STRING,
3107 .p_class = P_LOCAL,
3108 .ptr = &sDefault.szVetoFiles,
3109 .special = NULL,
3110 .enum_list = NULL,
3111 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3114 .label = "hide files",
3115 .type = P_STRING,
3116 .p_class = P_LOCAL,
3117 .ptr = &sDefault.szHideFiles,
3118 .special = NULL,
3119 .enum_list = NULL,
3120 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3123 .label = "veto oplock files",
3124 .type = P_STRING,
3125 .p_class = P_LOCAL,
3126 .ptr = &sDefault.szVetoOplockFiles,
3127 .special = NULL,
3128 .enum_list = NULL,
3129 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3132 .label = "map archive",
3133 .type = P_BOOL,
3134 .p_class = P_LOCAL,
3135 .ptr = &sDefault.bMap_archive,
3136 .special = NULL,
3137 .enum_list = NULL,
3138 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3141 .label = "map hidden",
3142 .type = P_BOOL,
3143 .p_class = P_LOCAL,
3144 .ptr = &sDefault.bMap_hidden,
3145 .special = NULL,
3146 .enum_list = NULL,
3147 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3150 .label = "map system",
3151 .type = P_BOOL,
3152 .p_class = P_LOCAL,
3153 .ptr = &sDefault.bMap_system,
3154 .special = NULL,
3155 .enum_list = NULL,
3156 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3159 .label = "map readonly",
3160 .type = P_ENUM,
3161 .p_class = P_LOCAL,
3162 .ptr = &sDefault.iMap_readonly,
3163 .special = NULL,
3164 .enum_list = enum_map_readonly,
3165 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3168 .label = "mangled names",
3169 .type = P_BOOL,
3170 .p_class = P_LOCAL,
3171 .ptr = &sDefault.bMangledNames,
3172 .special = NULL,
3173 .enum_list = NULL,
3174 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3177 .label = "max stat cache size",
3178 .type = P_INTEGER,
3179 .p_class = P_GLOBAL,
3180 .ptr = &Globals.iMaxStatCacheSize,
3181 .special = NULL,
3182 .enum_list = NULL,
3183 .flags = FLAG_ADVANCED,
3186 .label = "stat cache",
3187 .type = P_BOOL,
3188 .p_class = P_GLOBAL,
3189 .ptr = &Globals.bStatCache,
3190 .special = NULL,
3191 .enum_list = NULL,
3192 .flags = FLAG_ADVANCED,
3195 .label = "store dos attributes",
3196 .type = P_BOOL,
3197 .p_class = P_LOCAL,
3198 .ptr = &sDefault.bStoreDosAttributes,
3199 .special = NULL,
3200 .enum_list = NULL,
3201 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3204 .label = "dmapi support",
3205 .type = P_BOOL,
3206 .p_class = P_LOCAL,
3207 .ptr = &sDefault.bDmapiSupport,
3208 .special = NULL,
3209 .enum_list = NULL,
3210 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3214 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3217 .label = "machine password timeout",
3218 .type = P_INTEGER,
3219 .p_class = P_GLOBAL,
3220 .ptr = &Globals.machine_password_timeout,
3221 .special = NULL,
3222 .enum_list = NULL,
3223 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3226 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3229 .label = "add user script",
3230 .type = P_STRING,
3231 .p_class = P_GLOBAL,
3232 .ptr = &Globals.szAddUserScript,
3233 .special = NULL,
3234 .enum_list = NULL,
3235 .flags = FLAG_ADVANCED,
3238 .label = "rename user script",
3239 .type = P_STRING,
3240 .p_class = P_GLOBAL,
3241 .ptr = &Globals.szRenameUserScript,
3242 .special = NULL,
3243 .enum_list = NULL,
3244 .flags = FLAG_ADVANCED,
3247 .label = "delete user script",
3248 .type = P_STRING,
3249 .p_class = P_GLOBAL,
3250 .ptr = &Globals.szDelUserScript,
3251 .special = NULL,
3252 .enum_list = NULL,
3253 .flags = FLAG_ADVANCED,
3256 .label = "add group script",
3257 .type = P_STRING,
3258 .p_class = P_GLOBAL,
3259 .ptr = &Globals.szAddGroupScript,
3260 .special = NULL,
3261 .enum_list = NULL,
3262 .flags = FLAG_ADVANCED,
3265 .label = "delete group script",
3266 .type = P_STRING,
3267 .p_class = P_GLOBAL,
3268 .ptr = &Globals.szDelGroupScript,
3269 .special = NULL,
3270 .enum_list = NULL,
3271 .flags = FLAG_ADVANCED,
3274 .label = "add user to group script",
3275 .type = P_STRING,
3276 .p_class = P_GLOBAL,
3277 .ptr = &Globals.szAddUserToGroupScript,
3278 .special = NULL,
3279 .enum_list = NULL,
3280 .flags = FLAG_ADVANCED,
3283 .label = "delete user from group script",
3284 .type = P_STRING,
3285 .p_class = P_GLOBAL,
3286 .ptr = &Globals.szDelUserFromGroupScript,
3287 .special = NULL,
3288 .enum_list = NULL,
3289 .flags = FLAG_ADVANCED,
3292 .label = "set primary group script",
3293 .type = P_STRING,
3294 .p_class = P_GLOBAL,
3295 .ptr = &Globals.szSetPrimaryGroupScript,
3296 .special = NULL,
3297 .enum_list = NULL,
3298 .flags = FLAG_ADVANCED,
3301 .label = "add machine script",
3302 .type = P_STRING,
3303 .p_class = P_GLOBAL,
3304 .ptr = &Globals.szAddMachineScript,
3305 .special = NULL,
3306 .enum_list = NULL,
3307 .flags = FLAG_ADVANCED,
3310 .label = "shutdown script",
3311 .type = P_STRING,
3312 .p_class = P_GLOBAL,
3313 .ptr = &Globals.szShutdownScript,
3314 .special = NULL,
3315 .enum_list = NULL,
3316 .flags = FLAG_ADVANCED,
3319 .label = "abort shutdown script",
3320 .type = P_STRING,
3321 .p_class = P_GLOBAL,
3322 .ptr = &Globals.szAbortShutdownScript,
3323 .special = NULL,
3324 .enum_list = NULL,
3325 .flags = FLAG_ADVANCED,
3328 .label = "username map script",
3329 .type = P_STRING,
3330 .p_class = P_GLOBAL,
3331 .ptr = &Globals.szUsernameMapScript,
3332 .special = NULL,
3333 .enum_list = NULL,
3334 .flags = FLAG_ADVANCED,
3337 .label = "username map cache time",
3338 .type = P_INTEGER,
3339 .p_class = P_GLOBAL,
3340 .ptr = &Globals.iUsernameMapCacheTime,
3341 .special = NULL,
3342 .enum_list = NULL,
3343 .flags = FLAG_ADVANCED,
3346 .label = "logon script",
3347 .type = P_STRING,
3348 .p_class = P_GLOBAL,
3349 .ptr = &Globals.szLogonScript,
3350 .special = NULL,
3351 .enum_list = NULL,
3352 .flags = FLAG_ADVANCED,
3355 .label = "logon path",
3356 .type = P_STRING,
3357 .p_class = P_GLOBAL,
3358 .ptr = &Globals.szLogonPath,
3359 .special = NULL,
3360 .enum_list = NULL,
3361 .flags = FLAG_ADVANCED,
3364 .label = "logon drive",
3365 .type = P_STRING,
3366 .p_class = P_GLOBAL,
3367 .ptr = &Globals.szLogonDrive,
3368 .special = NULL,
3369 .enum_list = NULL,
3370 .flags = FLAG_ADVANCED,
3373 .label = "logon home",
3374 .type = P_STRING,
3375 .p_class = P_GLOBAL,
3376 .ptr = &Globals.szLogonHome,
3377 .special = NULL,
3378 .enum_list = NULL,
3379 .flags = FLAG_ADVANCED,
3382 .label = "domain logons",
3383 .type = P_BOOL,
3384 .p_class = P_GLOBAL,
3385 .ptr = &Globals.bDomainLogons,
3386 .special = NULL,
3387 .enum_list = NULL,
3388 .flags = FLAG_ADVANCED,
3392 .label = "init logon delayed hosts",
3393 .type = P_LIST,
3394 .p_class = P_GLOBAL,
3395 .ptr = &Globals.szInitLogonDelayedHosts,
3396 .special = NULL,
3397 .enum_list = NULL,
3398 .flags = FLAG_ADVANCED,
3402 .label = "init logon delay",
3403 .type = P_INTEGER,
3404 .p_class = P_GLOBAL,
3405 .ptr = &Globals.InitLogonDelay,
3406 .special = NULL,
3407 .enum_list = NULL,
3408 .flags = FLAG_ADVANCED,
3412 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3415 .label = "os level",
3416 .type = P_INTEGER,
3417 .p_class = P_GLOBAL,
3418 .ptr = &Globals.os_level,
3419 .special = NULL,
3420 .enum_list = NULL,
3421 .flags = FLAG_BASIC | FLAG_ADVANCED,
3424 .label = "lm announce",
3425 .type = P_ENUM,
3426 .p_class = P_GLOBAL,
3427 .ptr = &Globals.lm_announce,
3428 .special = NULL,
3429 .enum_list = enum_bool_auto,
3430 .flags = FLAG_ADVANCED,
3433 .label = "lm interval",
3434 .type = P_INTEGER,
3435 .p_class = P_GLOBAL,
3436 .ptr = &Globals.lm_interval,
3437 .special = NULL,
3438 .enum_list = NULL,
3439 .flags = FLAG_ADVANCED,
3442 .label = "preferred master",
3443 .type = P_ENUM,
3444 .p_class = P_GLOBAL,
3445 .ptr = &Globals.iPreferredMaster,
3446 .special = NULL,
3447 .enum_list = enum_bool_auto,
3448 .flags = FLAG_BASIC | FLAG_ADVANCED,
3451 .label = "prefered master",
3452 .type = P_ENUM,
3453 .p_class = P_GLOBAL,
3454 .ptr = &Globals.iPreferredMaster,
3455 .special = NULL,
3456 .enum_list = enum_bool_auto,
3457 .flags = FLAG_HIDE,
3460 .label = "local master",
3461 .type = P_BOOL,
3462 .p_class = P_GLOBAL,
3463 .ptr = &Globals.bLocalMaster,
3464 .special = NULL,
3465 .enum_list = NULL,
3466 .flags = FLAG_BASIC | FLAG_ADVANCED,
3469 .label = "domain master",
3470 .type = P_ENUM,
3471 .p_class = P_GLOBAL,
3472 .ptr = &Globals.iDomainMaster,
3473 .special = NULL,
3474 .enum_list = enum_bool_auto,
3475 .flags = FLAG_BASIC | FLAG_ADVANCED,
3478 .label = "browse list",
3479 .type = P_BOOL,
3480 .p_class = P_GLOBAL,
3481 .ptr = &Globals.bBrowseList,
3482 .special = NULL,
3483 .enum_list = NULL,
3484 .flags = FLAG_ADVANCED,
3487 .label = "browseable",
3488 .type = P_BOOL,
3489 .p_class = P_LOCAL,
3490 .ptr = &sDefault.bBrowseable,
3491 .special = NULL,
3492 .enum_list = NULL,
3493 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3496 .label = "browsable",
3497 .type = P_BOOL,
3498 .p_class = P_LOCAL,
3499 .ptr = &sDefault.bBrowseable,
3500 .special = NULL,
3501 .enum_list = NULL,
3502 .flags = FLAG_HIDE,
3505 .label = "access based share enum",
3506 .type = P_BOOL,
3507 .p_class = P_LOCAL,
3508 .ptr = &sDefault.bAccessBasedShareEnum,
3509 .special = NULL,
3510 .enum_list = NULL,
3511 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3514 .label = "enhanced browsing",
3515 .type = P_BOOL,
3516 .p_class = P_GLOBAL,
3517 .ptr = &Globals.enhanced_browsing,
3518 .special = NULL,
3519 .enum_list = NULL,
3520 .flags = FLAG_ADVANCED,
3523 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3526 .label = "dns proxy",
3527 .type = P_BOOL,
3528 .p_class = P_GLOBAL,
3529 .ptr = &Globals.bDNSproxy,
3530 .special = NULL,
3531 .enum_list = NULL,
3532 .flags = FLAG_ADVANCED,
3535 .label = "wins proxy",
3536 .type = P_BOOL,
3537 .p_class = P_GLOBAL,
3538 .ptr = &Globals.bWINSproxy,
3539 .special = NULL,
3540 .enum_list = NULL,
3541 .flags = FLAG_ADVANCED,
3544 .label = "wins server",
3545 .type = P_LIST,
3546 .p_class = P_GLOBAL,
3547 .ptr = &Globals.szWINSservers,
3548 .special = NULL,
3549 .enum_list = NULL,
3550 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3553 .label = "wins support",
3554 .type = P_BOOL,
3555 .p_class = P_GLOBAL,
3556 .ptr = &Globals.bWINSsupport,
3557 .special = NULL,
3558 .enum_list = NULL,
3559 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3562 .label = "wins hook",
3563 .type = P_STRING,
3564 .p_class = P_GLOBAL,
3565 .ptr = &Globals.szWINSHook,
3566 .special = NULL,
3567 .enum_list = NULL,
3568 .flags = FLAG_ADVANCED,
3571 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3574 .label = "blocking locks",
3575 .type = P_BOOL,
3576 .p_class = P_LOCAL,
3577 .ptr = &sDefault.bBlockingLocks,
3578 .special = NULL,
3579 .enum_list = NULL,
3580 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3583 .label = "csc policy",
3584 .type = P_ENUM,
3585 .p_class = P_LOCAL,
3586 .ptr = &sDefault.iCSCPolicy,
3587 .special = NULL,
3588 .enum_list = enum_csc_policy,
3589 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3592 .label = "fake oplocks",
3593 .type = P_BOOL,
3594 .p_class = P_LOCAL,
3595 .ptr = &sDefault.bFakeOplocks,
3596 .special = NULL,
3597 .enum_list = NULL,
3598 .flags = FLAG_ADVANCED | FLAG_SHARE,
3601 .label = "kernel oplocks",
3602 .type = P_BOOL,
3603 .p_class = P_GLOBAL,
3604 .ptr = &Globals.bKernelOplocks,
3605 .special = NULL,
3606 .enum_list = NULL,
3607 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3610 .label = "locking",
3611 .type = P_BOOL,
3612 .p_class = P_LOCAL,
3613 .ptr = &sDefault.bLocking,
3614 .special = NULL,
3615 .enum_list = NULL,
3616 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3619 .label = "lock spin time",
3620 .type = P_INTEGER,
3621 .p_class = P_GLOBAL,
3622 .ptr = &Globals.iLockSpinTime,
3623 .special = NULL,
3624 .enum_list = NULL,
3625 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3628 .label = "oplocks",
3629 .type = P_BOOL,
3630 .p_class = P_LOCAL,
3631 .ptr = &sDefault.bOpLocks,
3632 .special = NULL,
3633 .enum_list = NULL,
3634 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3637 .label = "level2 oplocks",
3638 .type = P_BOOL,
3639 .p_class = P_LOCAL,
3640 .ptr = &sDefault.bLevel2OpLocks,
3641 .special = NULL,
3642 .enum_list = NULL,
3643 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3646 .label = "oplock break wait time",
3647 .type = P_INTEGER,
3648 .p_class = P_GLOBAL,
3649 .ptr = &Globals.oplock_break_wait_time,
3650 .special = NULL,
3651 .enum_list = NULL,
3652 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3655 .label = "oplock contention limit",
3656 .type = P_INTEGER,
3657 .p_class = P_LOCAL,
3658 .ptr = &sDefault.iOplockContentionLimit,
3659 .special = NULL,
3660 .enum_list = NULL,
3661 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3664 .label = "posix locking",
3665 .type = P_BOOL,
3666 .p_class = P_LOCAL,
3667 .ptr = &sDefault.bPosixLocking,
3668 .special = NULL,
3669 .enum_list = NULL,
3670 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3673 .label = "strict locking",
3674 .type = P_ENUM,
3675 .p_class = P_LOCAL,
3676 .ptr = &sDefault.iStrictLocking,
3677 .special = NULL,
3678 .enum_list = enum_bool_auto,
3679 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3682 .label = "share modes",
3683 .type = P_BOOL,
3684 .p_class = P_LOCAL,
3685 .ptr = &sDefault.bShareModes,
3686 .special = NULL,
3687 .enum_list = NULL,
3688 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3691 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3694 .label = "ldap admin dn",
3695 .type = P_STRING,
3696 .p_class = P_GLOBAL,
3697 .ptr = &Globals.szLdapAdminDn,
3698 .special = NULL,
3699 .enum_list = NULL,
3700 .flags = FLAG_ADVANCED,
3703 .label = "ldap delete dn",
3704 .type = P_BOOL,
3705 .p_class = P_GLOBAL,
3706 .ptr = &Globals.ldap_delete_dn,
3707 .special = NULL,
3708 .enum_list = NULL,
3709 .flags = FLAG_ADVANCED,
3712 .label = "ldap group suffix",
3713 .type = P_STRING,
3714 .p_class = P_GLOBAL,
3715 .ptr = &Globals.szLdapGroupSuffix,
3716 .special = NULL,
3717 .enum_list = NULL,
3718 .flags = FLAG_ADVANCED,
3721 .label = "ldap idmap suffix",
3722 .type = P_STRING,
3723 .p_class = P_GLOBAL,
3724 .ptr = &Globals.szLdapIdmapSuffix,
3725 .special = NULL,
3726 .enum_list = NULL,
3727 .flags = FLAG_ADVANCED,
3730 .label = "ldap machine suffix",
3731 .type = P_STRING,
3732 .p_class = P_GLOBAL,
3733 .ptr = &Globals.szLdapMachineSuffix,
3734 .special = NULL,
3735 .enum_list = NULL,
3736 .flags = FLAG_ADVANCED,
3739 .label = "ldap passwd sync",
3740 .type = P_ENUM,
3741 .p_class = P_GLOBAL,
3742 .ptr = &Globals.ldap_passwd_sync,
3743 .special = NULL,
3744 .enum_list = enum_ldap_passwd_sync,
3745 .flags = FLAG_ADVANCED,
3748 .label = "ldap password sync",
3749 .type = P_ENUM,
3750 .p_class = P_GLOBAL,
3751 .ptr = &Globals.ldap_passwd_sync,
3752 .special = NULL,
3753 .enum_list = enum_ldap_passwd_sync,
3754 .flags = FLAG_HIDE,
3757 .label = "ldap replication sleep",
3758 .type = P_INTEGER,
3759 .p_class = P_GLOBAL,
3760 .ptr = &Globals.ldap_replication_sleep,
3761 .special = NULL,
3762 .enum_list = NULL,
3763 .flags = FLAG_ADVANCED,
3766 .label = "ldap suffix",
3767 .type = P_STRING,
3768 .p_class = P_GLOBAL,
3769 .ptr = &Globals.szLdapSuffix,
3770 .special = NULL,
3771 .enum_list = NULL,
3772 .flags = FLAG_ADVANCED,
3775 .label = "ldap ssl",
3776 .type = P_ENUM,
3777 .p_class = P_GLOBAL,
3778 .ptr = &Globals.ldap_ssl,
3779 .special = NULL,
3780 .enum_list = enum_ldap_ssl,
3781 .flags = FLAG_ADVANCED,
3784 .label = "ldap ssl ads",
3785 .type = P_BOOL,
3786 .p_class = P_GLOBAL,
3787 .ptr = &Globals.ldap_ssl_ads,
3788 .special = NULL,
3789 .enum_list = NULL,
3790 .flags = FLAG_ADVANCED,
3793 .label = "ldap deref",
3794 .type = P_ENUM,
3795 .p_class = P_GLOBAL,
3796 .ptr = &Globals.ldap_deref,
3797 .special = NULL,
3798 .enum_list = enum_ldap_deref,
3799 .flags = FLAG_ADVANCED,
3802 .label = "ldap follow referral",
3803 .type = P_ENUM,
3804 .p_class = P_GLOBAL,
3805 .ptr = &Globals.ldap_follow_referral,
3806 .special = NULL,
3807 .enum_list = enum_bool_auto,
3808 .flags = FLAG_ADVANCED,
3811 .label = "ldap timeout",
3812 .type = P_INTEGER,
3813 .p_class = P_GLOBAL,
3814 .ptr = &Globals.ldap_timeout,
3815 .special = NULL,
3816 .enum_list = NULL,
3817 .flags = FLAG_ADVANCED,
3820 .label = "ldap connection timeout",
3821 .type = P_INTEGER,
3822 .p_class = P_GLOBAL,
3823 .ptr = &Globals.ldap_connection_timeout,
3824 .special = NULL,
3825 .enum_list = NULL,
3826 .flags = FLAG_ADVANCED,
3829 .label = "ldap page size",
3830 .type = P_INTEGER,
3831 .p_class = P_GLOBAL,
3832 .ptr = &Globals.ldap_page_size,
3833 .special = NULL,
3834 .enum_list = NULL,
3835 .flags = FLAG_ADVANCED,
3838 .label = "ldap user suffix",
3839 .type = P_STRING,
3840 .p_class = P_GLOBAL,
3841 .ptr = &Globals.szLdapUserSuffix,
3842 .special = NULL,
3843 .enum_list = NULL,
3844 .flags = FLAG_ADVANCED,
3847 .label = "ldap debug level",
3848 .type = P_INTEGER,
3849 .p_class = P_GLOBAL,
3850 .ptr = &Globals.ldap_debug_level,
3851 .special = handle_ldap_debug_level,
3852 .enum_list = NULL,
3853 .flags = FLAG_ADVANCED,
3856 .label = "ldap debug threshold",
3857 .type = P_INTEGER,
3858 .p_class = P_GLOBAL,
3859 .ptr = &Globals.ldap_debug_threshold,
3860 .special = NULL,
3861 .enum_list = NULL,
3862 .flags = FLAG_ADVANCED,
3865 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3868 .label = "eventlog list",
3869 .type = P_LIST,
3870 .p_class = P_GLOBAL,
3871 .ptr = &Globals.szEventLogs,
3872 .special = NULL,
3873 .enum_list = NULL,
3874 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3877 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3880 .label = "add share command",
3881 .type = P_STRING,
3882 .p_class = P_GLOBAL,
3883 .ptr = &Globals.szAddShareCommand,
3884 .special = NULL,
3885 .enum_list = NULL,
3886 .flags = FLAG_ADVANCED,
3889 .label = "change share command",
3890 .type = P_STRING,
3891 .p_class = P_GLOBAL,
3892 .ptr = &Globals.szChangeShareCommand,
3893 .special = NULL,
3894 .enum_list = NULL,
3895 .flags = FLAG_ADVANCED,
3898 .label = "delete share command",
3899 .type = P_STRING,
3900 .p_class = P_GLOBAL,
3901 .ptr = &Globals.szDeleteShareCommand,
3902 .special = NULL,
3903 .enum_list = NULL,
3904 .flags = FLAG_ADVANCED,
3907 .label = "config file",
3908 .type = P_STRING,
3909 .p_class = P_GLOBAL,
3910 .ptr = &Globals.szConfigFile,
3911 .special = NULL,
3912 .enum_list = NULL,
3913 .flags = FLAG_HIDE|FLAG_META,
3916 .label = "preload",
3917 .type = P_STRING,
3918 .p_class = P_GLOBAL,
3919 .ptr = &Globals.szAutoServices,
3920 .special = NULL,
3921 .enum_list = NULL,
3922 .flags = FLAG_ADVANCED,
3925 .label = "auto services",
3926 .type = P_STRING,
3927 .p_class = P_GLOBAL,
3928 .ptr = &Globals.szAutoServices,
3929 .special = NULL,
3930 .enum_list = NULL,
3931 .flags = FLAG_ADVANCED,
3934 .label = "lock directory",
3935 .type = P_STRING,
3936 .p_class = P_GLOBAL,
3937 .ptr = &Globals.szLockDir,
3938 .special = NULL,
3939 .enum_list = NULL,
3940 .flags = FLAG_ADVANCED,
3943 .label = "lock dir",
3944 .type = P_STRING,
3945 .p_class = P_GLOBAL,
3946 .ptr = &Globals.szLockDir,
3947 .special = NULL,
3948 .enum_list = NULL,
3949 .flags = FLAG_HIDE,
3952 .label = "state directory",
3953 .type = P_STRING,
3954 .p_class = P_GLOBAL,
3955 .ptr = &Globals.szStateDir,
3956 .special = NULL,
3957 .enum_list = NULL,
3958 .flags = FLAG_ADVANCED,
3961 .label = "cache directory",
3962 .type = P_STRING,
3963 .p_class = P_GLOBAL,
3964 .ptr = &Globals.szCacheDir,
3965 .special = NULL,
3966 .enum_list = NULL,
3967 .flags = FLAG_ADVANCED,
3970 .label = "pid directory",
3971 .type = P_STRING,
3972 .p_class = P_GLOBAL,
3973 .ptr = &Globals.szPidDir,
3974 .special = NULL,
3975 .enum_list = NULL,
3976 .flags = FLAG_ADVANCED,
3978 #ifdef WITH_UTMP
3980 .label = "utmp directory",
3981 .type = P_STRING,
3982 .p_class = P_GLOBAL,
3983 .ptr = &Globals.szUtmpDir,
3984 .special = NULL,
3985 .enum_list = NULL,
3986 .flags = FLAG_ADVANCED,
3989 .label = "wtmp directory",
3990 .type = P_STRING,
3991 .p_class = P_GLOBAL,
3992 .ptr = &Globals.szWtmpDir,
3993 .special = NULL,
3994 .enum_list = NULL,
3995 .flags = FLAG_ADVANCED,
3998 .label = "utmp",
3999 .type = P_BOOL,
4000 .p_class = P_GLOBAL,
4001 .ptr = &Globals.bUtmp,
4002 .special = NULL,
4003 .enum_list = NULL,
4004 .flags = FLAG_ADVANCED,
4006 #endif
4008 .label = "default service",
4009 .type = P_STRING,
4010 .p_class = P_GLOBAL,
4011 .ptr = &Globals.szDefaultService,
4012 .special = NULL,
4013 .enum_list = NULL,
4014 .flags = FLAG_ADVANCED,
4017 .label = "default",
4018 .type = P_STRING,
4019 .p_class = P_GLOBAL,
4020 .ptr = &Globals.szDefaultService,
4021 .special = NULL,
4022 .enum_list = NULL,
4023 .flags = FLAG_ADVANCED,
4026 .label = "message command",
4027 .type = P_STRING,
4028 .p_class = P_GLOBAL,
4029 .ptr = &Globals.szMsgCommand,
4030 .special = NULL,
4031 .enum_list = NULL,
4032 .flags = FLAG_ADVANCED,
4035 .label = "dfree cache time",
4036 .type = P_INTEGER,
4037 .p_class = P_LOCAL,
4038 .ptr = &sDefault.iDfreeCacheTime,
4039 .special = NULL,
4040 .enum_list = NULL,
4041 .flags = FLAG_ADVANCED,
4044 .label = "dfree command",
4045 .type = P_STRING,
4046 .p_class = P_LOCAL,
4047 .ptr = &sDefault.szDfree,
4048 .special = NULL,
4049 .enum_list = NULL,
4050 .flags = FLAG_ADVANCED,
4053 .label = "get quota command",
4054 .type = P_STRING,
4055 .p_class = P_GLOBAL,
4056 .ptr = &Globals.szGetQuota,
4057 .special = NULL,
4058 .enum_list = NULL,
4059 .flags = FLAG_ADVANCED,
4062 .label = "set quota command",
4063 .type = P_STRING,
4064 .p_class = P_GLOBAL,
4065 .ptr = &Globals.szSetQuota,
4066 .special = NULL,
4067 .enum_list = NULL,
4068 .flags = FLAG_ADVANCED,
4071 .label = "remote announce",
4072 .type = P_STRING,
4073 .p_class = P_GLOBAL,
4074 .ptr = &Globals.szRemoteAnnounce,
4075 .special = NULL,
4076 .enum_list = NULL,
4077 .flags = FLAG_ADVANCED,
4080 .label = "remote browse sync",
4081 .type = P_STRING,
4082 .p_class = P_GLOBAL,
4083 .ptr = &Globals.szRemoteBrowseSync,
4084 .special = NULL,
4085 .enum_list = NULL,
4086 .flags = FLAG_ADVANCED,
4089 .label = "socket address",
4090 .type = P_STRING,
4091 .p_class = P_GLOBAL,
4092 .ptr = &Globals.szSocketAddress,
4093 .special = NULL,
4094 .enum_list = NULL,
4095 .flags = FLAG_ADVANCED,
4098 .label = "nmbd bind explicit broadcast",
4099 .type = P_BOOL,
4100 .p_class = P_GLOBAL,
4101 .ptr = &Globals.bNmbdBindExplicitBroadcast,
4102 .special = NULL,
4103 .enum_list = NULL,
4104 .flags = FLAG_ADVANCED,
4107 .label = "homedir map",
4108 .type = P_STRING,
4109 .p_class = P_GLOBAL,
4110 .ptr = &Globals.szNISHomeMapName,
4111 .special = NULL,
4112 .enum_list = NULL,
4113 .flags = FLAG_ADVANCED,
4116 .label = "afs username map",
4117 .type = P_STRING,
4118 .p_class = P_GLOBAL,
4119 .ptr = &Globals.szAfsUsernameMap,
4120 .special = NULL,
4121 .enum_list = NULL,
4122 .flags = FLAG_ADVANCED,
4125 .label = "afs token lifetime",
4126 .type = P_INTEGER,
4127 .p_class = P_GLOBAL,
4128 .ptr = &Globals.iAfsTokenLifetime,
4129 .special = NULL,
4130 .enum_list = NULL,
4131 .flags = FLAG_ADVANCED,
4134 .label = "log nt token command",
4135 .type = P_STRING,
4136 .p_class = P_GLOBAL,
4137 .ptr = &Globals.szLogNtTokenCommand,
4138 .special = NULL,
4139 .enum_list = NULL,
4140 .flags = FLAG_ADVANCED,
4143 .label = "time offset",
4144 .type = P_INTEGER,
4145 .p_class = P_GLOBAL,
4146 .ptr = &extra_time_offset,
4147 .special = NULL,
4148 .enum_list = NULL,
4149 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4152 .label = "NIS homedir",
4153 .type = P_BOOL,
4154 .p_class = P_GLOBAL,
4155 .ptr = &Globals.bNISHomeMap,
4156 .special = NULL,
4157 .enum_list = NULL,
4158 .flags = FLAG_ADVANCED,
4161 .label = "-valid",
4162 .type = P_BOOL,
4163 .p_class = P_LOCAL,
4164 .ptr = &sDefault.valid,
4165 .special = NULL,
4166 .enum_list = NULL,
4167 .flags = FLAG_HIDE,
4170 .label = "copy",
4171 .type = P_STRING,
4172 .p_class = P_LOCAL,
4173 .ptr = &sDefault.szCopy,
4174 .special = handle_copy,
4175 .enum_list = NULL,
4176 .flags = FLAG_HIDE,
4179 .label = "include",
4180 .type = P_STRING,
4181 .p_class = P_LOCAL,
4182 .ptr = &sDefault.szInclude,
4183 .special = handle_include,
4184 .enum_list = NULL,
4185 .flags = FLAG_HIDE|FLAG_META,
4188 .label = "preexec",
4189 .type = P_STRING,
4190 .p_class = P_LOCAL,
4191 .ptr = &sDefault.szPreExec,
4192 .special = NULL,
4193 .enum_list = NULL,
4194 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4197 .label = "exec",
4198 .type = P_STRING,
4199 .p_class = P_LOCAL,
4200 .ptr = &sDefault.szPreExec,
4201 .special = NULL,
4202 .enum_list = NULL,
4203 .flags = FLAG_ADVANCED,
4206 .label = "preexec close",
4207 .type = P_BOOL,
4208 .p_class = P_LOCAL,
4209 .ptr = &sDefault.bPreexecClose,
4210 .special = NULL,
4211 .enum_list = NULL,
4212 .flags = FLAG_ADVANCED | FLAG_SHARE,
4215 .label = "postexec",
4216 .type = P_STRING,
4217 .p_class = P_LOCAL,
4218 .ptr = &sDefault.szPostExec,
4219 .special = NULL,
4220 .enum_list = NULL,
4221 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4224 .label = "root preexec",
4225 .type = P_STRING,
4226 .p_class = P_LOCAL,
4227 .ptr = &sDefault.szRootPreExec,
4228 .special = NULL,
4229 .enum_list = NULL,
4230 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4233 .label = "root preexec close",
4234 .type = P_BOOL,
4235 .p_class = P_LOCAL,
4236 .ptr = &sDefault.bRootpreexecClose,
4237 .special = NULL,
4238 .enum_list = NULL,
4239 .flags = FLAG_ADVANCED | FLAG_SHARE,
4242 .label = "root postexec",
4243 .type = P_STRING,
4244 .p_class = P_LOCAL,
4245 .ptr = &sDefault.szRootPostExec,
4246 .special = NULL,
4247 .enum_list = NULL,
4248 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4251 .label = "available",
4252 .type = P_BOOL,
4253 .p_class = P_LOCAL,
4254 .ptr = &sDefault.bAvailable,
4255 .special = NULL,
4256 .enum_list = NULL,
4257 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4260 .label = "registry shares",
4261 .type = P_BOOL,
4262 .p_class = P_GLOBAL,
4263 .ptr = &Globals.bRegistryShares,
4264 .special = NULL,
4265 .enum_list = NULL,
4266 .flags = FLAG_ADVANCED,
4269 .label = "usershare allow guests",
4270 .type = P_BOOL,
4271 .p_class = P_GLOBAL,
4272 .ptr = &Globals.bUsershareAllowGuests,
4273 .special = NULL,
4274 .enum_list = NULL,
4275 .flags = FLAG_ADVANCED,
4278 .label = "usershare max shares",
4279 .type = P_INTEGER,
4280 .p_class = P_GLOBAL,
4281 .ptr = &Globals.iUsershareMaxShares,
4282 .special = NULL,
4283 .enum_list = NULL,
4284 .flags = FLAG_ADVANCED,
4287 .label = "usershare owner only",
4288 .type = P_BOOL,
4289 .p_class = P_GLOBAL,
4290 .ptr = &Globals.bUsershareOwnerOnly,
4291 .special = NULL,
4292 .enum_list = NULL,
4293 .flags = FLAG_ADVANCED,
4296 .label = "usershare path",
4297 .type = P_STRING,
4298 .p_class = P_GLOBAL,
4299 .ptr = &Globals.szUsersharePath,
4300 .special = NULL,
4301 .enum_list = NULL,
4302 .flags = FLAG_ADVANCED,
4305 .label = "usershare prefix allow list",
4306 .type = P_LIST,
4307 .p_class = P_GLOBAL,
4308 .ptr = &Globals.szUsersharePrefixAllowList,
4309 .special = NULL,
4310 .enum_list = NULL,
4311 .flags = FLAG_ADVANCED,
4314 .label = "usershare prefix deny list",
4315 .type = P_LIST,
4316 .p_class = P_GLOBAL,
4317 .ptr = &Globals.szUsersharePrefixDenyList,
4318 .special = NULL,
4319 .enum_list = NULL,
4320 .flags = FLAG_ADVANCED,
4323 .label = "usershare template share",
4324 .type = P_STRING,
4325 .p_class = P_GLOBAL,
4326 .ptr = &Globals.szUsershareTemplateShare,
4327 .special = NULL,
4328 .enum_list = NULL,
4329 .flags = FLAG_ADVANCED,
4332 .label = "volume",
4333 .type = P_STRING,
4334 .p_class = P_LOCAL,
4335 .ptr = &sDefault.volume,
4336 .special = NULL,
4337 .enum_list = NULL,
4338 .flags = FLAG_ADVANCED | FLAG_SHARE,
4341 .label = "fstype",
4342 .type = P_STRING,
4343 .p_class = P_LOCAL,
4344 .ptr = &sDefault.fstype,
4345 .special = NULL,
4346 .enum_list = NULL,
4347 .flags = FLAG_ADVANCED | FLAG_SHARE,
4350 .label = "set directory",
4351 .type = P_BOOLREV,
4352 .p_class = P_LOCAL,
4353 .ptr = &sDefault.bNo_set_dir,
4354 .special = NULL,
4355 .enum_list = NULL,
4356 .flags = FLAG_ADVANCED | FLAG_SHARE,
4359 .label = "wide links",
4360 .type = P_BOOL,
4361 .p_class = P_LOCAL,
4362 .ptr = &sDefault.bWidelinks,
4363 .special = NULL,
4364 .enum_list = NULL,
4365 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4368 .label = "follow symlinks",
4369 .type = P_BOOL,
4370 .p_class = P_LOCAL,
4371 .ptr = &sDefault.bSymlinks,
4372 .special = NULL,
4373 .enum_list = NULL,
4374 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4377 .label = "dont descend",
4378 .type = P_STRING,
4379 .p_class = P_LOCAL,
4380 .ptr = &sDefault.szDontdescend,
4381 .special = NULL,
4382 .enum_list = NULL,
4383 .flags = FLAG_ADVANCED | FLAG_SHARE,
4386 .label = "magic script",
4387 .type = P_STRING,
4388 .p_class = P_LOCAL,
4389 .ptr = &sDefault.szMagicScript,
4390 .special = NULL,
4391 .enum_list = NULL,
4392 .flags = FLAG_ADVANCED | FLAG_SHARE,
4395 .label = "magic output",
4396 .type = P_STRING,
4397 .p_class = P_LOCAL,
4398 .ptr = &sDefault.szMagicOutput,
4399 .special = NULL,
4400 .enum_list = NULL,
4401 .flags = FLAG_ADVANCED | FLAG_SHARE,
4404 .label = "delete readonly",
4405 .type = P_BOOL,
4406 .p_class = P_LOCAL,
4407 .ptr = &sDefault.bDeleteReadonly,
4408 .special = NULL,
4409 .enum_list = NULL,
4410 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4413 .label = "dos filemode",
4414 .type = P_BOOL,
4415 .p_class = P_LOCAL,
4416 .ptr = &sDefault.bDosFilemode,
4417 .special = NULL,
4418 .enum_list = NULL,
4419 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4422 .label = "dos filetimes",
4423 .type = P_BOOL,
4424 .p_class = P_LOCAL,
4425 .ptr = &sDefault.bDosFiletimes,
4426 .special = NULL,
4427 .enum_list = NULL,
4428 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4431 .label = "dos filetime resolution",
4432 .type = P_BOOL,
4433 .p_class = P_LOCAL,
4434 .ptr = &sDefault.bDosFiletimeResolution,
4435 .special = NULL,
4436 .enum_list = NULL,
4437 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4440 .label = "fake directory create times",
4441 .type = P_BOOL,
4442 .p_class = P_LOCAL,
4443 .ptr = &sDefault.bFakeDirCreateTimes,
4444 .special = NULL,
4445 .enum_list = NULL,
4446 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4449 .label = "async smb echo handler",
4450 .type = P_BOOL,
4451 .p_class = P_GLOBAL,
4452 .ptr = &Globals.bAsyncSMBEchoHandler,
4453 .special = NULL,
4454 .enum_list = NULL,
4455 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4458 .label = "multicast dns register",
4459 .type = P_BOOL,
4460 .p_class = P_GLOBAL,
4461 .ptr = &Globals.bMulticastDnsRegister,
4462 .special = NULL,
4463 .enum_list = NULL,
4464 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4467 .label = "panic action",
4468 .type = P_STRING,
4469 .p_class = P_GLOBAL,
4470 .ptr = &Globals.szPanicAction,
4471 .special = NULL,
4472 .enum_list = NULL,
4473 .flags = FLAG_ADVANCED,
4476 .label = "perfcount module",
4477 .type = P_STRING,
4478 .p_class = P_GLOBAL,
4479 .ptr = &Globals.szSMBPerfcountModule,
4480 .special = NULL,
4481 .enum_list = NULL,
4482 .flags = FLAG_ADVANCED,
4485 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4488 .label = "vfs objects",
4489 .type = P_LIST,
4490 .p_class = P_LOCAL,
4491 .ptr = &sDefault.szVfsObjects,
4492 .special = NULL,
4493 .enum_list = NULL,
4494 .flags = FLAG_ADVANCED | FLAG_SHARE,
4497 .label = "vfs object",
4498 .type = P_LIST,
4499 .p_class = P_LOCAL,
4500 .ptr = &sDefault.szVfsObjects,
4501 .special = NULL,
4502 .enum_list = NULL,
4503 .flags = FLAG_HIDE,
4507 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4510 .label = "msdfs root",
4511 .type = P_BOOL,
4512 .p_class = P_LOCAL,
4513 .ptr = &sDefault.bMSDfsRoot,
4514 .special = NULL,
4515 .enum_list = NULL,
4516 .flags = FLAG_ADVANCED | FLAG_SHARE,
4519 .label = "msdfs proxy",
4520 .type = P_STRING,
4521 .p_class = P_LOCAL,
4522 .ptr = &sDefault.szMSDfsProxy,
4523 .special = NULL,
4524 .enum_list = NULL,
4525 .flags = FLAG_ADVANCED | FLAG_SHARE,
4528 .label = "host msdfs",
4529 .type = P_BOOL,
4530 .p_class = P_GLOBAL,
4531 .ptr = &Globals.bHostMSDfs,
4532 .special = NULL,
4533 .enum_list = NULL,
4534 .flags = FLAG_ADVANCED,
4537 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4540 .label = "passdb expand explicit",
4541 .type = P_BOOL,
4542 .p_class = P_GLOBAL,
4543 .ptr = &Globals.bPassdbExpandExplicit,
4544 .special = NULL,
4545 .enum_list = NULL,
4546 .flags = FLAG_ADVANCED,
4549 .label = "idmap backend",
4550 .type = P_STRING,
4551 .p_class = P_GLOBAL,
4552 .ptr = &Globals.szIdmapBackend,
4553 .special = handle_idmap_backend,
4554 .enum_list = NULL,
4555 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4558 .label = "idmap cache time",
4559 .type = P_INTEGER,
4560 .p_class = P_GLOBAL,
4561 .ptr = &Globals.iIdmapCacheTime,
4562 .special = NULL,
4563 .enum_list = NULL,
4564 .flags = FLAG_ADVANCED,
4567 .label = "idmap negative cache time",
4568 .type = P_INTEGER,
4569 .p_class = P_GLOBAL,
4570 .ptr = &Globals.iIdmapNegativeCacheTime,
4571 .special = NULL,
4572 .enum_list = NULL,
4573 .flags = FLAG_ADVANCED,
4576 .label = "idmap uid",
4577 .type = P_STRING,
4578 .p_class = P_GLOBAL,
4579 .ptr = &Globals.szIdmapUID,
4580 .special = handle_idmap_uid,
4581 .enum_list = NULL,
4582 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4585 .label = "winbind uid",
4586 .type = P_STRING,
4587 .p_class = P_GLOBAL,
4588 .ptr = &Globals.szIdmapUID,
4589 .special = handle_idmap_uid,
4590 .enum_list = NULL,
4591 .flags = FLAG_HIDE,
4594 .label = "idmap gid",
4595 .type = P_STRING,
4596 .p_class = P_GLOBAL,
4597 .ptr = &Globals.szIdmapGID,
4598 .special = handle_idmap_gid,
4599 .enum_list = NULL,
4600 .flags = FLAG_ADVANCED | FLAG_DEPRECATED,
4603 .label = "winbind gid",
4604 .type = P_STRING,
4605 .p_class = P_GLOBAL,
4606 .ptr = &Globals.szIdmapGID,
4607 .special = handle_idmap_gid,
4608 .enum_list = NULL,
4609 .flags = FLAG_HIDE,
4612 .label = "template homedir",
4613 .type = P_STRING,
4614 .p_class = P_GLOBAL,
4615 .ptr = &Globals.szTemplateHomedir,
4616 .special = NULL,
4617 .enum_list = NULL,
4618 .flags = FLAG_ADVANCED,
4621 .label = "template shell",
4622 .type = P_STRING,
4623 .p_class = P_GLOBAL,
4624 .ptr = &Globals.szTemplateShell,
4625 .special = NULL,
4626 .enum_list = NULL,
4627 .flags = FLAG_ADVANCED,
4630 .label = "winbind separator",
4631 .type = P_STRING,
4632 .p_class = P_GLOBAL,
4633 .ptr = &Globals.szWinbindSeparator,
4634 .special = NULL,
4635 .enum_list = NULL,
4636 .flags = FLAG_ADVANCED,
4639 .label = "winbind cache time",
4640 .type = P_INTEGER,
4641 .p_class = P_GLOBAL,
4642 .ptr = &Globals.winbind_cache_time,
4643 .special = NULL,
4644 .enum_list = NULL,
4645 .flags = FLAG_ADVANCED,
4648 .label = "winbind reconnect delay",
4649 .type = P_INTEGER,
4650 .p_class = P_GLOBAL,
4651 .ptr = &Globals.winbind_reconnect_delay,
4652 .special = NULL,
4653 .enum_list = NULL,
4654 .flags = FLAG_ADVANCED,
4657 .label = "winbind max clients",
4658 .type = P_INTEGER,
4659 .p_class = P_GLOBAL,
4660 .ptr = &Globals.winbind_max_clients,
4661 .special = NULL,
4662 .enum_list = NULL,
4663 .flags = FLAG_ADVANCED,
4666 .label = "winbind enum users",
4667 .type = P_BOOL,
4668 .p_class = P_GLOBAL,
4669 .ptr = &Globals.bWinbindEnumUsers,
4670 .special = NULL,
4671 .enum_list = NULL,
4672 .flags = FLAG_ADVANCED,
4675 .label = "winbind enum groups",
4676 .type = P_BOOL,
4677 .p_class = P_GLOBAL,
4678 .ptr = &Globals.bWinbindEnumGroups,
4679 .special = NULL,
4680 .enum_list = NULL,
4681 .flags = FLAG_ADVANCED,
4684 .label = "winbind use default domain",
4685 .type = P_BOOL,
4686 .p_class = P_GLOBAL,
4687 .ptr = &Globals.bWinbindUseDefaultDomain,
4688 .special = NULL,
4689 .enum_list = NULL,
4690 .flags = FLAG_ADVANCED,
4693 .label = "winbind trusted domains only",
4694 .type = P_BOOL,
4695 .p_class = P_GLOBAL,
4696 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4697 .special = NULL,
4698 .enum_list = NULL,
4699 .flags = FLAG_ADVANCED,
4702 .label = "winbind nested groups",
4703 .type = P_BOOL,
4704 .p_class = P_GLOBAL,
4705 .ptr = &Globals.bWinbindNestedGroups,
4706 .special = NULL,
4707 .enum_list = NULL,
4708 .flags = FLAG_ADVANCED,
4711 .label = "winbind expand groups",
4712 .type = P_INTEGER,
4713 .p_class = P_GLOBAL,
4714 .ptr = &Globals.winbind_expand_groups,
4715 .special = NULL,
4716 .enum_list = NULL,
4717 .flags = FLAG_ADVANCED,
4720 .label = "winbind nss info",
4721 .type = P_LIST,
4722 .p_class = P_GLOBAL,
4723 .ptr = &Globals.szWinbindNssInfo,
4724 .special = NULL,
4725 .enum_list = NULL,
4726 .flags = FLAG_ADVANCED,
4729 .label = "winbind refresh tickets",
4730 .type = P_BOOL,
4731 .p_class = P_GLOBAL,
4732 .ptr = &Globals.bWinbindRefreshTickets,
4733 .special = NULL,
4734 .enum_list = NULL,
4735 .flags = FLAG_ADVANCED,
4738 .label = "winbind offline logon",
4739 .type = P_BOOL,
4740 .p_class = P_GLOBAL,
4741 .ptr = &Globals.bWinbindOfflineLogon,
4742 .special = NULL,
4743 .enum_list = NULL,
4744 .flags = FLAG_ADVANCED,
4747 .label = "winbind normalize names",
4748 .type = P_BOOL,
4749 .p_class = P_GLOBAL,
4750 .ptr = &Globals.bWinbindNormalizeNames,
4751 .special = NULL,
4752 .enum_list = NULL,
4753 .flags = FLAG_ADVANCED,
4756 .label = "winbind rpc only",
4757 .type = P_BOOL,
4758 .p_class = P_GLOBAL,
4759 .ptr = &Globals.bWinbindRpcOnly,
4760 .special = NULL,
4761 .enum_list = NULL,
4762 .flags = FLAG_ADVANCED,
4765 .label = "create krb5 conf",
4766 .type = P_BOOL,
4767 .p_class = P_GLOBAL,
4768 .ptr = &Globals.bCreateKrb5Conf,
4769 .special = NULL,
4770 .enum_list = NULL,
4771 .flags = FLAG_ADVANCED,
4774 .label = "ncalrpc dir",
4775 .type = P_STRING,
4776 .p_class = P_GLOBAL,
4777 .ptr = &Globals.ncalrpc_dir,
4778 .special = NULL,
4779 .enum_list = NULL,
4780 .flags = FLAG_ADVANCED,
4783 .label = "winbind max domain connections",
4784 .type = P_INTEGER,
4785 .p_class = P_GLOBAL,
4786 .ptr = &Globals.winbindMaxDomainConnections,
4787 .special = NULL,
4788 .enum_list = NULL,
4789 .flags = FLAG_ADVANCED,
4792 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4795 /***************************************************************************
4796 Initialise the sDefault parameter structure for the printer values.
4797 ***************************************************************************/
4799 static void init_printer_values(struct service *pService)
4801 /* choose defaults depending on the type of printing */
4802 switch (pService->iPrinting) {
4803 case PRINT_BSD:
4804 case PRINT_AIX:
4805 case PRINT_LPRNT:
4806 case PRINT_LPROS2:
4807 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4808 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4809 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4810 break;
4812 case PRINT_LPRNG:
4813 case PRINT_PLP:
4814 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4815 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4816 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4817 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4818 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4819 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4820 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4821 break;
4823 case PRINT_CUPS:
4824 case PRINT_IPRINT:
4825 #ifdef HAVE_CUPS
4826 /* set the lpq command to contain the destination printer
4827 name only. This is used by cups_queue_get() */
4828 string_set(&pService->szLpqcommand, "%p");
4829 string_set(&pService->szLprmcommand, "");
4830 string_set(&pService->szPrintcommand, "");
4831 string_set(&pService->szLppausecommand, "");
4832 string_set(&pService->szLpresumecommand, "");
4833 string_set(&pService->szQueuepausecommand, "");
4834 string_set(&pService->szQueueresumecommand, "");
4835 #else
4836 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4837 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4838 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4839 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4840 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4841 string_set(&pService->szQueuepausecommand, "disable '%p'");
4842 string_set(&pService->szQueueresumecommand, "enable '%p'");
4843 #endif /* HAVE_CUPS */
4844 break;
4846 case PRINT_SYSV:
4847 case PRINT_HPUX:
4848 string_set(&pService->szLpqcommand, "lpstat -o%p");
4849 string_set(&pService->szLprmcommand, "cancel %p-%j");
4850 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4851 string_set(&pService->szQueuepausecommand, "disable %p");
4852 string_set(&pService->szQueueresumecommand, "enable %p");
4853 #ifndef HPUX
4854 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4855 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4856 #endif /* HPUX */
4857 break;
4859 case PRINT_QNX:
4860 string_set(&pService->szLpqcommand, "lpq -P%p");
4861 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4862 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4863 break;
4865 #if defined(DEVELOPER) || defined(ENABLE_BUILD_FARM_HACKS)
4867 case PRINT_TEST:
4868 case PRINT_VLP: {
4869 const char *tdbfile;
4870 char *tmp;
4872 tdbfile = talloc_asprintf(
4873 talloc_tos(), "tdbfile=%s",
4874 lp_parm_const_string(-1, "vlp", "tdbfile",
4875 "/tmp/vlp.tdb"));
4876 if (tdbfile == NULL) {
4877 tdbfile="tdbfile=/tmp/vlp.tdb";
4880 tmp = talloc_asprintf(talloc_tos(), "vlp %s print %%p %%s",
4881 tdbfile);
4882 string_set(&pService->szPrintcommand,
4883 tmp ? tmp : "vlp print %p %s");
4884 TALLOC_FREE(tmp);
4886 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpq %%p",
4887 tdbfile);
4888 string_set(&pService->szLpqcommand,
4889 tmp ? tmp : "vlp lpq %p");
4890 TALLOC_FREE(tmp);
4892 tmp = talloc_asprintf(talloc_tos(), "vlp %s lprm %%p %%j",
4893 tdbfile);
4894 string_set(&pService->szLprmcommand,
4895 tmp ? tmp : "vlp lprm %p %j");
4896 TALLOC_FREE(tmp);
4898 tmp = talloc_asprintf(talloc_tos(), "vlp %s lppause %%p %%j",
4899 tdbfile);
4900 string_set(&pService->szLppausecommand,
4901 tmp ? tmp : "vlp lppause %p %j");
4902 TALLOC_FREE(tmp);
4904 tmp = talloc_asprintf(talloc_tos(), "vlp %s lpresume %%p %%j",
4905 tdbfile);
4906 string_set(&pService->szLpresumecommand,
4907 tmp ? tmp : "vlp lpresume %p %j");
4908 TALLOC_FREE(tmp);
4910 tmp = talloc_asprintf(talloc_tos(), "vlp %s queuepause %%p",
4911 tdbfile);
4912 string_set(&pService->szQueuepausecommand,
4913 tmp ? tmp : "vlp queuepause %p");
4914 TALLOC_FREE(tmp);
4916 tmp = talloc_asprintf(talloc_tos(), "vlp %s queueresume %%p",
4917 tdbfile);
4918 string_set(&pService->szQueueresumecommand,
4919 tmp ? tmp : "vlp queueresume %p");
4920 TALLOC_FREE(tmp);
4922 break;
4924 #endif /* DEVELOPER */
4929 * Function to return the default value for the maximum number of open
4930 * file descriptors permitted. This function tries to consult the
4931 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4932 * the smaller of those.
4934 static int max_open_files(void)
4936 int sysctl_max = MAX_OPEN_FILES;
4937 int rlimit_max = MAX_OPEN_FILES;
4939 #ifdef HAVE_SYSCTLBYNAME
4941 size_t size = sizeof(sysctl_max);
4942 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4945 #endif
4947 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4949 struct rlimit rl;
4951 ZERO_STRUCT(rl);
4953 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4954 rlimit_max = rl.rlim_cur;
4956 #if defined(RLIM_INFINITY)
4957 if(rl.rlim_cur == RLIM_INFINITY)
4958 rlimit_max = MAX_OPEN_FILES;
4959 #endif
4961 #endif
4963 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4964 DEBUG(2,("max_open_files: increasing sysctl_max (%d) to "
4965 "minimum Windows limit (%d)\n",
4966 sysctl_max,
4967 MIN_OPEN_FILES_WINDOWS));
4968 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4971 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4972 DEBUG(2,("rlimit_max: increasing rlimit_max (%d) to "
4973 "minimum Windows limit (%d)\n",
4974 rlimit_max,
4975 MIN_OPEN_FILES_WINDOWS));
4976 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4979 return MIN(sysctl_max, rlimit_max);
4983 * Common part of freeing allocated data for one parameter.
4985 static void free_one_parameter_common(void *parm_ptr,
4986 struct parm_struct parm)
4988 if ((parm.type == P_STRING) ||
4989 (parm.type == P_USTRING))
4991 string_free((char**)parm_ptr);
4992 } else if (parm.type == P_LIST) {
4993 TALLOC_FREE(*((char***)parm_ptr));
4998 * Free the allocated data for one parameter for a share
4999 * given as a service struct.
5001 static void free_one_parameter(struct service *service,
5002 struct parm_struct parm)
5004 void *parm_ptr;
5006 if (parm.p_class != P_LOCAL) {
5007 return;
5010 parm_ptr = lp_local_ptr(service, parm.ptr);
5012 free_one_parameter_common(parm_ptr, parm);
5016 * Free the allocated parameter data of a share given
5017 * as a service struct.
5019 static void free_parameters(struct service *service)
5021 uint32_t i;
5023 for (i=0; parm_table[i].label; i++) {
5024 free_one_parameter(service, parm_table[i]);
5029 * Free the allocated data for one parameter for a given share
5030 * specified by an snum.
5032 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
5034 void *parm_ptr;
5036 if (parm.ptr == NULL) {
5037 return;
5040 if (snum < 0) {
5041 parm_ptr = parm.ptr;
5042 } else if (parm.p_class != P_LOCAL) {
5043 return;
5044 } else {
5045 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
5048 free_one_parameter_common(parm_ptr, parm);
5052 * Free the allocated parameter data for a share specified
5053 * by an snum.
5055 static void free_parameters_by_snum(int snum)
5057 uint32_t i;
5059 for (i=0; parm_table[i].label; i++) {
5060 free_one_parameter_by_snum(snum, parm_table[i]);
5065 * Free the allocated global parameters.
5067 static void free_global_parameters(void)
5069 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
5072 static int map_parameter(const char *pszParmName);
5074 struct lp_stored_option {
5075 struct lp_stored_option *prev, *next;
5076 const char *label;
5077 const char *value;
5080 static struct lp_stored_option *stored_options;
5083 save options set by lp_set_cmdline() into a list. This list is
5084 re-applied when we do a globals reset, so that cmdline set options
5085 are sticky across reloads of smb.conf
5087 static bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
5089 struct lp_stored_option *entry, *entry_next;
5090 for (entry = stored_options; entry != NULL; entry = entry_next) {
5091 entry_next = entry->next;
5092 if (strcmp(pszParmName, entry->label) == 0) {
5093 DLIST_REMOVE(stored_options, entry);
5094 talloc_free(entry);
5095 break;
5099 entry = talloc(NULL, struct lp_stored_option);
5100 if (!entry) {
5101 return false;
5104 entry->label = talloc_strdup(entry, pszParmName);
5105 if (!entry->label) {
5106 talloc_free(entry);
5107 return false;
5110 entry->value = talloc_strdup(entry, pszParmValue);
5111 if (!entry->value) {
5112 talloc_free(entry);
5113 return false;
5116 DLIST_ADD_END(stored_options, entry, struct lp_stored_option);
5118 return true;
5121 static bool apply_lp_set_cmdline(void)
5123 struct lp_stored_option *entry = NULL;
5124 for (entry = stored_options; entry != NULL; entry = entry->next) {
5125 if (!lp_set_cmdline_helper(entry->label, entry->value, false)) {
5126 DEBUG(0, ("Failed to re-apply cmdline parameter %s = %s\n",
5127 entry->label, entry->value));
5128 return false;
5131 return true;
5134 /***************************************************************************
5135 Initialise the global parameter structure.
5136 ***************************************************************************/
5138 static void init_globals(bool reinit_globals)
5140 static bool done_init = False;
5141 char *s = NULL;
5142 int i;
5144 /* If requested to initialize only once and we've already done it... */
5145 if (!reinit_globals && done_init) {
5146 /* ... then we have nothing more to do */
5147 return;
5150 if (!done_init) {
5151 /* The logfile can be set before this is invoked. Free it if so. */
5152 if (Globals.szLogFile != NULL) {
5153 string_free(&Globals.szLogFile);
5154 Globals.szLogFile = NULL;
5156 done_init = True;
5157 } else {
5158 free_global_parameters();
5161 /* This memset and the free_global_parameters() above will
5162 * wipe out smb.conf options set with lp_set_cmdline(). The
5163 * apply_lp_set_cmdline() call puts these values back in the
5164 * table once the defaults are set */
5165 memset((void *)&Globals, '\0', sizeof(Globals));
5167 for (i = 0; parm_table[i].label; i++) {
5168 if ((parm_table[i].type == P_STRING ||
5169 parm_table[i].type == P_USTRING) &&
5170 parm_table[i].ptr)
5172 string_set((char **)parm_table[i].ptr, "");
5176 string_set(&sDefault.fstype, FSTYPE_STRING);
5177 string_set(&sDefault.szPrintjobUsername, "%U");
5179 init_printer_values(&sDefault);
5182 DEBUG(3, ("Initialising global parameters\n"));
5184 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
5185 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
5187 /* use the new 'hash2' method by default, with a prefix of 1 */
5188 string_set(&Globals.szManglingMethod, "hash2");
5189 Globals.mangle_prefix = 1;
5191 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5193 /* using UTF8 by default allows us to support all chars */
5194 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5196 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5197 /* If the system supports nl_langinfo(), try to grab the value
5198 from the user's locale */
5199 string_set(&Globals.display_charset, "LOCALE");
5200 #else
5201 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5202 #endif
5204 /* Use codepage 850 as a default for the dos character set */
5205 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5208 * Allow the default PASSWD_CHAT to be overridden in local.h.
5210 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5212 set_global_myname(myhostname());
5213 string_set(&Globals.szNetbiosName,global_myname());
5215 set_global_myworkgroup(WORKGROUP);
5216 string_set(&Globals.szWorkgroup, lp_workgroup());
5218 string_set(&Globals.szPasswdProgram, "");
5219 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5220 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5221 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5222 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5223 string_set(&Globals.szSocketAddress, "0.0.0.0");
5225 * By default support explicit binding to broadcast
5226 * addresses.
5228 Globals.bNmbdBindExplicitBroadcast = true;
5230 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5231 smb_panic("init_globals: ENOMEM");
5233 string_set(&Globals.szServerString, s);
5234 SAFE_FREE(s);
5235 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5236 DEFAULT_MINOR_VERSION) < 0) {
5237 smb_panic("init_globals: ENOMEM");
5239 string_set(&Globals.szAnnounceVersion, s);
5240 SAFE_FREE(s);
5241 #ifdef DEVELOPER
5242 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5243 #endif
5245 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5247 string_set(&Globals.szLogonDrive, "");
5248 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5249 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5250 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5252 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5253 string_set(&Globals.szPasswordServer, "*");
5255 Globals.AlgorithmicRidBase = BASE_RID;
5257 Globals.bLoadPrinters = True;
5258 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5260 Globals.ConfigBackend = config_backend;
5262 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5263 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5264 Globals.max_xmit = 0x4104;
5265 Globals.max_mux = 50; /* This is *needed* for profile support. */
5266 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5267 Globals.bDisableSpoolss = False;
5268 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5269 Globals.pwordlevel = 0;
5270 Globals.unamelevel = 0;
5271 Globals.deadtime = 0;
5272 Globals.getwd_cache = true;
5273 Globals.bLargeReadwrite = True;
5274 Globals.max_log_size = 5000;
5275 Globals.max_open_files = max_open_files();
5276 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5277 Globals.maxprotocol = PROTOCOL_NT1;
5278 Globals.minprotocol = PROTOCOL_CORE;
5279 Globals.security = SEC_USER;
5280 Globals.paranoid_server_security = True;
5281 Globals.bEncryptPasswords = True;
5282 Globals.bUpdateEncrypt = False;
5283 Globals.clientSchannel = Auto;
5284 Globals.serverSchannel = Auto;
5285 Globals.bReadRaw = True;
5286 Globals.bWriteRaw = True;
5287 Globals.bNullPasswords = False;
5288 Globals.bObeyPamRestrictions = False;
5289 Globals.syslog = 1;
5290 Globals.bSyslogOnly = False;
5291 Globals.bTimestampLogs = True;
5292 string_set(&Globals.szLogLevel, "0");
5293 Globals.bDebugPrefixTimestamp = False;
5294 Globals.bDebugHiresTimestamp = true;
5295 Globals.bDebugPid = False;
5296 Globals.bDebugUid = False;
5297 Globals.bDebugClass = False;
5298 Globals.bEnableCoreFiles = True;
5299 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5300 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5301 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5302 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5303 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5304 Globals.lm_interval = 60;
5305 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5306 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5307 Globals.bNISHomeMap = False;
5308 #ifdef WITH_NISPLUS_HOME
5309 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5310 #else
5311 string_set(&Globals.szNISHomeMapName, "auto.home");
5312 #endif
5313 #endif
5314 Globals.bTimeServer = False;
5315 Globals.bBindInterfacesOnly = False;
5316 Globals.bUnixPasswdSync = False;
5317 Globals.bPamPasswordChange = False;
5318 Globals.bPasswdChatDebug = False;
5319 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5320 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5321 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5322 Globals.bStatCache = True; /* use stat cache by default */
5323 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5324 Globals.restrict_anonymous = 0;
5325 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5326 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5327 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5328 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5329 Globals.bClientNTLMv2Auth = True; /* Client should always use use NTLMv2, as we can't tell that the server supports it, but most modern servers do */
5330 /* Note, that we will also use NTLM2 session security (which is different), if it is available */
5332 Globals.map_to_guest = 0; /* By Default, "Never" */
5333 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5334 Globals.enhanced_browsing = true;
5335 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5336 #ifdef MMAP_BLACKLIST
5337 Globals.bUseMmap = False;
5338 #else
5339 Globals.bUseMmap = True;
5340 #endif
5341 Globals.bUnixExtensions = True;
5342 Globals.bResetOnZeroVC = False;
5343 Globals.bLogWriteableFilesOnExit = False;
5344 Globals.bCreateKrb5Conf = true;
5345 Globals.winbindMaxDomainConnections = 1;
5347 /* hostname lookups can be very expensive and are broken on
5348 a large number of sites (tridge) */
5349 Globals.bHostnameLookups = False;
5351 string_set(&Globals.szPassdbBackend, "tdbsam");
5352 string_set(&Globals.szLdapSuffix, "");
5353 string_set(&Globals.szLdapMachineSuffix, "");
5354 string_set(&Globals.szLdapUserSuffix, "");
5355 string_set(&Globals.szLdapGroupSuffix, "");
5356 string_set(&Globals.szLdapIdmapSuffix, "");
5358 string_set(&Globals.szLdapAdminDn, "");
5359 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5360 Globals.ldap_ssl_ads = False;
5361 Globals.ldap_deref = -1;
5362 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5363 Globals.ldap_delete_dn = False;
5364 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5365 Globals.ldap_follow_referral = Auto;
5366 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5367 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5368 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5370 Globals.ldap_debug_level = 0;
5371 Globals.ldap_debug_threshold = 10;
5373 /* This is what we tell the afs client. in reality we set the token
5374 * to never expire, though, when this runs out the afs client will
5375 * forget the token. Set to 0 to get NEVERDATE.*/
5376 Globals.iAfsTokenLifetime = 604800;
5377 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5379 /* these parameters are set to defaults that are more appropriate
5380 for the increasing samba install base:
5382 as a member of the workgroup, that will possibly become a
5383 _local_ master browser (lm = True). this is opposed to a forced
5384 local master browser startup (pm = True).
5386 doesn't provide WINS server service by default (wsupp = False),
5387 and doesn't provide domain master browser services by default, either.
5391 Globals.bMsAddPrinterWizard = True;
5392 Globals.os_level = 20;
5393 Globals.bLocalMaster = True;
5394 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5395 Globals.bDomainLogons = False;
5396 Globals.bBrowseList = True;
5397 Globals.bWINSsupport = False;
5398 Globals.bWINSproxy = False;
5400 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5401 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5403 Globals.bDNSproxy = True;
5405 /* this just means to use them if they exist */
5406 Globals.bKernelOplocks = True;
5408 Globals.bAllowTrustedDomains = True;
5409 string_set(&Globals.szIdmapBackend, "tdb");
5410 Globals.bIdmapReadOnly = false;
5412 string_set(&Globals.szTemplateShell, "/bin/false");
5413 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5414 string_set(&Globals.szWinbindSeparator, "\\");
5416 string_set(&Globals.szCupsServer, "");
5417 string_set(&Globals.szIPrintServer, "");
5419 string_set(&Globals.ctdbdSocket, "");
5420 Globals.szClusterAddresses = NULL;
5421 Globals.clustering = False;
5422 Globals.ctdb_timeout = 0;
5423 Globals.ctdb_locktime_warn_threshold = 0;
5425 Globals.winbind_cache_time = 300; /* 5 minutes */
5426 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5427 Globals.winbind_max_clients = 200;
5428 Globals.bWinbindEnumUsers = False;
5429 Globals.bWinbindEnumGroups = False;
5430 Globals.bWinbindUseDefaultDomain = False;
5431 Globals.bWinbindTrustedDomainsOnly = False;
5432 Globals.bWinbindNestedGroups = True;
5433 Globals.winbind_expand_groups = 1;
5434 Globals.szWinbindNssInfo = str_list_make_v3(NULL, "template", NULL);
5435 Globals.bWinbindRefreshTickets = False;
5436 Globals.bWinbindOfflineLogon = False;
5438 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5439 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5441 Globals.bPassdbExpandExplicit = False;
5443 Globals.name_cache_timeout = 660; /* In seconds */
5445 Globals.bUseSpnego = True;
5446 Globals.bClientUseSpnego = True;
5448 Globals.client_signing = Auto;
5449 Globals.server_signing = False;
5451 Globals.bDeferSharingViolations = True;
5452 string_set(&Globals.smb_ports, SMB_PORTS);
5454 Globals.bEnablePrivileges = True;
5455 Globals.bHostMSDfs = True;
5456 Globals.bASUSupport = False;
5458 /* User defined shares. */
5459 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5460 smb_panic("init_globals: ENOMEM");
5462 string_set(&Globals.szUsersharePath, s);
5463 SAFE_FREE(s);
5464 string_set(&Globals.szUsershareTemplateShare, "");
5465 Globals.iUsershareMaxShares = 0;
5466 /* By default disallow sharing of directories not owned by the sharer. */
5467 Globals.bUsershareOwnerOnly = True;
5468 /* By default disallow guest access to usershares. */
5469 Globals.bUsershareAllowGuests = False;
5471 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5473 /* By default no shares out of the registry */
5474 Globals.bRegistryShares = False;
5476 Globals.iminreceivefile = 0;
5478 Globals.bMapUntrustedToDomain = false;
5479 Globals.bMulticastDnsRegister = true;
5481 Globals.ismb2_max_read = DEFAULT_SMB2_MAX_READ;
5482 Globals.ismb2_max_write = DEFAULT_SMB2_MAX_WRITE;
5483 Globals.ismb2_max_trans = DEFAULT_SMB2_MAX_TRANSACT;
5484 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5486 string_set(&Globals.ncalrpc_dir, get_dyn_NCALRPCDIR());
5488 /* Now put back the settings that were set with lp_set_cmdline() */
5489 apply_lp_set_cmdline();
5492 /*******************************************************************
5493 Convenience routine to grab string parameters into temporary memory
5494 and run standard_sub_basic on them. The buffers can be written to by
5495 callers without affecting the source string.
5496 ********************************************************************/
5498 static char *lp_string(const char *s)
5500 char *ret;
5501 TALLOC_CTX *ctx = talloc_tos();
5503 /* The follow debug is useful for tracking down memory problems
5504 especially if you have an inner loop that is calling a lp_*()
5505 function that returns a string. Perhaps this debug should be
5506 present all the time? */
5508 #if 0
5509 DEBUG(10, ("lp_string(%s)\n", s));
5510 #endif
5511 if (!s) {
5512 return NULL;
5515 ret = talloc_sub_basic(ctx,
5516 get_current_username(),
5517 current_user_info.domain,
5519 if (trim_char(ret, '\"', '\"')) {
5520 if (strchr(ret,'\"') != NULL) {
5521 TALLOC_FREE(ret);
5522 ret = talloc_sub_basic(ctx,
5523 get_current_username(),
5524 current_user_info.domain,
5528 return ret;
5532 In this section all the functions that are used to access the
5533 parameters from the rest of the program are defined
5536 #define FN_GLOBAL_STRING(fn_name,ptr) \
5537 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5538 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5539 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5540 #define FN_GLOBAL_LIST(fn_name,ptr) \
5541 const char **fn_name(void) {return(*(const char ***)(ptr));}
5542 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5543 bool fn_name(void) {return(*(bool *)(ptr));}
5544 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5545 char fn_name(void) {return(*(char *)(ptr));}
5546 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5547 int fn_name(void) {return(*(int *)(ptr));}
5549 #define FN_LOCAL_STRING(fn_name,val) \
5550 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5551 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5552 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5553 #define FN_LOCAL_LIST(fn_name,val) \
5554 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5555 #define FN_LOCAL_BOOL(fn_name,val) \
5556 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5557 #define FN_LOCAL_INTEGER(fn_name,val) \
5558 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5560 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5561 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5562 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5563 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5564 #define FN_LOCAL_CHAR(fn_name,val) \
5565 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5567 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5568 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5569 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5570 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5571 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5572 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5573 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5574 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5575 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5576 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5577 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5578 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5579 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5580 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5581 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5582 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5583 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5584 * build process or in smb.conf, we use that value. Otherwise they
5585 * default to the value of lp_lockdir(). */
5586 char *lp_statedir(void) {
5587 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5588 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5589 return(lp_string(*(char **)(&Globals.szStateDir) ?
5590 *(char **)(&Globals.szStateDir) : ""));
5591 else
5592 return(lp_string(*(char **)(&Globals.szLockDir) ?
5593 *(char **)(&Globals.szLockDir) : ""));
5595 char *lp_cachedir(void) {
5596 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5597 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5598 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5599 *(char **)(&Globals.szCacheDir) : ""));
5600 else
5601 return(lp_string(*(char **)(&Globals.szLockDir) ?
5602 *(char **)(&Globals.szLockDir) : ""));
5604 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5605 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5606 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5607 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5608 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5609 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5610 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5611 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5612 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5613 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5614 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5615 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5616 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5617 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5618 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5619 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5620 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5621 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5622 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5623 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5624 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5625 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5626 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5627 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5628 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5629 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5630 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5631 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5632 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5633 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5634 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5635 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5636 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5637 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5638 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5639 * lp_passdb_backend() should be replace by the this macro again after
5640 * some releases.
5641 * */
5642 const char *lp_passdb_backend(void)
5644 char *delim, *quote;
5646 delim = strchr( Globals.szPassdbBackend, ' ');
5647 /* no space at all */
5648 if (delim == NULL) {
5649 goto out;
5652 quote = strchr(Globals.szPassdbBackend, '"');
5653 /* no quote char or non in the first part */
5654 if (quote == NULL || quote > delim) {
5655 *delim = '\0';
5656 goto warn;
5659 quote = strchr(quote+1, '"');
5660 if (quote == NULL) {
5661 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5662 goto out;
5663 } else if (*(quote+1) == '\0') {
5664 /* space, fitting quote char, and one backend only */
5665 goto out;
5666 } else {
5667 /* terminate string after the fitting quote char */
5668 *(quote+1) = '\0';
5671 warn:
5672 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5673 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5674 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5675 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5677 out:
5678 return Globals.szPassdbBackend;
5680 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5681 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5682 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5683 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5684 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5686 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5687 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5688 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5689 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5690 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5691 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5693 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5695 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5696 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5697 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5698 FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
5700 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5702 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5703 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5704 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5705 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5706 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5707 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5708 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5709 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5710 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5711 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5712 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5713 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5714 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5715 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5716 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5717 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5718 static FN_GLOBAL_INTEGER(lp_winbind_max_domain_connections_int,
5719 &Globals.winbindMaxDomainConnections)
5721 int lp_winbind_max_domain_connections(void)
5723 if (lp_winbind_offline_logon() &&
5724 lp_winbind_max_domain_connections_int() > 1) {
5725 DEBUG(1, ("offline logons active, restricting max domain "
5726 "connections to 1\n"));
5727 return 1;
5729 return MAX(1, lp_winbind_max_domain_connections_int());
5732 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5733 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5734 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5735 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5736 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5738 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5739 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5740 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5741 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5742 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5743 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5744 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5745 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5746 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5747 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5748 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5749 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5750 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5751 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5752 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5753 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5754 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5755 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5756 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5757 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5759 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5761 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5762 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5763 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5764 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5765 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5766 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5767 &Globals.bLogWriteableFilesOnExit)
5768 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5769 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5770 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5771 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5772 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5773 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5774 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5775 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5776 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5777 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5778 FN_GLOBAL_BOOL(_lp_readraw, &Globals.bReadRaw)
5779 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5780 FN_GLOBAL_BOOL(_lp_writeraw, &Globals.bWriteRaw)
5781 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5782 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5783 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5784 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5785 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5786 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5787 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5788 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5789 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5790 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5791 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5792 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5793 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5794 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5795 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5796 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5797 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5798 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5799 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5800 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5801 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5802 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5803 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5804 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5805 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5806 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5807 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5808 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5809 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5810 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5811 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5812 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5813 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5814 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5815 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5816 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5817 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5818 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5819 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5820 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5821 FN_GLOBAL_BOOL(lp_client_use_spnego_principal, &Globals.client_use_spnego_principal)
5822 FN_GLOBAL_BOOL(lp_send_spnego_principal, &Globals.send_spnego_principal)
5823 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5824 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5825 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5826 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5827 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5828 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5829 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5830 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5831 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5832 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5833 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5834 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5835 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5836 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5837 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5838 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5839 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5840 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5841 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5842 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5843 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5844 static FN_GLOBAL_INTEGER(_lp_maxprotocol, &Globals.maxprotocol)
5845 int lp_maxprotocol(void)
5847 int ret = _lp_maxprotocol();
5848 if ((ret == PROTOCOL_SMB2) && (lp_security() == SEC_SHARE)) {
5849 DEBUG(2,("WARNING!!: \"security = share\" is incompatible "
5850 "with the SMB2 protocol. Resetting to SMB1.\n" ));
5851 lp_do_parameter(-1, "max protocol", "NT1");
5852 return PROTOCOL_NT1;
5854 return ret;
5856 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5857 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5858 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5859 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5860 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5861 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5862 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5863 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5864 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5865 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5866 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5867 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5868 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5869 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5870 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5871 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5872 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5873 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5874 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5875 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5876 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5877 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5878 int lp_smb2_max_credits(void)
5880 if (Globals.ismb2_max_credits == 0) {
5881 Globals.ismb2_max_credits = DEFAULT_SMB2_MAX_CREDITS;
5883 return Globals.ismb2_max_credits;
5885 FN_LOCAL_STRING(lp_preexec, szPreExec)
5886 FN_LOCAL_STRING(lp_postexec, szPostExec)
5887 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5888 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5889 FN_LOCAL_STRING(lp_servicename, szService)
5890 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5891 FN_LOCAL_STRING(lp_pathname, szPath)
5892 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5893 FN_LOCAL_STRING(lp_username, szUsername)
5894 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5895 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5896 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5897 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5898 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5899 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5900 int lp_cups_encrypt(void)
5902 int result = 0;
5903 #ifdef HAVE_HTTPCONNECTENCRYPT
5904 switch (Globals.CupsEncrypt) {
5905 case Auto:
5906 result = HTTP_ENCRYPT_REQUIRED;
5907 break;
5908 case True:
5909 result = HTTP_ENCRYPT_ALWAYS;
5910 break;
5911 case False:
5912 result = HTTP_ENCRYPT_NEVER;
5913 break;
5915 #endif
5916 return result;
5918 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5919 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5920 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5921 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5922 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5923 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5924 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5925 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5926 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5927 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5928 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5929 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5930 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5931 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5932 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5933 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5934 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5935 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5936 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5937 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5938 FN_LOCAL_STRING(lp_comment, comment)
5939 FN_LOCAL_STRING(lp_force_user, force_user)
5940 FN_LOCAL_STRING(lp_force_group, force_group)
5941 FN_LOCAL_LIST(lp_readlist, readlist)
5942 FN_LOCAL_LIST(lp_writelist, writelist)
5943 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5944 FN_LOCAL_STRING(lp_fstype, fstype)
5945 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5946 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5947 static FN_LOCAL_STRING(lp_volume, volume)
5948 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5949 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5950 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5951 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5952 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5953 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5954 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5955 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5956 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5957 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5958 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5959 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5960 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5961 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5962 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5963 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5964 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5965 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5966 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5967 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5968 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5969 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5970 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5971 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5972 FN_LOCAL_BOOL(lp_print_notify_backchannel, bPrintNotifyBackchannel)
5973 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5974 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5975 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5976 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5977 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5978 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5979 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5980 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5981 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5982 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5983 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5984 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5985 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5986 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5987 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5988 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5989 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5990 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5991 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5992 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5993 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5994 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5995 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5996 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5997 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5998 FN_GLOBAL_BOOL(lp_multicast_dns_register, &Globals.bMulticastDnsRegister)
5999 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
6000 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
6001 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
6002 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
6003 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
6004 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
6005 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
6006 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
6007 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
6008 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
6009 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
6010 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
6011 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
6012 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
6013 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
6014 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
6015 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
6016 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
6017 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
6018 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
6019 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
6020 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
6021 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
6022 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
6023 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
6024 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
6025 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
6026 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
6027 FN_LOCAL_INTEGER(lp_printing, iPrinting)
6028 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
6029 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
6030 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
6031 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
6032 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
6033 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
6034 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
6035 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
6036 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
6037 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
6038 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
6039 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
6040 FN_LOCAL_CHAR(lp_magicchar, magic_char)
6041 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
6042 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
6043 FN_GLOBAL_INTEGER(lp_winbind_max_clients, &Globals.winbind_max_clients)
6044 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
6045 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
6046 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
6047 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
6048 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
6049 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
6051 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
6053 /* local prototypes */
6055 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
6056 static const char *get_boolean(bool bool_value);
6057 static int getservicebyname(const char *pszServiceName,
6058 struct service *pserviceDest);
6059 static void copy_service(struct service *pserviceDest,
6060 struct service *pserviceSource,
6061 struct bitmap *pcopymapDest);
6062 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
6063 void *userdata);
6064 static bool do_section(const char *pszSectionName, void *userdata);
6065 static void init_copymap(struct service *pservice);
6066 static bool hash_a_service(const char *name, int number);
6067 static void free_service_byindex(int iService);
6068 static void free_param_opts(struct param_opt_struct **popts);
6069 static void show_parameter(int parmIndex);
6070 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
6073 * This is a helper function for parametrical options support. It returns a
6074 * pointer to parametrical option value if it exists or NULL otherwise. Actual
6075 * parametrical functions are quite simple
6077 static struct param_opt_struct *get_parametrics(int snum, const char *type,
6078 const char *option)
6080 bool global_section = False;
6081 char* param_key;
6082 struct param_opt_struct *data;
6084 if (snum >= iNumServices) return NULL;
6086 if (snum < 0) {
6087 data = Globals.param_opt;
6088 global_section = True;
6089 } else {
6090 data = ServicePtrs[snum]->param_opt;
6093 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
6094 DEBUG(0,("asprintf failed!\n"));
6095 return NULL;
6098 while (data) {
6099 if (strwicmp(data->key, param_key) == 0) {
6100 string_free(&param_key);
6101 return data;
6103 data = data->next;
6106 if (!global_section) {
6107 /* Try to fetch the same option but from globals */
6108 /* but only if we are not already working with Globals */
6109 data = Globals.param_opt;
6110 while (data) {
6111 if (strwicmp(data->key, param_key) == 0) {
6112 string_free(&param_key);
6113 return data;
6115 data = data->next;
6119 string_free(&param_key);
6121 return NULL;
6125 #define MISSING_PARAMETER(name) \
6126 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
6128 /*******************************************************************
6129 convenience routine to return int parameters.
6130 ********************************************************************/
6131 static int lp_int(const char *s)
6134 if (!s || !*s) {
6135 MISSING_PARAMETER(lp_int);
6136 return (-1);
6139 return (int)strtol(s, NULL, 0);
6142 /*******************************************************************
6143 convenience routine to return unsigned long parameters.
6144 ********************************************************************/
6145 static unsigned long lp_ulong(const char *s)
6148 if (!s || !*s) {
6149 MISSING_PARAMETER(lp_ulong);
6150 return (0);
6153 return strtoul(s, NULL, 0);
6156 /*******************************************************************
6157 convenience routine to return boolean parameters.
6158 ********************************************************************/
6159 static bool lp_bool(const char *s)
6161 bool ret = False;
6163 if (!s || !*s) {
6164 MISSING_PARAMETER(lp_bool);
6165 return False;
6168 if (!set_boolean(s, &ret)) {
6169 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
6170 return False;
6173 return ret;
6176 /*******************************************************************
6177 convenience routine to return enum parameters.
6178 ********************************************************************/
6179 static int lp_enum(const char *s,const struct enum_list *_enum)
6181 int i;
6183 if (!s || !*s || !_enum) {
6184 MISSING_PARAMETER(lp_enum);
6185 return (-1);
6188 for (i=0; _enum[i].name; i++) {
6189 if (strequal(_enum[i].name,s))
6190 return _enum[i].value;
6193 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
6194 return (-1);
6197 #undef MISSING_PARAMETER
6199 /* DO NOT USE lp_parm_string ANYMORE!!!!
6200 * use lp_parm_const_string or lp_parm_talloc_string
6202 * lp_parm_string is only used to let old modules find this symbol
6204 #undef lp_parm_string
6205 char *lp_parm_string(const char *servicename, const char *type, const char *option);
6206 char *lp_parm_string(const char *servicename, const char *type, const char *option)
6208 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
6211 /* Return parametric option from a given service. Type is a part of option before ':' */
6212 /* Parametric option has following syntax: 'Type: option = value' */
6213 /* the returned value is talloced on the talloc_tos() */
6214 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
6216 struct param_opt_struct *data = get_parametrics(snum, type, option);
6218 if (data == NULL||data->value==NULL) {
6219 if (def) {
6220 return lp_string(def);
6221 } else {
6222 return NULL;
6226 return lp_string(data->value);
6229 /* Return parametric option from a given service. Type is a part of option before ':' */
6230 /* Parametric option has following syntax: 'Type: option = value' */
6231 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6233 struct param_opt_struct *data = get_parametrics(snum, type, option);
6235 if (data == NULL||data->value==NULL)
6236 return def;
6238 return data->value;
6241 /* Return parametric option from a given service. Type is a part of option before ':' */
6242 /* Parametric option has following syntax: 'Type: option = value' */
6244 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6246 struct param_opt_struct *data = get_parametrics(snum, type, option);
6248 if (data == NULL||data->value==NULL)
6249 return (const char **)def;
6251 if (data->list==NULL) {
6252 data->list = str_list_make_v3(NULL, data->value, NULL);
6255 return (const char **)data->list;
6258 /* Return parametric option from a given service. Type is a part of option before ':' */
6259 /* Parametric option has following syntax: 'Type: option = value' */
6261 int lp_parm_int(int snum, const char *type, const char *option, int def)
6263 struct param_opt_struct *data = get_parametrics(snum, type, option);
6265 if (data && data->value && *data->value)
6266 return lp_int(data->value);
6268 return def;
6271 /* Return parametric option from a given service. Type is a part of option before ':' */
6272 /* Parametric option has following syntax: 'Type: option = value' */
6274 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6276 struct param_opt_struct *data = get_parametrics(snum, type, option);
6278 if (data && data->value && *data->value)
6279 return lp_ulong(data->value);
6281 return def;
6284 /* Return parametric option from a given service. Type is a part of option before ':' */
6285 /* Parametric option has following syntax: 'Type: option = value' */
6287 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6289 struct param_opt_struct *data = get_parametrics(snum, type, option);
6291 if (data && data->value && *data->value)
6292 return lp_bool(data->value);
6294 return def;
6297 /* Return parametric option from a given service. Type is a part of option before ':' */
6298 /* Parametric option has following syntax: 'Type: option = value' */
6300 int lp_parm_enum(int snum, const char *type, const char *option,
6301 const struct enum_list *_enum, int def)
6303 struct param_opt_struct *data = get_parametrics(snum, type, option);
6305 if (data && data->value && *data->value && _enum)
6306 return lp_enum(data->value, _enum);
6308 return def;
6312 /***************************************************************************
6313 Initialise a service to the defaults.
6314 ***************************************************************************/
6316 static void init_service(struct service *pservice)
6318 memset((char *)pservice, '\0', sizeof(struct service));
6319 copy_service(pservice, &sDefault, NULL);
6324 * free a param_opts structure.
6325 * param_opts handling should be moved to talloc;
6326 * then this whole functions reduces to a TALLOC_FREE().
6329 static void free_param_opts(struct param_opt_struct **popts)
6331 struct param_opt_struct *opt, *next_opt;
6333 if (popts == NULL) {
6334 return;
6337 if (*popts != NULL) {
6338 DEBUG(5, ("Freeing parametrics:\n"));
6340 opt = *popts;
6341 while (opt != NULL) {
6342 string_free(&opt->key);
6343 string_free(&opt->value);
6344 TALLOC_FREE(opt->list);
6345 next_opt = opt->next;
6346 SAFE_FREE(opt);
6347 opt = next_opt;
6349 *popts = NULL;
6352 /***************************************************************************
6353 Free the dynamically allocated parts of a service struct.
6354 ***************************************************************************/
6356 static void free_service(struct service *pservice)
6358 if (!pservice)
6359 return;
6361 if (pservice->szService)
6362 DEBUG(5, ("free_service: Freeing service %s\n",
6363 pservice->szService));
6365 free_parameters(pservice);
6367 string_free(&pservice->szService);
6368 TALLOC_FREE(pservice->copymap);
6370 free_param_opts(&pservice->param_opt);
6372 ZERO_STRUCTP(pservice);
6376 /***************************************************************************
6377 remove a service indexed in the ServicePtrs array from the ServiceHash
6378 and free the dynamically allocated parts
6379 ***************************************************************************/
6381 static void free_service_byindex(int idx)
6383 if ( !LP_SNUM_OK(idx) )
6384 return;
6386 ServicePtrs[idx]->valid = False;
6387 invalid_services[num_invalid_services++] = idx;
6389 /* we have to cleanup the hash record */
6391 if (ServicePtrs[idx]->szService) {
6392 char *canon_name = canonicalize_servicename(
6393 talloc_tos(),
6394 ServicePtrs[idx]->szService );
6396 dbwrap_delete_bystring(ServiceHash, canon_name );
6397 TALLOC_FREE(canon_name);
6400 free_service(ServicePtrs[idx]);
6403 /***************************************************************************
6404 Add a new service to the services array initialising it with the given
6405 service.
6406 ***************************************************************************/
6408 static int add_a_service(const struct service *pservice, const char *name)
6410 int i;
6411 struct service tservice;
6412 int num_to_alloc = iNumServices + 1;
6414 tservice = *pservice;
6416 /* it might already exist */
6417 if (name) {
6418 i = getservicebyname(name, NULL);
6419 if (i >= 0) {
6420 return (i);
6424 /* find an invalid one */
6425 i = iNumServices;
6426 if (num_invalid_services > 0) {
6427 i = invalid_services[--num_invalid_services];
6430 /* if not, then create one */
6431 if (i == iNumServices) {
6432 struct service **tsp;
6433 int *tinvalid;
6435 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6436 if (tsp == NULL) {
6437 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6438 return (-1);
6440 ServicePtrs = tsp;
6441 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6442 if (!ServicePtrs[iNumServices]) {
6443 DEBUG(0,("add_a_service: out of memory!\n"));
6444 return (-1);
6446 iNumServices++;
6448 /* enlarge invalid_services here for now... */
6449 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6450 num_to_alloc);
6451 if (tinvalid == NULL) {
6452 DEBUG(0,("add_a_service: failed to enlarge "
6453 "invalid_services!\n"));
6454 return (-1);
6456 invalid_services = tinvalid;
6457 } else {
6458 free_service_byindex(i);
6461 ServicePtrs[i]->valid = True;
6463 init_service(ServicePtrs[i]);
6464 copy_service(ServicePtrs[i], &tservice, NULL);
6465 if (name)
6466 string_set(&ServicePtrs[i]->szService, name);
6468 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6469 i, ServicePtrs[i]->szService));
6471 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6472 return (-1);
6475 return (i);
6478 /***************************************************************************
6479 Convert a string to uppercase and remove whitespaces.
6480 ***************************************************************************/
6482 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6484 char *result;
6486 if ( !src ) {
6487 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6488 return NULL;
6491 result = talloc_strdup(ctx, src);
6492 SMB_ASSERT(result != NULL);
6494 strlower_m(result);
6495 return result;
6498 /***************************************************************************
6499 Add a name/index pair for the services array to the hash table.
6500 ***************************************************************************/
6502 static bool hash_a_service(const char *name, int idx)
6504 char *canon_name;
6506 if ( !ServiceHash ) {
6507 DEBUG(10,("hash_a_service: creating servicehash\n"));
6508 ServiceHash = db_open_rbt(NULL);
6509 if ( !ServiceHash ) {
6510 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6511 return False;
6515 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6516 idx, name));
6518 canon_name = canonicalize_servicename(talloc_tos(), name );
6520 dbwrap_store_bystring(ServiceHash, canon_name,
6521 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6522 TDB_REPLACE);
6524 TALLOC_FREE(canon_name);
6526 return True;
6529 /***************************************************************************
6530 Add a new home service, with the specified home directory, defaults coming
6531 from service ifrom.
6532 ***************************************************************************/
6534 bool lp_add_home(const char *pszHomename, int iDefaultService,
6535 const char *user, const char *pszHomedir)
6537 int i;
6539 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6540 pszHomedir[0] == '\0') {
6541 return false;
6544 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6546 if (i < 0)
6547 return (False);
6549 if (!(*(ServicePtrs[iDefaultService]->szPath))
6550 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6551 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6554 if (!(*(ServicePtrs[i]->comment))) {
6555 char *comment = NULL;
6556 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6557 return false;
6559 string_set(&ServicePtrs[i]->comment, comment);
6560 SAFE_FREE(comment);
6563 /* set the browseable flag from the global default */
6565 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6566 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6568 ServicePtrs[i]->autoloaded = True;
6570 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6571 user, ServicePtrs[i]->szPath ));
6573 return (True);
6576 /***************************************************************************
6577 Add a new service, based on an old one.
6578 ***************************************************************************/
6580 int lp_add_service(const char *pszService, int iDefaultService)
6582 if (iDefaultService < 0) {
6583 return add_a_service(&sDefault, pszService);
6586 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6589 /***************************************************************************
6590 Add the IPC service.
6591 ***************************************************************************/
6593 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6595 char *comment = NULL;
6596 int i = add_a_service(&sDefault, ipc_name);
6598 if (i < 0)
6599 return (False);
6601 if (asprintf(&comment, "IPC Service (%s)",
6602 Globals.szServerString) < 0) {
6603 return (False);
6606 string_set(&ServicePtrs[i]->szPath, tmpdir());
6607 string_set(&ServicePtrs[i]->szUsername, "");
6608 string_set(&ServicePtrs[i]->comment, comment);
6609 string_set(&ServicePtrs[i]->fstype, "IPC");
6610 ServicePtrs[i]->iMaxConnections = 0;
6611 ServicePtrs[i]->bAvailable = True;
6612 ServicePtrs[i]->bRead_only = True;
6613 ServicePtrs[i]->bGuest_only = False;
6614 ServicePtrs[i]->bAdministrative_share = True;
6615 ServicePtrs[i]->bGuest_ok = guest_ok;
6616 ServicePtrs[i]->bPrint_ok = False;
6617 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6619 DEBUG(3, ("adding IPC service\n"));
6621 SAFE_FREE(comment);
6622 return (True);
6625 /***************************************************************************
6626 Add a new printer service, with defaults coming from service iFrom.
6627 ***************************************************************************/
6629 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6631 const char *comment = "From Printcap";
6632 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6634 if (i < 0)
6635 return (False);
6637 /* note that we do NOT default the availability flag to True - */
6638 /* we take it from the default service passed. This allows all */
6639 /* dynamic printers to be disabled by disabling the [printers] */
6640 /* entry (if/when the 'available' keyword is implemented!). */
6642 /* the printer name is set to the service name. */
6643 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6644 string_set(&ServicePtrs[i]->comment, comment);
6646 /* set the browseable flag from the gloabl default */
6647 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6649 /* Printers cannot be read_only. */
6650 ServicePtrs[i]->bRead_only = False;
6651 /* No share modes on printer services. */
6652 ServicePtrs[i]->bShareModes = False;
6653 /* No oplocks on printer services. */
6654 ServicePtrs[i]->bOpLocks = False;
6655 /* Printer services must be printable. */
6656 ServicePtrs[i]->bPrint_ok = True;
6658 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6660 return (True);
6664 /***************************************************************************
6665 Check whether the given parameter name is valid.
6666 Parametric options (names containing a colon) are considered valid.
6667 ***************************************************************************/
6669 bool lp_parameter_is_valid(const char *pszParmName)
6671 return ((map_parameter(pszParmName) != -1) ||
6672 (strchr(pszParmName, ':') != NULL));
6675 /***************************************************************************
6676 Check whether the given name is the name of a global parameter.
6677 Returns True for strings belonging to parameters of class
6678 P_GLOBAL, False for all other strings, also for parametric options
6679 and strings not belonging to any option.
6680 ***************************************************************************/
6682 bool lp_parameter_is_global(const char *pszParmName)
6684 int num = map_parameter(pszParmName);
6686 if (num >= 0) {
6687 return (parm_table[num].p_class == P_GLOBAL);
6690 return False;
6693 /**************************************************************************
6694 Check whether the given name is the canonical name of a parameter.
6695 Returns False if it is not a valid parameter Name.
6696 For parametric options, True is returned.
6697 **************************************************************************/
6699 bool lp_parameter_is_canonical(const char *parm_name)
6701 if (!lp_parameter_is_valid(parm_name)) {
6702 return False;
6705 return (map_parameter(parm_name) ==
6706 map_parameter_canonical(parm_name, NULL));
6709 /**************************************************************************
6710 Determine the canonical name for a parameter.
6711 Indicate when it is an inverse (boolean) synonym instead of a
6712 "usual" synonym.
6713 **************************************************************************/
6715 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6716 bool *inverse)
6718 int num;
6720 if (!lp_parameter_is_valid(parm_name)) {
6721 *canon_parm = NULL;
6722 return False;
6725 num = map_parameter_canonical(parm_name, inverse);
6726 if (num < 0) {
6727 /* parametric option */
6728 *canon_parm = parm_name;
6729 } else {
6730 *canon_parm = parm_table[num].label;
6733 return True;
6737 /**************************************************************************
6738 Determine the canonical name for a parameter.
6739 Turn the value given into the inverse boolean expression when
6740 the synonym is an invers boolean synonym.
6742 Return True if parm_name is a valid parameter name and
6743 in case it is an invers boolean synonym, if the val string could
6744 successfully be converted to the reverse bool.
6745 Return false in all other cases.
6746 **************************************************************************/
6748 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6749 const char *val,
6750 const char **canon_parm,
6751 const char **canon_val)
6753 int num;
6754 bool inverse;
6756 if (!lp_parameter_is_valid(parm_name)) {
6757 *canon_parm = NULL;
6758 *canon_val = NULL;
6759 return False;
6762 num = map_parameter_canonical(parm_name, &inverse);
6763 if (num < 0) {
6764 /* parametric option */
6765 *canon_parm = parm_name;
6766 *canon_val = val;
6767 } else {
6768 *canon_parm = parm_table[num].label;
6769 if (inverse) {
6770 if (!lp_invert_boolean(val, canon_val)) {
6771 *canon_val = NULL;
6772 return False;
6774 } else {
6775 *canon_val = val;
6779 return True;
6782 /***************************************************************************
6783 Map a parameter's string representation to something we can use.
6784 Returns False if the parameter string is not recognised, else TRUE.
6785 ***************************************************************************/
6787 static int map_parameter(const char *pszParmName)
6789 int iIndex;
6791 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6792 return (-1);
6794 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6795 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6796 return (iIndex);
6798 /* Warn only if it isn't parametric option */
6799 if (strchr(pszParmName, ':') == NULL)
6800 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6801 /* We do return 'fail' for parametric options as well because they are
6802 stored in different storage
6804 return (-1);
6807 /***************************************************************************
6808 Map a parameter's string representation to the index of the canonical
6809 form of the parameter (it might be a synonym).
6810 Returns -1 if the parameter string is not recognised.
6811 ***************************************************************************/
6813 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6815 int parm_num, canon_num;
6816 bool loc_inverse = False;
6818 parm_num = map_parameter(pszParmName);
6819 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6820 /* invalid, parametric or no canidate for synonyms ... */
6821 goto done;
6824 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6825 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6826 parm_num = canon_num;
6827 goto done;
6831 done:
6832 if (inverse != NULL) {
6833 *inverse = loc_inverse;
6835 return parm_num;
6838 /***************************************************************************
6839 return true if parameter number parm1 is a synonym of parameter
6840 number parm2 (parm2 being the principal name).
6841 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6842 False otherwise.
6843 ***************************************************************************/
6845 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6847 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6848 (parm_table[parm1].flags & FLAG_HIDE) &&
6849 !(parm_table[parm2].flags & FLAG_HIDE))
6851 if (inverse != NULL) {
6852 if ((parm_table[parm1].type == P_BOOLREV) &&
6853 (parm_table[parm2].type == P_BOOL))
6855 *inverse = True;
6856 } else {
6857 *inverse = False;
6860 return True;
6862 return False;
6865 /***************************************************************************
6866 Show one parameter's name, type, [values,] and flags.
6867 (helper functions for show_parameter_list)
6868 ***************************************************************************/
6870 static void show_parameter(int parmIndex)
6872 int enumIndex, flagIndex;
6873 int parmIndex2;
6874 bool hadFlag;
6875 bool hadSyn;
6876 bool inverse;
6877 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6878 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6879 "P_ENUM", "P_SEP"};
6880 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6881 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6882 FLAG_HIDE, FLAG_DOS_STRING};
6883 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6884 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6885 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6887 printf("%s=%s", parm_table[parmIndex].label,
6888 type[parm_table[parmIndex].type]);
6889 if (parm_table[parmIndex].type == P_ENUM) {
6890 printf(",");
6891 for (enumIndex=0;
6892 parm_table[parmIndex].enum_list[enumIndex].name;
6893 enumIndex++)
6895 printf("%s%s",
6896 enumIndex ? "|" : "",
6897 parm_table[parmIndex].enum_list[enumIndex].name);
6900 printf(",");
6901 hadFlag = False;
6902 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6903 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6904 printf("%s%s",
6905 hadFlag ? "|" : "",
6906 flag_names[flagIndex]);
6907 hadFlag = True;
6911 /* output synonyms */
6912 hadSyn = False;
6913 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6914 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6915 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6916 parm_table[parmIndex2].label);
6917 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6918 if (!hadSyn) {
6919 printf(" (synonyms: ");
6920 hadSyn = True;
6921 } else {
6922 printf(", ");
6924 printf("%s%s", parm_table[parmIndex2].label,
6925 inverse ? "[i]" : "");
6928 if (hadSyn) {
6929 printf(")");
6932 printf("\n");
6935 /***************************************************************************
6936 Show all parameter's name, type, [values,] and flags.
6937 ***************************************************************************/
6939 void show_parameter_list(void)
6941 int classIndex, parmIndex;
6942 const char *section_names[] = { "local", "global", NULL};
6944 for (classIndex=0; section_names[classIndex]; classIndex++) {
6945 printf("[%s]\n", section_names[classIndex]);
6946 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6947 if (parm_table[parmIndex].p_class == classIndex) {
6948 show_parameter(parmIndex);
6954 /***************************************************************************
6955 Check if a given string correctly represents a boolean value.
6956 ***************************************************************************/
6958 bool lp_string_is_valid_boolean(const char *parm_value)
6960 return set_boolean(parm_value, NULL);
6963 /***************************************************************************
6964 Get the standard string representation of a boolean value ("yes" or "no")
6965 ***************************************************************************/
6967 static const char *get_boolean(bool bool_value)
6969 static const char *yes_str = "yes";
6970 static const char *no_str = "no";
6972 return (bool_value ? yes_str : no_str);
6975 /***************************************************************************
6976 Provide the string of the negated boolean value associated to the boolean
6977 given as a string. Returns False if the passed string does not correctly
6978 represent a boolean.
6979 ***************************************************************************/
6981 bool lp_invert_boolean(const char *str, const char **inverse_str)
6983 bool val;
6985 if (!set_boolean(str, &val)) {
6986 return False;
6989 *inverse_str = get_boolean(!val);
6990 return True;
6993 /***************************************************************************
6994 Provide the canonical string representation of a boolean value given
6995 as a string. Return True on success, False if the string given does
6996 not correctly represent a boolean.
6997 ***************************************************************************/
6999 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
7001 bool val;
7003 if (!set_boolean(str, &val)) {
7004 return False;
7007 *canon_str = get_boolean(val);
7008 return True;
7011 /***************************************************************************
7012 Find a service by name. Otherwise works like get_service.
7013 ***************************************************************************/
7015 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
7017 int iService = -1;
7018 char *canon_name;
7019 TDB_DATA data;
7021 if (ServiceHash == NULL) {
7022 return -1;
7025 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
7027 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
7029 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
7030 iService = *(int *)data.dptr;
7033 TALLOC_FREE(canon_name);
7035 if ((iService != -1) && (LP_SNUM_OK(iService))
7036 && (pserviceDest != NULL)) {
7037 copy_service(pserviceDest, ServicePtrs[iService], NULL);
7040 return (iService);
7043 /***************************************************************************
7044 Copy a service structure to another.
7045 If pcopymapDest is NULL then copy all fields
7046 ***************************************************************************/
7049 * Add a parametric option to a param_opt_struct,
7050 * replacing old value, if already present.
7052 static void set_param_opt(struct param_opt_struct **opt_list,
7053 const char *opt_name,
7054 const char *opt_value,
7055 unsigned flags)
7057 struct param_opt_struct *new_opt, *opt;
7058 bool not_added;
7060 if (opt_list == NULL) {
7061 return;
7064 opt = *opt_list;
7065 not_added = true;
7067 /* Traverse destination */
7068 while (opt) {
7069 /* If we already have same option, override it */
7070 if (strwicmp(opt->key, opt_name) == 0) {
7071 if ((opt->flags & FLAG_CMDLINE) &&
7072 !(flags & FLAG_CMDLINE)) {
7073 /* it's been marked as not to be
7074 overridden */
7075 return;
7077 string_free(&opt->value);
7078 TALLOC_FREE(opt->list);
7079 opt->value = SMB_STRDUP(opt_value);
7080 opt->flags = flags;
7081 not_added = false;
7082 break;
7084 opt = opt->next;
7086 if (not_added) {
7087 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
7088 new_opt->key = SMB_STRDUP(opt_name);
7089 new_opt->value = SMB_STRDUP(opt_value);
7090 new_opt->list = NULL;
7091 new_opt->flags = flags;
7092 DLIST_ADD(*opt_list, new_opt);
7096 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
7097 struct bitmap *pcopymapDest)
7099 int i;
7100 bool bcopyall = (pcopymapDest == NULL);
7101 struct param_opt_struct *data;
7103 for (i = 0; parm_table[i].label; i++)
7104 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
7105 (bcopyall || bitmap_query(pcopymapDest,i))) {
7106 void *def_ptr = parm_table[i].ptr;
7107 void *src_ptr =
7108 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
7109 &sDefault);
7110 void *dest_ptr =
7111 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
7112 &sDefault);
7114 switch (parm_table[i].type) {
7115 case P_BOOL:
7116 case P_BOOLREV:
7117 *(bool *)dest_ptr = *(bool *)src_ptr;
7118 break;
7120 case P_INTEGER:
7121 case P_ENUM:
7122 case P_OCTAL:
7123 *(int *)dest_ptr = *(int *)src_ptr;
7124 break;
7126 case P_CHAR:
7127 *(char *)dest_ptr = *(char *)src_ptr;
7128 break;
7130 case P_STRING:
7131 string_set((char **)dest_ptr,
7132 *(char **)src_ptr);
7133 break;
7135 case P_USTRING:
7136 string_set((char **)dest_ptr,
7137 *(char **)src_ptr);
7138 strupper_m(*(char **)dest_ptr);
7139 break;
7140 case P_LIST:
7141 TALLOC_FREE(*((char ***)dest_ptr));
7142 *((char ***)dest_ptr) = str_list_copy(NULL,
7143 *(const char ***)src_ptr);
7144 break;
7145 default:
7146 break;
7150 if (bcopyall) {
7151 init_copymap(pserviceDest);
7152 if (pserviceSource->copymap)
7153 bitmap_copy(pserviceDest->copymap,
7154 pserviceSource->copymap);
7157 data = pserviceSource->param_opt;
7158 while (data) {
7159 set_param_opt(&pserviceDest->param_opt, data->key, data->value, data->flags);
7160 data = data->next;
7164 /***************************************************************************
7165 Check a service for consistency. Return False if the service is in any way
7166 incomplete or faulty, else True.
7167 ***************************************************************************/
7169 bool service_ok(int iService)
7171 bool bRetval;
7173 bRetval = True;
7174 if (ServicePtrs[iService]->szService[0] == '\0') {
7175 DEBUG(0, ("The following message indicates an internal error:\n"));
7176 DEBUG(0, ("No service name in service entry.\n"));
7177 bRetval = False;
7180 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
7181 /* I can't see why you'd want a non-printable printer service... */
7182 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
7183 if (!ServicePtrs[iService]->bPrint_ok) {
7184 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
7185 ServicePtrs[iService]->szService));
7186 ServicePtrs[iService]->bPrint_ok = True;
7188 /* [printers] service must also be non-browsable. */
7189 if (ServicePtrs[iService]->bBrowseable)
7190 ServicePtrs[iService]->bBrowseable = False;
7193 if (ServicePtrs[iService]->szPath[0] == '\0' &&
7194 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
7195 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
7197 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
7198 ServicePtrs[iService]->szService));
7199 ServicePtrs[iService]->bAvailable = False;
7202 /* If a service is flagged unavailable, log the fact at level 1. */
7203 if (!ServicePtrs[iService]->bAvailable)
7204 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
7205 ServicePtrs[iService]->szService));
7207 return (bRetval);
7210 static struct smbconf_ctx *lp_smbconf_ctx(void)
7212 sbcErr err;
7213 static struct smbconf_ctx *conf_ctx = NULL;
7215 if (conf_ctx == NULL) {
7216 err = smbconf_init(NULL, &conf_ctx, "registry:");
7217 if (!SBC_ERROR_IS_OK(err)) {
7218 DEBUG(1, ("error initializing registry configuration: "
7219 "%s\n", sbcErrorString(err)));
7220 conf_ctx = NULL;
7224 return conf_ctx;
7227 static bool process_smbconf_service(struct smbconf_service *service)
7229 uint32_t count;
7230 bool ret;
7232 if (service == NULL) {
7233 return false;
7236 ret = do_section(service->name, NULL);
7237 if (ret != true) {
7238 return false;
7240 for (count = 0; count < service->num_params; count++) {
7241 ret = do_parameter(service->param_names[count],
7242 service->param_values[count],
7243 NULL);
7244 if (ret != true) {
7245 return false;
7248 if (iServiceIndex >= 0) {
7249 return service_ok(iServiceIndex);
7251 return true;
7255 * load a service from registry and activate it
7257 bool process_registry_service(const char *service_name)
7259 sbcErr err;
7260 struct smbconf_service *service = NULL;
7261 TALLOC_CTX *mem_ctx = talloc_stackframe();
7262 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7263 bool ret = false;
7265 if (conf_ctx == NULL) {
7266 goto done;
7269 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7271 if (!smbconf_share_exists(conf_ctx, service_name)) {
7273 * Registry does not contain data for this service (yet),
7274 * but make sure lp_load doesn't return false.
7276 ret = true;
7277 goto done;
7280 err = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7281 if (!SBC_ERROR_IS_OK(err)) {
7282 goto done;
7285 ret = process_smbconf_service(service);
7286 if (!ret) {
7287 goto done;
7290 /* store the csn */
7291 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7293 done:
7294 TALLOC_FREE(mem_ctx);
7295 return ret;
7299 * process_registry_globals
7301 static bool process_registry_globals(void)
7303 bool ret;
7305 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7307 ret = do_parameter("registry shares", "yes", NULL);
7308 if (!ret) {
7309 return ret;
7312 return process_registry_service(GLOBAL_NAME);
7315 bool process_registry_shares(void)
7317 sbcErr err;
7318 uint32_t count;
7319 struct smbconf_service **service = NULL;
7320 uint32_t num_shares = 0;
7321 TALLOC_CTX *mem_ctx = talloc_stackframe();
7322 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7323 bool ret = false;
7325 if (conf_ctx == NULL) {
7326 goto done;
7329 err = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7330 if (!SBC_ERROR_IS_OK(err)) {
7331 goto done;
7334 ret = true;
7336 for (count = 0; count < num_shares; count++) {
7337 if (strequal(service[count]->name, GLOBAL_NAME)) {
7338 continue;
7340 ret = process_smbconf_service(service[count]);
7341 if (!ret) {
7342 goto done;
7346 /* store the csn */
7347 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7349 done:
7350 TALLOC_FREE(mem_ctx);
7351 return ret;
7355 * reload those shares from registry that are already
7356 * activated in the services array.
7358 static bool reload_registry_shares(void)
7360 int i;
7361 bool ret = true;
7363 for (i = 0; i < iNumServices; i++) {
7364 if (!VALID(i)) {
7365 continue;
7368 if (ServicePtrs[i]->usershare == USERSHARE_VALID) {
7369 continue;
7372 ret = process_registry_service(ServicePtrs[i]->szService);
7373 if (!ret) {
7374 goto done;
7378 done:
7379 return ret;
7383 #define MAX_INCLUDE_DEPTH 100
7385 static uint8_t include_depth;
7387 static struct file_lists {
7388 struct file_lists *next;
7389 char *name;
7390 char *subfname;
7391 time_t modtime;
7392 } *file_lists = NULL;
7394 /*******************************************************************
7395 Keep a linked list of all config files so we know when one has changed
7396 it's date and needs to be reloaded.
7397 ********************************************************************/
7399 static void add_to_file_list(const char *fname, const char *subfname)
7401 struct file_lists *f = file_lists;
7403 while (f) {
7404 if (f->name && !strcmp(f->name, fname))
7405 break;
7406 f = f->next;
7409 if (!f) {
7410 f = SMB_MALLOC_P(struct file_lists);
7411 if (!f)
7412 return;
7413 f->next = file_lists;
7414 f->name = SMB_STRDUP(fname);
7415 if (!f->name) {
7416 SAFE_FREE(f);
7417 return;
7419 f->subfname = SMB_STRDUP(subfname);
7420 if (!f->subfname) {
7421 SAFE_FREE(f->name);
7422 SAFE_FREE(f);
7423 return;
7425 file_lists = f;
7426 f->modtime = file_modtime(subfname);
7427 } else {
7428 time_t t = file_modtime(subfname);
7429 if (t)
7430 f->modtime = t;
7432 return;
7436 * Free the file lists
7438 static void free_file_list(void)
7440 struct file_lists *f;
7441 struct file_lists *next;
7443 f = file_lists;
7444 while( f ) {
7445 next = f->next;
7446 SAFE_FREE( f->name );
7447 SAFE_FREE( f->subfname );
7448 SAFE_FREE( f );
7449 f = next;
7451 file_lists = NULL;
7456 * Utility function for outsiders to check if we're running on registry.
7458 bool lp_config_backend_is_registry(void)
7460 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7464 * Utility function to check if the config backend is FILE.
7466 bool lp_config_backend_is_file(void)
7468 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7471 /*******************************************************************
7472 Check if a config file has changed date.
7473 ********************************************************************/
7475 bool lp_file_list_changed(void)
7477 struct file_lists *f = file_lists;
7479 DEBUG(6, ("lp_file_list_changed()\n"));
7481 while (f) {
7482 time_t mod_time;
7484 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7485 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7487 if (conf_ctx == NULL) {
7488 return false;
7490 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7491 NULL))
7493 DEBUGADD(6, ("registry config changed\n"));
7494 return true;
7496 } else {
7497 char *n2 = NULL;
7498 n2 = talloc_sub_basic(talloc_tos(),
7499 get_current_username(),
7500 current_user_info.domain,
7501 f->name);
7502 if (!n2) {
7503 return false;
7505 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7506 f->name, n2, ctime(&f->modtime)));
7508 mod_time = file_modtime(n2);
7510 if (mod_time &&
7511 ((f->modtime != mod_time) ||
7512 (f->subfname == NULL) ||
7513 (strcmp(n2, f->subfname) != 0)))
7515 DEBUGADD(6,
7516 ("file %s modified: %s\n", n2,
7517 ctime(&mod_time)));
7518 f->modtime = mod_time;
7519 SAFE_FREE(f->subfname);
7520 f->subfname = SMB_STRDUP(n2);
7521 TALLOC_FREE(n2);
7522 return true;
7524 TALLOC_FREE(n2);
7526 f = f->next;
7528 return (False);
7532 /***************************************************************************
7533 Run standard_sub_basic on netbios name... needed because global_myname
7534 is not accessed through any lp_ macro.
7535 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7536 ***************************************************************************/
7538 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7540 bool ret;
7541 char *netbios_name = talloc_sub_basic(
7542 talloc_tos(), get_current_username(), current_user_info.domain,
7543 pszParmValue);
7545 ret = set_global_myname(netbios_name);
7546 TALLOC_FREE(netbios_name);
7547 string_set(&Globals.szNetbiosName,global_myname());
7549 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7550 global_myname()));
7552 return ret;
7555 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7557 if (strcmp(*ptr, pszParmValue) != 0) {
7558 string_set(ptr, pszParmValue);
7559 init_iconv();
7561 return True;
7564 static bool handle_dos_charset(int snum, const char *pszParmValue, char **ptr)
7566 bool is_utf8 = false;
7567 size_t len = strlen(pszParmValue);
7569 if (len == 4 || len == 5) {
7570 /* Don't use StrCaseCmp here as we don't want to
7571 initialize iconv. */
7572 if ((toupper_m(pszParmValue[0]) == 'U') &&
7573 (toupper_m(pszParmValue[1]) == 'T') &&
7574 (toupper_m(pszParmValue[2]) == 'F')) {
7575 if (len == 4) {
7576 if (pszParmValue[3] == '8') {
7577 is_utf8 = true;
7579 } else {
7580 if (pszParmValue[3] == '-' &&
7581 pszParmValue[4] == '8') {
7582 is_utf8 = true;
7588 if (strcmp(*ptr, pszParmValue) != 0) {
7589 if (is_utf8) {
7590 DEBUG(0,("ERROR: invalid DOS charset: 'dos charset' must not "
7591 "be UTF8, using (default value) %s instead.\n",
7592 DEFAULT_DOS_CHARSET));
7593 pszParmValue = DEFAULT_DOS_CHARSET;
7595 string_set(ptr, pszParmValue);
7596 init_iconv();
7598 return True;
7603 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7605 bool ret;
7607 ret = set_global_myworkgroup(pszParmValue);
7608 string_set(&Globals.szWorkgroup,lp_workgroup());
7610 return ret;
7613 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7615 bool ret;
7617 ret = set_global_scope(pszParmValue);
7618 string_set(&Globals.szNetbiosScope,global_scope());
7620 return ret;
7623 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7625 TALLOC_FREE(Globals.szNetbiosAliases);
7626 Globals.szNetbiosAliases = str_list_make_v3(NULL, pszParmValue, NULL);
7627 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7630 /***************************************************************************
7631 Handle the include operation.
7632 ***************************************************************************/
7633 static bool bAllowIncludeRegistry = true;
7635 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7637 char *fname;
7639 if (include_depth >= MAX_INCLUDE_DEPTH) {
7640 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7641 include_depth));
7642 return false;
7645 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7646 if (!bAllowIncludeRegistry) {
7647 return true;
7649 if (bInGlobalSection) {
7650 bool ret;
7651 include_depth++;
7652 ret = process_registry_globals();
7653 include_depth--;
7654 return ret;
7655 } else {
7656 DEBUG(1, ("\"include = registry\" only effective "
7657 "in %s section\n", GLOBAL_NAME));
7658 return false;
7662 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7663 current_user_info.domain,
7664 pszParmValue);
7666 add_to_file_list(pszParmValue, fname);
7668 string_set(ptr, fname);
7670 if (file_exist(fname)) {
7671 bool ret;
7672 include_depth++;
7673 ret = pm_process(fname, do_section, do_parameter, NULL);
7674 include_depth--;
7675 TALLOC_FREE(fname);
7676 return ret;
7679 DEBUG(2, ("Can't find include file %s\n", fname));
7680 TALLOC_FREE(fname);
7681 return true;
7684 /***************************************************************************
7685 Handle the interpretation of the copy parameter.
7686 ***************************************************************************/
7688 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7690 bool bRetval;
7691 int iTemp;
7692 struct service serviceTemp;
7694 string_set(ptr, pszParmValue);
7696 init_service(&serviceTemp);
7698 bRetval = False;
7700 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7702 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7703 if (iTemp == iServiceIndex) {
7704 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7705 } else {
7706 copy_service(ServicePtrs[iServiceIndex],
7707 &serviceTemp,
7708 ServicePtrs[iServiceIndex]->copymap);
7709 bRetval = True;
7711 } else {
7712 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7713 bRetval = False;
7716 free_service(&serviceTemp);
7717 return (bRetval);
7720 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7722 Globals.ldap_debug_level = lp_int(pszParmValue);
7723 init_ldap_debugging();
7724 return true;
7727 /***************************************************************************
7728 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7729 parameters is:
7731 [global]
7733 idmap uid = 1000-1999
7734 idmap gid = 700-899
7736 We only do simple parsing checks here. The strings are parsed into useful
7737 structures in the idmap daemon code.
7739 ***************************************************************************/
7741 /* Some lp_ routines to return idmap [ug]id information */
7743 static uid_t idmap_uid_low, idmap_uid_high;
7744 static gid_t idmap_gid_low, idmap_gid_high;
7746 bool lp_idmap_uid(uid_t *low, uid_t *high)
7748 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7749 return False;
7751 if (low)
7752 *low = idmap_uid_low;
7754 if (high)
7755 *high = idmap_uid_high;
7757 return True;
7760 bool lp_idmap_gid(gid_t *low, gid_t *high)
7762 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7763 return False;
7765 if (low)
7766 *low = idmap_gid_low;
7768 if (high)
7769 *high = idmap_gid_high;
7771 return True;
7774 static bool handle_idmap_backend(int snum, const char *pszParmValue, char **ptr)
7776 lp_do_parameter(snum, "idmap config * : backend", pszParmValue);
7778 return true;
7781 /* Do some simple checks on "idmap [ug]id" parameter values */
7783 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7785 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7787 return True;
7790 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7792 lp_do_parameter(snum, "idmap config * : range", pszParmValue);
7794 return True;
7797 /***************************************************************************
7798 Handle the DEBUG level list.
7799 ***************************************************************************/
7801 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7803 string_set(ptr, pszParmValueIn);
7804 return debug_parse_levels(pszParmValueIn);
7807 /***************************************************************************
7808 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7809 ***************************************************************************/
7811 static const char *append_ldap_suffix( const char *str )
7813 const char *suffix_string;
7816 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7817 Globals.szLdapSuffix );
7818 if ( !suffix_string ) {
7819 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7820 return "";
7823 return suffix_string;
7826 const char *lp_ldap_machine_suffix(void)
7828 if (Globals.szLdapMachineSuffix[0])
7829 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7831 return lp_string(Globals.szLdapSuffix);
7834 const char *lp_ldap_user_suffix(void)
7836 if (Globals.szLdapUserSuffix[0])
7837 return append_ldap_suffix(Globals.szLdapUserSuffix);
7839 return lp_string(Globals.szLdapSuffix);
7842 const char *lp_ldap_group_suffix(void)
7844 if (Globals.szLdapGroupSuffix[0])
7845 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7847 return lp_string(Globals.szLdapSuffix);
7850 const char *lp_ldap_idmap_suffix(void)
7852 if (Globals.szLdapIdmapSuffix[0])
7853 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7855 return lp_string(Globals.szLdapSuffix);
7858 /****************************************************************************
7859 set the value for a P_ENUM
7860 ***************************************************************************/
7862 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7863 int *ptr )
7865 int i;
7867 for (i = 0; parm->enum_list[i].name; i++) {
7868 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7869 *ptr = parm->enum_list[i].value;
7870 return;
7873 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7874 pszParmValue, parm->label));
7877 /***************************************************************************
7878 ***************************************************************************/
7880 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7882 static int parm_num = -1;
7883 struct service *s;
7885 if ( parm_num == -1 )
7886 parm_num = map_parameter( "printing" );
7888 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7890 if ( snum < 0 )
7891 s = &sDefault;
7892 else
7893 s = ServicePtrs[snum];
7895 init_printer_values( s );
7897 return True;
7901 /***************************************************************************
7902 Initialise a copymap.
7903 ***************************************************************************/
7905 static void init_copymap(struct service *pservice)
7907 int i;
7909 TALLOC_FREE(pservice->copymap);
7911 pservice->copymap = bitmap_talloc(NULL, NUMPARAMETERS);
7912 if (!pservice->copymap)
7913 DEBUG(0,
7914 ("Couldn't allocate copymap!! (size %d)\n",
7915 (int)NUMPARAMETERS));
7916 else
7917 for (i = 0; i < NUMPARAMETERS; i++)
7918 bitmap_set(pservice->copymap, i);
7921 /***************************************************************************
7922 Return the local pointer to a parameter given a service struct and the
7923 pointer into the default structure.
7924 ***************************************************************************/
7926 static void *lp_local_ptr(struct service *service, void *ptr)
7928 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7931 /***************************************************************************
7932 Return the local pointer to a parameter given the service number and the
7933 pointer into the default structure.
7934 ***************************************************************************/
7936 void *lp_local_ptr_by_snum(int snum, void *ptr)
7938 return lp_local_ptr(ServicePtrs[snum], ptr);
7941 /***************************************************************************
7942 Process a parameter for a particular service number. If snum < 0
7943 then assume we are in the globals.
7944 ***************************************************************************/
7946 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7948 int parmnum, i;
7949 void *parm_ptr = NULL; /* where we are going to store the result */
7950 void *def_ptr = NULL;
7951 struct param_opt_struct **opt_list;
7953 parmnum = map_parameter(pszParmName);
7955 if (parmnum < 0) {
7956 if (strchr(pszParmName, ':') == NULL) {
7957 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7958 pszParmName));
7959 return (True);
7963 * We've got a parametric option
7966 opt_list = (snum < 0)
7967 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7968 set_param_opt(opt_list, pszParmName, pszParmValue, 0);
7970 return (True);
7973 /* if it's already been set by the command line, then we don't
7974 override here */
7975 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
7976 return true;
7979 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7980 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7981 pszParmName));
7984 def_ptr = parm_table[parmnum].ptr;
7986 /* we might point at a service, the default service or a global */
7987 if (snum < 0) {
7988 parm_ptr = def_ptr;
7989 } else {
7990 if (parm_table[parmnum].p_class == P_GLOBAL) {
7991 DEBUG(0,
7992 ("Global parameter %s found in service section!\n",
7993 pszParmName));
7994 return (True);
7996 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7999 if (snum >= 0) {
8000 if (!ServicePtrs[snum]->copymap)
8001 init_copymap(ServicePtrs[snum]);
8003 /* this handles the aliases - set the copymap for other entries with
8004 the same data pointer */
8005 for (i = 0; parm_table[i].label; i++)
8006 if (parm_table[i].ptr == parm_table[parmnum].ptr)
8007 bitmap_clear(ServicePtrs[snum]->copymap, i);
8010 /* if it is a special case then go ahead */
8011 if (parm_table[parmnum].special) {
8012 return parm_table[parmnum].special(snum, pszParmValue,
8013 (char **)parm_ptr);
8016 /* now switch on the type of variable it is */
8017 switch (parm_table[parmnum].type)
8019 case P_BOOL:
8020 *(bool *)parm_ptr = lp_bool(pszParmValue);
8021 break;
8023 case P_BOOLREV:
8024 *(bool *)parm_ptr = !lp_bool(pszParmValue);
8025 break;
8027 case P_INTEGER:
8028 *(int *)parm_ptr = lp_int(pszParmValue);
8029 break;
8031 case P_CHAR:
8032 *(char *)parm_ptr = *pszParmValue;
8033 break;
8035 case P_OCTAL:
8036 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
8037 if ( i != 1 ) {
8038 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
8040 break;
8042 case P_LIST:
8043 TALLOC_FREE(*((char ***)parm_ptr));
8044 *(char ***)parm_ptr = str_list_make_v3(
8045 NULL, pszParmValue, NULL);
8046 break;
8048 case P_STRING:
8049 string_set((char **)parm_ptr, pszParmValue);
8050 break;
8052 case P_USTRING:
8053 string_set((char **)parm_ptr, pszParmValue);
8054 strupper_m(*(char **)parm_ptr);
8055 break;
8057 case P_ENUM:
8058 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
8059 break;
8060 case P_SEP:
8061 break;
8064 return (True);
8067 /***************************************************************************
8068 set a parameter, marking it with FLAG_CMDLINE. Parameters marked as
8069 FLAG_CMDLINE won't be overridden by loads from smb.conf.
8070 ***************************************************************************/
8072 static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values)
8074 int parmnum, i;
8075 parmnum = map_parameter(pszParmName);
8076 if (parmnum >= 0) {
8077 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
8078 if (!lp_do_parameter(-1, pszParmName, pszParmValue)) {
8079 return false;
8081 parm_table[parmnum].flags |= FLAG_CMDLINE;
8083 /* we have to also set FLAG_CMDLINE on aliases. Aliases must
8084 * be grouped in the table, so we don't have to search the
8085 * whole table */
8086 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
8087 parm_table[i].flags |= FLAG_CMDLINE;
8089 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
8090 parm_table[i].flags |= FLAG_CMDLINE;
8093 if (store_values) {
8094 store_lp_set_cmdline(pszParmName, pszParmValue);
8096 return true;
8099 /* it might be parametric */
8100 if (strchr(pszParmName, ':') != NULL) {
8101 set_param_opt(&Globals.param_opt, pszParmName, pszParmValue, FLAG_CMDLINE);
8102 if (store_values) {
8103 store_lp_set_cmdline(pszParmName, pszParmValue);
8105 return true;
8108 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
8109 return true;
8112 bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
8114 return lp_set_cmdline_helper(pszParmName, pszParmValue, true);
8117 /***************************************************************************
8118 Process a parameter.
8119 ***************************************************************************/
8121 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
8122 void *userdata)
8124 if (!bInGlobalSection && bGlobalOnly)
8125 return (True);
8127 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
8129 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
8130 pszParmName, pszParmValue));
8134 set a option from the commandline in 'a=b' format. Use to support --option
8136 bool lp_set_option(const char *option)
8138 char *p, *s;
8139 bool ret;
8141 s = talloc_strdup(NULL, option);
8142 if (!s) {
8143 return false;
8146 p = strchr(s, '=');
8147 if (!p) {
8148 talloc_free(s);
8149 return false;
8152 *p = 0;
8154 /* skip white spaces after the = sign */
8155 do {
8156 p++;
8157 } while (*p == ' ');
8159 ret = lp_set_cmdline(s, p);
8160 talloc_free(s);
8161 return ret;
8164 /**************************************************************************
8165 Print a parameter of the specified type.
8166 ***************************************************************************/
8168 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
8170 int i;
8171 switch (p->type)
8173 case P_ENUM:
8174 for (i = 0; p->enum_list[i].name; i++) {
8175 if (*(int *)ptr == p->enum_list[i].value) {
8176 fprintf(f, "%s",
8177 p->enum_list[i].name);
8178 break;
8181 break;
8183 case P_BOOL:
8184 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
8185 break;
8187 case P_BOOLREV:
8188 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
8189 break;
8191 case P_INTEGER:
8192 fprintf(f, "%d", *(int *)ptr);
8193 break;
8195 case P_CHAR:
8196 fprintf(f, "%c", *(char *)ptr);
8197 break;
8199 case P_OCTAL: {
8200 char *o = octal_string(*(int *)ptr);
8201 fprintf(f, "%s", o);
8202 TALLOC_FREE(o);
8203 break;
8206 case P_LIST:
8207 if ((char ***)ptr && *(char ***)ptr) {
8208 char **list = *(char ***)ptr;
8209 for (; *list; list++) {
8210 /* surround strings with whitespace in double quotes */
8211 if ( strchr_m( *list, ' ' ) )
8212 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
8213 else
8214 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
8217 break;
8219 case P_STRING:
8220 case P_USTRING:
8221 if (*(char **)ptr) {
8222 fprintf(f, "%s", *(char **)ptr);
8224 break;
8225 case P_SEP:
8226 break;
8230 /***************************************************************************
8231 Check if two parameters are equal.
8232 ***************************************************************************/
8234 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
8236 switch (type) {
8237 case P_BOOL:
8238 case P_BOOLREV:
8239 return (*((bool *)ptr1) == *((bool *)ptr2));
8241 case P_INTEGER:
8242 case P_ENUM:
8243 case P_OCTAL:
8244 return (*((int *)ptr1) == *((int *)ptr2));
8246 case P_CHAR:
8247 return (*((char *)ptr1) == *((char *)ptr2));
8249 case P_LIST:
8250 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
8252 case P_STRING:
8253 case P_USTRING:
8255 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
8256 if (p1 && !*p1)
8257 p1 = NULL;
8258 if (p2 && !*p2)
8259 p2 = NULL;
8260 return (p1 == p2 || strequal(p1, p2));
8262 case P_SEP:
8263 break;
8265 return (False);
8268 /***************************************************************************
8269 Initialize any local varients in the sDefault table.
8270 ***************************************************************************/
8272 void init_locals(void)
8274 /* None as yet. */
8277 /***************************************************************************
8278 Process a new section (service). At this stage all sections are services.
8279 Later we'll have special sections that permit server parameters to be set.
8280 Returns True on success, False on failure.
8281 ***************************************************************************/
8283 static bool do_section(const char *pszSectionName, void *userdata)
8285 bool bRetval;
8286 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
8287 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
8288 bRetval = False;
8290 /* if we were in a global section then do the local inits */
8291 if (bInGlobalSection && !isglobal)
8292 init_locals();
8294 /* if we've just struck a global section, note the fact. */
8295 bInGlobalSection = isglobal;
8297 /* check for multiple global sections */
8298 if (bInGlobalSection) {
8299 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
8300 return (True);
8303 if (!bInGlobalSection && bGlobalOnly)
8304 return (True);
8306 /* if we have a current service, tidy it up before moving on */
8307 bRetval = True;
8309 if (iServiceIndex >= 0)
8310 bRetval = service_ok(iServiceIndex);
8312 /* if all is still well, move to the next record in the services array */
8313 if (bRetval) {
8314 /* We put this here to avoid an odd message order if messages are */
8315 /* issued by the post-processing of a previous section. */
8316 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
8318 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
8319 < 0) {
8320 DEBUG(0, ("Failed to add a new service\n"));
8321 return (False);
8323 /* Clean all parametric options for service */
8324 /* They will be added during parsing again */
8325 free_param_opts(&ServicePtrs[iServiceIndex]->param_opt);
8328 return (bRetval);
8332 /***************************************************************************
8333 Determine if a partcular base parameter is currentl set to the default value.
8334 ***************************************************************************/
8336 static bool is_default(int i)
8338 if (!defaults_saved)
8339 return False;
8340 switch (parm_table[i].type) {
8341 case P_LIST:
8342 return str_list_equal((const char **)parm_table[i].def.lvalue,
8343 *(const char ***)parm_table[i].ptr);
8344 case P_STRING:
8345 case P_USTRING:
8346 return strequal(parm_table[i].def.svalue,
8347 *(char **)parm_table[i].ptr);
8348 case P_BOOL:
8349 case P_BOOLREV:
8350 return parm_table[i].def.bvalue ==
8351 *(bool *)parm_table[i].ptr;
8352 case P_CHAR:
8353 return parm_table[i].def.cvalue ==
8354 *(char *)parm_table[i].ptr;
8355 case P_INTEGER:
8356 case P_OCTAL:
8357 case P_ENUM:
8358 return parm_table[i].def.ivalue ==
8359 *(int *)parm_table[i].ptr;
8360 case P_SEP:
8361 break;
8363 return False;
8366 /***************************************************************************
8367 Display the contents of the global structure.
8368 ***************************************************************************/
8370 static void dump_globals(FILE *f)
8372 int i;
8373 struct param_opt_struct *data;
8375 fprintf(f, "[global]\n");
8377 for (i = 0; parm_table[i].label; i++)
8378 if (parm_table[i].p_class == P_GLOBAL &&
8379 !(parm_table[i].flags & FLAG_META) &&
8380 parm_table[i].ptr &&
8381 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8382 if (defaults_saved && is_default(i))
8383 continue;
8384 fprintf(f, "\t%s = ", parm_table[i].label);
8385 print_parameter(&parm_table[i], parm_table[i].ptr, f);
8386 fprintf(f, "\n");
8388 if (Globals.param_opt != NULL) {
8389 data = Globals.param_opt;
8390 while(data) {
8391 fprintf(f, "\t%s = %s\n", data->key, data->value);
8392 data = data->next;
8398 /***************************************************************************
8399 Return True if a local parameter is currently set to the global default.
8400 ***************************************************************************/
8402 bool lp_is_default(int snum, struct parm_struct *parm)
8404 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8406 return equal_parameter(parm->type,
8407 ((char *)ServicePtrs[snum]) + pdiff,
8408 ((char *)&sDefault) + pdiff);
8411 /***************************************************************************
8412 Display the contents of a single services record.
8413 ***************************************************************************/
8415 static void dump_a_service(struct service *pService, FILE * f)
8417 int i;
8418 struct param_opt_struct *data;
8420 if (pService != &sDefault)
8421 fprintf(f, "[%s]\n", pService->szService);
8423 for (i = 0; parm_table[i].label; i++) {
8425 if (parm_table[i].p_class == P_LOCAL &&
8426 !(parm_table[i].flags & FLAG_META) &&
8427 parm_table[i].ptr &&
8428 (*parm_table[i].label != '-') &&
8429 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8431 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8433 if (pService == &sDefault) {
8434 if (defaults_saved && is_default(i))
8435 continue;
8436 } else {
8437 if (equal_parameter(parm_table[i].type,
8438 ((char *)pService) +
8439 pdiff,
8440 ((char *)&sDefault) +
8441 pdiff))
8442 continue;
8445 fprintf(f, "\t%s = ", parm_table[i].label);
8446 print_parameter(&parm_table[i],
8447 ((char *)pService) + pdiff, f);
8448 fprintf(f, "\n");
8452 if (pService->param_opt != NULL) {
8453 data = pService->param_opt;
8454 while(data) {
8455 fprintf(f, "\t%s = %s\n", data->key, data->value);
8456 data = data->next;
8461 /***************************************************************************
8462 Display the contents of a parameter of a single services record.
8463 ***************************************************************************/
8465 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8467 int i;
8468 bool result = False;
8469 parm_class p_class;
8470 unsigned flag = 0;
8471 fstring local_parm_name;
8472 char *parm_opt;
8473 const char *parm_opt_value;
8475 /* check for parametrical option */
8476 fstrcpy( local_parm_name, parm_name);
8477 parm_opt = strchr( local_parm_name, ':');
8479 if (parm_opt) {
8480 *parm_opt = '\0';
8481 parm_opt++;
8482 if (strlen(parm_opt)) {
8483 parm_opt_value = lp_parm_const_string( snum,
8484 local_parm_name, parm_opt, NULL);
8485 if (parm_opt_value) {
8486 printf( "%s\n", parm_opt_value);
8487 result = True;
8490 return result;
8493 /* check for a key and print the value */
8494 if (isGlobal) {
8495 p_class = P_GLOBAL;
8496 flag = FLAG_GLOBAL;
8497 } else
8498 p_class = P_LOCAL;
8500 for (i = 0; parm_table[i].label; i++) {
8501 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8502 !(parm_table[i].flags & FLAG_META) &&
8503 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8504 parm_table[i].ptr &&
8505 (*parm_table[i].label != '-') &&
8506 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8508 void *ptr;
8510 if (isGlobal) {
8511 ptr = parm_table[i].ptr;
8512 } else {
8513 struct service *pService = ServicePtrs[snum];
8514 ptr = ((char *)pService) +
8515 PTR_DIFF(parm_table[i].ptr, &sDefault);
8518 print_parameter(&parm_table[i],
8519 ptr, f);
8520 fprintf(f, "\n");
8521 result = True;
8522 break;
8526 return result;
8529 /***************************************************************************
8530 Return info about the requested parameter (given as a string).
8531 Return NULL when the string is not a valid parameter name.
8532 ***************************************************************************/
8534 struct parm_struct *lp_get_parameter(const char *param_name)
8536 int num = map_parameter(param_name);
8538 if (num < 0) {
8539 return NULL;
8542 return &parm_table[num];
8545 /***************************************************************************
8546 Return info about the next parameter in a service.
8547 snum==GLOBAL_SECTION_SNUM gives the globals.
8548 Return NULL when out of parameters.
8549 ***************************************************************************/
8551 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8553 if (snum < 0) {
8554 /* do the globals */
8555 for (; parm_table[*i].label; (*i)++) {
8556 if (parm_table[*i].p_class == P_SEPARATOR)
8557 return &parm_table[(*i)++];
8559 if (!parm_table[*i].ptr
8560 || (*parm_table[*i].label == '-'))
8561 continue;
8563 if ((*i) > 0
8564 && (parm_table[*i].ptr ==
8565 parm_table[(*i) - 1].ptr))
8566 continue;
8568 if (is_default(*i) && !allparameters)
8569 continue;
8571 return &parm_table[(*i)++];
8573 } else {
8574 struct service *pService = ServicePtrs[snum];
8576 for (; parm_table[*i].label; (*i)++) {
8577 if (parm_table[*i].p_class == P_SEPARATOR)
8578 return &parm_table[(*i)++];
8580 if (parm_table[*i].p_class == P_LOCAL &&
8581 parm_table[*i].ptr &&
8582 (*parm_table[*i].label != '-') &&
8583 ((*i) == 0 ||
8584 (parm_table[*i].ptr !=
8585 parm_table[(*i) - 1].ptr)))
8587 int pdiff =
8588 PTR_DIFF(parm_table[*i].ptr,
8589 &sDefault);
8591 if (allparameters ||
8592 !equal_parameter(parm_table[*i].type,
8593 ((char *)pService) +
8594 pdiff,
8595 ((char *)&sDefault) +
8596 pdiff))
8598 return &parm_table[(*i)++];
8604 return NULL;
8608 #if 0
8609 /***************************************************************************
8610 Display the contents of a single copy structure.
8611 ***************************************************************************/
8612 static void dump_copy_map(bool *pcopymap)
8614 int i;
8615 if (!pcopymap)
8616 return;
8618 printf("\n\tNon-Copied parameters:\n");
8620 for (i = 0; parm_table[i].label; i++)
8621 if (parm_table[i].p_class == P_LOCAL &&
8622 parm_table[i].ptr && !pcopymap[i] &&
8623 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8625 printf("\t\t%s\n", parm_table[i].label);
8628 #endif
8630 /***************************************************************************
8631 Return TRUE if the passed service number is within range.
8632 ***************************************************************************/
8634 bool lp_snum_ok(int iService)
8636 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8639 /***************************************************************************
8640 Auto-load some home services.
8641 ***************************************************************************/
8643 static void lp_add_auto_services(char *str)
8645 char *s;
8646 char *p;
8647 int homes;
8648 char *saveptr;
8650 if (!str)
8651 return;
8653 s = SMB_STRDUP(str);
8654 if (!s)
8655 return;
8657 homes = lp_servicenumber(HOMES_NAME);
8659 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8660 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8661 char *home;
8663 if (lp_servicenumber(p) >= 0)
8664 continue;
8666 home = get_user_home_dir(talloc_tos(), p);
8668 if (home && home[0] && homes >= 0)
8669 lp_add_home(p, homes, p, home);
8671 TALLOC_FREE(home);
8673 SAFE_FREE(s);
8676 /***************************************************************************
8677 Auto-load one printer.
8678 ***************************************************************************/
8680 void lp_add_one_printer(const char *name, const char *comment,
8681 const char *location, void *pdata)
8683 int printers = lp_servicenumber(PRINTERS_NAME);
8684 int i;
8686 if (lp_servicenumber(name) < 0) {
8687 lp_add_printer(name, printers);
8688 if ((i = lp_servicenumber(name)) >= 0) {
8689 string_set(&ServicePtrs[i]->comment, comment);
8690 ServicePtrs[i]->autoloaded = True;
8695 /***************************************************************************
8696 Have we loaded a services file yet?
8697 ***************************************************************************/
8699 bool lp_loaded(void)
8701 return (bLoaded);
8704 /***************************************************************************
8705 Unload unused services.
8706 ***************************************************************************/
8708 void lp_killunused(bool (*snumused) (int))
8710 int i;
8711 for (i = 0; i < iNumServices; i++) {
8712 if (!VALID(i))
8713 continue;
8715 /* don't kill autoloaded or usershare services */
8716 if ( ServicePtrs[i]->autoloaded ||
8717 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8718 continue;
8721 if (!snumused || !snumused(i)) {
8722 free_service_byindex(i);
8728 * Kill all except autoloaded and usershare services - convenience wrapper
8730 void lp_kill_all_services(void)
8732 lp_killunused(NULL);
8735 /***************************************************************************
8736 Unload a service.
8737 ***************************************************************************/
8739 void lp_killservice(int iServiceIn)
8741 if (VALID(iServiceIn)) {
8742 free_service_byindex(iServiceIn);
8746 /***************************************************************************
8747 Save the curent values of all global and sDefault parameters into the
8748 defaults union. This allows swat and testparm to show only the
8749 changed (ie. non-default) parameters.
8750 ***************************************************************************/
8752 static void lp_save_defaults(void)
8754 int i;
8755 for (i = 0; parm_table[i].label; i++) {
8756 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8757 continue;
8758 switch (parm_table[i].type) {
8759 case P_LIST:
8760 parm_table[i].def.lvalue = str_list_copy(
8761 NULL, *(const char ***)parm_table[i].ptr);
8762 break;
8763 case P_STRING:
8764 case P_USTRING:
8765 if (parm_table[i].ptr) {
8766 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8767 } else {
8768 parm_table[i].def.svalue = NULL;
8770 break;
8771 case P_BOOL:
8772 case P_BOOLREV:
8773 parm_table[i].def.bvalue =
8774 *(bool *)parm_table[i].ptr;
8775 break;
8776 case P_CHAR:
8777 parm_table[i].def.cvalue =
8778 *(char *)parm_table[i].ptr;
8779 break;
8780 case P_INTEGER:
8781 case P_OCTAL:
8782 case P_ENUM:
8783 parm_table[i].def.ivalue =
8784 *(int *)parm_table[i].ptr;
8785 break;
8786 case P_SEP:
8787 break;
8790 defaults_saved = True;
8793 /***********************************************************
8794 If we should send plaintext/LANMAN passwords in the clinet
8795 ************************************************************/
8797 static void set_allowed_client_auth(void)
8799 if (Globals.bClientNTLMv2Auth) {
8800 Globals.bClientLanManAuth = False;
8802 if (!Globals.bClientLanManAuth) {
8803 Globals.bClientPlaintextAuth = False;
8807 /***************************************************************************
8808 JRA.
8809 The following code allows smbd to read a user defined share file.
8810 Yes, this is my intent. Yes, I'm comfortable with that...
8812 THE FOLLOWING IS SECURITY CRITICAL CODE.
8814 It washes your clothes, it cleans your house, it guards you while you sleep...
8815 Do not f%^k with it....
8816 ***************************************************************************/
8818 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8820 /***************************************************************************
8821 Check allowed stat state of a usershare file.
8822 Ensure we print out who is dicking with us so the admin can
8823 get their sorry ass fired.
8824 ***************************************************************************/
8826 static bool check_usershare_stat(const char *fname,
8827 const SMB_STRUCT_STAT *psbuf)
8829 if (!S_ISREG(psbuf->st_ex_mode)) {
8830 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8831 "not a regular file\n",
8832 fname, (unsigned int)psbuf->st_ex_uid ));
8833 return False;
8836 /* Ensure this doesn't have the other write bit set. */
8837 if (psbuf->st_ex_mode & S_IWOTH) {
8838 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8839 "public write. Refusing to allow as a usershare file.\n",
8840 fname, (unsigned int)psbuf->st_ex_uid ));
8841 return False;
8844 /* Should be 10k or less. */
8845 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8846 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8847 "too large (%u) to be a user share file.\n",
8848 fname, (unsigned int)psbuf->st_ex_uid,
8849 (unsigned int)psbuf->st_ex_size ));
8850 return False;
8853 return True;
8856 /***************************************************************************
8857 Parse the contents of a usershare file.
8858 ***************************************************************************/
8860 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8861 SMB_STRUCT_STAT *psbuf,
8862 const char *servicename,
8863 int snum,
8864 char **lines,
8865 int numlines,
8866 char **pp_sharepath,
8867 char **pp_comment,
8868 char **pp_cp_servicename,
8869 struct security_descriptor **ppsd,
8870 bool *pallow_guest)
8872 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8873 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8874 int us_vers;
8875 SMB_STRUCT_DIR *dp;
8876 SMB_STRUCT_STAT sbuf;
8877 char *sharepath = NULL;
8878 char *comment = NULL;
8880 *pp_sharepath = NULL;
8881 *pp_comment = NULL;
8883 *pallow_guest = False;
8885 if (numlines < 4) {
8886 return USERSHARE_MALFORMED_FILE;
8889 if (strcmp(lines[0], "#VERSION 1") == 0) {
8890 us_vers = 1;
8891 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8892 us_vers = 2;
8893 if (numlines < 5) {
8894 return USERSHARE_MALFORMED_FILE;
8896 } else {
8897 return USERSHARE_BAD_VERSION;
8900 if (strncmp(lines[1], "path=", 5) != 0) {
8901 return USERSHARE_MALFORMED_PATH;
8904 sharepath = talloc_strdup(ctx, &lines[1][5]);
8905 if (!sharepath) {
8906 return USERSHARE_POSIX_ERR;
8908 trim_string(sharepath, " ", " ");
8910 if (strncmp(lines[2], "comment=", 8) != 0) {
8911 return USERSHARE_MALFORMED_COMMENT_DEF;
8914 comment = talloc_strdup(ctx, &lines[2][8]);
8915 if (!comment) {
8916 return USERSHARE_POSIX_ERR;
8918 trim_string(comment, " ", " ");
8919 trim_char(comment, '"', '"');
8921 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8922 return USERSHARE_MALFORMED_ACL_DEF;
8925 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8926 return USERSHARE_ACL_ERR;
8929 if (us_vers == 2) {
8930 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8931 return USERSHARE_MALFORMED_ACL_DEF;
8933 if (lines[4][9] == 'y') {
8934 *pallow_guest = True;
8937 /* Backwards compatible extension to file version #2. */
8938 if (numlines > 5) {
8939 if (strncmp(lines[5], "sharename=", 10) != 0) {
8940 return USERSHARE_MALFORMED_SHARENAME_DEF;
8942 if (!strequal(&lines[5][10], servicename)) {
8943 return USERSHARE_BAD_SHARENAME;
8945 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8946 if (!*pp_cp_servicename) {
8947 return USERSHARE_POSIX_ERR;
8952 if (*pp_cp_servicename == NULL) {
8953 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8954 if (!*pp_cp_servicename) {
8955 return USERSHARE_POSIX_ERR;
8959 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8960 /* Path didn't change, no checks needed. */
8961 *pp_sharepath = sharepath;
8962 *pp_comment = comment;
8963 return USERSHARE_OK;
8966 /* The path *must* be absolute. */
8967 if (sharepath[0] != '/') {
8968 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8969 servicename, sharepath));
8970 return USERSHARE_PATH_NOT_ABSOLUTE;
8973 /* If there is a usershare prefix deny list ensure one of these paths
8974 doesn't match the start of the user given path. */
8975 if (prefixdenylist) {
8976 int i;
8977 for ( i=0; prefixdenylist[i]; i++ ) {
8978 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8979 servicename, i, prefixdenylist[i], sharepath ));
8980 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8981 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8982 "usershare prefix deny list entries.\n",
8983 servicename, sharepath));
8984 return USERSHARE_PATH_IS_DENIED;
8989 /* If there is a usershare prefix allow list ensure one of these paths
8990 does match the start of the user given path. */
8992 if (prefixallowlist) {
8993 int i;
8994 for ( i=0; prefixallowlist[i]; i++ ) {
8995 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8996 servicename, i, prefixallowlist[i], sharepath ));
8997 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8998 break;
9001 if (prefixallowlist[i] == NULL) {
9002 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
9003 "usershare prefix allow list entries.\n",
9004 servicename, sharepath));
9005 return USERSHARE_PATH_NOT_ALLOWED;
9009 /* Ensure this is pointing to a directory. */
9010 dp = sys_opendir(sharepath);
9012 if (!dp) {
9013 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
9014 servicename, sharepath));
9015 return USERSHARE_PATH_NOT_DIRECTORY;
9018 /* Ensure the owner of the usershare file has permission to share
9019 this directory. */
9021 if (sys_stat(sharepath, &sbuf, false) == -1) {
9022 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
9023 servicename, sharepath, strerror(errno) ));
9024 sys_closedir(dp);
9025 return USERSHARE_POSIX_ERR;
9028 sys_closedir(dp);
9030 if (!S_ISDIR(sbuf.st_ex_mode)) {
9031 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
9032 servicename, sharepath ));
9033 return USERSHARE_PATH_NOT_DIRECTORY;
9036 /* Check if sharing is restricted to owner-only. */
9037 /* psbuf is the stat of the usershare definition file,
9038 sbuf is the stat of the target directory to be shared. */
9040 if (lp_usershare_owner_only()) {
9041 /* root can share anything. */
9042 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
9043 return USERSHARE_PATH_NOT_ALLOWED;
9047 *pp_sharepath = sharepath;
9048 *pp_comment = comment;
9049 return USERSHARE_OK;
9052 /***************************************************************************
9053 Deal with a usershare file.
9054 Returns:
9055 >= 0 - snum
9056 -1 - Bad name, invalid contents.
9057 - service name already existed and not a usershare, problem
9058 with permissions to share directory etc.
9059 ***************************************************************************/
9061 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
9063 SMB_STRUCT_STAT sbuf;
9064 SMB_STRUCT_STAT lsbuf;
9065 char *fname = NULL;
9066 char *sharepath = NULL;
9067 char *comment = NULL;
9068 char *cp_service_name = NULL;
9069 char **lines = NULL;
9070 int numlines = 0;
9071 int fd = -1;
9072 int iService = -1;
9073 TALLOC_CTX *ctx = talloc_stackframe();
9074 struct security_descriptor *psd = NULL;
9075 bool guest_ok = False;
9076 char *canon_name = NULL;
9077 bool added_service = false;
9078 int ret = -1;
9080 /* Ensure share name doesn't contain invalid characters. */
9081 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
9082 DEBUG(0,("process_usershare_file: share name %s contains "
9083 "invalid characters (any of %s)\n",
9084 file_name, INVALID_SHARENAME_CHARS ));
9085 goto out;
9088 canon_name = canonicalize_servicename(ctx, file_name);
9089 if (!canon_name) {
9090 goto out;
9093 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
9094 if (!fname) {
9095 goto out;
9098 /* Minimize the race condition by doing an lstat before we
9099 open and fstat. Ensure this isn't a symlink link. */
9101 if (sys_lstat(fname, &lsbuf, false) != 0) {
9102 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
9103 fname, strerror(errno) ));
9104 goto out;
9107 /* This must be a regular file, not a symlink, directory or
9108 other strange filetype. */
9109 if (!check_usershare_stat(fname, &lsbuf)) {
9110 goto out;
9114 TDB_DATA data = dbwrap_fetch_bystring(
9115 ServiceHash, canon_name, canon_name);
9117 iService = -1;
9119 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
9120 iService = *(int *)data.dptr;
9124 if (iService != -1 &&
9125 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9126 &lsbuf.st_ex_mtime) == 0) {
9127 /* Nothing changed - Mark valid and return. */
9128 DEBUG(10,("process_usershare_file: service %s not changed.\n",
9129 canon_name ));
9130 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9131 ret = iService;
9132 goto out;
9135 /* Try and open the file read only - no symlinks allowed. */
9136 #ifdef O_NOFOLLOW
9137 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
9138 #else
9139 fd = sys_open(fname, O_RDONLY, 0);
9140 #endif
9142 if (fd == -1) {
9143 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
9144 fname, strerror(errno) ));
9145 goto out;
9148 /* Now fstat to be *SURE* it's a regular file. */
9149 if (sys_fstat(fd, &sbuf, false) != 0) {
9150 close(fd);
9151 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
9152 fname, strerror(errno) ));
9153 goto out;
9156 /* Is it the same dev/inode as was lstated ? */
9157 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
9158 close(fd);
9159 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
9160 "Symlink spoofing going on ?\n", fname ));
9161 goto out;
9164 /* This must be a regular file, not a symlink, directory or
9165 other strange filetype. */
9166 if (!check_usershare_stat(fname, &sbuf)) {
9167 goto out;
9170 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
9172 close(fd);
9173 if (lines == NULL) {
9174 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
9175 fname, (unsigned int)sbuf.st_ex_uid ));
9176 goto out;
9179 if (parse_usershare_file(ctx, &sbuf, file_name,
9180 iService, lines, numlines, &sharepath,
9181 &comment, &cp_service_name,
9182 &psd, &guest_ok) != USERSHARE_OK) {
9183 goto out;
9186 /* Everything ok - add the service possibly using a template. */
9187 if (iService < 0) {
9188 const struct service *sp = &sDefault;
9189 if (snum_template != -1) {
9190 sp = ServicePtrs[snum_template];
9193 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
9194 DEBUG(0, ("process_usershare_file: Failed to add "
9195 "new service %s\n", cp_service_name));
9196 goto out;
9199 added_service = true;
9201 /* Read only is controlled by usershare ACL below. */
9202 ServicePtrs[iService]->bRead_only = False;
9205 /* Write the ACL of the new/modified share. */
9206 if (!set_share_security(canon_name, psd)) {
9207 DEBUG(0, ("process_usershare_file: Failed to set share "
9208 "security for user share %s\n",
9209 canon_name ));
9210 goto out;
9213 /* If from a template it may be marked invalid. */
9214 ServicePtrs[iService]->valid = True;
9216 /* Set the service as a valid usershare. */
9217 ServicePtrs[iService]->usershare = USERSHARE_VALID;
9219 /* Set guest access. */
9220 if (lp_usershare_allow_guests()) {
9221 ServicePtrs[iService]->bGuest_ok = guest_ok;
9224 /* And note when it was loaded. */
9225 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
9226 string_set(&ServicePtrs[iService]->szPath, sharepath);
9227 string_set(&ServicePtrs[iService]->comment, comment);
9229 ret = iService;
9231 out:
9233 if (ret == -1 && iService != -1 && added_service) {
9234 lp_remove_service(iService);
9237 TALLOC_FREE(lines);
9238 TALLOC_FREE(ctx);
9239 return ret;
9242 /***************************************************************************
9243 Checks if a usershare entry has been modified since last load.
9244 ***************************************************************************/
9246 static bool usershare_exists(int iService, struct timespec *last_mod)
9248 SMB_STRUCT_STAT lsbuf;
9249 const char *usersharepath = Globals.szUsersharePath;
9250 char *fname;
9252 if (asprintf(&fname, "%s/%s",
9253 usersharepath,
9254 ServicePtrs[iService]->szService) < 0) {
9255 return false;
9258 if (sys_lstat(fname, &lsbuf, false) != 0) {
9259 SAFE_FREE(fname);
9260 return false;
9263 if (!S_ISREG(lsbuf.st_ex_mode)) {
9264 SAFE_FREE(fname);
9265 return false;
9268 SAFE_FREE(fname);
9269 *last_mod = lsbuf.st_ex_mtime;
9270 return true;
9273 /***************************************************************************
9274 Load a usershare service by name. Returns a valid servicenumber or -1.
9275 ***************************************************************************/
9277 int load_usershare_service(const char *servicename)
9279 SMB_STRUCT_STAT sbuf;
9280 const char *usersharepath = Globals.szUsersharePath;
9281 int max_user_shares = Globals.iUsershareMaxShares;
9282 int snum_template = -1;
9284 if (*usersharepath == 0 || max_user_shares == 0) {
9285 return -1;
9288 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9289 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
9290 usersharepath, strerror(errno) ));
9291 return -1;
9294 if (!S_ISDIR(sbuf.st_ex_mode)) {
9295 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
9296 usersharepath ));
9297 return -1;
9301 * This directory must be owned by root, and have the 't' bit set.
9302 * It also must not be writable by "other".
9305 #ifdef S_ISVTX
9306 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9307 #else
9308 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9309 #endif
9310 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
9311 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9312 usersharepath ));
9313 return -1;
9316 /* Ensure the template share exists if it's set. */
9317 if (Globals.szUsershareTemplateShare[0]) {
9318 /* We can't use lp_servicenumber here as we are recommending that
9319 template shares have -valid=False set. */
9320 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9321 if (ServicePtrs[snum_template]->szService &&
9322 strequal(ServicePtrs[snum_template]->szService,
9323 Globals.szUsershareTemplateShare)) {
9324 break;
9328 if (snum_template == -1) {
9329 DEBUG(0,("load_usershare_service: usershare template share %s "
9330 "does not exist.\n",
9331 Globals.szUsershareTemplateShare ));
9332 return -1;
9336 return process_usershare_file(usersharepath, servicename, snum_template);
9339 /***************************************************************************
9340 Load all user defined shares from the user share directory.
9341 We only do this if we're enumerating the share list.
9342 This is the function that can delete usershares that have
9343 been removed.
9344 ***************************************************************************/
9346 int load_usershare_shares(void)
9348 SMB_STRUCT_DIR *dp;
9349 SMB_STRUCT_STAT sbuf;
9350 SMB_STRUCT_DIRENT *de;
9351 int num_usershares = 0;
9352 int max_user_shares = Globals.iUsershareMaxShares;
9353 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
9354 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
9355 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
9356 int iService;
9357 int snum_template = -1;
9358 const char *usersharepath = Globals.szUsersharePath;
9359 int ret = lp_numservices();
9361 if (max_user_shares == 0 || *usersharepath == '\0') {
9362 return lp_numservices();
9365 if (sys_stat(usersharepath, &sbuf, false) != 0) {
9366 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
9367 usersharepath, strerror(errno) ));
9368 return ret;
9372 * This directory must be owned by root, and have the 't' bit set.
9373 * It also must not be writable by "other".
9376 #ifdef S_ISVTX
9377 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
9378 #else
9379 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9380 #endif
9381 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9382 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9383 usersharepath ));
9384 return ret;
9387 /* Ensure the template share exists if it's set. */
9388 if (Globals.szUsershareTemplateShare[0]) {
9389 /* We can't use lp_servicenumber here as we are recommending that
9390 template shares have -valid=False set. */
9391 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9392 if (ServicePtrs[snum_template]->szService &&
9393 strequal(ServicePtrs[snum_template]->szService,
9394 Globals.szUsershareTemplateShare)) {
9395 break;
9399 if (snum_template == -1) {
9400 DEBUG(0,("load_usershare_shares: usershare template share %s "
9401 "does not exist.\n",
9402 Globals.szUsershareTemplateShare ));
9403 return ret;
9407 /* Mark all existing usershares as pending delete. */
9408 for (iService = iNumServices - 1; iService >= 0; iService--) {
9409 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9410 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9414 dp = sys_opendir(usersharepath);
9415 if (!dp) {
9416 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9417 usersharepath, strerror(errno) ));
9418 return ret;
9421 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9422 (de = sys_readdir(dp));
9423 num_dir_entries++ ) {
9424 int r;
9425 const char *n = de->d_name;
9427 /* Ignore . and .. */
9428 if (*n == '.') {
9429 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9430 continue;
9434 if (n[0] == ':') {
9435 /* Temporary file used when creating a share. */
9436 num_tmp_dir_entries++;
9439 /* Allow 20% tmp entries. */
9440 if (num_tmp_dir_entries > allowed_tmp_entries) {
9441 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9442 "in directory %s\n",
9443 num_tmp_dir_entries, usersharepath));
9444 break;
9447 r = process_usershare_file(usersharepath, n, snum_template);
9448 if (r == 0) {
9449 /* Update the services count. */
9450 num_usershares++;
9451 if (num_usershares >= max_user_shares) {
9452 DEBUG(0,("load_usershare_shares: max user shares reached "
9453 "on file %s in directory %s\n",
9454 n, usersharepath ));
9455 break;
9457 } else if (r == -1) {
9458 num_bad_dir_entries++;
9461 /* Allow 20% bad entries. */
9462 if (num_bad_dir_entries > allowed_bad_entries) {
9463 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9464 "in directory %s\n",
9465 num_bad_dir_entries, usersharepath));
9466 break;
9469 /* Allow 20% bad entries. */
9470 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9471 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9472 "in directory %s\n",
9473 num_dir_entries, usersharepath));
9474 break;
9478 sys_closedir(dp);
9480 /* Sweep through and delete any non-refreshed usershares that are
9481 not currently in use. */
9482 for (iService = iNumServices - 1; iService >= 0; iService--) {
9483 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9484 if (conn_snum_used(iService)) {
9485 continue;
9487 /* Remove from the share ACL db. */
9488 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9489 lp_servicename(iService) ));
9490 delete_share_security(lp_servicename(iService));
9491 free_service_byindex(iService);
9495 return lp_numservices();
9498 /********************************************************
9499 Destroy global resources allocated in this file
9500 ********************************************************/
9502 void gfree_loadparm(void)
9504 int i;
9506 free_file_list();
9508 /* Free resources allocated to services */
9510 for ( i = 0; i < iNumServices; i++ ) {
9511 if ( VALID(i) ) {
9512 free_service_byindex(i);
9516 SAFE_FREE( ServicePtrs );
9517 iNumServices = 0;
9519 /* Now release all resources allocated to global
9520 parameters and the default service */
9522 free_global_parameters();
9526 /***************************************************************************
9527 Allow client apps to specify that they are a client
9528 ***************************************************************************/
9529 void lp_set_in_client(bool b)
9531 in_client = b;
9535 /***************************************************************************
9536 Determine if we're running in a client app
9537 ***************************************************************************/
9538 bool lp_is_in_client(void)
9540 return in_client;
9543 /***************************************************************************
9544 Load the services array from the services file. Return True on success,
9545 False on failure.
9546 ***************************************************************************/
9548 static bool lp_load_ex(const char *pszFname,
9549 bool global_only,
9550 bool save_defaults,
9551 bool add_ipc,
9552 bool initialize_globals,
9553 bool allow_include_registry,
9554 bool allow_registry_shares)
9556 char *n2 = NULL;
9557 bool bRetval;
9559 bRetval = False;
9561 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9563 bInGlobalSection = True;
9564 bGlobalOnly = global_only;
9565 bAllowIncludeRegistry = allow_include_registry;
9567 init_globals(initialize_globals);
9569 free_file_list();
9571 if (save_defaults) {
9572 init_locals();
9573 lp_save_defaults();
9576 free_param_opts(&Globals.param_opt);
9578 lp_do_parameter(-1, "idmap config * : backend", Globals.szIdmapBackend);
9580 /* We get sections first, so have to start 'behind' to make up */
9581 iServiceIndex = -1;
9583 if (lp_config_backend_is_file()) {
9584 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9585 current_user_info.domain,
9586 pszFname);
9587 if (!n2) {
9588 smb_panic("lp_load_ex: out of memory");
9591 add_to_file_list(pszFname, n2);
9593 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9594 TALLOC_FREE(n2);
9596 /* finish up the last section */
9597 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9598 if (bRetval) {
9599 if (iServiceIndex >= 0) {
9600 bRetval = service_ok(iServiceIndex);
9604 if (lp_config_backend_is_registry()) {
9605 /* config backend changed to registry in config file */
9607 * We need to use this extra global variable here to
9608 * survive restart: init_globals uses this as a default
9609 * for ConfigBackend. Otherwise, init_globals would
9610 * send us into an endless loop here.
9612 config_backend = CONFIG_BACKEND_REGISTRY;
9613 /* start over */
9614 DEBUG(1, ("lp_load_ex: changing to config backend "
9615 "registry\n"));
9616 init_globals(true);
9617 lp_kill_all_services();
9618 return lp_load_ex(pszFname, global_only, save_defaults,
9619 add_ipc, initialize_globals,
9620 allow_include_registry,
9621 allow_registry_shares);
9623 } else if (lp_config_backend_is_registry()) {
9624 bRetval = process_registry_globals();
9625 } else {
9626 DEBUG(0, ("Illegal config backend given: %d\n",
9627 lp_config_backend()));
9628 bRetval = false;
9631 if (bRetval && lp_registry_shares()) {
9632 if (allow_registry_shares) {
9633 bRetval = process_registry_shares();
9634 } else {
9635 bRetval = reload_registry_shares();
9639 lp_add_auto_services(lp_auto_services());
9641 if (add_ipc) {
9642 /* When 'restrict anonymous = 2' guest connections to ipc$
9643 are denied */
9644 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9645 if ( lp_enable_asu_support() ) {
9646 lp_add_ipc("ADMIN$", false);
9650 set_server_role();
9651 set_default_server_announce_type();
9652 set_allowed_client_auth();
9654 if (lp_security() == SEC_SHARE) {
9655 DEBUG(1, ("WARNING: The security=share option is deprecated\n"));
9656 } else if (lp_security() == SEC_SERVER) {
9657 DEBUG(1, ("WARNING: The security=server option is deprecated\n"));
9660 if (lp_security() == SEC_ADS && strchr(lp_passwordserver(), ':')) {
9661 DEBUG(1, ("WARNING: The optional ':port' in password server = %s is deprecated\n",
9662 lp_passwordserver()));
9665 bLoaded = True;
9667 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9668 /* if bWINSsupport is true and we are in the client */
9669 if (lp_is_in_client() && Globals.bWINSsupport) {
9670 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9673 init_iconv();
9675 bAllowIncludeRegistry = true;
9677 return (bRetval);
9680 bool lp_load(const char *pszFname,
9681 bool global_only,
9682 bool save_defaults,
9683 bool add_ipc,
9684 bool initialize_globals)
9686 return lp_load_ex(pszFname,
9687 global_only,
9688 save_defaults,
9689 add_ipc,
9690 initialize_globals,
9691 true, /* allow_include_registry */
9692 false); /* allow_registry_shares*/
9695 bool lp_load_initial_only(const char *pszFname)
9697 return lp_load_ex(pszFname,
9698 true, /* global only */
9699 false, /* save_defaults */
9700 false, /* add_ipc */
9701 true, /* initialize_globals */
9702 false, /* allow_include_registry */
9703 false); /* allow_registry_shares*/
9706 bool lp_load_with_registry_shares(const char *pszFname,
9707 bool global_only,
9708 bool save_defaults,
9709 bool add_ipc,
9710 bool initialize_globals)
9712 return lp_load_ex(pszFname,
9713 global_only,
9714 save_defaults,
9715 add_ipc,
9716 initialize_globals,
9717 true, /* allow_include_registry */
9718 true); /* allow_registry_shares*/
9721 /***************************************************************************
9722 Return the max number of services.
9723 ***************************************************************************/
9725 int lp_numservices(void)
9727 return (iNumServices);
9730 /***************************************************************************
9731 Display the contents of the services array in human-readable form.
9732 ***************************************************************************/
9734 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9736 int iService;
9738 if (show_defaults)
9739 defaults_saved = False;
9741 dump_globals(f);
9743 dump_a_service(&sDefault, f);
9745 for (iService = 0; iService < maxtoprint; iService++) {
9746 fprintf(f,"\n");
9747 lp_dump_one(f, show_defaults, iService);
9751 /***************************************************************************
9752 Display the contents of one service in human-readable form.
9753 ***************************************************************************/
9755 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9757 if (VALID(snum)) {
9758 if (ServicePtrs[snum]->szService[0] == '\0')
9759 return;
9760 dump_a_service(ServicePtrs[snum], f);
9764 /***************************************************************************
9765 Return the number of the service with the given name, or -1 if it doesn't
9766 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9767 getservicebyname()! This works ONLY if all services have been loaded, and
9768 does not copy the found service.
9769 ***************************************************************************/
9771 int lp_servicenumber(const char *pszServiceName)
9773 int iService;
9774 fstring serviceName;
9776 if (!pszServiceName) {
9777 return GLOBAL_SECTION_SNUM;
9780 for (iService = iNumServices - 1; iService >= 0; iService--) {
9781 if (VALID(iService) && ServicePtrs[iService]->szService) {
9783 * The substitution here is used to support %U is
9784 * service names
9786 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9787 standard_sub_basic(get_current_username(),
9788 current_user_info.domain,
9789 serviceName,sizeof(serviceName));
9790 if (strequal(serviceName, pszServiceName)) {
9791 break;
9796 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9797 struct timespec last_mod;
9799 if (!usershare_exists(iService, &last_mod)) {
9800 /* Remove the share security tdb entry for it. */
9801 delete_share_security(lp_servicename(iService));
9802 /* Remove it from the array. */
9803 free_service_byindex(iService);
9804 /* Doesn't exist anymore. */
9805 return GLOBAL_SECTION_SNUM;
9808 /* Has it been modified ? If so delete and reload. */
9809 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9810 &last_mod) < 0) {
9811 /* Remove it from the array. */
9812 free_service_byindex(iService);
9813 /* and now reload it. */
9814 iService = load_usershare_service(pszServiceName);
9818 if (iService < 0) {
9819 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9820 return GLOBAL_SECTION_SNUM;
9823 return (iService);
9826 bool share_defined(const char *service_name)
9828 return (lp_servicenumber(service_name) != -1);
9831 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9832 const char *sharename)
9834 struct share_params *result;
9835 char *sname = NULL;
9836 int snum;
9838 snum = find_service(mem_ctx, sharename, &sname);
9839 if (snum < 0 || sname == NULL) {
9840 return NULL;
9843 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9844 DEBUG(0, ("talloc failed\n"));
9845 return NULL;
9848 result->service = snum;
9849 return result;
9852 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9854 struct share_iterator *result;
9856 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9857 DEBUG(0, ("talloc failed\n"));
9858 return NULL;
9861 result->next_id = 0;
9862 return result;
9865 struct share_params *next_share(struct share_iterator *list)
9867 struct share_params *result;
9869 while (!lp_snum_ok(list->next_id) &&
9870 (list->next_id < lp_numservices())) {
9871 list->next_id += 1;
9874 if (list->next_id >= lp_numservices()) {
9875 return NULL;
9878 if (!(result = TALLOC_P(list, struct share_params))) {
9879 DEBUG(0, ("talloc failed\n"));
9880 return NULL;
9883 result->service = list->next_id;
9884 list->next_id += 1;
9885 return result;
9888 struct share_params *next_printer(struct share_iterator *list)
9890 struct share_params *result;
9892 while ((result = next_share(list)) != NULL) {
9893 if (lp_print_ok(result->service)) {
9894 break;
9897 return result;
9901 * This is a hack for a transition period until we transformed all code from
9902 * service numbers to struct share_params.
9905 struct share_params *snum2params_static(int snum)
9907 static struct share_params result;
9908 result.service = snum;
9909 return &result;
9912 /*******************************************************************
9913 A useful volume label function.
9914 ********************************************************************/
9916 const char *volume_label(int snum)
9918 char *ret;
9919 const char *label = lp_volume(snum);
9920 if (!*label) {
9921 label = lp_servicename(snum);
9924 /* This returns a 33 byte guarenteed null terminated string. */
9925 ret = talloc_strndup(talloc_tos(), label, 32);
9926 if (!ret) {
9927 return "";
9929 return ret;
9932 /*******************************************************************
9933 Set the server type we will announce as via nmbd.
9934 ********************************************************************/
9936 static void set_default_server_announce_type(void)
9938 default_server_announce = 0;
9939 default_server_announce |= SV_TYPE_WORKSTATION;
9940 default_server_announce |= SV_TYPE_SERVER;
9941 default_server_announce |= SV_TYPE_SERVER_UNIX;
9943 /* note that the flag should be set only if we have a
9944 printer service but nmbd doesn't actually load the
9945 services so we can't tell --jerry */
9947 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9949 switch (lp_announce_as()) {
9950 case ANNOUNCE_AS_NT_SERVER:
9951 default_server_announce |= SV_TYPE_SERVER_NT;
9952 /* fall through... */
9953 case ANNOUNCE_AS_NT_WORKSTATION:
9954 default_server_announce |= SV_TYPE_NT;
9955 break;
9956 case ANNOUNCE_AS_WIN95:
9957 default_server_announce |= SV_TYPE_WIN95_PLUS;
9958 break;
9959 case ANNOUNCE_AS_WFW:
9960 default_server_announce |= SV_TYPE_WFW;
9961 break;
9962 default:
9963 break;
9966 switch (lp_server_role()) {
9967 case ROLE_DOMAIN_MEMBER:
9968 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9969 break;
9970 case ROLE_DOMAIN_PDC:
9971 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9972 break;
9973 case ROLE_DOMAIN_BDC:
9974 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9975 break;
9976 case ROLE_STANDALONE:
9977 default:
9978 break;
9980 if (lp_time_server())
9981 default_server_announce |= SV_TYPE_TIME_SOURCE;
9983 if (lp_host_msdfs())
9984 default_server_announce |= SV_TYPE_DFS_SERVER;
9987 /***********************************************************
9988 If we are PDC then prefer us as DMB
9989 ************************************************************/
9991 bool lp_domain_master(void)
9993 if (Globals.iDomainMaster == Auto)
9994 return (lp_server_role() == ROLE_DOMAIN_PDC);
9996 return (bool)Globals.iDomainMaster;
9999 /***********************************************************
10000 If we are PDC then prefer us as DMB
10001 ************************************************************/
10003 bool lp_domain_master_true_or_auto(void)
10005 if (Globals.iDomainMaster) /* auto or yes */
10006 return true;
10008 return false;
10011 /***********************************************************
10012 If we are DMB then prefer us as LMB
10013 ************************************************************/
10015 bool lp_preferred_master(void)
10017 if (Globals.iPreferredMaster == Auto)
10018 return (lp_local_master() && lp_domain_master());
10020 return (bool)Globals.iPreferredMaster;
10023 /*******************************************************************
10024 Remove a service.
10025 ********************************************************************/
10027 void lp_remove_service(int snum)
10029 ServicePtrs[snum]->valid = False;
10030 invalid_services[num_invalid_services++] = snum;
10033 /*******************************************************************
10034 Copy a service.
10035 ********************************************************************/
10037 void lp_copy_service(int snum, const char *new_name)
10039 do_section(new_name, NULL);
10040 if (snum >= 0) {
10041 snum = lp_servicenumber(new_name);
10042 if (snum >= 0)
10043 lp_do_parameter(snum, "copy", lp_servicename(snum));
10048 /*******************************************************************
10049 Get the default server type we will announce as via nmbd.
10050 ********************************************************************/
10052 int lp_default_server_announce(void)
10054 return default_server_announce;
10057 /*******************************************************************
10058 Split the announce version into major and minor numbers.
10059 ********************************************************************/
10061 int lp_major_announce_version(void)
10063 static bool got_major = False;
10064 static int major_version = DEFAULT_MAJOR_VERSION;
10065 char *vers;
10066 char *p;
10068 if (got_major)
10069 return major_version;
10071 got_major = True;
10072 if ((vers = lp_announce_version()) == NULL)
10073 return major_version;
10075 if ((p = strchr_m(vers, '.')) == 0)
10076 return major_version;
10078 *p = '\0';
10079 major_version = atoi(vers);
10080 return major_version;
10083 int lp_minor_announce_version(void)
10085 static bool got_minor = False;
10086 static int minor_version = DEFAULT_MINOR_VERSION;
10087 char *vers;
10088 char *p;
10090 if (got_minor)
10091 return minor_version;
10093 got_minor = True;
10094 if ((vers = lp_announce_version()) == NULL)
10095 return minor_version;
10097 if ((p = strchr_m(vers, '.')) == 0)
10098 return minor_version;
10100 p++;
10101 minor_version = atoi(p);
10102 return minor_version;
10105 /***********************************************************
10106 Set the global name resolution order (used in smbclient).
10107 ************************************************************/
10109 void lp_set_name_resolve_order(const char *new_order)
10111 string_set(&Globals.szNameResolveOrder, new_order);
10114 const char *lp_printername(int snum)
10116 const char *ret = _lp_printername(snum);
10117 if (ret == NULL || (ret != NULL && *ret == '\0'))
10118 ret = lp_const_servicename(snum);
10120 return ret;
10124 /***********************************************************
10125 Allow daemons such as winbindd to fix their logfile name.
10126 ************************************************************/
10128 void lp_set_logfile(const char *name)
10130 string_set(&Globals.szLogFile, name);
10131 debug_set_logfile(name);
10134 /*******************************************************************
10135 Return the max print jobs per queue.
10136 ********************************************************************/
10138 int lp_maxprintjobs(int snum)
10140 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
10141 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
10142 maxjobs = PRINT_MAX_JOBID - 1;
10144 return maxjobs;
10147 const char *lp_printcapname(void)
10149 if ((Globals.szPrintcapname != NULL) &&
10150 (Globals.szPrintcapname[0] != '\0'))
10151 return Globals.szPrintcapname;
10153 if (sDefault.iPrinting == PRINT_CUPS) {
10154 #ifdef HAVE_CUPS
10155 return "cups";
10156 #else
10157 return "lpstat";
10158 #endif
10161 if (sDefault.iPrinting == PRINT_BSD)
10162 return "/etc/printcap";
10164 return PRINTCAP_NAME;
10167 static uint32 spoolss_state;
10169 bool lp_disable_spoolss( void )
10171 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
10172 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10174 return spoolss_state == SVCCTL_STOPPED ? True : False;
10177 void lp_set_spoolss_state( uint32 state )
10179 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
10181 spoolss_state = state;
10184 uint32 lp_get_spoolss_state( void )
10186 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
10189 /*******************************************************************
10190 Ensure we don't use sendfile if server smb signing is active.
10191 ********************************************************************/
10193 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
10195 bool sign_active = false;
10197 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
10198 if (get_Protocol() < PROTOCOL_NT1) {
10199 return false;
10201 if (signing_state) {
10202 sign_active = smb_signing_is_active(signing_state);
10204 return (_lp_use_sendfile(snum) &&
10205 (get_remote_arch() != RA_WIN95) &&
10206 !sign_active);
10209 /*******************************************************************
10210 Turn off sendfile if we find the underlying OS doesn't support it.
10211 ********************************************************************/
10213 void set_use_sendfile(int snum, bool val)
10215 if (LP_SNUM_OK(snum))
10216 ServicePtrs[snum]->bUseSendfile = val;
10217 else
10218 sDefault.bUseSendfile = val;
10221 /*******************************************************************
10222 Turn off storing DOS attributes if this share doesn't support it.
10223 ********************************************************************/
10225 void set_store_dos_attributes(int snum, bool val)
10227 if (!LP_SNUM_OK(snum))
10228 return;
10229 ServicePtrs[(snum)]->bStoreDosAttributes = val;
10232 void lp_set_mangling_method(const char *new_method)
10234 string_set(&Globals.szManglingMethod, new_method);
10237 /*******************************************************************
10238 Global state for POSIX pathname processing.
10239 ********************************************************************/
10241 static bool posix_pathnames;
10243 bool lp_posix_pathnames(void)
10245 return posix_pathnames;
10248 /*******************************************************************
10249 Change everything needed to ensure POSIX pathname processing (currently
10250 not much).
10251 ********************************************************************/
10253 void lp_set_posix_pathnames(void)
10255 posix_pathnames = True;
10258 /*******************************************************************
10259 Global state for POSIX lock processing - CIFS unix extensions.
10260 ********************************************************************/
10262 bool posix_default_lock_was_set;
10263 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
10265 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
10267 if (posix_default_lock_was_set) {
10268 return posix_cifsx_locktype;
10269 } else {
10270 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
10274 /*******************************************************************
10275 ********************************************************************/
10277 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
10279 posix_default_lock_was_set = True;
10280 posix_cifsx_locktype = val;
10283 int lp_min_receive_file_size(void)
10285 if (Globals.iminreceivefile < 0) {
10286 return 0;
10288 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
10291 /*******************************************************************
10292 If socket address is an empty character string, it is necessary to
10293 define it as "0.0.0.0".
10294 ********************************************************************/
10296 const char *lp_socket_address(void)
10298 char *sock_addr = Globals.szSocketAddress;
10300 if (sock_addr[0] == '\0'){
10301 string_set(&Globals.szSocketAddress, "0.0.0.0");
10303 return Globals.szSocketAddress;
10306 void lp_set_passdb_backend(const char *backend)
10308 string_set(&Globals.szPassdbBackend, backend);
10311 /*******************************************************************
10312 Safe wide links checks.
10313 This helper function always verify the validity of wide links,
10314 even after a configuration file reload.
10315 ********************************************************************/
10317 static bool lp_widelinks_internal(int snum)
10319 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
10320 sDefault.bWidelinks);
10323 void widelinks_warning(int snum)
10325 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
10326 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
10327 "These parameters are incompatible. "
10328 "Wide links will be disabled for this share.\n",
10329 lp_servicename(snum) ));
10333 bool lp_widelinks(int snum)
10335 /* wide links is always incompatible with unix extensions */
10336 if (lp_unix_extensions()) {
10337 return false;
10340 return lp_widelinks_internal(snum);
10343 bool lp_writeraw(void)
10345 if (lp_async_smb_echo_handler()) {
10346 return false;
10348 return _lp_writeraw();
10351 bool lp_readraw(void)
10353 if (lp_async_smb_echo_handler()) {
10354 return false;
10356 return _lp_readraw();