WHATSNEW: Update changes.
[Samba.git] / source3 / param / loadparm.c
blobf65a9d50e95f7b5b74842223c6ef81834bb587e4
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 "printing.h"
56 #include "lib/smbconf/smbconf.h"
57 #include "lib/smbconf/smbconf_init.h"
58 #include "lib/smbconf/smbconf_reg.h"
60 #ifdef HAVE_SYS_SYSCTL_H
61 #include <sys/sysctl.h>
62 #endif
64 #ifdef HAVE_HTTPCONNECTENCRYPT
65 #include <cups/http.h>
66 #endif
68 bool bLoaded = False;
70 extern userdom_struct current_user_info;
72 #ifndef GLOBAL_NAME
73 #define GLOBAL_NAME "global"
74 #endif
76 #ifndef PRINTERS_NAME
77 #define PRINTERS_NAME "printers"
78 #endif
80 #ifndef HOMES_NAME
81 #define HOMES_NAME "homes"
82 #endif
84 /* the special value for the include parameter
85 * to be interpreted not as a file name but to
86 * trigger loading of the global smb.conf options
87 * from registry. */
88 #ifndef INCLUDE_REGISTRY_NAME
89 #define INCLUDE_REGISTRY_NAME "registry"
90 #endif
92 static bool in_client = False; /* Not in the client by default */
93 static struct smbconf_csn conf_last_csn;
95 #define CONFIG_BACKEND_FILE 0
96 #define CONFIG_BACKEND_REGISTRY 1
98 static int config_backend = CONFIG_BACKEND_FILE;
100 /* some helpful bits */
101 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
102 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
104 #define USERSHARE_VALID 1
105 #define USERSHARE_PENDING_DELETE 2
107 static bool defaults_saved = False;
109 struct param_opt_struct {
110 struct param_opt_struct *prev, *next;
111 char *key;
112 char *value;
113 char **list;
117 * This structure describes global (ie., server-wide) parameters.
119 struct global {
120 int ConfigBackend;
121 char *smb_ports;
122 char *dos_charset;
123 char *unix_charset;
124 char *display_charset;
125 char *szPrintcapname;
126 char *szAddPortCommand;
127 char *szEnumPortsCommand;
128 char *szAddPrinterCommand;
129 char *szDeletePrinterCommand;
130 char *szOs2DriverMap;
131 char *szLockDir;
132 char *szStateDir;
133 char *szCacheDir;
134 char *szPidDir;
135 char *szRootdir;
136 char *szDefaultService;
137 char *szGetQuota;
138 char *szSetQuota;
139 char *szMsgCommand;
140 char *szServerString;
141 char *szAutoServices;
142 char *szPasswdProgram;
143 char *szPasswdChat;
144 char *szLogFile;
145 char *szConfigFile;
146 char *szSMBPasswdFile;
147 char *szPrivateDir;
148 char *szPassdbBackend;
149 char **szPreloadModules;
150 char *szPasswordServer;
151 char *szSocketOptions;
152 char *szRealm;
153 char *szAfsUsernameMap;
154 int iAfsTokenLifetime;
155 char *szLogNtTokenCommand;
156 char *szUsernameMap;
157 char *szLogonScript;
158 char *szLogonPath;
159 char *szLogonDrive;
160 char *szLogonHome;
161 char **szWINSservers;
162 char **szInterfaces;
163 char *szRemoteAnnounce;
164 char *szRemoteBrowseSync;
165 char *szSocketAddress;
166 bool bNmbdBindExplicitBroadcast;
167 char *szNISHomeMapName;
168 char *szAnnounceVersion; /* This is initialised in init_globals */
169 char *szWorkgroup;
170 char *szNetbiosName;
171 char **szNetbiosAliases;
172 char *szNetbiosScope;
173 char *szNameResolveOrder;
174 char *szPanicAction;
175 char *szAddUserScript;
176 char *szRenameUserScript;
177 char *szDelUserScript;
178 char *szAddGroupScript;
179 char *szDelGroupScript;
180 char *szAddUserToGroupScript;
181 char *szDelUserFromGroupScript;
182 char *szSetPrimaryGroupScript;
183 char *szAddMachineScript;
184 char *szShutdownScript;
185 char *szAbortShutdownScript;
186 char *szUsernameMapScript;
187 int iUsernameMapCacheTime;
188 char *szCheckPasswordScript;
189 char *szWINSHook;
190 char *szUtmpDir;
191 char *szWtmpDir;
192 bool bUtmp;
193 char *szIdmapUID;
194 char *szIdmapGID;
195 bool bPassdbExpandExplicit;
196 int AlgorithmicRidBase;
197 char *szTemplateHomedir;
198 char *szTemplateShell;
199 char *szWinbindSeparator;
200 bool bWinbindEnumUsers;
201 bool bWinbindEnumGroups;
202 bool bWinbindUseDefaultDomain;
203 bool bWinbindTrustedDomainsOnly;
204 bool bWinbindNestedGroups;
205 int winbind_expand_groups;
206 bool bWinbindRefreshTickets;
207 bool bWinbindOfflineLogon;
208 bool bWinbindNormalizeNames;
209 bool bWinbindRpcOnly;
210 bool bCreateKrb5Conf;
211 char *szIdmapBackend;
212 char *szIdmapAllocBackend;
213 char *szAddShareCommand;
214 char *szChangeShareCommand;
215 char *szDeleteShareCommand;
216 char **szEventLogs;
217 char *szGuestaccount;
218 char *szManglingMethod;
219 char **szServicesList;
220 char *szUsersharePath;
221 char *szUsershareTemplateShare;
222 char **szUsersharePrefixAllowList;
223 char **szUsersharePrefixDenyList;
224 int mangle_prefix;
225 int max_log_size;
226 char *szLogLevel;
227 int max_xmit;
228 int max_mux;
229 int max_open_files;
230 int open_files_db_hash_size;
231 int pwordlevel;
232 int unamelevel;
233 int deadtime;
234 bool getwd_cache;
235 int maxprotocol;
236 int minprotocol;
237 int security;
238 char **AuthMethods;
239 bool paranoid_server_security;
240 int maxdisksize;
241 int lpqcachetime;
242 int iMaxSmbdProcesses;
243 bool bDisableSpoolss;
244 int syslog;
245 int os_level;
246 bool enhanced_browsing;
247 int max_ttl;
248 int max_wins_ttl;
249 int min_wins_ttl;
250 int lm_announce;
251 int lm_interval;
252 int announce_as; /* This is initialised in init_globals */
253 int machine_password_timeout;
254 int map_to_guest;
255 int oplock_break_wait_time;
256 int winbind_cache_time;
257 int winbind_reconnect_delay;
258 int winbind_max_idle_children;
259 char **szWinbindNssInfo;
260 int iLockSpinTime;
261 char *szLdapMachineSuffix;
262 char *szLdapUserSuffix;
263 char *szLdapIdmapSuffix;
264 char *szLdapGroupSuffix;
265 int ldap_ssl;
266 bool ldap_ssl_ads;
267 int ldap_deref;
268 int ldap_follow_referral;
269 char *szLdapSuffix;
270 char *szLdapAdminDn;
271 int ldap_debug_level;
272 int ldap_debug_threshold;
273 int iAclCompat;
274 char *szCupsServer;
275 int CupsEncrypt;
276 char *szIPrintServer;
277 char *ctdbdSocket;
278 char **szClusterAddresses;
279 bool clustering;
280 int ctdb_timeout;
281 int ctdb_locktime_warn_threshold;
282 int ldap_passwd_sync;
283 int ldap_replication_sleep;
284 int ldap_timeout; /* This is initialised in init_globals */
285 int ldap_connection_timeout;
286 int ldap_page_size;
287 bool ldap_delete_dn;
288 bool bMsAddPrinterWizard;
289 bool bDNSproxy;
290 bool bWINSsupport;
291 bool bWINSproxy;
292 bool bLocalMaster;
293 int iPreferredMaster;
294 int iDomainMaster;
295 bool bDomainLogons;
296 char **szInitLogonDelayedHosts;
297 int InitLogonDelay;
298 bool bEncryptPasswords;
299 bool bUpdateEncrypt;
300 int clientSchannel;
301 int serverSchannel;
302 bool bNullPasswords;
303 bool bObeyPamRestrictions;
304 bool bLoadPrinters;
305 int PrintcapCacheTime;
306 bool bLargeReadwrite;
307 bool bReadRaw;
308 bool bWriteRaw;
309 bool bSyslogOnly;
310 bool bBrowseList;
311 bool bNISHomeMap;
312 bool bTimeServer;
313 bool bBindInterfacesOnly;
314 bool bPamPasswordChange;
315 bool bUnixPasswdSync;
316 bool bPasswdChatDebug;
317 int iPasswdChatTimeout;
318 bool bTimestampLogs;
319 bool bNTSmbSupport;
320 bool bNTPipeSupport;
321 bool bNTStatusSupport;
322 bool bStatCache;
323 int iMaxStatCacheSize;
324 bool bKernelOplocks;
325 bool bAllowTrustedDomains;
326 bool bLanmanAuth;
327 bool bNTLMAuth;
328 bool bUseSpnego;
329 bool bClientLanManAuth;
330 bool bClientNTLMv2Auth;
331 bool bClientPlaintextAuth;
332 bool bClientUseSpnego;
333 bool bDebugPrefixTimestamp;
334 bool bDebugHiresTimestamp;
335 bool bDebugPid;
336 bool bDebugUid;
337 bool bDebugClass;
338 bool bEnableCoreFiles;
339 bool bHostMSDfs;
340 bool bUseMmap;
341 bool bHostnameLookups;
342 bool bUnixExtensions;
343 bool bDisableNetbios;
344 char * szDedicatedKeytabFile;
345 int iKerberosMethod;
346 bool bDeferSharingViolations;
347 bool bEnablePrivileges;
348 bool bASUSupport;
349 bool bUsershareOwnerOnly;
350 bool bUsershareAllowGuests;
351 bool bRegistryShares;
352 int restrict_anonymous;
353 int name_cache_timeout;
354 int client_signing;
355 int server_signing;
356 int client_ldap_sasl_wrapping;
357 int iUsershareMaxShares;
358 int iIdmapCacheTime;
359 int iIdmapNegativeCacheTime;
360 bool bResetOnZeroVC;
361 bool bLogWriteableFilesOnExit;
362 int iKeepalive;
363 int iminreceivefile;
364 struct param_opt_struct *param_opt;
365 int cups_connection_timeout;
366 char *szSMBPerfcountModule;
367 bool bMapUntrustedToDomain;
368 bool bAsyncSMBEchoHandler;
369 int ismb2_max_read;
370 int ismb2_max_write;
371 int ismb2_max_trans;
374 static struct global Globals;
377 * This structure describes a single service.
379 struct service {
380 bool valid;
381 bool autoloaded;
382 int usershare;
383 struct timespec usershare_last_mod;
384 char *szService;
385 char *szPath;
386 char *szUsername;
387 char **szInvalidUsers;
388 char **szValidUsers;
389 char **szAdminUsers;
390 char *szCopy;
391 char *szInclude;
392 char *szPreExec;
393 char *szPostExec;
394 char *szRootPreExec;
395 char *szRootPostExec;
396 char *szCupsOptions;
397 char *szPrintcommand;
398 char *szLpqcommand;
399 char *szLprmcommand;
400 char *szLppausecommand;
401 char *szLpresumecommand;
402 char *szQueuepausecommand;
403 char *szQueueresumecommand;
404 char *szPrintername;
405 char *szPrintjobUsername;
406 char *szDontdescend;
407 char **szHostsallow;
408 char **szHostsdeny;
409 char *szMagicScript;
410 char *szMagicOutput;
411 char *szVetoFiles;
412 char *szHideFiles;
413 char *szVetoOplockFiles;
414 char *comment;
415 char *force_user;
416 char *force_group;
417 char **readlist;
418 char **writelist;
419 char **printer_admin;
420 char *volume;
421 char *fstype;
422 char **szVfsObjects;
423 char *szMSDfsProxy;
424 char *szAioWriteBehind;
425 char *szDfree;
426 int iMinPrintSpace;
427 int iMaxPrintJobs;
428 int iMaxReportedPrintJobs;
429 int iWriteCacheSize;
430 int iCreate_mask;
431 int iCreate_force_mode;
432 int iSecurity_mask;
433 int iSecurity_force_mode;
434 int iDir_mask;
435 int iDir_force_mode;
436 int iDir_Security_mask;
437 int iDir_Security_force_mode;
438 int iMaxConnections;
439 int iDefaultCase;
440 int iPrinting;
441 int iOplockContentionLimit;
442 int iCSCPolicy;
443 int iBlock_size;
444 int iDfreeCacheTime;
445 bool bPreexecClose;
446 bool bRootpreexecClose;
447 int iCaseSensitive;
448 bool bCasePreserve;
449 bool bShortCasePreserve;
450 bool bHideDotFiles;
451 bool bHideSpecialFiles;
452 bool bHideUnReadable;
453 bool bHideUnWriteableFiles;
454 bool bBrowseable;
455 bool bAccessBasedShareEnum;
456 bool bAvailable;
457 bool bRead_only;
458 bool bNo_set_dir;
459 bool bGuest_only;
460 bool bAdministrative_share;
461 bool bGuest_ok;
462 bool bPrint_ok;
463 bool bMap_system;
464 bool bMap_hidden;
465 bool bMap_archive;
466 bool bStoreDosAttributes;
467 bool bDmapiSupport;
468 bool bLocking;
469 int iStrictLocking;
470 bool bPosixLocking;
471 bool bShareModes;
472 bool bOpLocks;
473 bool bLevel2OpLocks;
474 bool bOnlyUser;
475 bool bMangledNames;
476 bool bWidelinks;
477 bool bSymlinks;
478 bool bSyncAlways;
479 bool bStrictAllocate;
480 bool bStrictSync;
481 char magic_char;
482 struct bitmap *copymap;
483 bool bDeleteReadonly;
484 bool bFakeOplocks;
485 bool bDeleteVetoFiles;
486 bool bDosFilemode;
487 bool bDosFiletimes;
488 bool bDosFiletimeResolution;
489 bool bFakeDirCreateTimes;
490 bool bBlockingLocks;
491 bool bInheritPerms;
492 bool bInheritACLS;
493 bool bInheritOwner;
494 bool bMSDfsRoot;
495 bool bUseClientDriver;
496 bool bDefaultDevmode;
497 bool bForcePrintername;
498 bool bNTAclSupport;
499 bool bForceUnknownAclUser;
500 bool bUseSendfile;
501 bool bProfileAcls;
502 bool bMap_acl_inherit;
503 bool bAfs_Share;
504 bool bEASupport;
505 bool bAclCheckPermissions;
506 bool bAclMapFullControl;
507 bool bAclGroupControl;
508 bool bChangeNotify;
509 bool bKernelChangeNotify;
510 int iallocation_roundup_size;
511 int iAioReadSize;
512 int iAioWriteSize;
513 int iMap_readonly;
514 int iDirectoryNameCacheSize;
515 int ismb_encrypt;
516 struct param_opt_struct *param_opt;
518 char dummy[3]; /* for alignment */
522 /* This is a default service used to prime a services structure */
523 static struct service sDefault = {
524 True, /* valid */
525 False, /* not autoloaded */
526 0, /* not a usershare */
527 {0, }, /* No last mod time */
528 NULL, /* szService */
529 NULL, /* szPath */
530 NULL, /* szUsername */
531 NULL, /* szInvalidUsers */
532 NULL, /* szValidUsers */
533 NULL, /* szAdminUsers */
534 NULL, /* szCopy */
535 NULL, /* szInclude */
536 NULL, /* szPreExec */
537 NULL, /* szPostExec */
538 NULL, /* szRootPreExec */
539 NULL, /* szRootPostExec */
540 NULL, /* szCupsOptions */
541 NULL, /* szPrintcommand */
542 NULL, /* szLpqcommand */
543 NULL, /* szLprmcommand */
544 NULL, /* szLppausecommand */
545 NULL, /* szLpresumecommand */
546 NULL, /* szQueuepausecommand */
547 NULL, /* szQueueresumecommand */
548 NULL, /* szPrintername */
549 NULL, /* szPrintjobUsername */
550 NULL, /* szDontdescend */
551 NULL, /* szHostsallow */
552 NULL, /* szHostsdeny */
553 NULL, /* szMagicScript */
554 NULL, /* szMagicOutput */
555 NULL, /* szVetoFiles */
556 NULL, /* szHideFiles */
557 NULL, /* szVetoOplockFiles */
558 NULL, /* comment */
559 NULL, /* force user */
560 NULL, /* force group */
561 NULL, /* readlist */
562 NULL, /* writelist */
563 NULL, /* printer admin */
564 NULL, /* volume */
565 NULL, /* fstype */
566 NULL, /* vfs objects */
567 NULL, /* szMSDfsProxy */
568 NULL, /* szAioWriteBehind */
569 NULL, /* szDfree */
570 0, /* iMinPrintSpace */
571 1000, /* iMaxPrintJobs */
572 0, /* iMaxReportedPrintJobs */
573 0, /* iWriteCacheSize */
574 0744, /* iCreate_mask */
575 0000, /* iCreate_force_mode */
576 0777, /* iSecurity_mask */
577 0, /* iSecurity_force_mode */
578 0755, /* iDir_mask */
579 0000, /* iDir_force_mode */
580 0777, /* iDir_Security_mask */
581 0, /* iDir_Security_force_mode */
582 0, /* iMaxConnections */
583 CASE_LOWER, /* iDefaultCase */
584 DEFAULT_PRINTING, /* iPrinting */
585 2, /* iOplockContentionLimit */
586 0, /* iCSCPolicy */
587 1024, /* iBlock_size */
588 0, /* iDfreeCacheTime */
589 False, /* bPreexecClose */
590 False, /* bRootpreexecClose */
591 Auto, /* case sensitive */
592 True, /* case preserve */
593 True, /* short case preserve */
594 True, /* bHideDotFiles */
595 False, /* bHideSpecialFiles */
596 False, /* bHideUnReadable */
597 False, /* bHideUnWriteableFiles */
598 True, /* bBrowseable */
599 False, /* bAccessBasedShareEnum */
600 True, /* bAvailable */
601 True, /* bRead_only */
602 True, /* bNo_set_dir */
603 False, /* bGuest_only */
604 False, /* bAdministrative_share */
605 False, /* bGuest_ok */
606 False, /* bPrint_ok */
607 False, /* bMap_system */
608 False, /* bMap_hidden */
609 True, /* bMap_archive */
610 False, /* bStoreDosAttributes */
611 False, /* bDmapiSupport */
612 True, /* bLocking */
613 Auto, /* iStrictLocking */
614 True, /* bPosixLocking */
615 True, /* bShareModes */
616 True, /* bOpLocks */
617 True, /* bLevel2OpLocks */
618 False, /* bOnlyUser */
619 True, /* bMangledNames */
620 false, /* bWidelinks */
621 True, /* bSymlinks */
622 False, /* bSyncAlways */
623 False, /* bStrictAllocate */
624 False, /* bStrictSync */
625 '~', /* magic char */
626 NULL, /* copymap */
627 False, /* bDeleteReadonly */
628 False, /* bFakeOplocks */
629 False, /* bDeleteVetoFiles */
630 False, /* bDosFilemode */
631 True, /* bDosFiletimes */
632 False, /* bDosFiletimeResolution */
633 False, /* bFakeDirCreateTimes */
634 True, /* bBlockingLocks */
635 False, /* bInheritPerms */
636 False, /* bInheritACLS */
637 False, /* bInheritOwner */
638 False, /* bMSDfsRoot */
639 False, /* bUseClientDriver */
640 True, /* bDefaultDevmode */
641 False, /* bForcePrintername */
642 True, /* bNTAclSupport */
643 False, /* bForceUnknownAclUser */
644 False, /* bUseSendfile */
645 False, /* bProfileAcls */
646 False, /* bMap_acl_inherit */
647 False, /* bAfs_Share */
648 False, /* bEASupport */
649 True, /* bAclCheckPermissions */
650 True, /* bAclMapFullControl */
651 False, /* bAclGroupControl */
652 True, /* bChangeNotify */
653 True, /* bKernelChangeNotify */
654 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
655 0, /* iAioReadSize */
656 0, /* iAioWriteSize */
657 MAP_READONLY_YES, /* iMap_readonly */
658 #ifdef BROKEN_DIRECTORY_HANDLING
659 0, /* iDirectoryNameCacheSize */
660 #else
661 100, /* iDirectoryNameCacheSize */
662 #endif
663 Auto, /* ismb_encrypt */
664 NULL, /* Parametric options */
666 "" /* dummy */
669 /* local variables */
670 static struct service **ServicePtrs = NULL;
671 static int iNumServices = 0;
672 static int iServiceIndex = 0;
673 static struct db_context *ServiceHash;
674 static int *invalid_services = NULL;
675 static int num_invalid_services = 0;
676 static bool bInGlobalSection = True;
677 static bool bGlobalOnly = False;
678 static int default_server_announce;
680 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
682 /* prototypes for the special type handlers */
683 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
684 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
685 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
686 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
687 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
688 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
689 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
690 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
691 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
692 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
693 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
694 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
696 static void set_default_server_announce_type(void);
697 static void set_allowed_client_auth(void);
699 static void *lp_local_ptr(struct service *service, void *ptr);
701 static void add_to_file_list(const char *fname, const char *subfname);
703 static const struct enum_list enum_protocol[] = {
704 {PROTOCOL_SMB2, "SMB2"},
705 {PROTOCOL_NT1, "NT1"},
706 {PROTOCOL_LANMAN2, "LANMAN2"},
707 {PROTOCOL_LANMAN1, "LANMAN1"},
708 {PROTOCOL_CORE, "CORE"},
709 {PROTOCOL_COREPLUS, "COREPLUS"},
710 {PROTOCOL_COREPLUS, "CORE+"},
711 {-1, NULL}
714 static const struct enum_list enum_security[] = {
715 {SEC_SHARE, "SHARE"},
716 {SEC_USER, "USER"},
717 {SEC_SERVER, "SERVER"},
718 {SEC_DOMAIN, "DOMAIN"},
719 #ifdef HAVE_ADS
720 {SEC_ADS, "ADS"},
721 #endif
722 {-1, NULL}
725 static const struct enum_list enum_printing[] = {
726 {PRINT_SYSV, "sysv"},
727 {PRINT_AIX, "aix"},
728 {PRINT_HPUX, "hpux"},
729 {PRINT_BSD, "bsd"},
730 {PRINT_QNX, "qnx"},
731 {PRINT_PLP, "plp"},
732 {PRINT_LPRNG, "lprng"},
733 {PRINT_CUPS, "cups"},
734 {PRINT_IPRINT, "iprint"},
735 {PRINT_LPRNT, "nt"},
736 {PRINT_LPROS2, "os2"},
737 #ifdef DEVELOPER
738 {PRINT_TEST, "test"},
739 {PRINT_VLP, "vlp"},
740 #endif /* DEVELOPER */
741 {-1, NULL}
744 static const struct enum_list enum_ldap_sasl_wrapping[] = {
745 {0, "plain"},
746 {ADS_AUTH_SASL_SIGN, "sign"},
747 {ADS_AUTH_SASL_SEAL, "seal"},
748 {-1, NULL}
751 static const struct enum_list enum_ldap_ssl[] = {
752 {LDAP_SSL_OFF, "no"},
753 {LDAP_SSL_OFF, "off"},
754 {LDAP_SSL_START_TLS, "start tls"},
755 {LDAP_SSL_START_TLS, "start_tls"},
756 {-1, NULL}
759 /* LDAP Dereferencing Alias types */
760 #define SAMBA_LDAP_DEREF_NEVER 0
761 #define SAMBA_LDAP_DEREF_SEARCHING 1
762 #define SAMBA_LDAP_DEREF_FINDING 2
763 #define SAMBA_LDAP_DEREF_ALWAYS 3
765 static const struct enum_list enum_ldap_deref[] = {
766 {SAMBA_LDAP_DEREF_NEVER, "never"},
767 {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
768 {SAMBA_LDAP_DEREF_FINDING, "finding"},
769 {SAMBA_LDAP_DEREF_ALWAYS, "always"},
770 {-1, "auto"}
773 static const struct enum_list enum_ldap_passwd_sync[] = {
774 {LDAP_PASSWD_SYNC_OFF, "no"},
775 {LDAP_PASSWD_SYNC_OFF, "off"},
776 {LDAP_PASSWD_SYNC_ON, "yes"},
777 {LDAP_PASSWD_SYNC_ON, "on"},
778 {LDAP_PASSWD_SYNC_ONLY, "only"},
779 {-1, NULL}
782 /* Types of machine we can announce as. */
783 #define ANNOUNCE_AS_NT_SERVER 1
784 #define ANNOUNCE_AS_WIN95 2
785 #define ANNOUNCE_AS_WFW 3
786 #define ANNOUNCE_AS_NT_WORKSTATION 4
788 static const struct enum_list enum_announce_as[] = {
789 {ANNOUNCE_AS_NT_SERVER, "NT"},
790 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
791 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
792 {ANNOUNCE_AS_WIN95, "win95"},
793 {ANNOUNCE_AS_WFW, "WfW"},
794 {-1, NULL}
797 static const struct enum_list enum_map_readonly[] = {
798 {MAP_READONLY_NO, "no"},
799 {MAP_READONLY_NO, "false"},
800 {MAP_READONLY_NO, "0"},
801 {MAP_READONLY_YES, "yes"},
802 {MAP_READONLY_YES, "true"},
803 {MAP_READONLY_YES, "1"},
804 {MAP_READONLY_PERMISSIONS, "permissions"},
805 {MAP_READONLY_PERMISSIONS, "perms"},
806 {-1, NULL}
809 static const struct enum_list enum_case[] = {
810 {CASE_LOWER, "lower"},
811 {CASE_UPPER, "upper"},
812 {-1, NULL}
817 static const struct enum_list enum_bool_auto[] = {
818 {False, "No"},
819 {False, "False"},
820 {False, "0"},
821 {True, "Yes"},
822 {True, "True"},
823 {True, "1"},
824 {Auto, "Auto"},
825 {-1, NULL}
828 static const struct enum_list enum_csc_policy[] = {
829 {CSC_POLICY_MANUAL, "manual"},
830 {CSC_POLICY_DOCUMENTS, "documents"},
831 {CSC_POLICY_PROGRAMS, "programs"},
832 {CSC_POLICY_DISABLE, "disable"},
833 {-1, NULL}
836 /* SMB signing types. */
837 static const struct enum_list enum_smb_signing_vals[] = {
838 {False, "No"},
839 {False, "False"},
840 {False, "0"},
841 {False, "Off"},
842 {False, "disabled"},
843 {True, "Yes"},
844 {True, "True"},
845 {True, "1"},
846 {True, "On"},
847 {True, "enabled"},
848 {Auto, "auto"},
849 {Required, "required"},
850 {Required, "mandatory"},
851 {Required, "force"},
852 {Required, "forced"},
853 {Required, "enforced"},
854 {-1, NULL}
857 /* ACL compatibility options. */
858 static const struct enum_list enum_acl_compat_vals[] = {
859 { ACL_COMPAT_AUTO, "auto" },
860 { ACL_COMPAT_WINNT, "winnt" },
861 { ACL_COMPAT_WIN2K, "win2k" },
862 { -1, NULL}
866 Do you want session setups at user level security with a invalid
867 password to be rejected or allowed in as guest? WinNT rejects them
868 but it can be a pain as it means "net view" needs to use a password
870 You have 3 choices in the setting of map_to_guest:
872 "Never" means session setups with an invalid password
873 are rejected. This is the default.
875 "Bad User" means session setups with an invalid password
876 are rejected, unless the username does not exist, in which case it
877 is treated as a guest login
879 "Bad Password" means session setups with an invalid password
880 are treated as a guest login
882 Note that map_to_guest only has an effect in user or server
883 level security.
886 static const struct enum_list enum_map_to_guest[] = {
887 {NEVER_MAP_TO_GUEST, "Never"},
888 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
889 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
890 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
891 {-1, NULL}
894 /* Config backend options */
896 static const struct enum_list enum_config_backend[] = {
897 {CONFIG_BACKEND_FILE, "file"},
898 {CONFIG_BACKEND_REGISTRY, "registry"},
899 {-1, NULL}
902 /* ADS kerberos ticket verification options */
904 static const struct enum_list enum_kerberos_method[] = {
905 {KERBEROS_VERIFY_SECRETS, "default"},
906 {KERBEROS_VERIFY_SECRETS, "secrets only"},
907 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
908 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
909 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
910 {-1, NULL}
913 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
915 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
916 * screen in SWAT. This is used to exclude parameters as well as to squash all
917 * parameters that have been duplicated by pseudonyms.
919 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
920 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
921 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
922 * respective views.
924 * NOTE2: Handling of duplicated (synonym) parameters:
925 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
926 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
927 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
928 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
931 static struct parm_struct parm_table[] = {
932 {N_("Base Options"), P_SEP, P_SEPARATOR},
935 .label = "dos charset",
936 .type = P_STRING,
937 .p_class = P_GLOBAL,
938 .ptr = &Globals.dos_charset,
939 .special = handle_charset,
940 .enum_list = NULL,
941 .flags = FLAG_ADVANCED
944 .label = "unix charset",
945 .type = P_STRING,
946 .p_class = P_GLOBAL,
947 .ptr = &Globals.unix_charset,
948 .special = handle_charset,
949 .enum_list = NULL,
950 .flags = FLAG_ADVANCED
953 .label = "display charset",
954 .type = P_STRING,
955 .p_class = P_GLOBAL,
956 .ptr = &Globals.display_charset,
957 .special = handle_charset,
958 .enum_list = NULL,
959 .flags = FLAG_ADVANCED
962 .label = "comment",
963 .type = P_STRING,
964 .p_class = P_LOCAL,
965 .ptr = &sDefault.comment,
966 .special = NULL,
967 .enum_list = NULL,
968 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
971 .label = "path",
972 .type = P_STRING,
973 .p_class = P_LOCAL,
974 .ptr = &sDefault.szPath,
975 .special = NULL,
976 .enum_list = NULL,
977 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
980 .label = "directory",
981 .type = P_STRING,
982 .p_class = P_LOCAL,
983 .ptr = &sDefault.szPath,
984 .special = NULL,
985 .enum_list = NULL,
986 .flags = FLAG_HIDE,
989 .label = "workgroup",
990 .type = P_USTRING,
991 .p_class = P_GLOBAL,
992 .ptr = &Globals.szWorkgroup,
993 .special = handle_workgroup,
994 .enum_list = NULL,
995 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
997 #ifdef WITH_ADS
999 .label = "realm",
1000 .type = P_USTRING,
1001 .p_class = P_GLOBAL,
1002 .ptr = &Globals.szRealm,
1003 .special = NULL,
1004 .enum_list = NULL,
1005 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1007 #endif
1009 .label = "netbios name",
1010 .type = P_USTRING,
1011 .p_class = P_GLOBAL,
1012 .ptr = &Globals.szNetbiosName,
1013 .special = handle_netbios_name,
1014 .enum_list = NULL,
1015 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1018 .label = "netbios aliases",
1019 .type = P_LIST,
1020 .p_class = P_GLOBAL,
1021 .ptr = &Globals.szNetbiosAliases,
1022 .special = handle_netbios_aliases,
1023 .enum_list = NULL,
1024 .flags = FLAG_ADVANCED,
1027 .label = "netbios scope",
1028 .type = P_USTRING,
1029 .p_class = P_GLOBAL,
1030 .ptr = &Globals.szNetbiosScope,
1031 .special = handle_netbios_scope,
1032 .enum_list = NULL,
1033 .flags = FLAG_ADVANCED,
1036 .label = "server string",
1037 .type = P_STRING,
1038 .p_class = P_GLOBAL,
1039 .ptr = &Globals.szServerString,
1040 .special = NULL,
1041 .enum_list = NULL,
1042 .flags = FLAG_BASIC | FLAG_ADVANCED,
1045 .label = "interfaces",
1046 .type = P_LIST,
1047 .p_class = P_GLOBAL,
1048 .ptr = &Globals.szInterfaces,
1049 .special = NULL,
1050 .enum_list = NULL,
1051 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1054 .label = "bind interfaces only",
1055 .type = P_BOOL,
1056 .p_class = P_GLOBAL,
1057 .ptr = &Globals.bBindInterfacesOnly,
1058 .special = NULL,
1059 .enum_list = NULL,
1060 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1063 .label = "config backend",
1064 .type = P_ENUM,
1065 .p_class = P_GLOBAL,
1066 .ptr = &Globals.ConfigBackend,
1067 .special = NULL,
1068 .enum_list = enum_config_backend,
1069 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1072 {N_("Security Options"), P_SEP, P_SEPARATOR},
1075 .label = "security",
1076 .type = P_ENUM,
1077 .p_class = P_GLOBAL,
1078 .ptr = &Globals.security,
1079 .special = NULL,
1080 .enum_list = enum_security,
1081 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1084 .label = "auth methods",
1085 .type = P_LIST,
1086 .p_class = P_GLOBAL,
1087 .ptr = &Globals.AuthMethods,
1088 .special = NULL,
1089 .enum_list = NULL,
1090 .flags = FLAG_ADVANCED,
1093 .label = "encrypt passwords",
1094 .type = P_BOOL,
1095 .p_class = P_GLOBAL,
1096 .ptr = &Globals.bEncryptPasswords,
1097 .special = NULL,
1098 .enum_list = NULL,
1099 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1102 .label = "update encrypted",
1103 .type = P_BOOL,
1104 .p_class = P_GLOBAL,
1105 .ptr = &Globals.bUpdateEncrypt,
1106 .special = NULL,
1107 .enum_list = NULL,
1108 .flags = FLAG_ADVANCED,
1111 .label = "client schannel",
1112 .type = P_ENUM,
1113 .p_class = P_GLOBAL,
1114 .ptr = &Globals.clientSchannel,
1115 .special = NULL,
1116 .enum_list = enum_bool_auto,
1117 .flags = FLAG_BASIC | FLAG_ADVANCED,
1120 .label = "server schannel",
1121 .type = P_ENUM,
1122 .p_class = P_GLOBAL,
1123 .ptr = &Globals.serverSchannel,
1124 .special = NULL,
1125 .enum_list = enum_bool_auto,
1126 .flags = FLAG_BASIC | FLAG_ADVANCED,
1129 .label = "allow trusted domains",
1130 .type = P_BOOL,
1131 .p_class = P_GLOBAL,
1132 .ptr = &Globals.bAllowTrustedDomains,
1133 .special = NULL,
1134 .enum_list = NULL,
1135 .flags = FLAG_ADVANCED,
1138 .label = "map to guest",
1139 .type = P_ENUM,
1140 .p_class = P_GLOBAL,
1141 .ptr = &Globals.map_to_guest,
1142 .special = NULL,
1143 .enum_list = enum_map_to_guest,
1144 .flags = FLAG_ADVANCED,
1147 .label = "null passwords",
1148 .type = P_BOOL,
1149 .p_class = P_GLOBAL,
1150 .ptr = &Globals.bNullPasswords,
1151 .special = NULL,
1152 .enum_list = NULL,
1153 .flags = FLAG_ADVANCED,
1156 .label = "obey pam restrictions",
1157 .type = P_BOOL,
1158 .p_class = P_GLOBAL,
1159 .ptr = &Globals.bObeyPamRestrictions,
1160 .special = NULL,
1161 .enum_list = NULL,
1162 .flags = FLAG_ADVANCED,
1165 .label = "password server",
1166 .type = P_STRING,
1167 .p_class = P_GLOBAL,
1168 .ptr = &Globals.szPasswordServer,
1169 .special = NULL,
1170 .enum_list = NULL,
1171 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1174 .label = "smb passwd file",
1175 .type = P_STRING,
1176 .p_class = P_GLOBAL,
1177 .ptr = &Globals.szSMBPasswdFile,
1178 .special = NULL,
1179 .enum_list = NULL,
1180 .flags = FLAG_ADVANCED,
1183 .label = "private dir",
1184 .type = P_STRING,
1185 .p_class = P_GLOBAL,
1186 .ptr = &Globals.szPrivateDir,
1187 .special = NULL,
1188 .enum_list = NULL,
1189 .flags = FLAG_ADVANCED,
1192 .label = "passdb backend",
1193 .type = P_STRING,
1194 .p_class = P_GLOBAL,
1195 .ptr = &Globals.szPassdbBackend,
1196 .special = NULL,
1197 .enum_list = NULL,
1198 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1201 .label = "algorithmic rid base",
1202 .type = P_INTEGER,
1203 .p_class = P_GLOBAL,
1204 .ptr = &Globals.AlgorithmicRidBase,
1205 .special = NULL,
1206 .enum_list = NULL,
1207 .flags = FLAG_ADVANCED,
1210 .label = "root directory",
1211 .type = P_STRING,
1212 .p_class = P_GLOBAL,
1213 .ptr = &Globals.szRootdir,
1214 .special = NULL,
1215 .enum_list = NULL,
1216 .flags = FLAG_ADVANCED,
1219 .label = "root dir",
1220 .type = P_STRING,
1221 .p_class = P_GLOBAL,
1222 .ptr = &Globals.szRootdir,
1223 .special = NULL,
1224 .enum_list = NULL,
1225 .flags = FLAG_HIDE,
1228 .label = "root",
1229 .type = P_STRING,
1230 .p_class = P_GLOBAL,
1231 .ptr = &Globals.szRootdir,
1232 .special = NULL,
1233 .enum_list = NULL,
1234 .flags = FLAG_HIDE,
1237 .label = "guest account",
1238 .type = P_STRING,
1239 .p_class = P_GLOBAL,
1240 .ptr = &Globals.szGuestaccount,
1241 .special = NULL,
1242 .enum_list = NULL,
1243 .flags = FLAG_BASIC | FLAG_ADVANCED,
1246 .label = "enable privileges",
1247 .type = P_BOOL,
1248 .p_class = P_GLOBAL,
1249 .ptr = &Globals.bEnablePrivileges,
1250 .special = NULL,
1251 .enum_list = NULL,
1252 .flags = FLAG_ADVANCED,
1256 .label = "pam password change",
1257 .type = P_BOOL,
1258 .p_class = P_GLOBAL,
1259 .ptr = &Globals.bPamPasswordChange,
1260 .special = NULL,
1261 .enum_list = NULL,
1262 .flags = FLAG_ADVANCED,
1265 .label = "passwd program",
1266 .type = P_STRING,
1267 .p_class = P_GLOBAL,
1268 .ptr = &Globals.szPasswdProgram,
1269 .special = NULL,
1270 .enum_list = NULL,
1271 .flags = FLAG_ADVANCED,
1274 .label = "passwd chat",
1275 .type = P_STRING,
1276 .p_class = P_GLOBAL,
1277 .ptr = &Globals.szPasswdChat,
1278 .special = NULL,
1279 .enum_list = NULL,
1280 .flags = FLAG_ADVANCED,
1283 .label = "passwd chat debug",
1284 .type = P_BOOL,
1285 .p_class = P_GLOBAL,
1286 .ptr = &Globals.bPasswdChatDebug,
1287 .special = NULL,
1288 .enum_list = NULL,
1289 .flags = FLAG_ADVANCED,
1292 .label = "passwd chat timeout",
1293 .type = P_INTEGER,
1294 .p_class = P_GLOBAL,
1295 .ptr = &Globals.iPasswdChatTimeout,
1296 .special = NULL,
1297 .enum_list = NULL,
1298 .flags = FLAG_ADVANCED,
1301 .label = "check password script",
1302 .type = P_STRING,
1303 .p_class = P_GLOBAL,
1304 .ptr = &Globals.szCheckPasswordScript,
1305 .special = NULL,
1306 .enum_list = NULL,
1307 .flags = FLAG_ADVANCED,
1310 .label = "username map",
1311 .type = P_STRING,
1312 .p_class = P_GLOBAL,
1313 .ptr = &Globals.szUsernameMap,
1314 .special = NULL,
1315 .enum_list = NULL,
1316 .flags = FLAG_ADVANCED,
1319 .label = "password level",
1320 .type = P_INTEGER,
1321 .p_class = P_GLOBAL,
1322 .ptr = &Globals.pwordlevel,
1323 .special = NULL,
1324 .enum_list = NULL,
1325 .flags = FLAG_ADVANCED,
1328 .label = "username level",
1329 .type = P_INTEGER,
1330 .p_class = P_GLOBAL,
1331 .ptr = &Globals.unamelevel,
1332 .special = NULL,
1333 .enum_list = NULL,
1334 .flags = FLAG_ADVANCED,
1337 .label = "unix password sync",
1338 .type = P_BOOL,
1339 .p_class = P_GLOBAL,
1340 .ptr = &Globals.bUnixPasswdSync,
1341 .special = NULL,
1342 .enum_list = NULL,
1343 .flags = FLAG_ADVANCED,
1346 .label = "restrict anonymous",
1347 .type = P_INTEGER,
1348 .p_class = P_GLOBAL,
1349 .ptr = &Globals.restrict_anonymous,
1350 .special = NULL,
1351 .enum_list = NULL,
1352 .flags = FLAG_ADVANCED,
1355 .label = "lanman auth",
1356 .type = P_BOOL,
1357 .p_class = P_GLOBAL,
1358 .ptr = &Globals.bLanmanAuth,
1359 .special = NULL,
1360 .enum_list = NULL,
1361 .flags = FLAG_ADVANCED,
1364 .label = "ntlm auth",
1365 .type = P_BOOL,
1366 .p_class = P_GLOBAL,
1367 .ptr = &Globals.bNTLMAuth,
1368 .special = NULL,
1369 .enum_list = NULL,
1370 .flags = FLAG_ADVANCED,
1373 .label = "client NTLMv2 auth",
1374 .type = P_BOOL,
1375 .p_class = P_GLOBAL,
1376 .ptr = &Globals.bClientNTLMv2Auth,
1377 .special = NULL,
1378 .enum_list = NULL,
1379 .flags = FLAG_ADVANCED,
1382 .label = "client lanman auth",
1383 .type = P_BOOL,
1384 .p_class = P_GLOBAL,
1385 .ptr = &Globals.bClientLanManAuth,
1386 .special = NULL,
1387 .enum_list = NULL,
1388 .flags = FLAG_ADVANCED,
1391 .label = "client plaintext auth",
1392 .type = P_BOOL,
1393 .p_class = P_GLOBAL,
1394 .ptr = &Globals.bClientPlaintextAuth,
1395 .special = NULL,
1396 .enum_list = NULL,
1397 .flags = FLAG_ADVANCED,
1400 .label = "username",
1401 .type = P_STRING,
1402 .p_class = P_LOCAL,
1403 .ptr = &sDefault.szUsername,
1404 .special = NULL,
1405 .enum_list = NULL,
1406 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1409 .label = "user",
1410 .type = P_STRING,
1411 .p_class = P_LOCAL,
1412 .ptr = &sDefault.szUsername,
1413 .special = NULL,
1414 .enum_list = NULL,
1415 .flags = FLAG_HIDE,
1418 .label = "users",
1419 .type = P_STRING,
1420 .p_class = P_LOCAL,
1421 .ptr = &sDefault.szUsername,
1422 .special = NULL,
1423 .enum_list = NULL,
1424 .flags = FLAG_HIDE,
1427 .label = "invalid users",
1428 .type = P_LIST,
1429 .p_class = P_LOCAL,
1430 .ptr = &sDefault.szInvalidUsers,
1431 .special = NULL,
1432 .enum_list = NULL,
1433 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1436 .label = "valid users",
1437 .type = P_LIST,
1438 .p_class = P_LOCAL,
1439 .ptr = &sDefault.szValidUsers,
1440 .special = NULL,
1441 .enum_list = NULL,
1442 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1445 .label = "admin users",
1446 .type = P_LIST,
1447 .p_class = P_LOCAL,
1448 .ptr = &sDefault.szAdminUsers,
1449 .special = NULL,
1450 .enum_list = NULL,
1451 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1454 .label = "read list",
1455 .type = P_LIST,
1456 .p_class = P_LOCAL,
1457 .ptr = &sDefault.readlist,
1458 .special = NULL,
1459 .enum_list = NULL,
1460 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1463 .label = "write list",
1464 .type = P_LIST,
1465 .p_class = P_LOCAL,
1466 .ptr = &sDefault.writelist,
1467 .special = NULL,
1468 .enum_list = NULL,
1469 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1472 .label = "printer admin",
1473 .type = P_LIST,
1474 .p_class = P_LOCAL,
1475 .ptr = &sDefault.printer_admin,
1476 .special = NULL,
1477 .enum_list = NULL,
1478 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1481 .label = "force user",
1482 .type = P_STRING,
1483 .p_class = P_LOCAL,
1484 .ptr = &sDefault.force_user,
1485 .special = NULL,
1486 .enum_list = NULL,
1487 .flags = FLAG_ADVANCED | FLAG_SHARE,
1490 .label = "force group",
1491 .type = P_STRING,
1492 .p_class = P_LOCAL,
1493 .ptr = &sDefault.force_group,
1494 .special = NULL,
1495 .enum_list = NULL,
1496 .flags = FLAG_ADVANCED | FLAG_SHARE,
1499 .label = "group",
1500 .type = P_STRING,
1501 .p_class = P_LOCAL,
1502 .ptr = &sDefault.force_group,
1503 .special = NULL,
1504 .enum_list = NULL,
1505 .flags = FLAG_ADVANCED,
1508 .label = "read only",
1509 .type = P_BOOL,
1510 .p_class = P_LOCAL,
1511 .ptr = &sDefault.bRead_only,
1512 .special = NULL,
1513 .enum_list = NULL,
1514 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1517 .label = "write ok",
1518 .type = P_BOOLREV,
1519 .p_class = P_LOCAL,
1520 .ptr = &sDefault.bRead_only,
1521 .special = NULL,
1522 .enum_list = NULL,
1523 .flags = FLAG_HIDE,
1526 .label = "writeable",
1527 .type = P_BOOLREV,
1528 .p_class = P_LOCAL,
1529 .ptr = &sDefault.bRead_only,
1530 .special = NULL,
1531 .enum_list = NULL,
1532 .flags = FLAG_HIDE,
1535 .label = "writable",
1536 .type = P_BOOLREV,
1537 .p_class = P_LOCAL,
1538 .ptr = &sDefault.bRead_only,
1539 .special = NULL,
1540 .enum_list = NULL,
1541 .flags = FLAG_HIDE,
1544 .label = "acl check permissions",
1545 .type = P_BOOL,
1546 .p_class = P_LOCAL,
1547 .ptr = &sDefault.bAclCheckPermissions,
1548 .special = NULL,
1549 .enum_list = NULL,
1550 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1553 .label = "acl group control",
1554 .type = P_BOOL,
1555 .p_class = P_LOCAL,
1556 .ptr = &sDefault.bAclGroupControl,
1557 .special = NULL,
1558 .enum_list = NULL,
1559 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1562 .label = "acl map full control",
1563 .type = P_BOOL,
1564 .p_class = P_LOCAL,
1565 .ptr = &sDefault.bAclMapFullControl,
1566 .special = NULL,
1567 .enum_list = NULL,
1568 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1571 .label = "create mask",
1572 .type = P_OCTAL,
1573 .p_class = P_LOCAL,
1574 .ptr = &sDefault.iCreate_mask,
1575 .special = NULL,
1576 .enum_list = NULL,
1577 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1580 .label = "create mode",
1581 .type = P_OCTAL,
1582 .p_class = P_LOCAL,
1583 .ptr = &sDefault.iCreate_mask,
1584 .special = NULL,
1585 .enum_list = NULL,
1586 .flags = FLAG_HIDE,
1589 .label = "force create mode",
1590 .type = P_OCTAL,
1591 .p_class = P_LOCAL,
1592 .ptr = &sDefault.iCreate_force_mode,
1593 .special = NULL,
1594 .enum_list = NULL,
1595 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1598 .label = "security mask",
1599 .type = P_OCTAL,
1600 .p_class = P_LOCAL,
1601 .ptr = &sDefault.iSecurity_mask,
1602 .special = NULL,
1603 .enum_list = NULL,
1604 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1607 .label = "force security mode",
1608 .type = P_OCTAL,
1609 .p_class = P_LOCAL,
1610 .ptr = &sDefault.iSecurity_force_mode,
1611 .special = NULL,
1612 .enum_list = NULL,
1613 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1616 .label = "directory mask",
1617 .type = P_OCTAL,
1618 .p_class = P_LOCAL,
1619 .ptr = &sDefault.iDir_mask,
1620 .special = NULL,
1621 .enum_list = NULL,
1622 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1625 .label = "directory mode",
1626 .type = P_OCTAL,
1627 .p_class = P_LOCAL,
1628 .ptr = &sDefault.iDir_mask,
1629 .special = NULL,
1630 .enum_list = NULL,
1631 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1634 .label = "force directory mode",
1635 .type = P_OCTAL,
1636 .p_class = P_LOCAL,
1637 .ptr = &sDefault.iDir_force_mode,
1638 .special = NULL,
1639 .enum_list = NULL,
1640 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1643 .label = "directory security mask",
1644 .type = P_OCTAL,
1645 .p_class = P_LOCAL,
1646 .ptr = &sDefault.iDir_Security_mask,
1647 .special = NULL,
1648 .enum_list = NULL,
1649 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1652 .label = "force directory security mode",
1653 .type = P_OCTAL,
1654 .p_class = P_LOCAL,
1655 .ptr = &sDefault.iDir_Security_force_mode,
1656 .special = NULL,
1657 .enum_list = NULL,
1658 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1661 .label = "force unknown acl user",
1662 .type = P_BOOL,
1663 .p_class = P_LOCAL,
1664 .ptr = &sDefault.bForceUnknownAclUser,
1665 .special = NULL,
1666 .enum_list = NULL,
1667 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1670 .label = "inherit permissions",
1671 .type = P_BOOL,
1672 .p_class = P_LOCAL,
1673 .ptr = &sDefault.bInheritPerms,
1674 .special = NULL,
1675 .enum_list = NULL,
1676 .flags = FLAG_ADVANCED | FLAG_SHARE,
1679 .label = "inherit acls",
1680 .type = P_BOOL,
1681 .p_class = P_LOCAL,
1682 .ptr = &sDefault.bInheritACLS,
1683 .special = NULL,
1684 .enum_list = NULL,
1685 .flags = FLAG_ADVANCED | FLAG_SHARE,
1688 .label = "inherit owner",
1689 .type = P_BOOL,
1690 .p_class = P_LOCAL,
1691 .ptr = &sDefault.bInheritOwner,
1692 .special = NULL,
1693 .enum_list = NULL,
1694 .flags = FLAG_ADVANCED | FLAG_SHARE,
1697 .label = "guest only",
1698 .type = P_BOOL,
1699 .p_class = P_LOCAL,
1700 .ptr = &sDefault.bGuest_only,
1701 .special = NULL,
1702 .enum_list = NULL,
1703 .flags = FLAG_ADVANCED | FLAG_SHARE,
1706 .label = "only guest",
1707 .type = P_BOOL,
1708 .p_class = P_LOCAL,
1709 .ptr = &sDefault.bGuest_only,
1710 .special = NULL,
1711 .enum_list = NULL,
1712 .flags = FLAG_HIDE,
1715 .label = "administrative share",
1716 .type = P_BOOL,
1717 .p_class = P_LOCAL,
1718 .ptr = &sDefault.bAdministrative_share,
1719 .special = NULL,
1720 .enum_list = NULL,
1721 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1725 .label = "guest ok",
1726 .type = P_BOOL,
1727 .p_class = P_LOCAL,
1728 .ptr = &sDefault.bGuest_ok,
1729 .special = NULL,
1730 .enum_list = NULL,
1731 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1734 .label = "public",
1735 .type = P_BOOL,
1736 .p_class = P_LOCAL,
1737 .ptr = &sDefault.bGuest_ok,
1738 .special = NULL,
1739 .enum_list = NULL,
1740 .flags = FLAG_HIDE,
1743 .label = "only user",
1744 .type = P_BOOL,
1745 .p_class = P_LOCAL,
1746 .ptr = &sDefault.bOnlyUser,
1747 .special = NULL,
1748 .enum_list = NULL,
1749 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1752 .label = "hosts allow",
1753 .type = P_LIST,
1754 .p_class = P_LOCAL,
1755 .ptr = &sDefault.szHostsallow,
1756 .special = NULL,
1757 .enum_list = NULL,
1758 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1761 .label = "allow hosts",
1762 .type = P_LIST,
1763 .p_class = P_LOCAL,
1764 .ptr = &sDefault.szHostsallow,
1765 .special = NULL,
1766 .enum_list = NULL,
1767 .flags = FLAG_HIDE,
1770 .label = "hosts deny",
1771 .type = P_LIST,
1772 .p_class = P_LOCAL,
1773 .ptr = &sDefault.szHostsdeny,
1774 .special = NULL,
1775 .enum_list = NULL,
1776 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1779 .label = "deny hosts",
1780 .type = P_LIST,
1781 .p_class = P_LOCAL,
1782 .ptr = &sDefault.szHostsdeny,
1783 .special = NULL,
1784 .enum_list = NULL,
1785 .flags = FLAG_HIDE,
1788 .label = "preload modules",
1789 .type = P_LIST,
1790 .p_class = P_GLOBAL,
1791 .ptr = &Globals.szPreloadModules,
1792 .special = NULL,
1793 .enum_list = NULL,
1794 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1797 .label = "dedicated keytab file",
1798 .type = P_STRING,
1799 .p_class = P_GLOBAL,
1800 .ptr = &Globals.szDedicatedKeytabFile,
1801 .special = NULL,
1802 .enum_list = NULL,
1803 .flags = FLAG_ADVANCED,
1806 .label = "kerberos method",
1807 .type = P_ENUM,
1808 .p_class = P_GLOBAL,
1809 .ptr = &Globals.iKerberosMethod,
1810 .special = NULL,
1811 .enum_list = enum_kerberos_method,
1812 .flags = FLAG_ADVANCED,
1815 .label = "map untrusted to domain",
1816 .type = P_BOOL,
1817 .p_class = P_GLOBAL,
1818 .ptr = &Globals.bMapUntrustedToDomain,
1819 .special = NULL,
1820 .enum_list = NULL,
1821 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1825 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1828 .label = "log level",
1829 .type = P_STRING,
1830 .p_class = P_GLOBAL,
1831 .ptr = &Globals.szLogLevel,
1832 .special = handle_debug_list,
1833 .enum_list = NULL,
1834 .flags = FLAG_ADVANCED,
1837 .label = "debuglevel",
1838 .type = P_STRING,
1839 .p_class = P_GLOBAL,
1840 .ptr = &Globals.szLogLevel,
1841 .special = handle_debug_list,
1842 .enum_list = NULL,
1843 .flags = FLAG_HIDE,
1846 .label = "syslog",
1847 .type = P_INTEGER,
1848 .p_class = P_GLOBAL,
1849 .ptr = &Globals.syslog,
1850 .special = NULL,
1851 .enum_list = NULL,
1852 .flags = FLAG_ADVANCED,
1855 .label = "syslog only",
1856 .type = P_BOOL,
1857 .p_class = P_GLOBAL,
1858 .ptr = &Globals.bSyslogOnly,
1859 .special = NULL,
1860 .enum_list = NULL,
1861 .flags = FLAG_ADVANCED,
1864 .label = "log file",
1865 .type = P_STRING,
1866 .p_class = P_GLOBAL,
1867 .ptr = &Globals.szLogFile,
1868 .special = NULL,
1869 .enum_list = NULL,
1870 .flags = FLAG_ADVANCED,
1873 .label = "max log size",
1874 .type = P_INTEGER,
1875 .p_class = P_GLOBAL,
1876 .ptr = &Globals.max_log_size,
1877 .special = NULL,
1878 .enum_list = NULL,
1879 .flags = FLAG_ADVANCED,
1882 .label = "debug timestamp",
1883 .type = P_BOOL,
1884 .p_class = P_GLOBAL,
1885 .ptr = &Globals.bTimestampLogs,
1886 .special = NULL,
1887 .enum_list = NULL,
1888 .flags = FLAG_ADVANCED,
1891 .label = "timestamp logs",
1892 .type = P_BOOL,
1893 .p_class = P_GLOBAL,
1894 .ptr = &Globals.bTimestampLogs,
1895 .special = NULL,
1896 .enum_list = NULL,
1897 .flags = FLAG_ADVANCED,
1900 .label = "debug prefix timestamp",
1901 .type = P_BOOL,
1902 .p_class = P_GLOBAL,
1903 .ptr = &Globals.bDebugPrefixTimestamp,
1904 .special = NULL,
1905 .enum_list = NULL,
1906 .flags = FLAG_ADVANCED,
1909 .label = "debug hires timestamp",
1910 .type = P_BOOL,
1911 .p_class = P_GLOBAL,
1912 .ptr = &Globals.bDebugHiresTimestamp,
1913 .special = NULL,
1914 .enum_list = NULL,
1915 .flags = FLAG_ADVANCED,
1918 .label = "debug pid",
1919 .type = P_BOOL,
1920 .p_class = P_GLOBAL,
1921 .ptr = &Globals.bDebugPid,
1922 .special = NULL,
1923 .enum_list = NULL,
1924 .flags = FLAG_ADVANCED,
1927 .label = "debug uid",
1928 .type = P_BOOL,
1929 .p_class = P_GLOBAL,
1930 .ptr = &Globals.bDebugUid,
1931 .special = NULL,
1932 .enum_list = NULL,
1933 .flags = FLAG_ADVANCED,
1936 .label = "debug class",
1937 .type = P_BOOL,
1938 .p_class = P_GLOBAL,
1939 .ptr = &Globals.bDebugClass,
1940 .special = NULL,
1941 .enum_list = NULL,
1942 .flags = FLAG_ADVANCED,
1945 .label = "enable core files",
1946 .type = P_BOOL,
1947 .p_class = P_GLOBAL,
1948 .ptr = &Globals.bEnableCoreFiles,
1949 .special = NULL,
1950 .enum_list = NULL,
1951 .flags = FLAG_ADVANCED,
1954 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1957 .label = "allocation roundup size",
1958 .type = P_INTEGER,
1959 .p_class = P_LOCAL,
1960 .ptr = &sDefault.iallocation_roundup_size,
1961 .special = NULL,
1962 .enum_list = NULL,
1963 .flags = FLAG_ADVANCED,
1966 .label = "aio read size",
1967 .type = P_INTEGER,
1968 .p_class = P_LOCAL,
1969 .ptr = &sDefault.iAioReadSize,
1970 .special = NULL,
1971 .enum_list = NULL,
1972 .flags = FLAG_ADVANCED,
1975 .label = "aio write size",
1976 .type = P_INTEGER,
1977 .p_class = P_LOCAL,
1978 .ptr = &sDefault.iAioWriteSize,
1979 .special = NULL,
1980 .enum_list = NULL,
1981 .flags = FLAG_ADVANCED,
1984 .label = "aio write behind",
1985 .type = P_STRING,
1986 .p_class = P_LOCAL,
1987 .ptr = &sDefault.szAioWriteBehind,
1988 .special = NULL,
1989 .enum_list = NULL,
1990 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1993 .label = "smb ports",
1994 .type = P_STRING,
1995 .p_class = P_GLOBAL,
1996 .ptr = &Globals.smb_ports,
1997 .special = NULL,
1998 .enum_list = NULL,
1999 .flags = FLAG_ADVANCED,
2002 .label = "large readwrite",
2003 .type = P_BOOL,
2004 .p_class = P_GLOBAL,
2005 .ptr = &Globals.bLargeReadwrite,
2006 .special = NULL,
2007 .enum_list = NULL,
2008 .flags = FLAG_ADVANCED,
2011 .label = "max protocol",
2012 .type = P_ENUM,
2013 .p_class = P_GLOBAL,
2014 .ptr = &Globals.maxprotocol,
2015 .special = NULL,
2016 .enum_list = enum_protocol,
2017 .flags = FLAG_ADVANCED,
2020 .label = "protocol",
2021 .type = P_ENUM,
2022 .p_class = P_GLOBAL,
2023 .ptr = &Globals.maxprotocol,
2024 .special = NULL,
2025 .enum_list = enum_protocol,
2026 .flags = FLAG_ADVANCED,
2029 .label = "min protocol",
2030 .type = P_ENUM,
2031 .p_class = P_GLOBAL,
2032 .ptr = &Globals.minprotocol,
2033 .special = NULL,
2034 .enum_list = enum_protocol,
2035 .flags = FLAG_ADVANCED,
2038 .label = "min receivefile size",
2039 .type = P_INTEGER,
2040 .p_class = P_GLOBAL,
2041 .ptr = &Globals.iminreceivefile,
2042 .special = NULL,
2043 .enum_list = NULL,
2044 .flags = FLAG_ADVANCED,
2047 .label = "read raw",
2048 .type = P_BOOL,
2049 .p_class = P_GLOBAL,
2050 .ptr = &Globals.bReadRaw,
2051 .special = NULL,
2052 .enum_list = NULL,
2053 .flags = FLAG_ADVANCED,
2056 .label = "write raw",
2057 .type = P_BOOL,
2058 .p_class = P_GLOBAL,
2059 .ptr = &Globals.bWriteRaw,
2060 .special = NULL,
2061 .enum_list = NULL,
2062 .flags = FLAG_ADVANCED,
2065 .label = "disable netbios",
2066 .type = P_BOOL,
2067 .p_class = P_GLOBAL,
2068 .ptr = &Globals.bDisableNetbios,
2069 .special = NULL,
2070 .enum_list = NULL,
2071 .flags = FLAG_ADVANCED,
2074 .label = "reset on zero vc",
2075 .type = P_BOOL,
2076 .p_class = P_GLOBAL,
2077 .ptr = &Globals.bResetOnZeroVC,
2078 .special = NULL,
2079 .enum_list = NULL,
2080 .flags = FLAG_ADVANCED,
2083 .label = "log writeable files on exit",
2084 .type = P_BOOL,
2085 .p_class = P_GLOBAL,
2086 .ptr = &Globals.bLogWriteableFilesOnExit,
2087 .special = NULL,
2088 .enum_list = NULL,
2089 .flags = FLAG_ADVANCED,
2092 .label = "acl compatibility",
2093 .type = P_ENUM,
2094 .p_class = P_GLOBAL,
2095 .ptr = &Globals.iAclCompat,
2096 .special = NULL,
2097 .enum_list = enum_acl_compat_vals,
2098 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2101 .label = "defer sharing violations",
2102 .type = P_BOOL,
2103 .p_class = P_GLOBAL,
2104 .ptr = &Globals.bDeferSharingViolations,
2105 .special = NULL,
2106 .enum_list = NULL,
2107 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2110 .label = "ea support",
2111 .type = P_BOOL,
2112 .p_class = P_LOCAL,
2113 .ptr = &sDefault.bEASupport,
2114 .special = NULL,
2115 .enum_list = NULL,
2116 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2119 .label = "nt acl support",
2120 .type = P_BOOL,
2121 .p_class = P_LOCAL,
2122 .ptr = &sDefault.bNTAclSupport,
2123 .special = NULL,
2124 .enum_list = NULL,
2125 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2128 .label = "nt pipe support",
2129 .type = P_BOOL,
2130 .p_class = P_GLOBAL,
2131 .ptr = &Globals.bNTPipeSupport,
2132 .special = NULL,
2133 .enum_list = NULL,
2134 .flags = FLAG_ADVANCED,
2137 .label = "nt status support",
2138 .type = P_BOOL,
2139 .p_class = P_GLOBAL,
2140 .ptr = &Globals.bNTStatusSupport,
2141 .special = NULL,
2142 .enum_list = NULL,
2143 .flags = FLAG_ADVANCED,
2146 .label = "profile acls",
2147 .type = P_BOOL,
2148 .p_class = P_LOCAL,
2149 .ptr = &sDefault.bProfileAcls,
2150 .special = NULL,
2151 .enum_list = NULL,
2152 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2155 .label = "announce version",
2156 .type = P_STRING,
2157 .p_class = P_GLOBAL,
2158 .ptr = &Globals.szAnnounceVersion,
2159 .special = NULL,
2160 .enum_list = NULL,
2161 .flags = FLAG_ADVANCED,
2164 .label = "announce as",
2165 .type = P_ENUM,
2166 .p_class = P_GLOBAL,
2167 .ptr = &Globals.announce_as,
2168 .special = NULL,
2169 .enum_list = enum_announce_as,
2170 .flags = FLAG_ADVANCED,
2173 .label = "map acl inherit",
2174 .type = P_BOOL,
2175 .p_class = P_LOCAL,
2176 .ptr = &sDefault.bMap_acl_inherit,
2177 .special = NULL,
2178 .enum_list = NULL,
2179 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2182 .label = "afs share",
2183 .type = P_BOOL,
2184 .p_class = P_LOCAL,
2185 .ptr = &sDefault.bAfs_Share,
2186 .special = NULL,
2187 .enum_list = NULL,
2188 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2191 .label = "max mux",
2192 .type = P_INTEGER,
2193 .p_class = P_GLOBAL,
2194 .ptr = &Globals.max_mux,
2195 .special = NULL,
2196 .enum_list = NULL,
2197 .flags = FLAG_ADVANCED,
2200 .label = "max xmit",
2201 .type = P_INTEGER,
2202 .p_class = P_GLOBAL,
2203 .ptr = &Globals.max_xmit,
2204 .special = NULL,
2205 .enum_list = NULL,
2206 .flags = FLAG_ADVANCED,
2209 .label = "name resolve order",
2210 .type = P_STRING,
2211 .p_class = P_GLOBAL,
2212 .ptr = &Globals.szNameResolveOrder,
2213 .special = NULL,
2214 .enum_list = NULL,
2215 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2218 .label = "max ttl",
2219 .type = P_INTEGER,
2220 .p_class = P_GLOBAL,
2221 .ptr = &Globals.max_ttl,
2222 .special = NULL,
2223 .enum_list = NULL,
2224 .flags = FLAG_ADVANCED,
2227 .label = "max wins ttl",
2228 .type = P_INTEGER,
2229 .p_class = P_GLOBAL,
2230 .ptr = &Globals.max_wins_ttl,
2231 .special = NULL,
2232 .enum_list = NULL,
2233 .flags = FLAG_ADVANCED,
2236 .label = "min wins ttl",
2237 .type = P_INTEGER,
2238 .p_class = P_GLOBAL,
2239 .ptr = &Globals.min_wins_ttl,
2240 .special = NULL,
2241 .enum_list = NULL,
2242 .flags = FLAG_ADVANCED,
2245 .label = "time server",
2246 .type = P_BOOL,
2247 .p_class = P_GLOBAL,
2248 .ptr = &Globals.bTimeServer,
2249 .special = NULL,
2250 .enum_list = NULL,
2251 .flags = FLAG_ADVANCED,
2254 .label = "unix extensions",
2255 .type = P_BOOL,
2256 .p_class = P_GLOBAL,
2257 .ptr = &Globals.bUnixExtensions,
2258 .special = NULL,
2259 .enum_list = NULL,
2260 .flags = FLAG_ADVANCED,
2263 .label = "use spnego",
2264 .type = P_BOOL,
2265 .p_class = P_GLOBAL,
2266 .ptr = &Globals.bUseSpnego,
2267 .special = NULL,
2268 .enum_list = NULL,
2269 .flags = FLAG_ADVANCED,
2272 .label = "client signing",
2273 .type = P_ENUM,
2274 .p_class = P_GLOBAL,
2275 .ptr = &Globals.client_signing,
2276 .special = NULL,
2277 .enum_list = enum_smb_signing_vals,
2278 .flags = FLAG_ADVANCED,
2281 .label = "server signing",
2282 .type = P_ENUM,
2283 .p_class = P_GLOBAL,
2284 .ptr = &Globals.server_signing,
2285 .special = NULL,
2286 .enum_list = enum_smb_signing_vals,
2287 .flags = FLAG_ADVANCED,
2290 .label = "smb encrypt",
2291 .type = P_ENUM,
2292 .p_class = P_LOCAL,
2293 .ptr = &sDefault.ismb_encrypt,
2294 .special = NULL,
2295 .enum_list = enum_smb_signing_vals,
2296 .flags = FLAG_ADVANCED,
2299 .label = "client use spnego",
2300 .type = P_BOOL,
2301 .p_class = P_GLOBAL,
2302 .ptr = &Globals.bClientUseSpnego,
2303 .special = NULL,
2304 .enum_list = NULL,
2305 .flags = FLAG_ADVANCED,
2308 .label = "client ldap sasl wrapping",
2309 .type = P_ENUM,
2310 .p_class = P_GLOBAL,
2311 .ptr = &Globals.client_ldap_sasl_wrapping,
2312 .special = NULL,
2313 .enum_list = enum_ldap_sasl_wrapping,
2314 .flags = FLAG_ADVANCED,
2317 .label = "enable asu support",
2318 .type = P_BOOL,
2319 .p_class = P_GLOBAL,
2320 .ptr = &Globals.bASUSupport,
2321 .special = NULL,
2322 .enum_list = NULL,
2323 .flags = FLAG_ADVANCED,
2326 .label = "svcctl list",
2327 .type = P_LIST,
2328 .p_class = P_GLOBAL,
2329 .ptr = &Globals.szServicesList,
2330 .special = NULL,
2331 .enum_list = NULL,
2332 .flags = FLAG_ADVANCED,
2335 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2338 .label = "block size",
2339 .type = P_INTEGER,
2340 .p_class = P_LOCAL,
2341 .ptr = &sDefault.iBlock_size,
2342 .special = NULL,
2343 .enum_list = NULL,
2344 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2347 .label = "deadtime",
2348 .type = P_INTEGER,
2349 .p_class = P_GLOBAL,
2350 .ptr = &Globals.deadtime,
2351 .special = NULL,
2352 .enum_list = NULL,
2353 .flags = FLAG_ADVANCED,
2356 .label = "getwd cache",
2357 .type = P_BOOL,
2358 .p_class = P_GLOBAL,
2359 .ptr = &Globals.getwd_cache,
2360 .special = NULL,
2361 .enum_list = NULL,
2362 .flags = FLAG_ADVANCED,
2365 .label = "keepalive",
2366 .type = P_INTEGER,
2367 .p_class = P_GLOBAL,
2368 .ptr = &Globals.iKeepalive,
2369 .special = NULL,
2370 .enum_list = NULL,
2371 .flags = FLAG_ADVANCED,
2374 .label = "change notify",
2375 .type = P_BOOL,
2376 .p_class = P_LOCAL,
2377 .ptr = &sDefault.bChangeNotify,
2378 .special = NULL,
2379 .enum_list = NULL,
2380 .flags = FLAG_ADVANCED | FLAG_SHARE,
2383 .label = "directory name cache size",
2384 .type = P_INTEGER,
2385 .p_class = P_LOCAL,
2386 .ptr = &sDefault.iDirectoryNameCacheSize,
2387 .special = NULL,
2388 .enum_list = NULL,
2389 .flags = FLAG_ADVANCED | FLAG_SHARE,
2392 .label = "kernel change notify",
2393 .type = P_BOOL,
2394 .p_class = P_LOCAL,
2395 .ptr = &sDefault.bKernelChangeNotify,
2396 .special = NULL,
2397 .enum_list = NULL,
2398 .flags = FLAG_ADVANCED | FLAG_SHARE,
2401 .label = "lpq cache time",
2402 .type = P_INTEGER,
2403 .p_class = P_GLOBAL,
2404 .ptr = &Globals.lpqcachetime,
2405 .special = NULL,
2406 .enum_list = NULL,
2407 .flags = FLAG_ADVANCED,
2410 .label = "max smbd processes",
2411 .type = P_INTEGER,
2412 .p_class = P_GLOBAL,
2413 .ptr = &Globals.iMaxSmbdProcesses,
2414 .special = NULL,
2415 .enum_list = NULL,
2416 .flags = FLAG_ADVANCED,
2419 .label = "max connections",
2420 .type = P_INTEGER,
2421 .p_class = P_LOCAL,
2422 .ptr = &sDefault.iMaxConnections,
2423 .special = NULL,
2424 .enum_list = NULL,
2425 .flags = FLAG_ADVANCED | FLAG_SHARE,
2428 .label = "paranoid server security",
2429 .type = P_BOOL,
2430 .p_class = P_GLOBAL,
2431 .ptr = &Globals.paranoid_server_security,
2432 .special = NULL,
2433 .enum_list = NULL,
2434 .flags = FLAG_ADVANCED,
2437 .label = "max disk size",
2438 .type = P_INTEGER,
2439 .p_class = P_GLOBAL,
2440 .ptr = &Globals.maxdisksize,
2441 .special = NULL,
2442 .enum_list = NULL,
2443 .flags = FLAG_ADVANCED,
2446 .label = "max open files",
2447 .type = P_INTEGER,
2448 .p_class = P_GLOBAL,
2449 .ptr = &Globals.max_open_files,
2450 .special = NULL,
2451 .enum_list = NULL,
2452 .flags = FLAG_ADVANCED,
2455 .label = "min print space",
2456 .type = P_INTEGER,
2457 .p_class = P_LOCAL,
2458 .ptr = &sDefault.iMinPrintSpace,
2459 .special = NULL,
2460 .enum_list = NULL,
2461 .flags = FLAG_ADVANCED | FLAG_PRINT,
2464 .label = "socket options",
2465 .type = P_STRING,
2466 .p_class = P_GLOBAL,
2467 .ptr = &Globals.szSocketOptions,
2468 .special = NULL,
2469 .enum_list = NULL,
2470 .flags = FLAG_ADVANCED,
2473 .label = "strict allocate",
2474 .type = P_BOOL,
2475 .p_class = P_LOCAL,
2476 .ptr = &sDefault.bStrictAllocate,
2477 .special = NULL,
2478 .enum_list = NULL,
2479 .flags = FLAG_ADVANCED | FLAG_SHARE,
2482 .label = "strict sync",
2483 .type = P_BOOL,
2484 .p_class = P_LOCAL,
2485 .ptr = &sDefault.bStrictSync,
2486 .special = NULL,
2487 .enum_list = NULL,
2488 .flags = FLAG_ADVANCED | FLAG_SHARE,
2491 .label = "sync always",
2492 .type = P_BOOL,
2493 .p_class = P_LOCAL,
2494 .ptr = &sDefault.bSyncAlways,
2495 .special = NULL,
2496 .enum_list = NULL,
2497 .flags = FLAG_ADVANCED | FLAG_SHARE,
2500 .label = "use mmap",
2501 .type = P_BOOL,
2502 .p_class = P_GLOBAL,
2503 .ptr = &Globals.bUseMmap,
2504 .special = NULL,
2505 .enum_list = NULL,
2506 .flags = FLAG_ADVANCED,
2509 .label = "use sendfile",
2510 .type = P_BOOL,
2511 .p_class = P_LOCAL,
2512 .ptr = &sDefault.bUseSendfile,
2513 .special = NULL,
2514 .enum_list = NULL,
2515 .flags = FLAG_ADVANCED | FLAG_SHARE,
2518 .label = "hostname lookups",
2519 .type = P_BOOL,
2520 .p_class = P_GLOBAL,
2521 .ptr = &Globals.bHostnameLookups,
2522 .special = NULL,
2523 .enum_list = NULL,
2524 .flags = FLAG_ADVANCED,
2527 .label = "write cache size",
2528 .type = P_INTEGER,
2529 .p_class = P_LOCAL,
2530 .ptr = &sDefault.iWriteCacheSize,
2531 .special = NULL,
2532 .enum_list = NULL,
2533 .flags = FLAG_ADVANCED | FLAG_SHARE,
2536 .label = "name cache timeout",
2537 .type = P_INTEGER,
2538 .p_class = P_GLOBAL,
2539 .ptr = &Globals.name_cache_timeout,
2540 .special = NULL,
2541 .enum_list = NULL,
2542 .flags = FLAG_ADVANCED,
2545 .label = "ctdbd socket",
2546 .type = P_STRING,
2547 .p_class = P_GLOBAL,
2548 .ptr = &Globals.ctdbdSocket,
2549 .special = NULL,
2550 .enum_list = NULL,
2551 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2554 .label = "cluster addresses",
2555 .type = P_LIST,
2556 .p_class = P_GLOBAL,
2557 .ptr = &Globals.szClusterAddresses,
2558 .special = NULL,
2559 .enum_list = NULL,
2560 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2563 .label = "clustering",
2564 .type = P_BOOL,
2565 .p_class = P_GLOBAL,
2566 .ptr = &Globals.clustering,
2567 .special = NULL,
2568 .enum_list = NULL,
2569 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2572 .label = "ctdb timeout",
2573 .type = P_INTEGER,
2574 .p_class = P_GLOBAL,
2575 .ptr = &Globals.ctdb_timeout,
2576 .special = NULL,
2577 .enum_list = NULL,
2578 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2581 .label = "ctdb locktime warn threshold",
2582 .type = P_INTEGER,
2583 .p_class = P_GLOBAL,
2584 .ptr = &Globals.ctdb_locktime_warn_threshold,
2585 .special = NULL,
2586 .enum_list = NULL,
2587 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2590 .label = "smb2 max read",
2591 .type = P_INTEGER,
2592 .p_class = P_GLOBAL,
2593 .ptr = &Globals.ismb2_max_read,
2594 .special = NULL,
2595 .enum_list = NULL,
2596 .flags = FLAG_ADVANCED,
2599 .label = "smb2 max write",
2600 .type = P_INTEGER,
2601 .p_class = P_GLOBAL,
2602 .ptr = &Globals.ismb2_max_write,
2603 .special = NULL,
2604 .enum_list = NULL,
2605 .flags = FLAG_ADVANCED,
2608 .label = "smb2 max trans",
2609 .type = P_INTEGER,
2610 .p_class = P_GLOBAL,
2611 .ptr = &Globals.ismb2_max_trans,
2612 .special = NULL,
2613 .enum_list = NULL,
2614 .flags = FLAG_ADVANCED,
2617 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2620 .label = "max reported print jobs",
2621 .type = P_INTEGER,
2622 .p_class = P_LOCAL,
2623 .ptr = &sDefault.iMaxReportedPrintJobs,
2624 .special = NULL,
2625 .enum_list = NULL,
2626 .flags = FLAG_ADVANCED | FLAG_PRINT,
2629 .label = "max print jobs",
2630 .type = P_INTEGER,
2631 .p_class = P_LOCAL,
2632 .ptr = &sDefault.iMaxPrintJobs,
2633 .special = NULL,
2634 .enum_list = NULL,
2635 .flags = FLAG_ADVANCED | FLAG_PRINT,
2638 .label = "load printers",
2639 .type = P_BOOL,
2640 .p_class = P_GLOBAL,
2641 .ptr = &Globals.bLoadPrinters,
2642 .special = NULL,
2643 .enum_list = NULL,
2644 .flags = FLAG_ADVANCED | FLAG_PRINT,
2647 .label = "printcap cache time",
2648 .type = P_INTEGER,
2649 .p_class = P_GLOBAL,
2650 .ptr = &Globals.PrintcapCacheTime,
2651 .special = NULL,
2652 .enum_list = NULL,
2653 .flags = FLAG_ADVANCED | FLAG_PRINT,
2656 .label = "printcap name",
2657 .type = P_STRING,
2658 .p_class = P_GLOBAL,
2659 .ptr = &Globals.szPrintcapname,
2660 .special = NULL,
2661 .enum_list = NULL,
2662 .flags = FLAG_ADVANCED | FLAG_PRINT,
2665 .label = "printcap",
2666 .type = P_STRING,
2667 .p_class = P_GLOBAL,
2668 .ptr = &Globals.szPrintcapname,
2669 .special = NULL,
2670 .enum_list = NULL,
2671 .flags = FLAG_HIDE,
2674 .label = "printable",
2675 .type = P_BOOL,
2676 .p_class = P_LOCAL,
2677 .ptr = &sDefault.bPrint_ok,
2678 .special = NULL,
2679 .enum_list = NULL,
2680 .flags = FLAG_ADVANCED | FLAG_PRINT,
2683 .label = "print ok",
2684 .type = P_BOOL,
2685 .p_class = P_LOCAL,
2686 .ptr = &sDefault.bPrint_ok,
2687 .special = NULL,
2688 .enum_list = NULL,
2689 .flags = FLAG_HIDE,
2692 .label = "printing",
2693 .type = P_ENUM,
2694 .p_class = P_LOCAL,
2695 .ptr = &sDefault.iPrinting,
2696 .special = handle_printing,
2697 .enum_list = enum_printing,
2698 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2701 .label = "cups options",
2702 .type = P_STRING,
2703 .p_class = P_LOCAL,
2704 .ptr = &sDefault.szCupsOptions,
2705 .special = NULL,
2706 .enum_list = NULL,
2707 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2710 .label = "cups server",
2711 .type = P_STRING,
2712 .p_class = P_GLOBAL,
2713 .ptr = &Globals.szCupsServer,
2714 .special = NULL,
2715 .enum_list = NULL,
2716 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2719 .label = "cups encrypt",
2720 .type = P_ENUM,
2721 .p_class = P_GLOBAL,
2722 .ptr = &Globals.CupsEncrypt,
2723 .special = NULL,
2724 .enum_list = enum_bool_auto,
2725 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2729 .label = "cups connection timeout",
2730 .type = P_INTEGER,
2731 .p_class = P_GLOBAL,
2732 .ptr = &Globals.cups_connection_timeout,
2733 .special = NULL,
2734 .enum_list = NULL,
2735 .flags = FLAG_ADVANCED,
2738 .label = "iprint server",
2739 .type = P_STRING,
2740 .p_class = P_GLOBAL,
2741 .ptr = &Globals.szIPrintServer,
2742 .special = NULL,
2743 .enum_list = NULL,
2744 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2747 .label = "print command",
2748 .type = P_STRING,
2749 .p_class = P_LOCAL,
2750 .ptr = &sDefault.szPrintcommand,
2751 .special = NULL,
2752 .enum_list = NULL,
2753 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2756 .label = "disable spoolss",
2757 .type = P_BOOL,
2758 .p_class = P_GLOBAL,
2759 .ptr = &Globals.bDisableSpoolss,
2760 .special = NULL,
2761 .enum_list = NULL,
2762 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2765 .label = "enable spoolss",
2766 .type = P_BOOLREV,
2767 .p_class = P_GLOBAL,
2768 .ptr = &Globals.bDisableSpoolss,
2769 .special = NULL,
2770 .enum_list = NULL,
2771 .flags = FLAG_HIDE,
2774 .label = "lpq command",
2775 .type = P_STRING,
2776 .p_class = P_LOCAL,
2777 .ptr = &sDefault.szLpqcommand,
2778 .special = NULL,
2779 .enum_list = NULL,
2780 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2783 .label = "lprm command",
2784 .type = P_STRING,
2785 .p_class = P_LOCAL,
2786 .ptr = &sDefault.szLprmcommand,
2787 .special = NULL,
2788 .enum_list = NULL,
2789 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2792 .label = "lppause command",
2793 .type = P_STRING,
2794 .p_class = P_LOCAL,
2795 .ptr = &sDefault.szLppausecommand,
2796 .special = NULL,
2797 .enum_list = NULL,
2798 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2801 .label = "lpresume command",
2802 .type = P_STRING,
2803 .p_class = P_LOCAL,
2804 .ptr = &sDefault.szLpresumecommand,
2805 .special = NULL,
2806 .enum_list = NULL,
2807 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2810 .label = "queuepause command",
2811 .type = P_STRING,
2812 .p_class = P_LOCAL,
2813 .ptr = &sDefault.szQueuepausecommand,
2814 .special = NULL,
2815 .enum_list = NULL,
2816 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2819 .label = "queueresume command",
2820 .type = P_STRING,
2821 .p_class = P_LOCAL,
2822 .ptr = &sDefault.szQueueresumecommand,
2823 .special = NULL,
2824 .enum_list = NULL,
2825 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2828 .label = "addport command",
2829 .type = P_STRING,
2830 .p_class = P_GLOBAL,
2831 .ptr = &Globals.szAddPortCommand,
2832 .special = NULL,
2833 .enum_list = NULL,
2834 .flags = FLAG_ADVANCED,
2837 .label = "enumports command",
2838 .type = P_STRING,
2839 .p_class = P_GLOBAL,
2840 .ptr = &Globals.szEnumPortsCommand,
2841 .special = NULL,
2842 .enum_list = NULL,
2843 .flags = FLAG_ADVANCED,
2846 .label = "addprinter command",
2847 .type = P_STRING,
2848 .p_class = P_GLOBAL,
2849 .ptr = &Globals.szAddPrinterCommand,
2850 .special = NULL,
2851 .enum_list = NULL,
2852 .flags = FLAG_ADVANCED,
2855 .label = "deleteprinter command",
2856 .type = P_STRING,
2857 .p_class = P_GLOBAL,
2858 .ptr = &Globals.szDeletePrinterCommand,
2859 .special = NULL,
2860 .enum_list = NULL,
2861 .flags = FLAG_ADVANCED,
2864 .label = "show add printer wizard",
2865 .type = P_BOOL,
2866 .p_class = P_GLOBAL,
2867 .ptr = &Globals.bMsAddPrinterWizard,
2868 .special = NULL,
2869 .enum_list = NULL,
2870 .flags = FLAG_ADVANCED,
2873 .label = "os2 driver map",
2874 .type = P_STRING,
2875 .p_class = P_GLOBAL,
2876 .ptr = &Globals.szOs2DriverMap,
2877 .special = NULL,
2878 .enum_list = NULL,
2879 .flags = FLAG_ADVANCED,
2883 .label = "printer name",
2884 .type = P_STRING,
2885 .p_class = P_LOCAL,
2886 .ptr = &sDefault.szPrintername,
2887 .special = NULL,
2888 .enum_list = NULL,
2889 .flags = FLAG_ADVANCED | FLAG_PRINT,
2892 .label = "printer",
2893 .type = P_STRING,
2894 .p_class = P_LOCAL,
2895 .ptr = &sDefault.szPrintername,
2896 .special = NULL,
2897 .enum_list = NULL,
2898 .flags = FLAG_HIDE,
2901 .label = "use client driver",
2902 .type = P_BOOL,
2903 .p_class = P_LOCAL,
2904 .ptr = &sDefault.bUseClientDriver,
2905 .special = NULL,
2906 .enum_list = NULL,
2907 .flags = FLAG_ADVANCED | FLAG_PRINT,
2910 .label = "default devmode",
2911 .type = P_BOOL,
2912 .p_class = P_LOCAL,
2913 .ptr = &sDefault.bDefaultDevmode,
2914 .special = NULL,
2915 .enum_list = NULL,
2916 .flags = FLAG_ADVANCED | FLAG_PRINT,
2919 .label = "force printername",
2920 .type = P_BOOL,
2921 .p_class = P_LOCAL,
2922 .ptr = &sDefault.bForcePrintername,
2923 .special = NULL,
2924 .enum_list = NULL,
2925 .flags = FLAG_ADVANCED | FLAG_PRINT,
2928 .label = "printjob username",
2929 .type = P_STRING,
2930 .p_class = P_LOCAL,
2931 .ptr = &sDefault.szPrintjobUsername,
2932 .special = NULL,
2933 .enum_list = NULL,
2934 .flags = FLAG_ADVANCED | FLAG_PRINT,
2937 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2940 .label = "mangling method",
2941 .type = P_STRING,
2942 .p_class = P_GLOBAL,
2943 .ptr = &Globals.szManglingMethod,
2944 .special = NULL,
2945 .enum_list = NULL,
2946 .flags = FLAG_ADVANCED,
2949 .label = "mangle prefix",
2950 .type = P_INTEGER,
2951 .p_class = P_GLOBAL,
2952 .ptr = &Globals.mangle_prefix,
2953 .special = NULL,
2954 .enum_list = NULL,
2955 .flags = FLAG_ADVANCED,
2959 .label = "default case",
2960 .type = P_ENUM,
2961 .p_class = P_LOCAL,
2962 .ptr = &sDefault.iDefaultCase,
2963 .special = NULL,
2964 .enum_list = enum_case,
2965 .flags = FLAG_ADVANCED | FLAG_SHARE,
2968 .label = "case sensitive",
2969 .type = P_ENUM,
2970 .p_class = P_LOCAL,
2971 .ptr = &sDefault.iCaseSensitive,
2972 .special = NULL,
2973 .enum_list = enum_bool_auto,
2974 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2977 .label = "casesignames",
2978 .type = P_ENUM,
2979 .p_class = P_LOCAL,
2980 .ptr = &sDefault.iCaseSensitive,
2981 .special = NULL,
2982 .enum_list = enum_bool_auto,
2983 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2986 .label = "preserve case",
2987 .type = P_BOOL,
2988 .p_class = P_LOCAL,
2989 .ptr = &sDefault.bCasePreserve,
2990 .special = NULL,
2991 .enum_list = NULL,
2992 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2995 .label = "short preserve case",
2996 .type = P_BOOL,
2997 .p_class = P_LOCAL,
2998 .ptr = &sDefault.bShortCasePreserve,
2999 .special = NULL,
3000 .enum_list = NULL,
3001 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3004 .label = "mangling char",
3005 .type = P_CHAR,
3006 .p_class = P_LOCAL,
3007 .ptr = &sDefault.magic_char,
3008 .special = NULL,
3009 .enum_list = NULL,
3010 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3013 .label = "hide dot files",
3014 .type = P_BOOL,
3015 .p_class = P_LOCAL,
3016 .ptr = &sDefault.bHideDotFiles,
3017 .special = NULL,
3018 .enum_list = NULL,
3019 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3022 .label = "hide special files",
3023 .type = P_BOOL,
3024 .p_class = P_LOCAL,
3025 .ptr = &sDefault.bHideSpecialFiles,
3026 .special = NULL,
3027 .enum_list = NULL,
3028 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3031 .label = "hide unreadable",
3032 .type = P_BOOL,
3033 .p_class = P_LOCAL,
3034 .ptr = &sDefault.bHideUnReadable,
3035 .special = NULL,
3036 .enum_list = NULL,
3037 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3040 .label = "hide unwriteable files",
3041 .type = P_BOOL,
3042 .p_class = P_LOCAL,
3043 .ptr = &sDefault.bHideUnWriteableFiles,
3044 .special = NULL,
3045 .enum_list = NULL,
3046 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3049 .label = "delete veto files",
3050 .type = P_BOOL,
3051 .p_class = P_LOCAL,
3052 .ptr = &sDefault.bDeleteVetoFiles,
3053 .special = NULL,
3054 .enum_list = NULL,
3055 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3058 .label = "veto files",
3059 .type = P_STRING,
3060 .p_class = P_LOCAL,
3061 .ptr = &sDefault.szVetoFiles,
3062 .special = NULL,
3063 .enum_list = NULL,
3064 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3067 .label = "hide files",
3068 .type = P_STRING,
3069 .p_class = P_LOCAL,
3070 .ptr = &sDefault.szHideFiles,
3071 .special = NULL,
3072 .enum_list = NULL,
3073 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3076 .label = "veto oplock files",
3077 .type = P_STRING,
3078 .p_class = P_LOCAL,
3079 .ptr = &sDefault.szVetoOplockFiles,
3080 .special = NULL,
3081 .enum_list = NULL,
3082 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3085 .label = "map archive",
3086 .type = P_BOOL,
3087 .p_class = P_LOCAL,
3088 .ptr = &sDefault.bMap_archive,
3089 .special = NULL,
3090 .enum_list = NULL,
3091 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3094 .label = "map hidden",
3095 .type = P_BOOL,
3096 .p_class = P_LOCAL,
3097 .ptr = &sDefault.bMap_hidden,
3098 .special = NULL,
3099 .enum_list = NULL,
3100 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3103 .label = "map system",
3104 .type = P_BOOL,
3105 .p_class = P_LOCAL,
3106 .ptr = &sDefault.bMap_system,
3107 .special = NULL,
3108 .enum_list = NULL,
3109 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3112 .label = "map readonly",
3113 .type = P_ENUM,
3114 .p_class = P_LOCAL,
3115 .ptr = &sDefault.iMap_readonly,
3116 .special = NULL,
3117 .enum_list = enum_map_readonly,
3118 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3121 .label = "mangled names",
3122 .type = P_BOOL,
3123 .p_class = P_LOCAL,
3124 .ptr = &sDefault.bMangledNames,
3125 .special = NULL,
3126 .enum_list = NULL,
3127 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3130 .label = "max stat cache size",
3131 .type = P_INTEGER,
3132 .p_class = P_GLOBAL,
3133 .ptr = &Globals.iMaxStatCacheSize,
3134 .special = NULL,
3135 .enum_list = NULL,
3136 .flags = FLAG_ADVANCED,
3139 .label = "stat cache",
3140 .type = P_BOOL,
3141 .p_class = P_GLOBAL,
3142 .ptr = &Globals.bStatCache,
3143 .special = NULL,
3144 .enum_list = NULL,
3145 .flags = FLAG_ADVANCED,
3148 .label = "store dos attributes",
3149 .type = P_BOOL,
3150 .p_class = P_LOCAL,
3151 .ptr = &sDefault.bStoreDosAttributes,
3152 .special = NULL,
3153 .enum_list = NULL,
3154 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3157 .label = "dmapi support",
3158 .type = P_BOOL,
3159 .p_class = P_LOCAL,
3160 .ptr = &sDefault.bDmapiSupport,
3161 .special = NULL,
3162 .enum_list = NULL,
3163 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3167 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3170 .label = "machine password timeout",
3171 .type = P_INTEGER,
3172 .p_class = P_GLOBAL,
3173 .ptr = &Globals.machine_password_timeout,
3174 .special = NULL,
3175 .enum_list = NULL,
3176 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3179 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3182 .label = "add user script",
3183 .type = P_STRING,
3184 .p_class = P_GLOBAL,
3185 .ptr = &Globals.szAddUserScript,
3186 .special = NULL,
3187 .enum_list = NULL,
3188 .flags = FLAG_ADVANCED,
3191 .label = "rename user script",
3192 .type = P_STRING,
3193 .p_class = P_GLOBAL,
3194 .ptr = &Globals.szRenameUserScript,
3195 .special = NULL,
3196 .enum_list = NULL,
3197 .flags = FLAG_ADVANCED,
3200 .label = "delete user script",
3201 .type = P_STRING,
3202 .p_class = P_GLOBAL,
3203 .ptr = &Globals.szDelUserScript,
3204 .special = NULL,
3205 .enum_list = NULL,
3206 .flags = FLAG_ADVANCED,
3209 .label = "add group script",
3210 .type = P_STRING,
3211 .p_class = P_GLOBAL,
3212 .ptr = &Globals.szAddGroupScript,
3213 .special = NULL,
3214 .enum_list = NULL,
3215 .flags = FLAG_ADVANCED,
3218 .label = "delete group script",
3219 .type = P_STRING,
3220 .p_class = P_GLOBAL,
3221 .ptr = &Globals.szDelGroupScript,
3222 .special = NULL,
3223 .enum_list = NULL,
3224 .flags = FLAG_ADVANCED,
3227 .label = "add user to group script",
3228 .type = P_STRING,
3229 .p_class = P_GLOBAL,
3230 .ptr = &Globals.szAddUserToGroupScript,
3231 .special = NULL,
3232 .enum_list = NULL,
3233 .flags = FLAG_ADVANCED,
3236 .label = "delete user from group script",
3237 .type = P_STRING,
3238 .p_class = P_GLOBAL,
3239 .ptr = &Globals.szDelUserFromGroupScript,
3240 .special = NULL,
3241 .enum_list = NULL,
3242 .flags = FLAG_ADVANCED,
3245 .label = "set primary group script",
3246 .type = P_STRING,
3247 .p_class = P_GLOBAL,
3248 .ptr = &Globals.szSetPrimaryGroupScript,
3249 .special = NULL,
3250 .enum_list = NULL,
3251 .flags = FLAG_ADVANCED,
3254 .label = "add machine script",
3255 .type = P_STRING,
3256 .p_class = P_GLOBAL,
3257 .ptr = &Globals.szAddMachineScript,
3258 .special = NULL,
3259 .enum_list = NULL,
3260 .flags = FLAG_ADVANCED,
3263 .label = "shutdown script",
3264 .type = P_STRING,
3265 .p_class = P_GLOBAL,
3266 .ptr = &Globals.szShutdownScript,
3267 .special = NULL,
3268 .enum_list = NULL,
3269 .flags = FLAG_ADVANCED,
3272 .label = "abort shutdown script",
3273 .type = P_STRING,
3274 .p_class = P_GLOBAL,
3275 .ptr = &Globals.szAbortShutdownScript,
3276 .special = NULL,
3277 .enum_list = NULL,
3278 .flags = FLAG_ADVANCED,
3281 .label = "username map script",
3282 .type = P_STRING,
3283 .p_class = P_GLOBAL,
3284 .ptr = &Globals.szUsernameMapScript,
3285 .special = NULL,
3286 .enum_list = NULL,
3287 .flags = FLAG_ADVANCED,
3290 .label = "username map cache time",
3291 .type = P_INTEGER,
3292 .p_class = P_GLOBAL,
3293 .ptr = &Globals.iUsernameMapCacheTime,
3294 .special = NULL,
3295 .enum_list = NULL,
3296 .flags = FLAG_ADVANCED,
3299 .label = "logon script",
3300 .type = P_STRING,
3301 .p_class = P_GLOBAL,
3302 .ptr = &Globals.szLogonScript,
3303 .special = NULL,
3304 .enum_list = NULL,
3305 .flags = FLAG_ADVANCED,
3308 .label = "logon path",
3309 .type = P_STRING,
3310 .p_class = P_GLOBAL,
3311 .ptr = &Globals.szLogonPath,
3312 .special = NULL,
3313 .enum_list = NULL,
3314 .flags = FLAG_ADVANCED,
3317 .label = "logon drive",
3318 .type = P_STRING,
3319 .p_class = P_GLOBAL,
3320 .ptr = &Globals.szLogonDrive,
3321 .special = NULL,
3322 .enum_list = NULL,
3323 .flags = FLAG_ADVANCED,
3326 .label = "logon home",
3327 .type = P_STRING,
3328 .p_class = P_GLOBAL,
3329 .ptr = &Globals.szLogonHome,
3330 .special = NULL,
3331 .enum_list = NULL,
3332 .flags = FLAG_ADVANCED,
3335 .label = "domain logons",
3336 .type = P_BOOL,
3337 .p_class = P_GLOBAL,
3338 .ptr = &Globals.bDomainLogons,
3339 .special = NULL,
3340 .enum_list = NULL,
3341 .flags = FLAG_ADVANCED,
3345 .label = "init logon delayed hosts",
3346 .type = P_LIST,
3347 .p_class = P_GLOBAL,
3348 .ptr = &Globals.szInitLogonDelayedHosts,
3349 .special = NULL,
3350 .enum_list = NULL,
3351 .flags = FLAG_ADVANCED,
3355 .label = "init logon delay",
3356 .type = P_INTEGER,
3357 .p_class = P_GLOBAL,
3358 .ptr = &Globals.InitLogonDelay,
3359 .special = NULL,
3360 .enum_list = NULL,
3361 .flags = FLAG_ADVANCED,
3365 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3368 .label = "os level",
3369 .type = P_INTEGER,
3370 .p_class = P_GLOBAL,
3371 .ptr = &Globals.os_level,
3372 .special = NULL,
3373 .enum_list = NULL,
3374 .flags = FLAG_BASIC | FLAG_ADVANCED,
3377 .label = "lm announce",
3378 .type = P_ENUM,
3379 .p_class = P_GLOBAL,
3380 .ptr = &Globals.lm_announce,
3381 .special = NULL,
3382 .enum_list = enum_bool_auto,
3383 .flags = FLAG_ADVANCED,
3386 .label = "lm interval",
3387 .type = P_INTEGER,
3388 .p_class = P_GLOBAL,
3389 .ptr = &Globals.lm_interval,
3390 .special = NULL,
3391 .enum_list = NULL,
3392 .flags = FLAG_ADVANCED,
3395 .label = "preferred master",
3396 .type = P_ENUM,
3397 .p_class = P_GLOBAL,
3398 .ptr = &Globals.iPreferredMaster,
3399 .special = NULL,
3400 .enum_list = enum_bool_auto,
3401 .flags = FLAG_BASIC | FLAG_ADVANCED,
3404 .label = "prefered master",
3405 .type = P_ENUM,
3406 .p_class = P_GLOBAL,
3407 .ptr = &Globals.iPreferredMaster,
3408 .special = NULL,
3409 .enum_list = enum_bool_auto,
3410 .flags = FLAG_HIDE,
3413 .label = "local master",
3414 .type = P_BOOL,
3415 .p_class = P_GLOBAL,
3416 .ptr = &Globals.bLocalMaster,
3417 .special = NULL,
3418 .enum_list = NULL,
3419 .flags = FLAG_BASIC | FLAG_ADVANCED,
3422 .label = "domain master",
3423 .type = P_ENUM,
3424 .p_class = P_GLOBAL,
3425 .ptr = &Globals.iDomainMaster,
3426 .special = NULL,
3427 .enum_list = enum_bool_auto,
3428 .flags = FLAG_BASIC | FLAG_ADVANCED,
3431 .label = "browse list",
3432 .type = P_BOOL,
3433 .p_class = P_GLOBAL,
3434 .ptr = &Globals.bBrowseList,
3435 .special = NULL,
3436 .enum_list = NULL,
3437 .flags = FLAG_ADVANCED,
3440 .label = "browseable",
3441 .type = P_BOOL,
3442 .p_class = P_LOCAL,
3443 .ptr = &sDefault.bBrowseable,
3444 .special = NULL,
3445 .enum_list = NULL,
3446 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3449 .label = "browsable",
3450 .type = P_BOOL,
3451 .p_class = P_LOCAL,
3452 .ptr = &sDefault.bBrowseable,
3453 .special = NULL,
3454 .enum_list = NULL,
3455 .flags = FLAG_HIDE,
3458 .label = "access based share enum",
3459 .type = P_BOOL,
3460 .p_class = P_LOCAL,
3461 .ptr = &sDefault.bAccessBasedShareEnum,
3462 .special = NULL,
3463 .enum_list = NULL,
3464 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3467 .label = "enhanced browsing",
3468 .type = P_BOOL,
3469 .p_class = P_GLOBAL,
3470 .ptr = &Globals.enhanced_browsing,
3471 .special = NULL,
3472 .enum_list = NULL,
3473 .flags = FLAG_ADVANCED,
3476 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3479 .label = "dns proxy",
3480 .type = P_BOOL,
3481 .p_class = P_GLOBAL,
3482 .ptr = &Globals.bDNSproxy,
3483 .special = NULL,
3484 .enum_list = NULL,
3485 .flags = FLAG_ADVANCED,
3488 .label = "wins proxy",
3489 .type = P_BOOL,
3490 .p_class = P_GLOBAL,
3491 .ptr = &Globals.bWINSproxy,
3492 .special = NULL,
3493 .enum_list = NULL,
3494 .flags = FLAG_ADVANCED,
3497 .label = "wins server",
3498 .type = P_LIST,
3499 .p_class = P_GLOBAL,
3500 .ptr = &Globals.szWINSservers,
3501 .special = NULL,
3502 .enum_list = NULL,
3503 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3506 .label = "wins support",
3507 .type = P_BOOL,
3508 .p_class = P_GLOBAL,
3509 .ptr = &Globals.bWINSsupport,
3510 .special = NULL,
3511 .enum_list = NULL,
3512 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3515 .label = "wins hook",
3516 .type = P_STRING,
3517 .p_class = P_GLOBAL,
3518 .ptr = &Globals.szWINSHook,
3519 .special = NULL,
3520 .enum_list = NULL,
3521 .flags = FLAG_ADVANCED,
3524 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3527 .label = "blocking locks",
3528 .type = P_BOOL,
3529 .p_class = P_LOCAL,
3530 .ptr = &sDefault.bBlockingLocks,
3531 .special = NULL,
3532 .enum_list = NULL,
3533 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3536 .label = "csc policy",
3537 .type = P_ENUM,
3538 .p_class = P_LOCAL,
3539 .ptr = &sDefault.iCSCPolicy,
3540 .special = NULL,
3541 .enum_list = enum_csc_policy,
3542 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3545 .label = "fake oplocks",
3546 .type = P_BOOL,
3547 .p_class = P_LOCAL,
3548 .ptr = &sDefault.bFakeOplocks,
3549 .special = NULL,
3550 .enum_list = NULL,
3551 .flags = FLAG_ADVANCED | FLAG_SHARE,
3554 .label = "kernel oplocks",
3555 .type = P_BOOL,
3556 .p_class = P_GLOBAL,
3557 .ptr = &Globals.bKernelOplocks,
3558 .special = NULL,
3559 .enum_list = NULL,
3560 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3563 .label = "locking",
3564 .type = P_BOOL,
3565 .p_class = P_LOCAL,
3566 .ptr = &sDefault.bLocking,
3567 .special = NULL,
3568 .enum_list = NULL,
3569 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3572 .label = "lock spin time",
3573 .type = P_INTEGER,
3574 .p_class = P_GLOBAL,
3575 .ptr = &Globals.iLockSpinTime,
3576 .special = NULL,
3577 .enum_list = NULL,
3578 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3581 .label = "oplocks",
3582 .type = P_BOOL,
3583 .p_class = P_LOCAL,
3584 .ptr = &sDefault.bOpLocks,
3585 .special = NULL,
3586 .enum_list = NULL,
3587 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3590 .label = "level2 oplocks",
3591 .type = P_BOOL,
3592 .p_class = P_LOCAL,
3593 .ptr = &sDefault.bLevel2OpLocks,
3594 .special = NULL,
3595 .enum_list = NULL,
3596 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3599 .label = "oplock break wait time",
3600 .type = P_INTEGER,
3601 .p_class = P_GLOBAL,
3602 .ptr = &Globals.oplock_break_wait_time,
3603 .special = NULL,
3604 .enum_list = NULL,
3605 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3608 .label = "oplock contention limit",
3609 .type = P_INTEGER,
3610 .p_class = P_LOCAL,
3611 .ptr = &sDefault.iOplockContentionLimit,
3612 .special = NULL,
3613 .enum_list = NULL,
3614 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3617 .label = "posix locking",
3618 .type = P_BOOL,
3619 .p_class = P_LOCAL,
3620 .ptr = &sDefault.bPosixLocking,
3621 .special = NULL,
3622 .enum_list = NULL,
3623 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3626 .label = "strict locking",
3627 .type = P_ENUM,
3628 .p_class = P_LOCAL,
3629 .ptr = &sDefault.iStrictLocking,
3630 .special = NULL,
3631 .enum_list = enum_bool_auto,
3632 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3635 .label = "share modes",
3636 .type = P_BOOL,
3637 .p_class = P_LOCAL,
3638 .ptr = &sDefault.bShareModes,
3639 .special = NULL,
3640 .enum_list = NULL,
3641 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3644 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3647 .label = "ldap admin dn",
3648 .type = P_STRING,
3649 .p_class = P_GLOBAL,
3650 .ptr = &Globals.szLdapAdminDn,
3651 .special = NULL,
3652 .enum_list = NULL,
3653 .flags = FLAG_ADVANCED,
3656 .label = "ldap delete dn",
3657 .type = P_BOOL,
3658 .p_class = P_GLOBAL,
3659 .ptr = &Globals.ldap_delete_dn,
3660 .special = NULL,
3661 .enum_list = NULL,
3662 .flags = FLAG_ADVANCED,
3665 .label = "ldap group suffix",
3666 .type = P_STRING,
3667 .p_class = P_GLOBAL,
3668 .ptr = &Globals.szLdapGroupSuffix,
3669 .special = NULL,
3670 .enum_list = NULL,
3671 .flags = FLAG_ADVANCED,
3674 .label = "ldap idmap suffix",
3675 .type = P_STRING,
3676 .p_class = P_GLOBAL,
3677 .ptr = &Globals.szLdapIdmapSuffix,
3678 .special = NULL,
3679 .enum_list = NULL,
3680 .flags = FLAG_ADVANCED,
3683 .label = "ldap machine suffix",
3684 .type = P_STRING,
3685 .p_class = P_GLOBAL,
3686 .ptr = &Globals.szLdapMachineSuffix,
3687 .special = NULL,
3688 .enum_list = NULL,
3689 .flags = FLAG_ADVANCED,
3692 .label = "ldap passwd sync",
3693 .type = P_ENUM,
3694 .p_class = P_GLOBAL,
3695 .ptr = &Globals.ldap_passwd_sync,
3696 .special = NULL,
3697 .enum_list = enum_ldap_passwd_sync,
3698 .flags = FLAG_ADVANCED,
3701 .label = "ldap password sync",
3702 .type = P_ENUM,
3703 .p_class = P_GLOBAL,
3704 .ptr = &Globals.ldap_passwd_sync,
3705 .special = NULL,
3706 .enum_list = enum_ldap_passwd_sync,
3707 .flags = FLAG_HIDE,
3710 .label = "ldap replication sleep",
3711 .type = P_INTEGER,
3712 .p_class = P_GLOBAL,
3713 .ptr = &Globals.ldap_replication_sleep,
3714 .special = NULL,
3715 .enum_list = NULL,
3716 .flags = FLAG_ADVANCED,
3719 .label = "ldap suffix",
3720 .type = P_STRING,
3721 .p_class = P_GLOBAL,
3722 .ptr = &Globals.szLdapSuffix,
3723 .special = NULL,
3724 .enum_list = NULL,
3725 .flags = FLAG_ADVANCED,
3728 .label = "ldap ssl",
3729 .type = P_ENUM,
3730 .p_class = P_GLOBAL,
3731 .ptr = &Globals.ldap_ssl,
3732 .special = NULL,
3733 .enum_list = enum_ldap_ssl,
3734 .flags = FLAG_ADVANCED,
3737 .label = "ldap ssl ads",
3738 .type = P_BOOL,
3739 .p_class = P_GLOBAL,
3740 .ptr = &Globals.ldap_ssl_ads,
3741 .special = NULL,
3742 .enum_list = NULL,
3743 .flags = FLAG_ADVANCED,
3746 .label = "ldap deref",
3747 .type = P_ENUM,
3748 .p_class = P_GLOBAL,
3749 .ptr = &Globals.ldap_deref,
3750 .special = NULL,
3751 .enum_list = enum_ldap_deref,
3752 .flags = FLAG_ADVANCED,
3755 .label = "ldap follow referral",
3756 .type = P_ENUM,
3757 .p_class = P_GLOBAL,
3758 .ptr = &Globals.ldap_follow_referral,
3759 .special = NULL,
3760 .enum_list = enum_bool_auto,
3761 .flags = FLAG_ADVANCED,
3764 .label = "ldap timeout",
3765 .type = P_INTEGER,
3766 .p_class = P_GLOBAL,
3767 .ptr = &Globals.ldap_timeout,
3768 .special = NULL,
3769 .enum_list = NULL,
3770 .flags = FLAG_ADVANCED,
3773 .label = "ldap connection timeout",
3774 .type = P_INTEGER,
3775 .p_class = P_GLOBAL,
3776 .ptr = &Globals.ldap_connection_timeout,
3777 .special = NULL,
3778 .enum_list = NULL,
3779 .flags = FLAG_ADVANCED,
3782 .label = "ldap page size",
3783 .type = P_INTEGER,
3784 .p_class = P_GLOBAL,
3785 .ptr = &Globals.ldap_page_size,
3786 .special = NULL,
3787 .enum_list = NULL,
3788 .flags = FLAG_ADVANCED,
3791 .label = "ldap user suffix",
3792 .type = P_STRING,
3793 .p_class = P_GLOBAL,
3794 .ptr = &Globals.szLdapUserSuffix,
3795 .special = NULL,
3796 .enum_list = NULL,
3797 .flags = FLAG_ADVANCED,
3800 .label = "ldap debug level",
3801 .type = P_INTEGER,
3802 .p_class = P_GLOBAL,
3803 .ptr = &Globals.ldap_debug_level,
3804 .special = handle_ldap_debug_level,
3805 .enum_list = NULL,
3806 .flags = FLAG_ADVANCED,
3809 .label = "ldap debug threshold",
3810 .type = P_INTEGER,
3811 .p_class = P_GLOBAL,
3812 .ptr = &Globals.ldap_debug_threshold,
3813 .special = NULL,
3814 .enum_list = NULL,
3815 .flags = FLAG_ADVANCED,
3818 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3821 .label = "eventlog list",
3822 .type = P_LIST,
3823 .p_class = P_GLOBAL,
3824 .ptr = &Globals.szEventLogs,
3825 .special = NULL,
3826 .enum_list = NULL,
3827 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3830 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3833 .label = "add share command",
3834 .type = P_STRING,
3835 .p_class = P_GLOBAL,
3836 .ptr = &Globals.szAddShareCommand,
3837 .special = NULL,
3838 .enum_list = NULL,
3839 .flags = FLAG_ADVANCED,
3842 .label = "change share command",
3843 .type = P_STRING,
3844 .p_class = P_GLOBAL,
3845 .ptr = &Globals.szChangeShareCommand,
3846 .special = NULL,
3847 .enum_list = NULL,
3848 .flags = FLAG_ADVANCED,
3851 .label = "delete share command",
3852 .type = P_STRING,
3853 .p_class = P_GLOBAL,
3854 .ptr = &Globals.szDeleteShareCommand,
3855 .special = NULL,
3856 .enum_list = NULL,
3857 .flags = FLAG_ADVANCED,
3860 .label = "config file",
3861 .type = P_STRING,
3862 .p_class = P_GLOBAL,
3863 .ptr = &Globals.szConfigFile,
3864 .special = NULL,
3865 .enum_list = NULL,
3866 .flags = FLAG_HIDE|FLAG_META,
3869 .label = "preload",
3870 .type = P_STRING,
3871 .p_class = P_GLOBAL,
3872 .ptr = &Globals.szAutoServices,
3873 .special = NULL,
3874 .enum_list = NULL,
3875 .flags = FLAG_ADVANCED,
3878 .label = "auto services",
3879 .type = P_STRING,
3880 .p_class = P_GLOBAL,
3881 .ptr = &Globals.szAutoServices,
3882 .special = NULL,
3883 .enum_list = NULL,
3884 .flags = FLAG_ADVANCED,
3887 .label = "lock directory",
3888 .type = P_STRING,
3889 .p_class = P_GLOBAL,
3890 .ptr = &Globals.szLockDir,
3891 .special = NULL,
3892 .enum_list = NULL,
3893 .flags = FLAG_ADVANCED,
3896 .label = "lock dir",
3897 .type = P_STRING,
3898 .p_class = P_GLOBAL,
3899 .ptr = &Globals.szLockDir,
3900 .special = NULL,
3901 .enum_list = NULL,
3902 .flags = FLAG_HIDE,
3905 .label = "state directory",
3906 .type = P_STRING,
3907 .p_class = P_GLOBAL,
3908 .ptr = &Globals.szStateDir,
3909 .special = NULL,
3910 .enum_list = NULL,
3911 .flags = FLAG_ADVANCED,
3914 .label = "cache directory",
3915 .type = P_STRING,
3916 .p_class = P_GLOBAL,
3917 .ptr = &Globals.szCacheDir,
3918 .special = NULL,
3919 .enum_list = NULL,
3920 .flags = FLAG_ADVANCED,
3923 .label = "pid directory",
3924 .type = P_STRING,
3925 .p_class = P_GLOBAL,
3926 .ptr = &Globals.szPidDir,
3927 .special = NULL,
3928 .enum_list = NULL,
3929 .flags = FLAG_ADVANCED,
3931 #ifdef WITH_UTMP
3933 .label = "utmp directory",
3934 .type = P_STRING,
3935 .p_class = P_GLOBAL,
3936 .ptr = &Globals.szUtmpDir,
3937 .special = NULL,
3938 .enum_list = NULL,
3939 .flags = FLAG_ADVANCED,
3942 .label = "wtmp directory",
3943 .type = P_STRING,
3944 .p_class = P_GLOBAL,
3945 .ptr = &Globals.szWtmpDir,
3946 .special = NULL,
3947 .enum_list = NULL,
3948 .flags = FLAG_ADVANCED,
3951 .label = "utmp",
3952 .type = P_BOOL,
3953 .p_class = P_GLOBAL,
3954 .ptr = &Globals.bUtmp,
3955 .special = NULL,
3956 .enum_list = NULL,
3957 .flags = FLAG_ADVANCED,
3959 #endif
3961 .label = "default service",
3962 .type = P_STRING,
3963 .p_class = P_GLOBAL,
3964 .ptr = &Globals.szDefaultService,
3965 .special = NULL,
3966 .enum_list = NULL,
3967 .flags = FLAG_ADVANCED,
3970 .label = "default",
3971 .type = P_STRING,
3972 .p_class = P_GLOBAL,
3973 .ptr = &Globals.szDefaultService,
3974 .special = NULL,
3975 .enum_list = NULL,
3976 .flags = FLAG_ADVANCED,
3979 .label = "message command",
3980 .type = P_STRING,
3981 .p_class = P_GLOBAL,
3982 .ptr = &Globals.szMsgCommand,
3983 .special = NULL,
3984 .enum_list = NULL,
3985 .flags = FLAG_ADVANCED,
3988 .label = "dfree cache time",
3989 .type = P_INTEGER,
3990 .p_class = P_LOCAL,
3991 .ptr = &sDefault.iDfreeCacheTime,
3992 .special = NULL,
3993 .enum_list = NULL,
3994 .flags = FLAG_ADVANCED,
3997 .label = "dfree command",
3998 .type = P_STRING,
3999 .p_class = P_LOCAL,
4000 .ptr = &sDefault.szDfree,
4001 .special = NULL,
4002 .enum_list = NULL,
4003 .flags = FLAG_ADVANCED,
4006 .label = "get quota command",
4007 .type = P_STRING,
4008 .p_class = P_GLOBAL,
4009 .ptr = &Globals.szGetQuota,
4010 .special = NULL,
4011 .enum_list = NULL,
4012 .flags = FLAG_ADVANCED,
4015 .label = "set quota command",
4016 .type = P_STRING,
4017 .p_class = P_GLOBAL,
4018 .ptr = &Globals.szSetQuota,
4019 .special = NULL,
4020 .enum_list = NULL,
4021 .flags = FLAG_ADVANCED,
4024 .label = "remote announce",
4025 .type = P_STRING,
4026 .p_class = P_GLOBAL,
4027 .ptr = &Globals.szRemoteAnnounce,
4028 .special = NULL,
4029 .enum_list = NULL,
4030 .flags = FLAG_ADVANCED,
4033 .label = "remote browse sync",
4034 .type = P_STRING,
4035 .p_class = P_GLOBAL,
4036 .ptr = &Globals.szRemoteBrowseSync,
4037 .special = NULL,
4038 .enum_list = NULL,
4039 .flags = FLAG_ADVANCED,
4042 .label = "socket address",
4043 .type = P_STRING,
4044 .p_class = P_GLOBAL,
4045 .ptr = &Globals.szSocketAddress,
4046 .special = NULL,
4047 .enum_list = NULL,
4048 .flags = FLAG_ADVANCED,
4051 .label = "nmbd bind explicit broadcast",
4052 .type = P_BOOL,
4053 .p_class = P_GLOBAL,
4054 .ptr = &Globals.bNmbdBindExplicitBroadcast,
4055 .special = NULL,
4056 .enum_list = NULL,
4057 .flags = FLAG_ADVANCED,
4060 .label = "homedir map",
4061 .type = P_STRING,
4062 .p_class = P_GLOBAL,
4063 .ptr = &Globals.szNISHomeMapName,
4064 .special = NULL,
4065 .enum_list = NULL,
4066 .flags = FLAG_ADVANCED,
4069 .label = "afs username map",
4070 .type = P_STRING,
4071 .p_class = P_GLOBAL,
4072 .ptr = &Globals.szAfsUsernameMap,
4073 .special = NULL,
4074 .enum_list = NULL,
4075 .flags = FLAG_ADVANCED,
4078 .label = "afs token lifetime",
4079 .type = P_INTEGER,
4080 .p_class = P_GLOBAL,
4081 .ptr = &Globals.iAfsTokenLifetime,
4082 .special = NULL,
4083 .enum_list = NULL,
4084 .flags = FLAG_ADVANCED,
4087 .label = "log nt token command",
4088 .type = P_STRING,
4089 .p_class = P_GLOBAL,
4090 .ptr = &Globals.szLogNtTokenCommand,
4091 .special = NULL,
4092 .enum_list = NULL,
4093 .flags = FLAG_ADVANCED,
4096 .label = "time offset",
4097 .type = P_INTEGER,
4098 .p_class = P_GLOBAL,
4099 .ptr = &extra_time_offset,
4100 .special = NULL,
4101 .enum_list = NULL,
4102 .flags = FLAG_ADVANCED,
4105 .label = "NIS homedir",
4106 .type = P_BOOL,
4107 .p_class = P_GLOBAL,
4108 .ptr = &Globals.bNISHomeMap,
4109 .special = NULL,
4110 .enum_list = NULL,
4111 .flags = FLAG_ADVANCED,
4114 .label = "-valid",
4115 .type = P_BOOL,
4116 .p_class = P_LOCAL,
4117 .ptr = &sDefault.valid,
4118 .special = NULL,
4119 .enum_list = NULL,
4120 .flags = FLAG_HIDE,
4123 .label = "copy",
4124 .type = P_STRING,
4125 .p_class = P_LOCAL,
4126 .ptr = &sDefault.szCopy,
4127 .special = handle_copy,
4128 .enum_list = NULL,
4129 .flags = FLAG_HIDE,
4132 .label = "include",
4133 .type = P_STRING,
4134 .p_class = P_LOCAL,
4135 .ptr = &sDefault.szInclude,
4136 .special = handle_include,
4137 .enum_list = NULL,
4138 .flags = FLAG_HIDE|FLAG_META,
4141 .label = "preexec",
4142 .type = P_STRING,
4143 .p_class = P_LOCAL,
4144 .ptr = &sDefault.szPreExec,
4145 .special = NULL,
4146 .enum_list = NULL,
4147 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4150 .label = "exec",
4151 .type = P_STRING,
4152 .p_class = P_LOCAL,
4153 .ptr = &sDefault.szPreExec,
4154 .special = NULL,
4155 .enum_list = NULL,
4156 .flags = FLAG_ADVANCED,
4159 .label = "preexec close",
4160 .type = P_BOOL,
4161 .p_class = P_LOCAL,
4162 .ptr = &sDefault.bPreexecClose,
4163 .special = NULL,
4164 .enum_list = NULL,
4165 .flags = FLAG_ADVANCED | FLAG_SHARE,
4168 .label = "postexec",
4169 .type = P_STRING,
4170 .p_class = P_LOCAL,
4171 .ptr = &sDefault.szPostExec,
4172 .special = NULL,
4173 .enum_list = NULL,
4174 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4177 .label = "root preexec",
4178 .type = P_STRING,
4179 .p_class = P_LOCAL,
4180 .ptr = &sDefault.szRootPreExec,
4181 .special = NULL,
4182 .enum_list = NULL,
4183 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4186 .label = "root preexec close",
4187 .type = P_BOOL,
4188 .p_class = P_LOCAL,
4189 .ptr = &sDefault.bRootpreexecClose,
4190 .special = NULL,
4191 .enum_list = NULL,
4192 .flags = FLAG_ADVANCED | FLAG_SHARE,
4195 .label = "root postexec",
4196 .type = P_STRING,
4197 .p_class = P_LOCAL,
4198 .ptr = &sDefault.szRootPostExec,
4199 .special = NULL,
4200 .enum_list = NULL,
4201 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4204 .label = "available",
4205 .type = P_BOOL,
4206 .p_class = P_LOCAL,
4207 .ptr = &sDefault.bAvailable,
4208 .special = NULL,
4209 .enum_list = NULL,
4210 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4213 .label = "registry shares",
4214 .type = P_BOOL,
4215 .p_class = P_GLOBAL,
4216 .ptr = &Globals.bRegistryShares,
4217 .special = NULL,
4218 .enum_list = NULL,
4219 .flags = FLAG_ADVANCED,
4222 .label = "usershare allow guests",
4223 .type = P_BOOL,
4224 .p_class = P_GLOBAL,
4225 .ptr = &Globals.bUsershareAllowGuests,
4226 .special = NULL,
4227 .enum_list = NULL,
4228 .flags = FLAG_ADVANCED,
4231 .label = "usershare max shares",
4232 .type = P_INTEGER,
4233 .p_class = P_GLOBAL,
4234 .ptr = &Globals.iUsershareMaxShares,
4235 .special = NULL,
4236 .enum_list = NULL,
4237 .flags = FLAG_ADVANCED,
4240 .label = "usershare owner only",
4241 .type = P_BOOL,
4242 .p_class = P_GLOBAL,
4243 .ptr = &Globals.bUsershareOwnerOnly,
4244 .special = NULL,
4245 .enum_list = NULL,
4246 .flags = FLAG_ADVANCED,
4249 .label = "usershare path",
4250 .type = P_STRING,
4251 .p_class = P_GLOBAL,
4252 .ptr = &Globals.szUsersharePath,
4253 .special = NULL,
4254 .enum_list = NULL,
4255 .flags = FLAG_ADVANCED,
4258 .label = "usershare prefix allow list",
4259 .type = P_LIST,
4260 .p_class = P_GLOBAL,
4261 .ptr = &Globals.szUsersharePrefixAllowList,
4262 .special = NULL,
4263 .enum_list = NULL,
4264 .flags = FLAG_ADVANCED,
4267 .label = "usershare prefix deny list",
4268 .type = P_LIST,
4269 .p_class = P_GLOBAL,
4270 .ptr = &Globals.szUsersharePrefixDenyList,
4271 .special = NULL,
4272 .enum_list = NULL,
4273 .flags = FLAG_ADVANCED,
4276 .label = "usershare template share",
4277 .type = P_STRING,
4278 .p_class = P_GLOBAL,
4279 .ptr = &Globals.szUsershareTemplateShare,
4280 .special = NULL,
4281 .enum_list = NULL,
4282 .flags = FLAG_ADVANCED,
4285 .label = "volume",
4286 .type = P_STRING,
4287 .p_class = P_LOCAL,
4288 .ptr = &sDefault.volume,
4289 .special = NULL,
4290 .enum_list = NULL,
4291 .flags = FLAG_ADVANCED | FLAG_SHARE,
4294 .label = "fstype",
4295 .type = P_STRING,
4296 .p_class = P_LOCAL,
4297 .ptr = &sDefault.fstype,
4298 .special = NULL,
4299 .enum_list = NULL,
4300 .flags = FLAG_ADVANCED | FLAG_SHARE,
4303 .label = "set directory",
4304 .type = P_BOOLREV,
4305 .p_class = P_LOCAL,
4306 .ptr = &sDefault.bNo_set_dir,
4307 .special = NULL,
4308 .enum_list = NULL,
4309 .flags = FLAG_ADVANCED | FLAG_SHARE,
4312 .label = "wide links",
4313 .type = P_BOOL,
4314 .p_class = P_LOCAL,
4315 .ptr = &sDefault.bWidelinks,
4316 .special = NULL,
4317 .enum_list = NULL,
4318 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4321 .label = "follow symlinks",
4322 .type = P_BOOL,
4323 .p_class = P_LOCAL,
4324 .ptr = &sDefault.bSymlinks,
4325 .special = NULL,
4326 .enum_list = NULL,
4327 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4330 .label = "dont descend",
4331 .type = P_STRING,
4332 .p_class = P_LOCAL,
4333 .ptr = &sDefault.szDontdescend,
4334 .special = NULL,
4335 .enum_list = NULL,
4336 .flags = FLAG_ADVANCED | FLAG_SHARE,
4339 .label = "magic script",
4340 .type = P_STRING,
4341 .p_class = P_LOCAL,
4342 .ptr = &sDefault.szMagicScript,
4343 .special = NULL,
4344 .enum_list = NULL,
4345 .flags = FLAG_ADVANCED | FLAG_SHARE,
4348 .label = "magic output",
4349 .type = P_STRING,
4350 .p_class = P_LOCAL,
4351 .ptr = &sDefault.szMagicOutput,
4352 .special = NULL,
4353 .enum_list = NULL,
4354 .flags = FLAG_ADVANCED | FLAG_SHARE,
4357 .label = "delete readonly",
4358 .type = P_BOOL,
4359 .p_class = P_LOCAL,
4360 .ptr = &sDefault.bDeleteReadonly,
4361 .special = NULL,
4362 .enum_list = NULL,
4363 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4366 .label = "dos filemode",
4367 .type = P_BOOL,
4368 .p_class = P_LOCAL,
4369 .ptr = &sDefault.bDosFilemode,
4370 .special = NULL,
4371 .enum_list = NULL,
4372 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4375 .label = "dos filetimes",
4376 .type = P_BOOL,
4377 .p_class = P_LOCAL,
4378 .ptr = &sDefault.bDosFiletimes,
4379 .special = NULL,
4380 .enum_list = NULL,
4381 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4384 .label = "dos filetime resolution",
4385 .type = P_BOOL,
4386 .p_class = P_LOCAL,
4387 .ptr = &sDefault.bDosFiletimeResolution,
4388 .special = NULL,
4389 .enum_list = NULL,
4390 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4393 .label = "fake directory create times",
4394 .type = P_BOOL,
4395 .p_class = P_LOCAL,
4396 .ptr = &sDefault.bFakeDirCreateTimes,
4397 .special = NULL,
4398 .enum_list = NULL,
4399 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4402 .label = "async smb echo handler",
4403 .type = P_BOOL,
4404 .p_class = P_GLOBAL,
4405 .ptr = &Globals.bAsyncSMBEchoHandler,
4406 .special = NULL,
4407 .enum_list = NULL,
4408 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
4411 .label = "panic action",
4412 .type = P_STRING,
4413 .p_class = P_GLOBAL,
4414 .ptr = &Globals.szPanicAction,
4415 .special = NULL,
4416 .enum_list = NULL,
4417 .flags = FLAG_ADVANCED,
4420 .label = "perfcount module",
4421 .type = P_STRING,
4422 .p_class = P_GLOBAL,
4423 .ptr = &Globals.szSMBPerfcountModule,
4424 .special = NULL,
4425 .enum_list = NULL,
4426 .flags = FLAG_ADVANCED,
4429 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4432 .label = "vfs objects",
4433 .type = P_LIST,
4434 .p_class = P_LOCAL,
4435 .ptr = &sDefault.szVfsObjects,
4436 .special = NULL,
4437 .enum_list = NULL,
4438 .flags = FLAG_ADVANCED | FLAG_SHARE,
4441 .label = "vfs object",
4442 .type = P_LIST,
4443 .p_class = P_LOCAL,
4444 .ptr = &sDefault.szVfsObjects,
4445 .special = NULL,
4446 .enum_list = NULL,
4447 .flags = FLAG_HIDE,
4451 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4454 .label = "msdfs root",
4455 .type = P_BOOL,
4456 .p_class = P_LOCAL,
4457 .ptr = &sDefault.bMSDfsRoot,
4458 .special = NULL,
4459 .enum_list = NULL,
4460 .flags = FLAG_ADVANCED | FLAG_SHARE,
4463 .label = "msdfs proxy",
4464 .type = P_STRING,
4465 .p_class = P_LOCAL,
4466 .ptr = &sDefault.szMSDfsProxy,
4467 .special = NULL,
4468 .enum_list = NULL,
4469 .flags = FLAG_ADVANCED | FLAG_SHARE,
4472 .label = "host msdfs",
4473 .type = P_BOOL,
4474 .p_class = P_GLOBAL,
4475 .ptr = &Globals.bHostMSDfs,
4476 .special = NULL,
4477 .enum_list = NULL,
4478 .flags = FLAG_ADVANCED,
4481 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4484 .label = "passdb expand explicit",
4485 .type = P_BOOL,
4486 .p_class = P_GLOBAL,
4487 .ptr = &Globals.bPassdbExpandExplicit,
4488 .special = NULL,
4489 .enum_list = NULL,
4490 .flags = FLAG_ADVANCED,
4493 .label = "idmap backend",
4494 .type = P_STRING,
4495 .p_class = P_GLOBAL,
4496 .ptr = &Globals.szIdmapBackend,
4497 .special = NULL,
4498 .enum_list = NULL,
4499 .flags = FLAG_ADVANCED,
4502 .label = "idmap alloc backend",
4503 .type = P_STRING,
4504 .p_class = P_GLOBAL,
4505 .ptr = &Globals.szIdmapAllocBackend,
4506 .special = NULL,
4507 .enum_list = NULL,
4508 .flags = FLAG_ADVANCED,
4511 .label = "idmap cache time",
4512 .type = P_INTEGER,
4513 .p_class = P_GLOBAL,
4514 .ptr = &Globals.iIdmapCacheTime,
4515 .special = NULL,
4516 .enum_list = NULL,
4517 .flags = FLAG_ADVANCED,
4520 .label = "idmap negative cache time",
4521 .type = P_INTEGER,
4522 .p_class = P_GLOBAL,
4523 .ptr = &Globals.iIdmapNegativeCacheTime,
4524 .special = NULL,
4525 .enum_list = NULL,
4526 .flags = FLAG_ADVANCED,
4529 .label = "idmap uid",
4530 .type = P_STRING,
4531 .p_class = P_GLOBAL,
4532 .ptr = &Globals.szIdmapUID,
4533 .special = handle_idmap_uid,
4534 .enum_list = NULL,
4535 .flags = FLAG_ADVANCED,
4538 .label = "winbind uid",
4539 .type = P_STRING,
4540 .p_class = P_GLOBAL,
4541 .ptr = &Globals.szIdmapUID,
4542 .special = handle_idmap_uid,
4543 .enum_list = NULL,
4544 .flags = FLAG_HIDE,
4547 .label = "idmap gid",
4548 .type = P_STRING,
4549 .p_class = P_GLOBAL,
4550 .ptr = &Globals.szIdmapGID,
4551 .special = handle_idmap_gid,
4552 .enum_list = NULL,
4553 .flags = FLAG_ADVANCED,
4556 .label = "winbind gid",
4557 .type = P_STRING,
4558 .p_class = P_GLOBAL,
4559 .ptr = &Globals.szIdmapGID,
4560 .special = handle_idmap_gid,
4561 .enum_list = NULL,
4562 .flags = FLAG_HIDE,
4565 .label = "template homedir",
4566 .type = P_STRING,
4567 .p_class = P_GLOBAL,
4568 .ptr = &Globals.szTemplateHomedir,
4569 .special = NULL,
4570 .enum_list = NULL,
4571 .flags = FLAG_ADVANCED,
4574 .label = "template shell",
4575 .type = P_STRING,
4576 .p_class = P_GLOBAL,
4577 .ptr = &Globals.szTemplateShell,
4578 .special = NULL,
4579 .enum_list = NULL,
4580 .flags = FLAG_ADVANCED,
4583 .label = "winbind separator",
4584 .type = P_STRING,
4585 .p_class = P_GLOBAL,
4586 .ptr = &Globals.szWinbindSeparator,
4587 .special = NULL,
4588 .enum_list = NULL,
4589 .flags = FLAG_ADVANCED,
4592 .label = "winbind cache time",
4593 .type = P_INTEGER,
4594 .p_class = P_GLOBAL,
4595 .ptr = &Globals.winbind_cache_time,
4596 .special = NULL,
4597 .enum_list = NULL,
4598 .flags = FLAG_ADVANCED,
4601 .label = "winbind reconnect delay",
4602 .type = P_INTEGER,
4603 .p_class = P_GLOBAL,
4604 .ptr = &Globals.winbind_reconnect_delay,
4605 .special = NULL,
4606 .enum_list = NULL,
4607 .flags = FLAG_ADVANCED,
4610 .label = "winbind enum users",
4611 .type = P_BOOL,
4612 .p_class = P_GLOBAL,
4613 .ptr = &Globals.bWinbindEnumUsers,
4614 .special = NULL,
4615 .enum_list = NULL,
4616 .flags = FLAG_ADVANCED,
4619 .label = "winbind enum groups",
4620 .type = P_BOOL,
4621 .p_class = P_GLOBAL,
4622 .ptr = &Globals.bWinbindEnumGroups,
4623 .special = NULL,
4624 .enum_list = NULL,
4625 .flags = FLAG_ADVANCED,
4628 .label = "winbind use default domain",
4629 .type = P_BOOL,
4630 .p_class = P_GLOBAL,
4631 .ptr = &Globals.bWinbindUseDefaultDomain,
4632 .special = NULL,
4633 .enum_list = NULL,
4634 .flags = FLAG_ADVANCED,
4637 .label = "winbind trusted domains only",
4638 .type = P_BOOL,
4639 .p_class = P_GLOBAL,
4640 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4641 .special = NULL,
4642 .enum_list = NULL,
4643 .flags = FLAG_ADVANCED,
4646 .label = "winbind nested groups",
4647 .type = P_BOOL,
4648 .p_class = P_GLOBAL,
4649 .ptr = &Globals.bWinbindNestedGroups,
4650 .special = NULL,
4651 .enum_list = NULL,
4652 .flags = FLAG_ADVANCED,
4655 .label = "winbind expand groups",
4656 .type = P_INTEGER,
4657 .p_class = P_GLOBAL,
4658 .ptr = &Globals.winbind_expand_groups,
4659 .special = NULL,
4660 .enum_list = NULL,
4661 .flags = FLAG_ADVANCED,
4664 .label = "winbind nss info",
4665 .type = P_LIST,
4666 .p_class = P_GLOBAL,
4667 .ptr = &Globals.szWinbindNssInfo,
4668 .special = NULL,
4669 .enum_list = NULL,
4670 .flags = FLAG_ADVANCED,
4673 .label = "winbind refresh tickets",
4674 .type = P_BOOL,
4675 .p_class = P_GLOBAL,
4676 .ptr = &Globals.bWinbindRefreshTickets,
4677 .special = NULL,
4678 .enum_list = NULL,
4679 .flags = FLAG_ADVANCED,
4682 .label = "winbind offline logon",
4683 .type = P_BOOL,
4684 .p_class = P_GLOBAL,
4685 .ptr = &Globals.bWinbindOfflineLogon,
4686 .special = NULL,
4687 .enum_list = NULL,
4688 .flags = FLAG_ADVANCED,
4691 .label = "winbind normalize names",
4692 .type = P_BOOL,
4693 .p_class = P_GLOBAL,
4694 .ptr = &Globals.bWinbindNormalizeNames,
4695 .special = NULL,
4696 .enum_list = NULL,
4697 .flags = FLAG_ADVANCED,
4700 .label = "winbind rpc only",
4701 .type = P_BOOL,
4702 .p_class = P_GLOBAL,
4703 .ptr = &Globals.bWinbindRpcOnly,
4704 .special = NULL,
4705 .enum_list = NULL,
4706 .flags = FLAG_ADVANCED,
4709 .label = "create krb5 conf",
4710 .type = P_BOOL,
4711 .p_class = P_GLOBAL,
4712 .ptr = &Globals.bCreateKrb5Conf,
4713 .special = NULL,
4714 .enum_list = NULL,
4715 .flags = FLAG_ADVANCED,
4718 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4721 /***************************************************************************
4722 Initialise the sDefault parameter structure for the printer values.
4723 ***************************************************************************/
4725 static void init_printer_values(struct service *pService)
4727 /* choose defaults depending on the type of printing */
4728 switch (pService->iPrinting) {
4729 case PRINT_BSD:
4730 case PRINT_AIX:
4731 case PRINT_LPRNT:
4732 case PRINT_LPROS2:
4733 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4734 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4735 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4736 break;
4738 case PRINT_LPRNG:
4739 case PRINT_PLP:
4740 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4741 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4742 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4743 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4744 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4745 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4746 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4747 break;
4749 case PRINT_CUPS:
4750 case PRINT_IPRINT:
4751 #ifdef HAVE_CUPS
4752 /* set the lpq command to contain the destination printer
4753 name only. This is used by cups_queue_get() */
4754 string_set(&pService->szLpqcommand, "%p");
4755 string_set(&pService->szLprmcommand, "");
4756 string_set(&pService->szPrintcommand, "");
4757 string_set(&pService->szLppausecommand, "");
4758 string_set(&pService->szLpresumecommand, "");
4759 string_set(&pService->szQueuepausecommand, "");
4760 string_set(&pService->szQueueresumecommand, "");
4761 #else
4762 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4763 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4764 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4765 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4766 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4767 string_set(&pService->szQueuepausecommand, "disable '%p'");
4768 string_set(&pService->szQueueresumecommand, "enable '%p'");
4769 #endif /* HAVE_CUPS */
4770 break;
4772 case PRINT_SYSV:
4773 case PRINT_HPUX:
4774 string_set(&pService->szLpqcommand, "lpstat -o%p");
4775 string_set(&pService->szLprmcommand, "cancel %p-%j");
4776 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4777 string_set(&pService->szQueuepausecommand, "disable %p");
4778 string_set(&pService->szQueueresumecommand, "enable %p");
4779 #ifndef HPUX
4780 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4781 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4782 #endif /* HPUX */
4783 break;
4785 case PRINT_QNX:
4786 string_set(&pService->szLpqcommand, "lpq -P%p");
4787 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4788 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4789 break;
4791 #ifdef DEVELOPER
4792 case PRINT_TEST:
4793 case PRINT_VLP:
4794 string_set(&pService->szPrintcommand, "vlp print %p %s");
4795 string_set(&pService->szLpqcommand, "vlp lpq %p");
4796 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4797 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4798 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4799 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4800 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4801 break;
4802 #endif /* DEVELOPER */
4807 * Function to return the default value for the maximum number of open
4808 * file descriptors permitted. This function tries to consult the
4809 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4810 * the smaller of those.
4812 static int max_open_files(void)
4814 int sysctl_max = MAX_OPEN_FILES;
4815 int rlimit_max = MAX_OPEN_FILES;
4817 #ifdef HAVE_SYSCTLBYNAME
4819 size_t size = sizeof(sysctl_max);
4820 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4823 #endif
4825 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4827 struct rlimit rl;
4829 ZERO_STRUCT(rl);
4831 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4832 rlimit_max = rl.rlim_cur;
4834 #if defined(RLIM_INFINITY)
4835 if(rl.rlim_cur == RLIM_INFINITY)
4836 rlimit_max = MAX_OPEN_FILES;
4838 #endif
4839 #endif
4841 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4842 DEBUG(2,("max_open_files: sysctl_max (%d) below "
4843 "minimum Windows limit (%d)\n",
4844 sysctl_max,
4845 MIN_OPEN_FILES_WINDOWS));
4846 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4849 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4850 DEBUG(2,("rlimit_max: rlimit_max (%d) below "
4851 "minimum Windows limit (%d)\n",
4852 rlimit_max,
4853 MIN_OPEN_FILES_WINDOWS));
4854 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4857 return MIN(sysctl_max, rlimit_max);
4861 * Common part of freeing allocated data for one parameter.
4863 static void free_one_parameter_common(void *parm_ptr,
4864 struct parm_struct parm)
4866 if ((parm.type == P_STRING) ||
4867 (parm.type == P_USTRING))
4869 string_free((char**)parm_ptr);
4870 } else if (parm.type == P_LIST) {
4871 TALLOC_FREE(*((char***)parm_ptr));
4876 * Free the allocated data for one parameter for a share
4877 * given as a service struct.
4879 static void free_one_parameter(struct service *service,
4880 struct parm_struct parm)
4882 void *parm_ptr;
4884 if (parm.p_class != P_LOCAL) {
4885 return;
4888 parm_ptr = lp_local_ptr(service, parm.ptr);
4890 free_one_parameter_common(parm_ptr, parm);
4894 * Free the allocated parameter data of a share given
4895 * as a service struct.
4897 static void free_parameters(struct service *service)
4899 uint32_t i;
4901 for (i=0; parm_table[i].label; i++) {
4902 free_one_parameter(service, parm_table[i]);
4907 * Free the allocated data for one parameter for a given share
4908 * specified by an snum.
4910 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4912 void *parm_ptr;
4914 if (parm.ptr == NULL) {
4915 return;
4918 if (snum < 0) {
4919 parm_ptr = parm.ptr;
4920 } else if (parm.p_class != P_LOCAL) {
4921 return;
4922 } else {
4923 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4926 free_one_parameter_common(parm_ptr, parm);
4930 * Free the allocated parameter data for a share specified
4931 * by an snum.
4933 static void free_parameters_by_snum(int snum)
4935 uint32_t i;
4937 for (i=0; parm_table[i].label; i++) {
4938 free_one_parameter_by_snum(snum, parm_table[i]);
4943 * Free the allocated global parameters.
4945 static void free_global_parameters(void)
4947 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4950 /***************************************************************************
4951 Initialise the global parameter structure.
4952 ***************************************************************************/
4954 static void init_globals(bool first_time_only)
4956 static bool done_init = False;
4957 char *s = NULL;
4958 int i;
4960 /* If requested to initialize only once and we've already done it... */
4961 if (first_time_only && done_init) {
4962 /* ... then we have nothing more to do */
4963 return;
4966 if (!done_init) {
4967 /* The logfile can be set before this is invoked. Free it if so. */
4968 if (Globals.szLogFile != NULL) {
4969 string_free(&Globals.szLogFile);
4970 Globals.szLogFile = NULL;
4972 done_init = True;
4973 } else {
4974 free_global_parameters();
4977 memset((void *)&Globals, '\0', sizeof(Globals));
4979 for (i = 0; parm_table[i].label; i++) {
4980 if ((parm_table[i].type == P_STRING ||
4981 parm_table[i].type == P_USTRING) &&
4982 parm_table[i].ptr)
4984 string_set((char **)parm_table[i].ptr, "");
4988 string_set(&sDefault.fstype, FSTYPE_STRING);
4989 string_set(&sDefault.szPrintjobUsername, "%U");
4991 init_printer_values(&sDefault);
4994 DEBUG(3, ("Initialising global parameters\n"));
4996 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4997 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4999 /* use the new 'hash2' method by default, with a prefix of 1 */
5000 string_set(&Globals.szManglingMethod, "hash2");
5001 Globals.mangle_prefix = 1;
5003 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
5005 /* using UTF8 by default allows us to support all chars */
5006 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
5008 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
5009 /* If the system supports nl_langinfo(), try to grab the value
5010 from the user's locale */
5011 string_set(&Globals.display_charset, "LOCALE");
5012 #else
5013 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
5014 #endif
5016 /* Use codepage 850 as a default for the dos character set */
5017 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
5020 * Allow the default PASSWD_CHAT to be overridden in local.h.
5022 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
5024 set_global_myname(myhostname());
5025 string_set(&Globals.szNetbiosName,global_myname());
5027 set_global_myworkgroup(WORKGROUP);
5028 string_set(&Globals.szWorkgroup, lp_workgroup());
5030 string_set(&Globals.szPasswdProgram, "");
5031 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
5032 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
5033 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
5034 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
5035 string_set(&Globals.szSocketAddress, "0.0.0.0");
5037 * By default support explicit binding to broadcast
5038 * addresses.
5040 Globals.bNmbdBindExplicitBroadcast = true;
5042 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
5043 smb_panic("init_globals: ENOMEM");
5045 string_set(&Globals.szServerString, s);
5046 SAFE_FREE(s);
5047 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5048 DEFAULT_MINOR_VERSION) < 0) {
5049 smb_panic("init_globals: ENOMEM");
5051 string_set(&Globals.szAnnounceVersion, s);
5052 SAFE_FREE(s);
5053 #ifdef DEVELOPER
5054 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5055 #endif
5057 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5059 string_set(&Globals.szLogonDrive, "");
5060 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5061 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5062 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5064 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5065 string_set(&Globals.szPasswordServer, "*");
5067 Globals.AlgorithmicRidBase = BASE_RID;
5069 Globals.bLoadPrinters = True;
5070 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
5072 Globals.ConfigBackend = config_backend;
5074 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5075 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5076 Globals.max_xmit = 0x4104;
5077 Globals.max_mux = 50; /* This is *needed* for profile support. */
5078 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
5079 Globals.bDisableSpoolss = False;
5080 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5081 Globals.pwordlevel = 0;
5082 Globals.unamelevel = 0;
5083 Globals.deadtime = 0;
5084 Globals.getwd_cache = true;
5085 Globals.bLargeReadwrite = True;
5086 Globals.max_log_size = 5000;
5087 Globals.max_open_files = max_open_files();
5088 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5089 Globals.maxprotocol = PROTOCOL_NT1;
5090 Globals.minprotocol = PROTOCOL_CORE;
5091 Globals.security = SEC_USER;
5092 Globals.paranoid_server_security = True;
5093 Globals.bEncryptPasswords = True;
5094 Globals.bUpdateEncrypt = False;
5095 Globals.clientSchannel = Auto;
5096 Globals.serverSchannel = Auto;
5097 Globals.bReadRaw = True;
5098 Globals.bWriteRaw = True;
5099 Globals.bNullPasswords = False;
5100 Globals.bObeyPamRestrictions = False;
5101 Globals.syslog = 1;
5102 Globals.bSyslogOnly = False;
5103 Globals.bTimestampLogs = True;
5104 string_set(&Globals.szLogLevel, "0");
5105 Globals.bDebugPrefixTimestamp = False;
5106 Globals.bDebugHiresTimestamp = true;
5107 Globals.bDebugPid = False;
5108 Globals.bDebugUid = False;
5109 Globals.bDebugClass = False;
5110 Globals.bEnableCoreFiles = True;
5111 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
5112 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
5113 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
5114 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
5115 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
5116 Globals.lm_interval = 60;
5117 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5118 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5119 Globals.bNISHomeMap = False;
5120 #ifdef WITH_NISPLUS_HOME
5121 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5122 #else
5123 string_set(&Globals.szNISHomeMapName, "auto.home");
5124 #endif
5125 #endif
5126 Globals.bTimeServer = False;
5127 Globals.bBindInterfacesOnly = False;
5128 Globals.bUnixPasswdSync = False;
5129 Globals.bPamPasswordChange = False;
5130 Globals.bPasswdChatDebug = False;
5131 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5132 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
5133 Globals.bNTStatusSupport = True; /* Use NT status by default. */
5134 Globals.bStatCache = True; /* use stat cache by default */
5135 Globals.iMaxStatCacheSize = 256; /* 256k by default */
5136 Globals.restrict_anonymous = 0;
5137 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
5138 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
5139 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
5140 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5141 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
5142 /* Note, that we will use NTLM2 session security (which is different), if it is available */
5144 Globals.map_to_guest = 0; /* By Default, "Never" */
5145 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
5146 Globals.enhanced_browsing = true;
5147 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5148 #ifdef MMAP_BLACKLIST
5149 Globals.bUseMmap = False;
5150 #else
5151 Globals.bUseMmap = True;
5152 #endif
5153 Globals.bUnixExtensions = True;
5154 Globals.bResetOnZeroVC = False;
5155 Globals.bLogWriteableFilesOnExit = False;
5156 Globals.bCreateKrb5Conf = true;
5158 /* hostname lookups can be very expensive and are broken on
5159 a large number of sites (tridge) */
5160 Globals.bHostnameLookups = False;
5162 string_set(&Globals.szPassdbBackend, "tdbsam");
5163 string_set(&Globals.szLdapSuffix, "");
5164 string_set(&Globals.szLdapMachineSuffix, "");
5165 string_set(&Globals.szLdapUserSuffix, "");
5166 string_set(&Globals.szLdapGroupSuffix, "");
5167 string_set(&Globals.szLdapIdmapSuffix, "");
5169 string_set(&Globals.szLdapAdminDn, "");
5170 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5171 Globals.ldap_ssl_ads = False;
5172 Globals.ldap_deref = -1;
5173 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5174 Globals.ldap_delete_dn = False;
5175 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5176 Globals.ldap_follow_referral = Auto;
5177 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5178 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5179 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5181 Globals.ldap_debug_level = 0;
5182 Globals.ldap_debug_threshold = 10;
5184 /* This is what we tell the afs client. in reality we set the token
5185 * to never expire, though, when this runs out the afs client will
5186 * forget the token. Set to 0 to get NEVERDATE.*/
5187 Globals.iAfsTokenLifetime = 604800;
5188 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5190 /* these parameters are set to defaults that are more appropriate
5191 for the increasing samba install base:
5193 as a member of the workgroup, that will possibly become a
5194 _local_ master browser (lm = True). this is opposed to a forced
5195 local master browser startup (pm = True).
5197 doesn't provide WINS server service by default (wsupp = False),
5198 and doesn't provide domain master browser services by default, either.
5202 Globals.bMsAddPrinterWizard = True;
5203 Globals.os_level = 20;
5204 Globals.bLocalMaster = True;
5205 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5206 Globals.bDomainLogons = False;
5207 Globals.bBrowseList = True;
5208 Globals.bWINSsupport = False;
5209 Globals.bWINSproxy = False;
5211 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5212 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5214 Globals.bDNSproxy = True;
5216 /* this just means to use them if they exist */
5217 Globals.bKernelOplocks = True;
5219 Globals.bAllowTrustedDomains = True;
5220 string_set(&Globals.szIdmapBackend, "tdb");
5222 string_set(&Globals.szTemplateShell, "/bin/false");
5223 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5224 string_set(&Globals.szWinbindSeparator, "\\");
5226 string_set(&Globals.szCupsServer, "");
5227 string_set(&Globals.szIPrintServer, "");
5229 string_set(&Globals.ctdbdSocket, "");
5230 Globals.szClusterAddresses = NULL;
5231 Globals.clustering = False;
5232 Globals.ctdb_timeout = 0;
5233 Globals.ctdb_locktime_warn_threshold = 0;
5235 Globals.winbind_cache_time = 300; /* 5 minutes */
5236 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5237 Globals.bWinbindEnumUsers = False;
5238 Globals.bWinbindEnumGroups = False;
5239 Globals.bWinbindUseDefaultDomain = False;
5240 Globals.bWinbindTrustedDomainsOnly = False;
5241 Globals.bWinbindNestedGroups = True;
5242 Globals.winbind_expand_groups = 1;
5243 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5244 Globals.bWinbindRefreshTickets = False;
5245 Globals.bWinbindOfflineLogon = False;
5247 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5248 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5250 Globals.bPassdbExpandExplicit = False;
5252 Globals.name_cache_timeout = 660; /* In seconds */
5254 Globals.bUseSpnego = True;
5255 Globals.bClientUseSpnego = True;
5257 Globals.client_signing = Auto;
5258 Globals.server_signing = False;
5260 Globals.bDeferSharingViolations = True;
5261 string_set(&Globals.smb_ports, SMB_PORTS);
5263 Globals.bEnablePrivileges = True;
5264 Globals.bHostMSDfs = True;
5265 Globals.bASUSupport = False;
5267 /* User defined shares. */
5268 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5269 smb_panic("init_globals: ENOMEM");
5271 string_set(&Globals.szUsersharePath, s);
5272 SAFE_FREE(s);
5273 string_set(&Globals.szUsershareTemplateShare, "");
5274 Globals.iUsershareMaxShares = 0;
5275 /* By default disallow sharing of directories not owned by the sharer. */
5276 Globals.bUsershareOwnerOnly = True;
5277 /* By default disallow guest access to usershares. */
5278 Globals.bUsershareAllowGuests = False;
5280 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5282 /* By default no shares out of the registry */
5283 Globals.bRegistryShares = False;
5285 Globals.iminreceivefile = 0;
5287 Globals.bMapUntrustedToDomain = false;
5289 Globals.ismb2_max_read = 1024*1024;
5290 Globals.ismb2_max_write = 1024*1024;
5291 Globals.ismb2_max_trans = 1024*1024;
5294 /*******************************************************************
5295 Convenience routine to grab string parameters into temporary memory
5296 and run standard_sub_basic on them. The buffers can be written to by
5297 callers without affecting the source string.
5298 ********************************************************************/
5300 static char *lp_string(const char *s)
5302 char *ret;
5303 TALLOC_CTX *ctx = talloc_tos();
5305 /* The follow debug is useful for tracking down memory problems
5306 especially if you have an inner loop that is calling a lp_*()
5307 function that returns a string. Perhaps this debug should be
5308 present all the time? */
5310 #if 0
5311 DEBUG(10, ("lp_string(%s)\n", s));
5312 #endif
5313 if (!s) {
5314 return NULL;
5317 ret = talloc_sub_basic(ctx,
5318 get_current_username(),
5319 current_user_info.domain,
5321 if (trim_char(ret, '\"', '\"')) {
5322 if (strchr(ret,'\"') != NULL) {
5323 TALLOC_FREE(ret);
5324 ret = talloc_sub_basic(ctx,
5325 get_current_username(),
5326 current_user_info.domain,
5330 return ret;
5334 In this section all the functions that are used to access the
5335 parameters from the rest of the program are defined
5338 #define FN_GLOBAL_STRING(fn_name,ptr) \
5339 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5340 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5341 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5342 #define FN_GLOBAL_LIST(fn_name,ptr) \
5343 const char **fn_name(void) {return(*(const char ***)(ptr));}
5344 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5345 bool fn_name(void) {return(*(bool *)(ptr));}
5346 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5347 char fn_name(void) {return(*(char *)(ptr));}
5348 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5349 int fn_name(void) {return(*(int *)(ptr));}
5351 #define FN_LOCAL_STRING(fn_name,val) \
5352 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5353 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5354 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5355 #define FN_LOCAL_LIST(fn_name,val) \
5356 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5357 #define FN_LOCAL_BOOL(fn_name,val) \
5358 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5359 #define FN_LOCAL_INTEGER(fn_name,val) \
5360 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5362 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5363 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5364 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5365 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5366 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5367 char *fn_name(const struct share_params *p) {return(lp_string((LP_SNUM_OK(p->service) && ServicePtrs[(p->service)]->val) ? ServicePtrs[(p->service)]->val : sDefault.val));}
5368 #define FN_LOCAL_CHAR(fn_name,val) \
5369 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5371 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5372 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5373 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5374 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5375 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5376 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5377 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5378 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5379 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5380 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5381 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5382 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5383 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5384 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5385 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5386 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5387 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5388 * build process or in smb.conf, we use that value. Otherwise they
5389 * default to the value of lp_lockdir(). */
5390 char *lp_statedir(void) {
5391 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5392 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5393 return(lp_string(*(char **)(&Globals.szStateDir) ?
5394 *(char **)(&Globals.szStateDir) : ""));
5395 else
5396 return(lp_string(*(char **)(&Globals.szLockDir) ?
5397 *(char **)(&Globals.szLockDir) : ""));
5399 char *lp_cachedir(void) {
5400 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5401 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5402 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5403 *(char **)(&Globals.szCacheDir) : ""));
5404 else
5405 return(lp_string(*(char **)(&Globals.szLockDir) ?
5406 *(char **)(&Globals.szLockDir) : ""));
5408 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5409 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5410 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5411 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5412 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5413 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5414 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5415 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5416 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5417 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5418 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5419 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5420 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5421 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5422 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5423 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5424 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5425 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5426 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5427 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5428 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5429 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5430 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5431 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5432 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5433 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5434 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5435 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5436 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5437 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5438 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5439 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5440 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5441 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5442 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5443 * lp_passdb_backend() should be replace by the this macro again after
5444 * some releases.
5445 * */
5446 const char *lp_passdb_backend(void)
5448 char *delim, *quote;
5450 delim = strchr( Globals.szPassdbBackend, ' ');
5451 /* no space at all */
5452 if (delim == NULL) {
5453 goto out;
5456 quote = strchr(Globals.szPassdbBackend, '"');
5457 /* no quote char or non in the first part */
5458 if (quote == NULL || quote > delim) {
5459 *delim = '\0';
5460 goto warn;
5463 quote = strchr(quote+1, '"');
5464 if (quote == NULL) {
5465 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5466 goto out;
5467 } else if (*(quote+1) == '\0') {
5468 /* space, fitting quote char, and one backend only */
5469 goto out;
5470 } else {
5471 /* terminate string after the fitting quote char */
5472 *(quote+1) = '\0';
5475 warn:
5476 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5477 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5478 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5479 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5481 out:
5482 return Globals.szPassdbBackend;
5484 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5485 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5486 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5487 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5488 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5490 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5491 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5492 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5493 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5494 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5495 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5497 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5499 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5500 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5501 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5502 FN_GLOBAL_INTEGER(lp_username_map_cache_time, &Globals.iUsernameMapCacheTime)
5504 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5506 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5507 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5508 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5509 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5510 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5511 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5512 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5513 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5514 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5515 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5516 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5517 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5518 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5519 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5520 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5521 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5523 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5524 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5525 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5526 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5527 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5528 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5530 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5531 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5532 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5533 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5534 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5535 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5536 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5537 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5538 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5539 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5540 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5541 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5542 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5543 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5544 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5545 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5546 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5547 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5548 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5549 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5551 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5553 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5554 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5555 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5556 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5557 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5558 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5559 &Globals.bLogWriteableFilesOnExit)
5560 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5561 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5562 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5563 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5564 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5565 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5566 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5567 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5568 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5569 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5570 FN_GLOBAL_BOOL(_lp_readraw, &Globals.bReadRaw)
5571 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5572 FN_GLOBAL_BOOL(_lp_writeraw, &Globals.bWriteRaw)
5573 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5574 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5575 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5576 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5577 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5578 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5579 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5580 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5581 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5582 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5583 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5584 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5585 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5586 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5587 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5588 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5589 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5590 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5591 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5592 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5593 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5594 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5595 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5596 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5597 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5598 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5599 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5600 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5601 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5602 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5603 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5604 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5605 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5606 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5607 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5608 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5609 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5610 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5611 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5612 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5613 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5614 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5615 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5616 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5617 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5618 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5619 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5620 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5621 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5622 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5623 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5624 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5625 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5626 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5627 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5628 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5629 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5630 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5631 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5632 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5633 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5634 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5635 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5636 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5637 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5638 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5639 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5640 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5641 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5642 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5643 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5644 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5645 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5646 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5647 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5648 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5649 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5650 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5651 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5652 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5653 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5654 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5655 FN_GLOBAL_INTEGER(lp_smb2_max_read, &Globals.ismb2_max_read)
5656 FN_GLOBAL_INTEGER(lp_smb2_max_write, &Globals.ismb2_max_write)
5657 FN_GLOBAL_INTEGER(lp_smb2_max_trans, &Globals.ismb2_max_trans)
5659 FN_LOCAL_STRING(lp_preexec, szPreExec)
5660 FN_LOCAL_STRING(lp_postexec, szPostExec)
5661 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5662 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5663 FN_LOCAL_STRING(lp_servicename, szService)
5664 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5665 FN_LOCAL_STRING(lp_pathname, szPath)
5666 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5667 FN_LOCAL_STRING(lp_username, szUsername)
5668 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5669 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5670 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5671 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5672 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5673 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5674 int lp_cups_encrypt(void)
5676 int result = 0;
5677 #ifdef HAVE_HTTPCONNECTENCRYPT
5678 switch (Globals.CupsEncrypt) {
5679 case Auto:
5680 result = HTTP_ENCRYPT_REQUIRED;
5681 break;
5682 case True:
5683 result = HTTP_ENCRYPT_ALWAYS;
5684 break;
5685 case False:
5686 result = HTTP_ENCRYPT_NEVER;
5687 break;
5689 #endif
5690 return result;
5692 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5693 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5694 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5695 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5696 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5697 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5698 FN_GLOBAL_INTEGER(lp_ctdb_locktime_warn_threshold, &Globals.ctdb_locktime_warn_threshold)
5699 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5700 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5701 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5702 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5703 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5704 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5705 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5706 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5707 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5708 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5709 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5710 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5711 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5712 FN_LOCAL_STRING(lp_comment, comment)
5713 FN_LOCAL_STRING(lp_force_user, force_user)
5714 FN_LOCAL_STRING(lp_force_group, force_group)
5715 FN_LOCAL_LIST(lp_readlist, readlist)
5716 FN_LOCAL_LIST(lp_writelist, writelist)
5717 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5718 FN_LOCAL_STRING(lp_fstype, fstype)
5719 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5720 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5721 static FN_LOCAL_STRING(lp_volume, volume)
5722 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5723 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5724 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5725 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5726 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5727 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5728 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5729 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5730 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5731 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5732 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5733 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5734 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5735 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5736 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5737 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5738 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5739 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5740 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5741 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5742 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5743 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5744 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5745 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5746 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5747 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5748 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5749 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5750 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5751 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5752 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5753 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5754 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5755 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5756 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5757 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5758 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5759 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5760 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5761 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5762 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5763 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5764 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5765 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5766 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5767 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5768 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5769 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5770 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5771 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5772 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5773 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5774 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5775 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5776 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5777 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5778 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5779 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5780 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5781 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5782 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5783 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5784 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5785 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5786 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5787 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5788 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5789 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5790 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5791 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5792 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5793 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5794 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5795 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5796 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5797 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5798 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5799 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5800 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5801 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5802 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5803 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5804 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5805 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5806 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5807 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5808 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5809 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5810 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5811 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5812 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5813 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5814 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5815 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5816 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5817 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5818 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5819 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5820 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5822 /* local prototypes */
5824 static int map_parameter(const char *pszParmName);
5825 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5826 static const char *get_boolean(bool bool_value);
5827 static int getservicebyname(const char *pszServiceName,
5828 struct service *pserviceDest);
5829 static void copy_service(struct service *pserviceDest,
5830 struct service *pserviceSource,
5831 struct bitmap *pcopymapDest);
5832 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5833 void *userdata);
5834 static bool do_section(const char *pszSectionName, void *userdata);
5835 static void init_copymap(struct service *pservice);
5836 static bool hash_a_service(const char *name, int number);
5837 static void free_service_byindex(int iService);
5838 static void free_param_opts(struct param_opt_struct **popts);
5839 static void show_parameter(int parmIndex);
5840 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5843 * This is a helper function for parametrical options support. It returns a
5844 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5845 * parametrical functions are quite simple
5847 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5848 const char *option)
5850 bool global_section = False;
5851 char* param_key;
5852 struct param_opt_struct *data;
5854 if (snum >= iNumServices) return NULL;
5856 if (snum < 0) {
5857 data = Globals.param_opt;
5858 global_section = True;
5859 } else {
5860 data = ServicePtrs[snum]->param_opt;
5863 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5864 DEBUG(0,("asprintf failed!\n"));
5865 return NULL;
5868 while (data) {
5869 if (strwicmp(data->key, param_key) == 0) {
5870 string_free(&param_key);
5871 return data;
5873 data = data->next;
5876 if (!global_section) {
5877 /* Try to fetch the same option but from globals */
5878 /* but only if we are not already working with Globals */
5879 data = Globals.param_opt;
5880 while (data) {
5881 if (strwicmp(data->key, param_key) == 0) {
5882 string_free(&param_key);
5883 return data;
5885 data = data->next;
5889 string_free(&param_key);
5891 return NULL;
5895 #define MISSING_PARAMETER(name) \
5896 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5898 /*******************************************************************
5899 convenience routine to return int parameters.
5900 ********************************************************************/
5901 static int lp_int(const char *s)
5904 if (!s || !*s) {
5905 MISSING_PARAMETER(lp_int);
5906 return (-1);
5909 return (int)strtol(s, NULL, 0);
5912 /*******************************************************************
5913 convenience routine to return unsigned long parameters.
5914 ********************************************************************/
5915 static unsigned long lp_ulong(const char *s)
5918 if (!s || !*s) {
5919 MISSING_PARAMETER(lp_ulong);
5920 return (0);
5923 return strtoul(s, NULL, 0);
5926 /*******************************************************************
5927 convenience routine to return boolean parameters.
5928 ********************************************************************/
5929 static bool lp_bool(const char *s)
5931 bool ret = False;
5933 if (!s || !*s) {
5934 MISSING_PARAMETER(lp_bool);
5935 return False;
5938 if (!set_boolean(s, &ret)) {
5939 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5940 return False;
5943 return ret;
5946 /*******************************************************************
5947 convenience routine to return enum parameters.
5948 ********************************************************************/
5949 static int lp_enum(const char *s,const struct enum_list *_enum)
5951 int i;
5953 if (!s || !*s || !_enum) {
5954 MISSING_PARAMETER(lp_enum);
5955 return (-1);
5958 for (i=0; _enum[i].name; i++) {
5959 if (strequal(_enum[i].name,s))
5960 return _enum[i].value;
5963 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5964 return (-1);
5967 #undef MISSING_PARAMETER
5969 /* DO NOT USE lp_parm_string ANYMORE!!!!
5970 * use lp_parm_const_string or lp_parm_talloc_string
5972 * lp_parm_string is only used to let old modules find this symbol
5974 #undef lp_parm_string
5975 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5976 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5978 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5981 /* Return parametric option from a given service. Type is a part of option before ':' */
5982 /* Parametric option has following syntax: 'Type: option = value' */
5983 /* the returned value is talloced on the talloc_tos() */
5984 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5986 struct param_opt_struct *data = get_parametrics(snum, type, option);
5988 if (data == NULL||data->value==NULL) {
5989 if (def) {
5990 return lp_string(def);
5991 } else {
5992 return NULL;
5996 return lp_string(data->value);
5999 /* Return parametric option from a given service. Type is a part of option before ':' */
6000 /* Parametric option has following syntax: 'Type: option = value' */
6001 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
6003 struct param_opt_struct *data = get_parametrics(snum, type, option);
6005 if (data == NULL||data->value==NULL)
6006 return def;
6008 return data->value;
6011 /* Return parametric option from a given service. Type is a part of option before ':' */
6012 /* Parametric option has following syntax: 'Type: option = value' */
6014 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
6016 struct param_opt_struct *data = get_parametrics(snum, type, option);
6018 if (data == NULL||data->value==NULL)
6019 return (const char **)def;
6021 if (data->list==NULL) {
6022 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
6025 return (const char **)data->list;
6028 /* Return parametric option from a given service. Type is a part of option before ':' */
6029 /* Parametric option has following syntax: 'Type: option = value' */
6031 int lp_parm_int(int snum, const char *type, const char *option, int def)
6033 struct param_opt_struct *data = get_parametrics(snum, type, option);
6035 if (data && data->value && *data->value)
6036 return lp_int(data->value);
6038 return def;
6041 /* Return parametric option from a given service. Type is a part of option before ':' */
6042 /* Parametric option has following syntax: 'Type: option = value' */
6044 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
6046 struct param_opt_struct *data = get_parametrics(snum, type, option);
6048 if (data && data->value && *data->value)
6049 return lp_ulong(data->value);
6051 return def;
6054 /* Return parametric option from a given service. Type is a part of option before ':' */
6055 /* Parametric option has following syntax: 'Type: option = value' */
6057 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6059 struct param_opt_struct *data = get_parametrics(snum, type, option);
6061 if (data && data->value && *data->value)
6062 return lp_bool(data->value);
6064 return def;
6067 /* Return parametric option from a given service. Type is a part of option before ':' */
6068 /* Parametric option has following syntax: 'Type: option = value' */
6070 int lp_parm_enum(int snum, const char *type, const char *option,
6071 const struct enum_list *_enum, int def)
6073 struct param_opt_struct *data = get_parametrics(snum, type, option);
6075 if (data && data->value && *data->value && _enum)
6076 return lp_enum(data->value, _enum);
6078 return def;
6082 /***************************************************************************
6083 Initialise a service to the defaults.
6084 ***************************************************************************/
6086 static void init_service(struct service *pservice)
6088 memset((char *)pservice, '\0', sizeof(struct service));
6089 copy_service(pservice, &sDefault, NULL);
6094 * free a param_opts structure.
6095 * param_opts handling should be moved to talloc;
6096 * then this whole functions reduces to a TALLOC_FREE().
6099 static void free_param_opts(struct param_opt_struct **popts)
6101 struct param_opt_struct *opt, *next_opt;
6103 if (popts == NULL) {
6104 return;
6107 if (*popts != NULL) {
6108 DEBUG(5, ("Freeing parametrics:\n"));
6110 opt = *popts;
6111 while (opt != NULL) {
6112 string_free(&opt->key);
6113 string_free(&opt->value);
6114 TALLOC_FREE(opt->list);
6115 next_opt = opt->next;
6116 SAFE_FREE(opt);
6117 opt = next_opt;
6119 *popts = NULL;
6122 /***************************************************************************
6123 Free the dynamically allocated parts of a service struct.
6124 ***************************************************************************/
6126 static void free_service(struct service *pservice)
6128 if (!pservice)
6129 return;
6131 if (pservice->szService)
6132 DEBUG(5, ("free_service: Freeing service %s\n",
6133 pservice->szService));
6135 free_parameters(pservice);
6137 string_free(&pservice->szService);
6138 TALLOC_FREE(pservice->copymap);
6140 free_param_opts(&pservice->param_opt);
6142 ZERO_STRUCTP(pservice);
6146 /***************************************************************************
6147 remove a service indexed in the ServicePtrs array from the ServiceHash
6148 and free the dynamically allocated parts
6149 ***************************************************************************/
6151 static void free_service_byindex(int idx)
6153 if ( !LP_SNUM_OK(idx) )
6154 return;
6156 ServicePtrs[idx]->valid = False;
6157 invalid_services[num_invalid_services++] = idx;
6159 /* we have to cleanup the hash record */
6161 if (ServicePtrs[idx]->szService) {
6162 char *canon_name = canonicalize_servicename(
6163 talloc_tos(),
6164 ServicePtrs[idx]->szService );
6166 dbwrap_delete_bystring(ServiceHash, canon_name );
6167 TALLOC_FREE(canon_name);
6170 free_service(ServicePtrs[idx]);
6173 /***************************************************************************
6174 Add a new service to the services array initialising it with the given
6175 service.
6176 ***************************************************************************/
6178 static int add_a_service(const struct service *pservice, const char *name)
6180 int i;
6181 struct service tservice;
6182 int num_to_alloc = iNumServices + 1;
6184 tservice = *pservice;
6186 /* it might already exist */
6187 if (name) {
6188 i = getservicebyname(name, NULL);
6189 if (i >= 0) {
6190 /* Clean all parametric options for service */
6191 /* They will be added during parsing again */
6192 free_param_opts(&ServicePtrs[i]->param_opt);
6193 return (i);
6197 /* find an invalid one */
6198 i = iNumServices;
6199 if (num_invalid_services > 0) {
6200 i = invalid_services[--num_invalid_services];
6203 /* if not, then create one */
6204 if (i == iNumServices) {
6205 struct service **tsp;
6206 int *tinvalid;
6208 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6209 if (tsp == NULL) {
6210 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6211 return (-1);
6213 ServicePtrs = tsp;
6214 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6215 if (!ServicePtrs[iNumServices]) {
6216 DEBUG(0,("add_a_service: out of memory!\n"));
6217 return (-1);
6219 iNumServices++;
6221 /* enlarge invalid_services here for now... */
6222 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6223 num_to_alloc);
6224 if (tinvalid == NULL) {
6225 DEBUG(0,("add_a_service: failed to enlarge "
6226 "invalid_services!\n"));
6227 return (-1);
6229 invalid_services = tinvalid;
6230 } else {
6231 free_service_byindex(i);
6234 ServicePtrs[i]->valid = True;
6236 init_service(ServicePtrs[i]);
6237 copy_service(ServicePtrs[i], &tservice, NULL);
6238 if (name)
6239 string_set(&ServicePtrs[i]->szService, name);
6241 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6242 i, ServicePtrs[i]->szService));
6244 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6245 return (-1);
6248 return (i);
6251 /***************************************************************************
6252 Convert a string to uppercase and remove whitespaces.
6253 ***************************************************************************/
6255 char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src)
6257 char *result;
6259 if ( !src ) {
6260 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6261 return NULL;
6264 result = talloc_strdup(ctx, src);
6265 SMB_ASSERT(result != NULL);
6267 strlower_m(result);
6268 return result;
6271 /***************************************************************************
6272 Add a name/index pair for the services array to the hash table.
6273 ***************************************************************************/
6275 static bool hash_a_service(const char *name, int idx)
6277 char *canon_name;
6279 if ( !ServiceHash ) {
6280 DEBUG(10,("hash_a_service: creating servicehash\n"));
6281 ServiceHash = db_open_rbt(NULL);
6282 if ( !ServiceHash ) {
6283 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6284 return False;
6288 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6289 idx, name));
6291 canon_name = canonicalize_servicename(talloc_tos(), name );
6293 dbwrap_store_bystring(ServiceHash, canon_name,
6294 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6295 TDB_REPLACE);
6297 TALLOC_FREE(canon_name);
6299 return True;
6302 /***************************************************************************
6303 Add a new home service, with the specified home directory, defaults coming
6304 from service ifrom.
6305 ***************************************************************************/
6307 bool lp_add_home(const char *pszHomename, int iDefaultService,
6308 const char *user, const char *pszHomedir)
6310 int i;
6312 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6313 pszHomedir[0] == '\0') {
6314 return false;
6317 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6319 if (i < 0)
6320 return (False);
6322 if (!(*(ServicePtrs[iDefaultService]->szPath))
6323 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6324 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6327 if (!(*(ServicePtrs[i]->comment))) {
6328 char *comment = NULL;
6329 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6330 return false;
6332 string_set(&ServicePtrs[i]->comment, comment);
6333 SAFE_FREE(comment);
6336 /* set the browseable flag from the global default */
6338 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6339 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6341 ServicePtrs[i]->autoloaded = True;
6343 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6344 user, ServicePtrs[i]->szPath ));
6346 return (True);
6349 /***************************************************************************
6350 Add a new service, based on an old one.
6351 ***************************************************************************/
6353 int lp_add_service(const char *pszService, int iDefaultService)
6355 if (iDefaultService < 0) {
6356 return add_a_service(&sDefault, pszService);
6359 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6362 /***************************************************************************
6363 Add the IPC service.
6364 ***************************************************************************/
6366 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6368 char *comment = NULL;
6369 int i = add_a_service(&sDefault, ipc_name);
6371 if (i < 0)
6372 return (False);
6374 if (asprintf(&comment, "IPC Service (%s)",
6375 Globals.szServerString) < 0) {
6376 return (False);
6379 string_set(&ServicePtrs[i]->szPath, tmpdir());
6380 string_set(&ServicePtrs[i]->szUsername, "");
6381 string_set(&ServicePtrs[i]->comment, comment);
6382 string_set(&ServicePtrs[i]->fstype, "IPC");
6383 ServicePtrs[i]->iMaxConnections = 0;
6384 ServicePtrs[i]->bAvailable = True;
6385 ServicePtrs[i]->bRead_only = True;
6386 ServicePtrs[i]->bGuest_only = False;
6387 ServicePtrs[i]->bAdministrative_share = True;
6388 ServicePtrs[i]->bGuest_ok = guest_ok;
6389 ServicePtrs[i]->bPrint_ok = False;
6390 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6392 DEBUG(3, ("adding IPC service\n"));
6394 SAFE_FREE(comment);
6395 return (True);
6398 /***************************************************************************
6399 Add a new printer service, with defaults coming from service iFrom.
6400 ***************************************************************************/
6402 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6404 const char *comment = "From Printcap";
6405 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6407 if (i < 0)
6408 return (False);
6410 /* note that we do NOT default the availability flag to True - */
6411 /* we take it from the default service passed. This allows all */
6412 /* dynamic printers to be disabled by disabling the [printers] */
6413 /* entry (if/when the 'available' keyword is implemented!). */
6415 /* the printer name is set to the service name. */
6416 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6417 string_set(&ServicePtrs[i]->comment, comment);
6419 /* set the browseable flag from the gloabl default */
6420 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6422 /* Printers cannot be read_only. */
6423 ServicePtrs[i]->bRead_only = False;
6424 /* No share modes on printer services. */
6425 ServicePtrs[i]->bShareModes = False;
6426 /* No oplocks on printer services. */
6427 ServicePtrs[i]->bOpLocks = False;
6428 /* Printer services must be printable. */
6429 ServicePtrs[i]->bPrint_ok = True;
6431 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6433 return (True);
6437 /***************************************************************************
6438 Check whether the given parameter name is valid.
6439 Parametric options (names containing a colon) are considered valid.
6440 ***************************************************************************/
6442 bool lp_parameter_is_valid(const char *pszParmName)
6444 return ((map_parameter(pszParmName) != -1) ||
6445 (strchr(pszParmName, ':') != NULL));
6448 /***************************************************************************
6449 Check whether the given name is the name of a global parameter.
6450 Returns True for strings belonging to parameters of class
6451 P_GLOBAL, False for all other strings, also for parametric options
6452 and strings not belonging to any option.
6453 ***************************************************************************/
6455 bool lp_parameter_is_global(const char *pszParmName)
6457 int num = map_parameter(pszParmName);
6459 if (num >= 0) {
6460 return (parm_table[num].p_class == P_GLOBAL);
6463 return False;
6466 /**************************************************************************
6467 Check whether the given name is the canonical name of a parameter.
6468 Returns False if it is not a valid parameter Name.
6469 For parametric options, True is returned.
6470 **************************************************************************/
6472 bool lp_parameter_is_canonical(const char *parm_name)
6474 if (!lp_parameter_is_valid(parm_name)) {
6475 return False;
6478 return (map_parameter(parm_name) ==
6479 map_parameter_canonical(parm_name, NULL));
6482 /**************************************************************************
6483 Determine the canonical name for a parameter.
6484 Indicate when it is an inverse (boolean) synonym instead of a
6485 "usual" synonym.
6486 **************************************************************************/
6488 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6489 bool *inverse)
6491 int num;
6493 if (!lp_parameter_is_valid(parm_name)) {
6494 *canon_parm = NULL;
6495 return False;
6498 num = map_parameter_canonical(parm_name, inverse);
6499 if (num < 0) {
6500 /* parametric option */
6501 *canon_parm = parm_name;
6502 } else {
6503 *canon_parm = parm_table[num].label;
6506 return True;
6510 /**************************************************************************
6511 Determine the canonical name for a parameter.
6512 Turn the value given into the inverse boolean expression when
6513 the synonym is an invers boolean synonym.
6515 Return True if parm_name is a valid parameter name and
6516 in case it is an invers boolean synonym, if the val string could
6517 successfully be converted to the reverse bool.
6518 Return false in all other cases.
6519 **************************************************************************/
6521 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6522 const char *val,
6523 const char **canon_parm,
6524 const char **canon_val)
6526 int num;
6527 bool inverse;
6529 if (!lp_parameter_is_valid(parm_name)) {
6530 *canon_parm = NULL;
6531 *canon_val = NULL;
6532 return False;
6535 num = map_parameter_canonical(parm_name, &inverse);
6536 if (num < 0) {
6537 /* parametric option */
6538 *canon_parm = parm_name;
6539 *canon_val = val;
6540 } else {
6541 *canon_parm = parm_table[num].label;
6542 if (inverse) {
6543 if (!lp_invert_boolean(val, canon_val)) {
6544 *canon_val = NULL;
6545 return False;
6547 } else {
6548 *canon_val = val;
6552 return True;
6555 /***************************************************************************
6556 Map a parameter's string representation to something we can use.
6557 Returns False if the parameter string is not recognised, else TRUE.
6558 ***************************************************************************/
6560 static int map_parameter(const char *pszParmName)
6562 int iIndex;
6564 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6565 return (-1);
6567 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6568 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6569 return (iIndex);
6571 /* Warn only if it isn't parametric option */
6572 if (strchr(pszParmName, ':') == NULL)
6573 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6574 /* We do return 'fail' for parametric options as well because they are
6575 stored in different storage
6577 return (-1);
6580 /***************************************************************************
6581 Map a parameter's string representation to the index of the canonical
6582 form of the parameter (it might be a synonym).
6583 Returns -1 if the parameter string is not recognised.
6584 ***************************************************************************/
6586 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6588 int parm_num, canon_num;
6589 bool loc_inverse = False;
6591 parm_num = map_parameter(pszParmName);
6592 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6593 /* invalid, parametric or no canidate for synonyms ... */
6594 goto done;
6597 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6598 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6599 parm_num = canon_num;
6600 goto done;
6604 done:
6605 if (inverse != NULL) {
6606 *inverse = loc_inverse;
6608 return parm_num;
6611 /***************************************************************************
6612 return true if parameter number parm1 is a synonym of parameter
6613 number parm2 (parm2 being the principal name).
6614 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6615 False otherwise.
6616 ***************************************************************************/
6618 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6620 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6621 (parm_table[parm1].flags & FLAG_HIDE) &&
6622 !(parm_table[parm2].flags & FLAG_HIDE))
6624 if (inverse != NULL) {
6625 if ((parm_table[parm1].type == P_BOOLREV) &&
6626 (parm_table[parm2].type == P_BOOL))
6628 *inverse = True;
6629 } else {
6630 *inverse = False;
6633 return True;
6635 return False;
6638 /***************************************************************************
6639 Show one parameter's name, type, [values,] and flags.
6640 (helper functions for show_parameter_list)
6641 ***************************************************************************/
6643 static void show_parameter(int parmIndex)
6645 int enumIndex, flagIndex;
6646 int parmIndex2;
6647 bool hadFlag;
6648 bool hadSyn;
6649 bool inverse;
6650 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6651 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6652 "P_ENUM", "P_SEP"};
6653 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6654 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6655 FLAG_HIDE, FLAG_DOS_STRING};
6656 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6657 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6658 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6660 printf("%s=%s", parm_table[parmIndex].label,
6661 type[parm_table[parmIndex].type]);
6662 if (parm_table[parmIndex].type == P_ENUM) {
6663 printf(",");
6664 for (enumIndex=0;
6665 parm_table[parmIndex].enum_list[enumIndex].name;
6666 enumIndex++)
6668 printf("%s%s",
6669 enumIndex ? "|" : "",
6670 parm_table[parmIndex].enum_list[enumIndex].name);
6673 printf(",");
6674 hadFlag = False;
6675 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6676 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6677 printf("%s%s",
6678 hadFlag ? "|" : "",
6679 flag_names[flagIndex]);
6680 hadFlag = True;
6684 /* output synonyms */
6685 hadSyn = False;
6686 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6687 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6688 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6689 parm_table[parmIndex2].label);
6690 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6691 if (!hadSyn) {
6692 printf(" (synonyms: ");
6693 hadSyn = True;
6694 } else {
6695 printf(", ");
6697 printf("%s%s", parm_table[parmIndex2].label,
6698 inverse ? "[i]" : "");
6701 if (hadSyn) {
6702 printf(")");
6705 printf("\n");
6708 /***************************************************************************
6709 Show all parameter's name, type, [values,] and flags.
6710 ***************************************************************************/
6712 void show_parameter_list(void)
6714 int classIndex, parmIndex;
6715 const char *section_names[] = { "local", "global", NULL};
6717 for (classIndex=0; section_names[classIndex]; classIndex++) {
6718 printf("[%s]\n", section_names[classIndex]);
6719 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6720 if (parm_table[parmIndex].p_class == classIndex) {
6721 show_parameter(parmIndex);
6727 /***************************************************************************
6728 Check if a given string correctly represents a boolean value.
6729 ***************************************************************************/
6731 bool lp_string_is_valid_boolean(const char *parm_value)
6733 return set_boolean(parm_value, NULL);
6736 /***************************************************************************
6737 Get the standard string representation of a boolean value ("yes" or "no")
6738 ***************************************************************************/
6740 static const char *get_boolean(bool bool_value)
6742 static const char *yes_str = "yes";
6743 static const char *no_str = "no";
6745 return (bool_value ? yes_str : no_str);
6748 /***************************************************************************
6749 Provide the string of the negated boolean value associated to the boolean
6750 given as a string. Returns False if the passed string does not correctly
6751 represent a boolean.
6752 ***************************************************************************/
6754 bool lp_invert_boolean(const char *str, const char **inverse_str)
6756 bool val;
6758 if (!set_boolean(str, &val)) {
6759 return False;
6762 *inverse_str = get_boolean(!val);
6763 return True;
6766 /***************************************************************************
6767 Provide the canonical string representation of a boolean value given
6768 as a string. Return True on success, False if the string given does
6769 not correctly represent a boolean.
6770 ***************************************************************************/
6772 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6774 bool val;
6776 if (!set_boolean(str, &val)) {
6777 return False;
6780 *canon_str = get_boolean(val);
6781 return True;
6784 /***************************************************************************
6785 Find a service by name. Otherwise works like get_service.
6786 ***************************************************************************/
6788 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6790 int iService = -1;
6791 char *canon_name;
6792 TDB_DATA data;
6794 if (ServiceHash == NULL) {
6795 return -1;
6798 canon_name = canonicalize_servicename(talloc_tos(), pszServiceName);
6800 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6802 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6803 iService = *(int *)data.dptr;
6806 TALLOC_FREE(canon_name);
6808 if ((iService != -1) && (LP_SNUM_OK(iService))
6809 && (pserviceDest != NULL)) {
6810 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6813 return (iService);
6816 /***************************************************************************
6817 Copy a service structure to another.
6818 If pcopymapDest is NULL then copy all fields
6819 ***************************************************************************/
6822 * Add a parametric option to a param_opt_struct,
6823 * replacing old value, if already present.
6825 static void set_param_opt(struct param_opt_struct **opt_list,
6826 const char *opt_name,
6827 const char *opt_value)
6829 struct param_opt_struct *new_opt, *opt;
6830 bool not_added;
6832 if (opt_list == NULL) {
6833 return;
6836 opt = *opt_list;
6837 not_added = true;
6839 /* Traverse destination */
6840 while (opt) {
6841 /* If we already have same option, override it */
6842 if (strwicmp(opt->key, opt_name) == 0) {
6843 string_free(&opt->value);
6844 TALLOC_FREE(opt->list);
6845 opt->value = SMB_STRDUP(opt_value);
6846 not_added = false;
6847 break;
6849 opt = opt->next;
6851 if (not_added) {
6852 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6853 new_opt->key = SMB_STRDUP(opt_name);
6854 new_opt->value = SMB_STRDUP(opt_value);
6855 new_opt->list = NULL;
6856 DLIST_ADD(*opt_list, new_opt);
6860 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6861 struct bitmap *pcopymapDest)
6863 int i;
6864 bool bcopyall = (pcopymapDest == NULL);
6865 struct param_opt_struct *data;
6867 for (i = 0; parm_table[i].label; i++)
6868 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6869 (bcopyall || bitmap_query(pcopymapDest,i))) {
6870 void *def_ptr = parm_table[i].ptr;
6871 void *src_ptr =
6872 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6873 &sDefault);
6874 void *dest_ptr =
6875 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6876 &sDefault);
6878 switch (parm_table[i].type) {
6879 case P_BOOL:
6880 case P_BOOLREV:
6881 *(bool *)dest_ptr = *(bool *)src_ptr;
6882 break;
6884 case P_INTEGER:
6885 case P_ENUM:
6886 case P_OCTAL:
6887 *(int *)dest_ptr = *(int *)src_ptr;
6888 break;
6890 case P_CHAR:
6891 *(char *)dest_ptr = *(char *)src_ptr;
6892 break;
6894 case P_STRING:
6895 string_set((char **)dest_ptr,
6896 *(char **)src_ptr);
6897 break;
6899 case P_USTRING:
6900 string_set((char **)dest_ptr,
6901 *(char **)src_ptr);
6902 strupper_m(*(char **)dest_ptr);
6903 break;
6904 case P_LIST:
6905 TALLOC_FREE(*((char ***)dest_ptr));
6906 *((char ***)dest_ptr) = str_list_copy(NULL,
6907 *(const char ***)src_ptr);
6908 break;
6909 default:
6910 break;
6914 if (bcopyall) {
6915 init_copymap(pserviceDest);
6916 if (pserviceSource->copymap)
6917 bitmap_copy(pserviceDest->copymap,
6918 pserviceSource->copymap);
6921 data = pserviceSource->param_opt;
6922 while (data) {
6923 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6924 data = data->next;
6928 /***************************************************************************
6929 Check a service for consistency. Return False if the service is in any way
6930 incomplete or faulty, else True.
6931 ***************************************************************************/
6933 bool service_ok(int iService)
6935 bool bRetval;
6937 bRetval = True;
6938 if (ServicePtrs[iService]->szService[0] == '\0') {
6939 DEBUG(0, ("The following message indicates an internal error:\n"));
6940 DEBUG(0, ("No service name in service entry.\n"));
6941 bRetval = False;
6944 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6945 /* I can't see why you'd want a non-printable printer service... */
6946 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6947 if (!ServicePtrs[iService]->bPrint_ok) {
6948 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6949 ServicePtrs[iService]->szService));
6950 ServicePtrs[iService]->bPrint_ok = True;
6952 /* [printers] service must also be non-browsable. */
6953 if (ServicePtrs[iService]->bBrowseable)
6954 ServicePtrs[iService]->bBrowseable = False;
6957 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6958 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6959 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6961 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6962 ServicePtrs[iService]->szService));
6963 ServicePtrs[iService]->bAvailable = False;
6966 /* If a service is flagged unavailable, log the fact at level 1. */
6967 if (!ServicePtrs[iService]->bAvailable)
6968 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6969 ServicePtrs[iService]->szService));
6971 return (bRetval);
6974 static struct smbconf_ctx *lp_smbconf_ctx(void)
6976 WERROR werr;
6977 static struct smbconf_ctx *conf_ctx = NULL;
6979 if (conf_ctx == NULL) {
6980 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6981 if (!W_ERROR_IS_OK(werr)) {
6982 DEBUG(1, ("error initializing registry configuration: "
6983 "%s\n", win_errstr(werr)));
6984 conf_ctx = NULL;
6988 return conf_ctx;
6991 static bool process_smbconf_service(struct smbconf_service *service)
6993 uint32_t count;
6994 bool ret;
6996 if (service == NULL) {
6997 return false;
7000 ret = do_section(service->name, NULL);
7001 if (ret != true) {
7002 return false;
7004 for (count = 0; count < service->num_params; count++) {
7005 ret = do_parameter(service->param_names[count],
7006 service->param_values[count],
7007 NULL);
7008 if (ret != true) {
7009 return false;
7012 if (iServiceIndex >= 0) {
7013 return service_ok(iServiceIndex);
7015 return true;
7019 * load a service from registry and activate it
7021 bool process_registry_service(const char *service_name)
7023 WERROR werr;
7024 struct smbconf_service *service = NULL;
7025 TALLOC_CTX *mem_ctx = talloc_stackframe();
7026 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7027 bool ret = false;
7029 if (conf_ctx == NULL) {
7030 goto done;
7033 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
7035 if (!smbconf_share_exists(conf_ctx, service_name)) {
7037 * Registry does not contain data for this service (yet),
7038 * but make sure lp_load doesn't return false.
7040 ret = true;
7041 goto done;
7044 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
7045 if (!W_ERROR_IS_OK(werr)) {
7046 goto done;
7049 ret = process_smbconf_service(service);
7050 if (!ret) {
7051 goto done;
7054 /* store the csn */
7055 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7057 done:
7058 TALLOC_FREE(mem_ctx);
7059 return ret;
7063 * process_registry_globals
7065 static bool process_registry_globals(void)
7067 bool ret;
7069 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7071 ret = do_parameter("registry shares", "yes", NULL);
7072 if (!ret) {
7073 return ret;
7076 return process_registry_service(GLOBAL_NAME);
7079 bool process_registry_shares(void)
7081 WERROR werr;
7082 uint32_t count;
7083 struct smbconf_service **service = NULL;
7084 uint32_t num_shares = 0;
7085 TALLOC_CTX *mem_ctx = talloc_stackframe();
7086 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7087 bool ret = false;
7089 if (conf_ctx == NULL) {
7090 goto done;
7093 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7094 if (!W_ERROR_IS_OK(werr)) {
7095 goto done;
7098 ret = true;
7100 for (count = 0; count < num_shares; count++) {
7101 if (strequal(service[count]->name, GLOBAL_NAME)) {
7102 continue;
7104 ret = process_smbconf_service(service[count]);
7105 if (!ret) {
7106 goto done;
7110 /* store the csn */
7111 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7113 done:
7114 TALLOC_FREE(mem_ctx);
7115 return ret;
7118 #define MAX_INCLUDE_DEPTH 100
7120 static uint8_t include_depth;
7122 static struct file_lists {
7123 struct file_lists *next;
7124 char *name;
7125 char *subfname;
7126 time_t modtime;
7127 } *file_lists = NULL;
7129 /*******************************************************************
7130 Keep a linked list of all config files so we know when one has changed
7131 it's date and needs to be reloaded.
7132 ********************************************************************/
7134 static void add_to_file_list(const char *fname, const char *subfname)
7136 struct file_lists *f = file_lists;
7138 while (f) {
7139 if (f->name && !strcmp(f->name, fname))
7140 break;
7141 f = f->next;
7144 if (!f) {
7145 f = SMB_MALLOC_P(struct file_lists);
7146 if (!f)
7147 return;
7148 f->next = file_lists;
7149 f->name = SMB_STRDUP(fname);
7150 if (!f->name) {
7151 SAFE_FREE(f);
7152 return;
7154 f->subfname = SMB_STRDUP(subfname);
7155 if (!f->subfname) {
7156 SAFE_FREE(f->name);
7157 SAFE_FREE(f);
7158 return;
7160 file_lists = f;
7161 f->modtime = file_modtime(subfname);
7162 } else {
7163 time_t t = file_modtime(subfname);
7164 if (t)
7165 f->modtime = t;
7167 return;
7171 * Free the file lists
7173 static void free_file_list(void)
7175 struct file_lists *f;
7176 struct file_lists *next;
7178 f = file_lists;
7179 while( f ) {
7180 next = f->next;
7181 SAFE_FREE( f->name );
7182 SAFE_FREE( f->subfname );
7183 SAFE_FREE( f );
7184 f = next;
7186 file_lists = NULL;
7191 * Utility function for outsiders to check if we're running on registry.
7193 bool lp_config_backend_is_registry(void)
7195 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7199 * Utility function to check if the config backend is FILE.
7201 bool lp_config_backend_is_file(void)
7203 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7206 /*******************************************************************
7207 Check if a config file has changed date.
7208 ********************************************************************/
7210 bool lp_file_list_changed(void)
7212 struct file_lists *f = file_lists;
7214 DEBUG(6, ("lp_file_list_changed()\n"));
7216 while (f) {
7217 time_t mod_time;
7219 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7220 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7222 if (conf_ctx == NULL) {
7223 return false;
7225 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7226 NULL))
7228 DEBUGADD(6, ("registry config changed\n"));
7229 return true;
7231 } else {
7232 char *n2 = NULL;
7233 n2 = talloc_sub_basic(talloc_tos(),
7234 get_current_username(),
7235 current_user_info.domain,
7236 f->name);
7237 if (!n2) {
7238 return false;
7240 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7241 f->name, n2, ctime(&f->modtime)));
7243 mod_time = file_modtime(n2);
7245 if (mod_time &&
7246 ((f->modtime != mod_time) ||
7247 (f->subfname == NULL) ||
7248 (strcmp(n2, f->subfname) != 0)))
7250 DEBUGADD(6,
7251 ("file %s modified: %s\n", n2,
7252 ctime(&mod_time)));
7253 f->modtime = mod_time;
7254 SAFE_FREE(f->subfname);
7255 f->subfname = SMB_STRDUP(n2);
7256 TALLOC_FREE(n2);
7257 return true;
7259 TALLOC_FREE(n2);
7261 f = f->next;
7263 return (False);
7267 /***************************************************************************
7268 Run standard_sub_basic on netbios name... needed because global_myname
7269 is not accessed through any lp_ macro.
7270 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7271 ***************************************************************************/
7273 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7275 bool ret;
7276 char *netbios_name = talloc_sub_basic(
7277 talloc_tos(), get_current_username(), current_user_info.domain,
7278 pszParmValue);
7280 ret = set_global_myname(netbios_name);
7281 TALLOC_FREE(netbios_name);
7282 string_set(&Globals.szNetbiosName,global_myname());
7284 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7285 global_myname()));
7287 return ret;
7290 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7292 if (strcmp(*ptr, pszParmValue) != 0) {
7293 string_set(ptr, pszParmValue);
7294 init_iconv();
7296 return True;
7301 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7303 bool ret;
7305 ret = set_global_myworkgroup(pszParmValue);
7306 string_set(&Globals.szWorkgroup,lp_workgroup());
7308 return ret;
7311 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7313 bool ret;
7315 ret = set_global_scope(pszParmValue);
7316 string_set(&Globals.szNetbiosScope,global_scope());
7318 return ret;
7321 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7323 TALLOC_FREE(Globals.szNetbiosAliases);
7324 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7325 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7328 /***************************************************************************
7329 Handle the include operation.
7330 ***************************************************************************/
7331 static bool bAllowIncludeRegistry = true;
7333 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7335 char *fname;
7337 if (include_depth >= MAX_INCLUDE_DEPTH) {
7338 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7339 include_depth));
7340 return false;
7343 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7344 if (!bAllowIncludeRegistry) {
7345 return true;
7347 if (bInGlobalSection) {
7348 bool ret;
7349 include_depth++;
7350 ret = process_registry_globals();
7351 include_depth--;
7352 return ret;
7353 } else {
7354 DEBUG(1, ("\"include = registry\" only effective "
7355 "in %s section\n", GLOBAL_NAME));
7356 return false;
7360 fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7361 current_user_info.domain,
7362 pszParmValue);
7364 add_to_file_list(pszParmValue, fname);
7366 string_set(ptr, fname);
7368 if (file_exist(fname)) {
7369 bool ret;
7370 include_depth++;
7371 ret = pm_process(fname, do_section, do_parameter, NULL);
7372 include_depth--;
7373 TALLOC_FREE(fname);
7374 return ret;
7377 DEBUG(2, ("Can't find include file %s\n", fname));
7378 TALLOC_FREE(fname);
7379 return true;
7382 /***************************************************************************
7383 Handle the interpretation of the copy parameter.
7384 ***************************************************************************/
7386 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7388 bool bRetval;
7389 int iTemp;
7390 struct service serviceTemp;
7392 string_set(ptr, pszParmValue);
7394 init_service(&serviceTemp);
7396 bRetval = False;
7398 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7400 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7401 if (iTemp == iServiceIndex) {
7402 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7403 } else {
7404 copy_service(ServicePtrs[iServiceIndex],
7405 &serviceTemp,
7406 ServicePtrs[iServiceIndex]->copymap);
7407 bRetval = True;
7409 } else {
7410 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7411 bRetval = False;
7414 free_service(&serviceTemp);
7415 return (bRetval);
7418 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7420 Globals.ldap_debug_level = lp_int(pszParmValue);
7421 init_ldap_debugging();
7422 return true;
7425 /***************************************************************************
7426 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7427 parameters is:
7429 [global]
7431 idmap uid = 1000-1999
7432 idmap gid = 700-899
7434 We only do simple parsing checks here. The strings are parsed into useful
7435 structures in the idmap daemon code.
7437 ***************************************************************************/
7439 /* Some lp_ routines to return idmap [ug]id information */
7441 static uid_t idmap_uid_low, idmap_uid_high;
7442 static gid_t idmap_gid_low, idmap_gid_high;
7444 bool lp_idmap_uid(uid_t *low, uid_t *high)
7446 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7447 return False;
7449 if (low)
7450 *low = idmap_uid_low;
7452 if (high)
7453 *high = idmap_uid_high;
7455 return True;
7458 bool lp_idmap_gid(gid_t *low, gid_t *high)
7460 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7461 return False;
7463 if (low)
7464 *low = idmap_gid_low;
7466 if (high)
7467 *high = idmap_gid_high;
7469 return True;
7472 /* Do some simple checks on "idmap [ug]id" parameter values */
7474 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7476 uint32 low, high;
7478 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7479 return False;
7481 /* Parse OK */
7483 string_set(ptr, pszParmValue);
7485 idmap_uid_low = low;
7486 idmap_uid_high = high;
7488 return True;
7491 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7493 uint32 low, high;
7495 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7496 return False;
7498 /* Parse OK */
7500 string_set(ptr, pszParmValue);
7502 idmap_gid_low = low;
7503 idmap_gid_high = high;
7505 return True;
7508 /***************************************************************************
7509 Handle the DEBUG level list.
7510 ***************************************************************************/
7512 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7514 string_set(ptr, pszParmValueIn);
7515 return debug_parse_levels(pszParmValueIn);
7518 /***************************************************************************
7519 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7520 ***************************************************************************/
7522 static const char *append_ldap_suffix( const char *str )
7524 const char *suffix_string;
7527 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7528 Globals.szLdapSuffix );
7529 if ( !suffix_string ) {
7530 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7531 return "";
7534 return suffix_string;
7537 const char *lp_ldap_machine_suffix(void)
7539 if (Globals.szLdapMachineSuffix[0])
7540 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7542 return lp_string(Globals.szLdapSuffix);
7545 const char *lp_ldap_user_suffix(void)
7547 if (Globals.szLdapUserSuffix[0])
7548 return append_ldap_suffix(Globals.szLdapUserSuffix);
7550 return lp_string(Globals.szLdapSuffix);
7553 const char *lp_ldap_group_suffix(void)
7555 if (Globals.szLdapGroupSuffix[0])
7556 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7558 return lp_string(Globals.szLdapSuffix);
7561 const char *lp_ldap_idmap_suffix(void)
7563 if (Globals.szLdapIdmapSuffix[0])
7564 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7566 return lp_string(Globals.szLdapSuffix);
7569 /****************************************************************************
7570 set the value for a P_ENUM
7571 ***************************************************************************/
7573 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7574 int *ptr )
7576 int i;
7578 for (i = 0; parm->enum_list[i].name; i++) {
7579 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7580 *ptr = parm->enum_list[i].value;
7581 return;
7584 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7585 pszParmValue, parm->label));
7588 /***************************************************************************
7589 ***************************************************************************/
7591 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7593 static int parm_num = -1;
7594 struct service *s;
7596 if ( parm_num == -1 )
7597 parm_num = map_parameter( "printing" );
7599 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7601 if ( snum < 0 )
7602 s = &sDefault;
7603 else
7604 s = ServicePtrs[snum];
7606 init_printer_values( s );
7608 return True;
7612 /***************************************************************************
7613 Initialise a copymap.
7614 ***************************************************************************/
7616 static void init_copymap(struct service *pservice)
7618 int i;
7620 TALLOC_FREE(pservice->copymap);
7622 pservice->copymap = bitmap_talloc(talloc_autofree_context(),
7623 NUMPARAMETERS);
7624 if (!pservice->copymap)
7625 DEBUG(0,
7626 ("Couldn't allocate copymap!! (size %d)\n",
7627 (int)NUMPARAMETERS));
7628 else
7629 for (i = 0; i < NUMPARAMETERS; i++)
7630 bitmap_set(pservice->copymap, i);
7633 /***************************************************************************
7634 Return the local pointer to a parameter given a service struct and the
7635 pointer into the default structure.
7636 ***************************************************************************/
7638 static void *lp_local_ptr(struct service *service, void *ptr)
7640 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7643 /***************************************************************************
7644 Return the local pointer to a parameter given the service number and the
7645 pointer into the default structure.
7646 ***************************************************************************/
7648 void *lp_local_ptr_by_snum(int snum, void *ptr)
7650 return lp_local_ptr(ServicePtrs[snum], ptr);
7653 /***************************************************************************
7654 Process a parameter for a particular service number. If snum < 0
7655 then assume we are in the globals.
7656 ***************************************************************************/
7658 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7660 int parmnum, i;
7661 void *parm_ptr = NULL; /* where we are going to store the result */
7662 void *def_ptr = NULL;
7663 struct param_opt_struct **opt_list;
7665 parmnum = map_parameter(pszParmName);
7667 if (parmnum < 0) {
7668 if (strchr(pszParmName, ':') == NULL) {
7669 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7670 pszParmName));
7671 return (True);
7675 * We've got a parametric option
7678 opt_list = (snum < 0)
7679 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7680 set_param_opt(opt_list, pszParmName, pszParmValue);
7682 return (True);
7685 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7686 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7687 pszParmName));
7690 def_ptr = parm_table[parmnum].ptr;
7692 /* we might point at a service, the default service or a global */
7693 if (snum < 0) {
7694 parm_ptr = def_ptr;
7695 } else {
7696 if (parm_table[parmnum].p_class == P_GLOBAL) {
7697 DEBUG(0,
7698 ("Global parameter %s found in service section!\n",
7699 pszParmName));
7700 return (True);
7702 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7705 if (snum >= 0) {
7706 if (!ServicePtrs[snum]->copymap)
7707 init_copymap(ServicePtrs[snum]);
7709 /* this handles the aliases - set the copymap for other entries with
7710 the same data pointer */
7711 for (i = 0; parm_table[i].label; i++)
7712 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7713 bitmap_clear(ServicePtrs[snum]->copymap, i);
7716 /* if it is a special case then go ahead */
7717 if (parm_table[parmnum].special) {
7718 return parm_table[parmnum].special(snum, pszParmValue,
7719 (char **)parm_ptr);
7722 /* now switch on the type of variable it is */
7723 switch (parm_table[parmnum].type)
7725 case P_BOOL:
7726 *(bool *)parm_ptr = lp_bool(pszParmValue);
7727 break;
7729 case P_BOOLREV:
7730 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7731 break;
7733 case P_INTEGER:
7734 *(int *)parm_ptr = lp_int(pszParmValue);
7735 break;
7737 case P_CHAR:
7738 *(char *)parm_ptr = *pszParmValue;
7739 break;
7741 case P_OCTAL:
7742 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7743 if ( i != 1 ) {
7744 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7746 break;
7748 case P_LIST:
7749 TALLOC_FREE(*((char ***)parm_ptr));
7750 *(char ***)parm_ptr = str_list_make_v3(
7751 talloc_autofree_context(), pszParmValue, NULL);
7752 break;
7754 case P_STRING:
7755 string_set((char **)parm_ptr, pszParmValue);
7756 break;
7758 case P_USTRING:
7759 string_set((char **)parm_ptr, pszParmValue);
7760 strupper_m(*(char **)parm_ptr);
7761 break;
7763 case P_ENUM:
7764 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7765 break;
7766 case P_SEP:
7767 break;
7770 return (True);
7773 /***************************************************************************
7774 Process a parameter.
7775 ***************************************************************************/
7777 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7778 void *userdata)
7780 if (!bInGlobalSection && bGlobalOnly)
7781 return (True);
7783 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7785 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7786 pszParmName, pszParmValue));
7789 /***************************************************************************
7790 Print a parameter of the specified type.
7791 ***************************************************************************/
7793 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7795 int i;
7796 switch (p->type)
7798 case P_ENUM:
7799 for (i = 0; p->enum_list[i].name; i++) {
7800 if (*(int *)ptr == p->enum_list[i].value) {
7801 fprintf(f, "%s",
7802 p->enum_list[i].name);
7803 break;
7806 break;
7808 case P_BOOL:
7809 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7810 break;
7812 case P_BOOLREV:
7813 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7814 break;
7816 case P_INTEGER:
7817 fprintf(f, "%d", *(int *)ptr);
7818 break;
7820 case P_CHAR:
7821 fprintf(f, "%c", *(char *)ptr);
7822 break;
7824 case P_OCTAL: {
7825 char *o = octal_string(*(int *)ptr);
7826 fprintf(f, "%s", o);
7827 TALLOC_FREE(o);
7828 break;
7831 case P_LIST:
7832 if ((char ***)ptr && *(char ***)ptr) {
7833 char **list = *(char ***)ptr;
7834 for (; *list; list++) {
7835 /* surround strings with whitespace in double quotes */
7836 if ( strchr_m( *list, ' ' ) )
7837 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7838 else
7839 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7842 break;
7844 case P_STRING:
7845 case P_USTRING:
7846 if (*(char **)ptr) {
7847 fprintf(f, "%s", *(char **)ptr);
7849 break;
7850 case P_SEP:
7851 break;
7855 /***************************************************************************
7856 Check if two parameters are equal.
7857 ***************************************************************************/
7859 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7861 switch (type) {
7862 case P_BOOL:
7863 case P_BOOLREV:
7864 return (*((bool *)ptr1) == *((bool *)ptr2));
7866 case P_INTEGER:
7867 case P_ENUM:
7868 case P_OCTAL:
7869 return (*((int *)ptr1) == *((int *)ptr2));
7871 case P_CHAR:
7872 return (*((char *)ptr1) == *((char *)ptr2));
7874 case P_LIST:
7875 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7877 case P_STRING:
7878 case P_USTRING:
7880 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7881 if (p1 && !*p1)
7882 p1 = NULL;
7883 if (p2 && !*p2)
7884 p2 = NULL;
7885 return (p1 == p2 || strequal(p1, p2));
7887 case P_SEP:
7888 break;
7890 return (False);
7893 /***************************************************************************
7894 Initialize any local varients in the sDefault table.
7895 ***************************************************************************/
7897 void init_locals(void)
7899 /* None as yet. */
7902 /***************************************************************************
7903 Process a new section (service). At this stage all sections are services.
7904 Later we'll have special sections that permit server parameters to be set.
7905 Returns True on success, False on failure.
7906 ***************************************************************************/
7908 static bool do_section(const char *pszSectionName, void *userdata)
7910 bool bRetval;
7911 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7912 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7913 bRetval = False;
7915 /* if we were in a global section then do the local inits */
7916 if (bInGlobalSection && !isglobal)
7917 init_locals();
7919 /* if we've just struck a global section, note the fact. */
7920 bInGlobalSection = isglobal;
7922 /* check for multiple global sections */
7923 if (bInGlobalSection) {
7924 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7925 return (True);
7928 if (!bInGlobalSection && bGlobalOnly)
7929 return (True);
7931 /* if we have a current service, tidy it up before moving on */
7932 bRetval = True;
7934 if (iServiceIndex >= 0)
7935 bRetval = service_ok(iServiceIndex);
7937 /* if all is still well, move to the next record in the services array */
7938 if (bRetval) {
7939 /* We put this here to avoid an odd message order if messages are */
7940 /* issued by the post-processing of a previous section. */
7941 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7943 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7944 < 0) {
7945 DEBUG(0, ("Failed to add a new service\n"));
7946 return (False);
7950 return (bRetval);
7954 /***************************************************************************
7955 Determine if a partcular base parameter is currentl set to the default value.
7956 ***************************************************************************/
7958 static bool is_default(int i)
7960 if (!defaults_saved)
7961 return False;
7962 switch (parm_table[i].type) {
7963 case P_LIST:
7964 return str_list_equal((const char **)parm_table[i].def.lvalue,
7965 *(const char ***)parm_table[i].ptr);
7966 case P_STRING:
7967 case P_USTRING:
7968 return strequal(parm_table[i].def.svalue,
7969 *(char **)parm_table[i].ptr);
7970 case P_BOOL:
7971 case P_BOOLREV:
7972 return parm_table[i].def.bvalue ==
7973 *(bool *)parm_table[i].ptr;
7974 case P_CHAR:
7975 return parm_table[i].def.cvalue ==
7976 *(char *)parm_table[i].ptr;
7977 case P_INTEGER:
7978 case P_OCTAL:
7979 case P_ENUM:
7980 return parm_table[i].def.ivalue ==
7981 *(int *)parm_table[i].ptr;
7982 case P_SEP:
7983 break;
7985 return False;
7988 /***************************************************************************
7989 Display the contents of the global structure.
7990 ***************************************************************************/
7992 static void dump_globals(FILE *f)
7994 int i;
7995 struct param_opt_struct *data;
7997 fprintf(f, "[global]\n");
7999 for (i = 0; parm_table[i].label; i++)
8000 if (parm_table[i].p_class == P_GLOBAL &&
8001 !(parm_table[i].flags & FLAG_META) &&
8002 parm_table[i].ptr &&
8003 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
8004 if (defaults_saved && is_default(i))
8005 continue;
8006 fprintf(f, "\t%s = ", parm_table[i].label);
8007 print_parameter(&parm_table[i], parm_table[i].ptr, f);
8008 fprintf(f, "\n");
8010 if (Globals.param_opt != NULL) {
8011 data = Globals.param_opt;
8012 while(data) {
8013 fprintf(f, "\t%s = %s\n", data->key, data->value);
8014 data = data->next;
8020 /***************************************************************************
8021 Return True if a local parameter is currently set to the global default.
8022 ***************************************************************************/
8024 bool lp_is_default(int snum, struct parm_struct *parm)
8026 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
8028 return equal_parameter(parm->type,
8029 ((char *)ServicePtrs[snum]) + pdiff,
8030 ((char *)&sDefault) + pdiff);
8033 /***************************************************************************
8034 Display the contents of a single services record.
8035 ***************************************************************************/
8037 static void dump_a_service(struct service *pService, FILE * f)
8039 int i;
8040 struct param_opt_struct *data;
8042 if (pService != &sDefault)
8043 fprintf(f, "[%s]\n", pService->szService);
8045 for (i = 0; parm_table[i].label; i++) {
8047 if (parm_table[i].p_class == P_LOCAL &&
8048 !(parm_table[i].flags & FLAG_META) &&
8049 parm_table[i].ptr &&
8050 (*parm_table[i].label != '-') &&
8051 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8053 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
8055 if (pService == &sDefault) {
8056 if (defaults_saved && is_default(i))
8057 continue;
8058 } else {
8059 if (equal_parameter(parm_table[i].type,
8060 ((char *)pService) +
8061 pdiff,
8062 ((char *)&sDefault) +
8063 pdiff))
8064 continue;
8067 fprintf(f, "\t%s = ", parm_table[i].label);
8068 print_parameter(&parm_table[i],
8069 ((char *)pService) + pdiff, f);
8070 fprintf(f, "\n");
8074 if (pService->param_opt != NULL) {
8075 data = pService->param_opt;
8076 while(data) {
8077 fprintf(f, "\t%s = %s\n", data->key, data->value);
8078 data = data->next;
8083 /***************************************************************************
8084 Display the contents of a parameter of a single services record.
8085 ***************************************************************************/
8087 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8089 int i;
8090 bool result = False;
8091 parm_class p_class;
8092 unsigned flag = 0;
8093 fstring local_parm_name;
8094 char *parm_opt;
8095 const char *parm_opt_value;
8097 /* check for parametrical option */
8098 fstrcpy( local_parm_name, parm_name);
8099 parm_opt = strchr( local_parm_name, ':');
8101 if (parm_opt) {
8102 *parm_opt = '\0';
8103 parm_opt++;
8104 if (strlen(parm_opt)) {
8105 parm_opt_value = lp_parm_const_string( snum,
8106 local_parm_name, parm_opt, NULL);
8107 if (parm_opt_value) {
8108 printf( "%s\n", parm_opt_value);
8109 result = True;
8112 return result;
8115 /* check for a key and print the value */
8116 if (isGlobal) {
8117 p_class = P_GLOBAL;
8118 flag = FLAG_GLOBAL;
8119 } else
8120 p_class = P_LOCAL;
8122 for (i = 0; parm_table[i].label; i++) {
8123 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8124 !(parm_table[i].flags & FLAG_META) &&
8125 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8126 parm_table[i].ptr &&
8127 (*parm_table[i].label != '-') &&
8128 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8130 void *ptr;
8132 if (isGlobal) {
8133 ptr = parm_table[i].ptr;
8134 } else {
8135 struct service *pService = ServicePtrs[snum];
8136 ptr = ((char *)pService) +
8137 PTR_DIFF(parm_table[i].ptr, &sDefault);
8140 print_parameter(&parm_table[i],
8141 ptr, f);
8142 fprintf(f, "\n");
8143 result = True;
8144 break;
8148 return result;
8151 /***************************************************************************
8152 Return info about the requested parameter (given as a string).
8153 Return NULL when the string is not a valid parameter name.
8154 ***************************************************************************/
8156 struct parm_struct *lp_get_parameter(const char *param_name)
8158 int num = map_parameter(param_name);
8160 if (num < 0) {
8161 return NULL;
8164 return &parm_table[num];
8167 /***************************************************************************
8168 Return info about the next parameter in a service.
8169 snum==GLOBAL_SECTION_SNUM gives the globals.
8170 Return NULL when out of parameters.
8171 ***************************************************************************/
8173 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8175 if (snum < 0) {
8176 /* do the globals */
8177 for (; parm_table[*i].label; (*i)++) {
8178 if (parm_table[*i].p_class == P_SEPARATOR)
8179 return &parm_table[(*i)++];
8181 if (!parm_table[*i].ptr
8182 || (*parm_table[*i].label == '-'))
8183 continue;
8185 if ((*i) > 0
8186 && (parm_table[*i].ptr ==
8187 parm_table[(*i) - 1].ptr))
8188 continue;
8190 if (is_default(*i) && !allparameters)
8191 continue;
8193 return &parm_table[(*i)++];
8195 } else {
8196 struct service *pService = ServicePtrs[snum];
8198 for (; parm_table[*i].label; (*i)++) {
8199 if (parm_table[*i].p_class == P_SEPARATOR)
8200 return &parm_table[(*i)++];
8202 if (parm_table[*i].p_class == P_LOCAL &&
8203 parm_table[*i].ptr &&
8204 (*parm_table[*i].label != '-') &&
8205 ((*i) == 0 ||
8206 (parm_table[*i].ptr !=
8207 parm_table[(*i) - 1].ptr)))
8209 int pdiff =
8210 PTR_DIFF(parm_table[*i].ptr,
8211 &sDefault);
8213 if (allparameters ||
8214 !equal_parameter(parm_table[*i].type,
8215 ((char *)pService) +
8216 pdiff,
8217 ((char *)&sDefault) +
8218 pdiff))
8220 return &parm_table[(*i)++];
8226 return NULL;
8230 #if 0
8231 /***************************************************************************
8232 Display the contents of a single copy structure.
8233 ***************************************************************************/
8234 static void dump_copy_map(bool *pcopymap)
8236 int i;
8237 if (!pcopymap)
8238 return;
8240 printf("\n\tNon-Copied parameters:\n");
8242 for (i = 0; parm_table[i].label; i++)
8243 if (parm_table[i].p_class == P_LOCAL &&
8244 parm_table[i].ptr && !pcopymap[i] &&
8245 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8247 printf("\t\t%s\n", parm_table[i].label);
8250 #endif
8252 /***************************************************************************
8253 Return TRUE if the passed service number is within range.
8254 ***************************************************************************/
8256 bool lp_snum_ok(int iService)
8258 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8261 /***************************************************************************
8262 Auto-load some home services.
8263 ***************************************************************************/
8265 static void lp_add_auto_services(char *str)
8267 char *s;
8268 char *p;
8269 int homes;
8270 char *saveptr;
8272 if (!str)
8273 return;
8275 s = SMB_STRDUP(str);
8276 if (!s)
8277 return;
8279 homes = lp_servicenumber(HOMES_NAME);
8281 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8282 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8283 char *home;
8285 if (lp_servicenumber(p) >= 0)
8286 continue;
8288 home = get_user_home_dir(talloc_tos(), p);
8290 if (home && home[0] && homes >= 0)
8291 lp_add_home(p, homes, p, home);
8293 TALLOC_FREE(home);
8295 SAFE_FREE(s);
8298 /***************************************************************************
8299 Auto-load one printer.
8300 ***************************************************************************/
8302 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8304 int printers = lp_servicenumber(PRINTERS_NAME);
8305 int i;
8307 if (lp_servicenumber(name) < 0) {
8308 lp_add_printer(name, printers);
8309 if ((i = lp_servicenumber(name)) >= 0) {
8310 string_set(&ServicePtrs[i]->comment, comment);
8311 ServicePtrs[i]->autoloaded = True;
8316 /***************************************************************************
8317 Have we loaded a services file yet?
8318 ***************************************************************************/
8320 bool lp_loaded(void)
8322 return (bLoaded);
8325 /***************************************************************************
8326 Unload unused services.
8327 ***************************************************************************/
8329 void lp_killunused(bool (*snumused) (int))
8331 int i;
8332 for (i = 0; i < iNumServices; i++) {
8333 if (!VALID(i))
8334 continue;
8336 /* don't kill autoloaded or usershare services */
8337 if ( ServicePtrs[i]->autoloaded ||
8338 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8339 continue;
8342 if (!snumused || !snumused(i)) {
8343 free_service_byindex(i);
8349 * Kill all except autoloaded and usershare services - convenience wrapper
8351 void lp_kill_all_services(void)
8353 lp_killunused(NULL);
8356 /***************************************************************************
8357 Unload a service.
8358 ***************************************************************************/
8360 void lp_killservice(int iServiceIn)
8362 if (VALID(iServiceIn)) {
8363 free_service_byindex(iServiceIn);
8367 /***************************************************************************
8368 Save the curent values of all global and sDefault parameters into the
8369 defaults union. This allows swat and testparm to show only the
8370 changed (ie. non-default) parameters.
8371 ***************************************************************************/
8373 static void lp_save_defaults(void)
8375 int i;
8376 for (i = 0; parm_table[i].label; i++) {
8377 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8378 continue;
8379 switch (parm_table[i].type) {
8380 case P_LIST:
8381 parm_table[i].def.lvalue = str_list_copy(
8382 NULL, *(const char ***)parm_table[i].ptr);
8383 break;
8384 case P_STRING:
8385 case P_USTRING:
8386 if (parm_table[i].ptr) {
8387 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8388 } else {
8389 parm_table[i].def.svalue = NULL;
8391 break;
8392 case P_BOOL:
8393 case P_BOOLREV:
8394 parm_table[i].def.bvalue =
8395 *(bool *)parm_table[i].ptr;
8396 break;
8397 case P_CHAR:
8398 parm_table[i].def.cvalue =
8399 *(char *)parm_table[i].ptr;
8400 break;
8401 case P_INTEGER:
8402 case P_OCTAL:
8403 case P_ENUM:
8404 parm_table[i].def.ivalue =
8405 *(int *)parm_table[i].ptr;
8406 break;
8407 case P_SEP:
8408 break;
8411 defaults_saved = True;
8414 /***********************************************************
8415 If we should send plaintext/LANMAN passwords in the clinet
8416 ************************************************************/
8418 static void set_allowed_client_auth(void)
8420 if (Globals.bClientNTLMv2Auth) {
8421 Globals.bClientLanManAuth = False;
8423 if (!Globals.bClientLanManAuth) {
8424 Globals.bClientPlaintextAuth = False;
8428 /***************************************************************************
8429 JRA.
8430 The following code allows smbd to read a user defined share file.
8431 Yes, this is my intent. Yes, I'm comfortable with that...
8433 THE FOLLOWING IS SECURITY CRITICAL CODE.
8435 It washes your clothes, it cleans your house, it guards you while you sleep...
8436 Do not f%^k with it....
8437 ***************************************************************************/
8439 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8441 /***************************************************************************
8442 Check allowed stat state of a usershare file.
8443 Ensure we print out who is dicking with us so the admin can
8444 get their sorry ass fired.
8445 ***************************************************************************/
8447 static bool check_usershare_stat(const char *fname,
8448 const SMB_STRUCT_STAT *psbuf)
8450 if (!S_ISREG(psbuf->st_ex_mode)) {
8451 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8452 "not a regular file\n",
8453 fname, (unsigned int)psbuf->st_ex_uid ));
8454 return False;
8457 /* Ensure this doesn't have the other write bit set. */
8458 if (psbuf->st_ex_mode & S_IWOTH) {
8459 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8460 "public write. Refusing to allow as a usershare file.\n",
8461 fname, (unsigned int)psbuf->st_ex_uid ));
8462 return False;
8465 /* Should be 10k or less. */
8466 if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8467 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8468 "too large (%u) to be a user share file.\n",
8469 fname, (unsigned int)psbuf->st_ex_uid,
8470 (unsigned int)psbuf->st_ex_size ));
8471 return False;
8474 return True;
8477 /***************************************************************************
8478 Parse the contents of a usershare file.
8479 ***************************************************************************/
8481 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8482 SMB_STRUCT_STAT *psbuf,
8483 const char *servicename,
8484 int snum,
8485 char **lines,
8486 int numlines,
8487 char **pp_sharepath,
8488 char **pp_comment,
8489 char **pp_cp_servicename,
8490 struct security_descriptor **ppsd,
8491 bool *pallow_guest)
8493 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8494 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8495 int us_vers;
8496 SMB_STRUCT_DIR *dp;
8497 SMB_STRUCT_STAT sbuf;
8498 char *sharepath = NULL;
8499 char *comment = NULL;
8501 *pp_sharepath = NULL;
8502 *pp_comment = NULL;
8504 *pallow_guest = False;
8506 if (numlines < 4) {
8507 return USERSHARE_MALFORMED_FILE;
8510 if (strcmp(lines[0], "#VERSION 1") == 0) {
8511 us_vers = 1;
8512 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8513 us_vers = 2;
8514 if (numlines < 5) {
8515 return USERSHARE_MALFORMED_FILE;
8517 } else {
8518 return USERSHARE_BAD_VERSION;
8521 if (strncmp(lines[1], "path=", 5) != 0) {
8522 return USERSHARE_MALFORMED_PATH;
8525 sharepath = talloc_strdup(ctx, &lines[1][5]);
8526 if (!sharepath) {
8527 return USERSHARE_POSIX_ERR;
8529 trim_string(sharepath, " ", " ");
8531 if (strncmp(lines[2], "comment=", 8) != 0) {
8532 return USERSHARE_MALFORMED_COMMENT_DEF;
8535 comment = talloc_strdup(ctx, &lines[2][8]);
8536 if (!comment) {
8537 return USERSHARE_POSIX_ERR;
8539 trim_string(comment, " ", " ");
8540 trim_char(comment, '"', '"');
8542 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8543 return USERSHARE_MALFORMED_ACL_DEF;
8546 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8547 return USERSHARE_ACL_ERR;
8550 if (us_vers == 2) {
8551 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8552 return USERSHARE_MALFORMED_ACL_DEF;
8554 if (lines[4][9] == 'y') {
8555 *pallow_guest = True;
8558 /* Backwards compatible extension to file version #2. */
8559 if (numlines > 5) {
8560 if (strncmp(lines[5], "sharename=", 10) != 0) {
8561 return USERSHARE_MALFORMED_SHARENAME_DEF;
8563 if (!strequal(&lines[5][10], servicename)) {
8564 return USERSHARE_BAD_SHARENAME;
8566 *pp_cp_servicename = talloc_strdup(ctx, &lines[5][10]);
8567 if (!*pp_cp_servicename) {
8568 return USERSHARE_POSIX_ERR;
8573 if (*pp_cp_servicename == NULL) {
8574 *pp_cp_servicename = talloc_strdup(ctx, servicename);
8575 if (!*pp_cp_servicename) {
8576 return USERSHARE_POSIX_ERR;
8580 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8581 /* Path didn't change, no checks needed. */
8582 *pp_sharepath = sharepath;
8583 *pp_comment = comment;
8584 return USERSHARE_OK;
8587 /* The path *must* be absolute. */
8588 if (sharepath[0] != '/') {
8589 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8590 servicename, sharepath));
8591 return USERSHARE_PATH_NOT_ABSOLUTE;
8594 /* If there is a usershare prefix deny list ensure one of these paths
8595 doesn't match the start of the user given path. */
8596 if (prefixdenylist) {
8597 int i;
8598 for ( i=0; prefixdenylist[i]; i++ ) {
8599 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8600 servicename, i, prefixdenylist[i], sharepath ));
8601 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8602 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8603 "usershare prefix deny list entries.\n",
8604 servicename, sharepath));
8605 return USERSHARE_PATH_IS_DENIED;
8610 /* If there is a usershare prefix allow list ensure one of these paths
8611 does match the start of the user given path. */
8613 if (prefixallowlist) {
8614 int i;
8615 for ( i=0; prefixallowlist[i]; i++ ) {
8616 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8617 servicename, i, prefixallowlist[i], sharepath ));
8618 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8619 break;
8622 if (prefixallowlist[i] == NULL) {
8623 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8624 "usershare prefix allow list entries.\n",
8625 servicename, sharepath));
8626 return USERSHARE_PATH_NOT_ALLOWED;
8630 /* Ensure this is pointing to a directory. */
8631 dp = sys_opendir(sharepath);
8633 if (!dp) {
8634 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8635 servicename, sharepath));
8636 return USERSHARE_PATH_NOT_DIRECTORY;
8639 /* Ensure the owner of the usershare file has permission to share
8640 this directory. */
8642 if (sys_stat(sharepath, &sbuf, false) == -1) {
8643 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8644 servicename, sharepath, strerror(errno) ));
8645 sys_closedir(dp);
8646 return USERSHARE_POSIX_ERR;
8649 sys_closedir(dp);
8651 if (!S_ISDIR(sbuf.st_ex_mode)) {
8652 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8653 servicename, sharepath ));
8654 return USERSHARE_PATH_NOT_DIRECTORY;
8657 /* Check if sharing is restricted to owner-only. */
8658 /* psbuf is the stat of the usershare definition file,
8659 sbuf is the stat of the target directory to be shared. */
8661 if (lp_usershare_owner_only()) {
8662 /* root can share anything. */
8663 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8664 return USERSHARE_PATH_NOT_ALLOWED;
8668 *pp_sharepath = sharepath;
8669 *pp_comment = comment;
8670 return USERSHARE_OK;
8673 /***************************************************************************
8674 Deal with a usershare file.
8675 Returns:
8676 >= 0 - snum
8677 -1 - Bad name, invalid contents.
8678 - service name already existed and not a usershare, problem
8679 with permissions to share directory etc.
8680 ***************************************************************************/
8682 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8684 SMB_STRUCT_STAT sbuf;
8685 SMB_STRUCT_STAT lsbuf;
8686 char *fname = NULL;
8687 char *sharepath = NULL;
8688 char *comment = NULL;
8689 char *cp_service_name = NULL;
8690 char **lines = NULL;
8691 int numlines = 0;
8692 int fd = -1;
8693 int iService = -1;
8694 TALLOC_CTX *ctx = talloc_stackframe();
8695 struct security_descriptor *psd = NULL;
8696 bool guest_ok = False;
8697 char *canon_name = NULL;
8698 bool added_service = false;
8699 int ret = -1;
8701 /* Ensure share name doesn't contain invalid characters. */
8702 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8703 DEBUG(0,("process_usershare_file: share name %s contains "
8704 "invalid characters (any of %s)\n",
8705 file_name, INVALID_SHARENAME_CHARS ));
8706 goto out;
8709 canon_name = canonicalize_servicename(ctx, file_name);
8710 if (!canon_name) {
8711 goto out;
8714 fname = talloc_asprintf(ctx, "%s/%s", dir_name, file_name);
8715 if (!fname) {
8716 goto out;
8719 /* Minimize the race condition by doing an lstat before we
8720 open and fstat. Ensure this isn't a symlink link. */
8722 if (sys_lstat(fname, &lsbuf, false) != 0) {
8723 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8724 fname, strerror(errno) ));
8725 goto out;
8728 /* This must be a regular file, not a symlink, directory or
8729 other strange filetype. */
8730 if (!check_usershare_stat(fname, &lsbuf)) {
8731 goto out;
8735 TDB_DATA data = dbwrap_fetch_bystring(
8736 ServiceHash, canon_name, canon_name);
8738 iService = -1;
8740 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8741 iService = *(int *)data.dptr;
8745 if (iService != -1 &&
8746 timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8747 &lsbuf.st_ex_mtime) == 0) {
8748 /* Nothing changed - Mark valid and return. */
8749 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8750 canon_name ));
8751 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8752 ret = iService;
8753 goto out;
8756 /* Try and open the file read only - no symlinks allowed. */
8757 #ifdef O_NOFOLLOW
8758 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8759 #else
8760 fd = sys_open(fname, O_RDONLY, 0);
8761 #endif
8763 if (fd == -1) {
8764 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8765 fname, strerror(errno) ));
8766 goto out;
8769 /* Now fstat to be *SURE* it's a regular file. */
8770 if (sys_fstat(fd, &sbuf, false) != 0) {
8771 close(fd);
8772 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8773 fname, strerror(errno) ));
8774 goto out;
8777 /* Is it the same dev/inode as was lstated ? */
8778 if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8779 close(fd);
8780 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8781 "Symlink spoofing going on ?\n", fname ));
8782 goto out;
8785 /* This must be a regular file, not a symlink, directory or
8786 other strange filetype. */
8787 if (!check_usershare_stat(fname, &sbuf)) {
8788 goto out;
8791 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8793 close(fd);
8794 if (lines == NULL) {
8795 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8796 fname, (unsigned int)sbuf.st_ex_uid ));
8797 goto out;
8800 if (parse_usershare_file(ctx, &sbuf, file_name,
8801 iService, lines, numlines, &sharepath,
8802 &comment, &cp_service_name,
8803 &psd, &guest_ok) != USERSHARE_OK) {
8804 goto out;
8807 /* Everything ok - add the service possibly using a template. */
8808 if (iService < 0) {
8809 const struct service *sp = &sDefault;
8810 if (snum_template != -1) {
8811 sp = ServicePtrs[snum_template];
8814 if ((iService = add_a_service(sp, cp_service_name)) < 0) {
8815 DEBUG(0, ("process_usershare_file: Failed to add "
8816 "new service %s\n", cp_service_name));
8817 goto out;
8820 added_service = true;
8822 /* Read only is controlled by usershare ACL below. */
8823 ServicePtrs[iService]->bRead_only = False;
8826 /* Write the ACL of the new/modified share. */
8827 if (!set_share_security(canon_name, psd)) {
8828 DEBUG(0, ("process_usershare_file: Failed to set share "
8829 "security for user share %s\n",
8830 canon_name ));
8831 goto out;
8834 /* If from a template it may be marked invalid. */
8835 ServicePtrs[iService]->valid = True;
8837 /* Set the service as a valid usershare. */
8838 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8840 /* Set guest access. */
8841 if (lp_usershare_allow_guests()) {
8842 ServicePtrs[iService]->bGuest_ok = guest_ok;
8845 /* And note when it was loaded. */
8846 ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8847 string_set(&ServicePtrs[iService]->szPath, sharepath);
8848 string_set(&ServicePtrs[iService]->comment, comment);
8850 ret = iService;
8852 out:
8854 if (ret == -1 && iService != -1 && added_service) {
8855 lp_remove_service(iService);
8858 TALLOC_FREE(lines);
8859 TALLOC_FREE(ctx);
8860 return ret;
8863 /***************************************************************************
8864 Checks if a usershare entry has been modified since last load.
8865 ***************************************************************************/
8867 static bool usershare_exists(int iService, struct timespec *last_mod)
8869 SMB_STRUCT_STAT lsbuf;
8870 const char *usersharepath = Globals.szUsersharePath;
8871 char *fname;
8873 if (asprintf(&fname, "%s/%s",
8874 usersharepath,
8875 ServicePtrs[iService]->szService) < 0) {
8876 return false;
8879 if (sys_lstat(fname, &lsbuf, false) != 0) {
8880 SAFE_FREE(fname);
8881 return false;
8884 if (!S_ISREG(lsbuf.st_ex_mode)) {
8885 SAFE_FREE(fname);
8886 return false;
8889 SAFE_FREE(fname);
8890 *last_mod = lsbuf.st_ex_mtime;
8891 return true;
8894 /***************************************************************************
8895 Load a usershare service by name. Returns a valid servicenumber or -1.
8896 ***************************************************************************/
8898 int load_usershare_service(const char *servicename)
8900 SMB_STRUCT_STAT sbuf;
8901 const char *usersharepath = Globals.szUsersharePath;
8902 int max_user_shares = Globals.iUsershareMaxShares;
8903 int snum_template = -1;
8905 if (*usersharepath == 0 || max_user_shares == 0) {
8906 return -1;
8909 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8910 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8911 usersharepath, strerror(errno) ));
8912 return -1;
8915 if (!S_ISDIR(sbuf.st_ex_mode)) {
8916 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8917 usersharepath ));
8918 return -1;
8922 * This directory must be owned by root, and have the 't' bit set.
8923 * It also must not be writable by "other".
8926 #ifdef S_ISVTX
8927 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8928 #else
8929 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
8930 #endif
8931 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8932 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8933 usersharepath ));
8934 return -1;
8937 /* Ensure the template share exists if it's set. */
8938 if (Globals.szUsershareTemplateShare[0]) {
8939 /* We can't use lp_servicenumber here as we are recommending that
8940 template shares have -valid=False set. */
8941 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8942 if (ServicePtrs[snum_template]->szService &&
8943 strequal(ServicePtrs[snum_template]->szService,
8944 Globals.szUsershareTemplateShare)) {
8945 break;
8949 if (snum_template == -1) {
8950 DEBUG(0,("load_usershare_service: usershare template share %s "
8951 "does not exist.\n",
8952 Globals.szUsershareTemplateShare ));
8953 return -1;
8957 return process_usershare_file(usersharepath, servicename, snum_template);
8960 /***************************************************************************
8961 Load all user defined shares from the user share directory.
8962 We only do this if we're enumerating the share list.
8963 This is the function that can delete usershares that have
8964 been removed.
8965 ***************************************************************************/
8967 int load_usershare_shares(void)
8969 SMB_STRUCT_DIR *dp;
8970 SMB_STRUCT_STAT sbuf;
8971 SMB_STRUCT_DIRENT *de;
8972 int num_usershares = 0;
8973 int max_user_shares = Globals.iUsershareMaxShares;
8974 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8975 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8976 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8977 int iService;
8978 int snum_template = -1;
8979 const char *usersharepath = Globals.szUsersharePath;
8980 int ret = lp_numservices();
8982 if (max_user_shares == 0 || *usersharepath == '\0') {
8983 return lp_numservices();
8986 if (sys_stat(usersharepath, &sbuf, false) != 0) {
8987 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8988 usersharepath, strerror(errno) ));
8989 return ret;
8993 * This directory must be owned by root, and have the 't' bit set.
8994 * It also must not be writable by "other".
8997 #ifdef S_ISVTX
8998 if (sbuf.st_ex_uid != 0 || !(sbuf.st_ex_mode & S_ISVTX) || (sbuf.st_ex_mode & S_IWOTH)) {
8999 #else
9000 if (sbuf.st_ex_uid != 0 || (sbuf.st_ex_mode & S_IWOTH)) {
9001 #endif
9002 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
9003 "or does not have the sticky bit 't' set or is writable by anyone.\n",
9004 usersharepath ));
9005 return ret;
9008 /* Ensure the template share exists if it's set. */
9009 if (Globals.szUsershareTemplateShare[0]) {
9010 /* We can't use lp_servicenumber here as we are recommending that
9011 template shares have -valid=False set. */
9012 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
9013 if (ServicePtrs[snum_template]->szService &&
9014 strequal(ServicePtrs[snum_template]->szService,
9015 Globals.szUsershareTemplateShare)) {
9016 break;
9020 if (snum_template == -1) {
9021 DEBUG(0,("load_usershare_shares: usershare template share %s "
9022 "does not exist.\n",
9023 Globals.szUsershareTemplateShare ));
9024 return ret;
9028 /* Mark all existing usershares as pending delete. */
9029 for (iService = iNumServices - 1; iService >= 0; iService--) {
9030 if (VALID(iService) && ServicePtrs[iService]->usershare) {
9031 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
9035 dp = sys_opendir(usersharepath);
9036 if (!dp) {
9037 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
9038 usersharepath, strerror(errno) ));
9039 return ret;
9042 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
9043 (de = sys_readdir(dp));
9044 num_dir_entries++ ) {
9045 int r;
9046 const char *n = de->d_name;
9048 /* Ignore . and .. */
9049 if (*n == '.') {
9050 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9051 continue;
9055 if (n[0] == ':') {
9056 /* Temporary file used when creating a share. */
9057 num_tmp_dir_entries++;
9060 /* Allow 20% tmp entries. */
9061 if (num_tmp_dir_entries > allowed_tmp_entries) {
9062 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
9063 "in directory %s\n",
9064 num_tmp_dir_entries, usersharepath));
9065 break;
9068 r = process_usershare_file(usersharepath, n, snum_template);
9069 if (r == 0) {
9070 /* Update the services count. */
9071 num_usershares++;
9072 if (num_usershares >= max_user_shares) {
9073 DEBUG(0,("load_usershare_shares: max user shares reached "
9074 "on file %s in directory %s\n",
9075 n, usersharepath ));
9076 break;
9078 } else if (r == -1) {
9079 num_bad_dir_entries++;
9082 /* Allow 20% bad entries. */
9083 if (num_bad_dir_entries > allowed_bad_entries) {
9084 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
9085 "in directory %s\n",
9086 num_bad_dir_entries, usersharepath));
9087 break;
9090 /* Allow 20% bad entries. */
9091 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
9092 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
9093 "in directory %s\n",
9094 num_dir_entries, usersharepath));
9095 break;
9099 sys_closedir(dp);
9101 /* Sweep through and delete any non-refreshed usershares that are
9102 not currently in use. */
9103 for (iService = iNumServices - 1; iService >= 0; iService--) {
9104 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
9105 if (conn_snum_used(iService)) {
9106 continue;
9108 /* Remove from the share ACL db. */
9109 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
9110 lp_servicename(iService) ));
9111 delete_share_security(lp_servicename(iService));
9112 free_service_byindex(iService);
9116 return lp_numservices();
9119 /********************************************************
9120 Destroy global resources allocated in this file
9121 ********************************************************/
9123 void gfree_loadparm(void)
9125 int i;
9127 free_file_list();
9129 /* Free resources allocated to services */
9131 for ( i = 0; i < iNumServices; i++ ) {
9132 if ( VALID(i) ) {
9133 free_service_byindex(i);
9137 SAFE_FREE( ServicePtrs );
9138 iNumServices = 0;
9140 /* Now release all resources allocated to global
9141 parameters and the default service */
9143 free_global_parameters();
9147 /***************************************************************************
9148 Allow client apps to specify that they are a client
9149 ***************************************************************************/
9150 void lp_set_in_client(bool b)
9152 in_client = b;
9156 /***************************************************************************
9157 Determine if we're running in a client app
9158 ***************************************************************************/
9159 bool lp_is_in_client(void)
9161 return in_client;
9164 /***************************************************************************
9165 Load the services array from the services file. Return True on success,
9166 False on failure.
9167 ***************************************************************************/
9169 bool lp_load_ex(const char *pszFname,
9170 bool global_only,
9171 bool save_defaults,
9172 bool add_ipc,
9173 bool initialize_globals,
9174 bool allow_include_registry,
9175 bool allow_registry_shares)
9177 char *n2 = NULL;
9178 bool bRetval;
9180 bRetval = False;
9182 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9184 bInGlobalSection = True;
9185 bGlobalOnly = global_only;
9186 bAllowIncludeRegistry = allow_include_registry;
9188 init_globals(! initialize_globals);
9189 debug_init();
9191 free_file_list();
9193 if (save_defaults) {
9194 init_locals();
9195 lp_save_defaults();
9198 free_param_opts(&Globals.param_opt);
9200 /* We get sections first, so have to start 'behind' to make up */
9201 iServiceIndex = -1;
9203 if (lp_config_backend_is_file()) {
9204 n2 = talloc_sub_basic(talloc_tos(), get_current_username(),
9205 current_user_info.domain,
9206 pszFname);
9207 if (!n2) {
9208 smb_panic("lp_load_ex: out of memory");
9211 add_to_file_list(pszFname, n2);
9213 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9214 TALLOC_FREE(n2);
9216 /* finish up the last section */
9217 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9218 if (bRetval) {
9219 if (iServiceIndex >= 0) {
9220 bRetval = service_ok(iServiceIndex);
9224 if (lp_config_backend_is_registry()) {
9225 /* config backend changed to registry in config file */
9227 * We need to use this extra global variable here to
9228 * survive restart: init_globals uses this as a default
9229 * for ConfigBackend. Otherwise, init_globals would
9230 * send us into an endless loop here.
9232 config_backend = CONFIG_BACKEND_REGISTRY;
9233 /* start over */
9234 DEBUG(1, ("lp_load_ex: changing to config backend "
9235 "registry\n"));
9236 init_globals(false);
9237 lp_kill_all_services();
9238 return lp_load_ex(pszFname, global_only, save_defaults,
9239 add_ipc, initialize_globals,
9240 allow_include_registry,
9241 allow_registry_shares);
9243 } else if (lp_config_backend_is_registry()) {
9244 bRetval = process_registry_globals();
9245 } else {
9246 DEBUG(0, ("Illegal config backend given: %d\n",
9247 lp_config_backend()));
9248 bRetval = false;
9251 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9252 bRetval = process_registry_shares();
9255 lp_add_auto_services(lp_auto_services());
9257 if (add_ipc) {
9258 /* When 'restrict anonymous = 2' guest connections to ipc$
9259 are denied */
9260 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9261 if ( lp_enable_asu_support() ) {
9262 lp_add_ipc("ADMIN$", false);
9266 set_server_role();
9267 set_default_server_announce_type();
9268 set_allowed_client_auth();
9270 bLoaded = True;
9272 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9273 /* if bWINSsupport is true and we are in the client */
9274 if (lp_is_in_client() && Globals.bWINSsupport) {
9275 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9278 init_iconv();
9280 bAllowIncludeRegistry = true;
9282 return (bRetval);
9285 bool lp_load(const char *pszFname,
9286 bool global_only,
9287 bool save_defaults,
9288 bool add_ipc,
9289 bool initialize_globals)
9291 return lp_load_ex(pszFname,
9292 global_only,
9293 save_defaults,
9294 add_ipc,
9295 initialize_globals,
9296 true, false);
9299 bool lp_load_initial_only(const char *pszFname)
9301 return lp_load_ex(pszFname,
9302 true,
9303 false,
9304 false,
9305 true,
9306 false,
9307 false);
9310 bool lp_load_with_registry_shares(const char *pszFname,
9311 bool global_only,
9312 bool save_defaults,
9313 bool add_ipc,
9314 bool initialize_globals)
9316 return lp_load_ex(pszFname,
9317 global_only,
9318 save_defaults,
9319 add_ipc,
9320 initialize_globals,
9321 true,
9322 true);
9325 /***************************************************************************
9326 Return the max number of services.
9327 ***************************************************************************/
9329 int lp_numservices(void)
9331 return (iNumServices);
9334 /***************************************************************************
9335 Display the contents of the services array in human-readable form.
9336 ***************************************************************************/
9338 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9340 int iService;
9342 if (show_defaults)
9343 defaults_saved = False;
9345 dump_globals(f);
9347 dump_a_service(&sDefault, f);
9349 for (iService = 0; iService < maxtoprint; iService++) {
9350 fprintf(f,"\n");
9351 lp_dump_one(f, show_defaults, iService);
9355 /***************************************************************************
9356 Display the contents of one service in human-readable form.
9357 ***************************************************************************/
9359 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9361 if (VALID(snum)) {
9362 if (ServicePtrs[snum]->szService[0] == '\0')
9363 return;
9364 dump_a_service(ServicePtrs[snum], f);
9368 /***************************************************************************
9369 Return the number of the service with the given name, or -1 if it doesn't
9370 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9371 getservicebyname()! This works ONLY if all services have been loaded, and
9372 does not copy the found service.
9373 ***************************************************************************/
9375 int lp_servicenumber(const char *pszServiceName)
9377 int iService;
9378 fstring serviceName;
9380 if (!pszServiceName) {
9381 return GLOBAL_SECTION_SNUM;
9384 for (iService = iNumServices - 1; iService >= 0; iService--) {
9385 if (VALID(iService) && ServicePtrs[iService]->szService) {
9387 * The substitution here is used to support %U is
9388 * service names
9390 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9391 standard_sub_basic(get_current_username(),
9392 current_user_info.domain,
9393 serviceName,sizeof(serviceName));
9394 if (strequal(serviceName, pszServiceName)) {
9395 break;
9400 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9401 struct timespec last_mod;
9403 if (!usershare_exists(iService, &last_mod)) {
9404 /* Remove the share security tdb entry for it. */
9405 delete_share_security(lp_servicename(iService));
9406 /* Remove it from the array. */
9407 free_service_byindex(iService);
9408 /* Doesn't exist anymore. */
9409 return GLOBAL_SECTION_SNUM;
9412 /* Has it been modified ? If so delete and reload. */
9413 if (timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
9414 &last_mod) < 0) {
9415 /* Remove it from the array. */
9416 free_service_byindex(iService);
9417 /* and now reload it. */
9418 iService = load_usershare_service(pszServiceName);
9422 if (iService < 0) {
9423 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9424 return GLOBAL_SECTION_SNUM;
9427 return (iService);
9430 bool share_defined(const char *service_name)
9432 return (lp_servicenumber(service_name) != -1);
9435 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9436 const char *sharename)
9438 struct share_params *result;
9439 char *sname;
9440 int snum;
9442 if (!(sname = SMB_STRDUP(sharename))) {
9443 return NULL;
9446 snum = find_service(sname);
9447 SAFE_FREE(sname);
9449 if (snum < 0) {
9450 return NULL;
9453 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9454 DEBUG(0, ("talloc failed\n"));
9455 return NULL;
9458 result->service = snum;
9459 return result;
9462 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9464 struct share_iterator *result;
9466 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9467 DEBUG(0, ("talloc failed\n"));
9468 return NULL;
9471 result->next_id = 0;
9472 return result;
9475 struct share_params *next_share(struct share_iterator *list)
9477 struct share_params *result;
9479 while (!lp_snum_ok(list->next_id) &&
9480 (list->next_id < lp_numservices())) {
9481 list->next_id += 1;
9484 if (list->next_id >= lp_numservices()) {
9485 return NULL;
9488 if (!(result = TALLOC_P(list, struct share_params))) {
9489 DEBUG(0, ("talloc failed\n"));
9490 return NULL;
9493 result->service = list->next_id;
9494 list->next_id += 1;
9495 return result;
9498 struct share_params *next_printer(struct share_iterator *list)
9500 struct share_params *result;
9502 while ((result = next_share(list)) != NULL) {
9503 if (lp_print_ok(result->service)) {
9504 break;
9507 return result;
9511 * This is a hack for a transition period until we transformed all code from
9512 * service numbers to struct share_params.
9515 struct share_params *snum2params_static(int snum)
9517 static struct share_params result;
9518 result.service = snum;
9519 return &result;
9522 /*******************************************************************
9523 A useful volume label function.
9524 ********************************************************************/
9526 const char *volume_label(int snum)
9528 char *ret;
9529 const char *label = lp_volume(snum);
9530 if (!*label) {
9531 label = lp_servicename(snum);
9534 /* This returns a 33 byte guarenteed null terminated string. */
9535 ret = talloc_strndup(talloc_tos(), label, 32);
9536 if (!ret) {
9537 return "";
9539 return ret;
9542 /*******************************************************************
9543 Set the server type we will announce as via nmbd.
9544 ********************************************************************/
9546 static void set_default_server_announce_type(void)
9548 default_server_announce = 0;
9549 default_server_announce |= SV_TYPE_WORKSTATION;
9550 default_server_announce |= SV_TYPE_SERVER;
9551 default_server_announce |= SV_TYPE_SERVER_UNIX;
9553 /* note that the flag should be set only if we have a
9554 printer service but nmbd doesn't actually load the
9555 services so we can't tell --jerry */
9557 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9559 switch (lp_announce_as()) {
9560 case ANNOUNCE_AS_NT_SERVER:
9561 default_server_announce |= SV_TYPE_SERVER_NT;
9562 /* fall through... */
9563 case ANNOUNCE_AS_NT_WORKSTATION:
9564 default_server_announce |= SV_TYPE_NT;
9565 break;
9566 case ANNOUNCE_AS_WIN95:
9567 default_server_announce |= SV_TYPE_WIN95_PLUS;
9568 break;
9569 case ANNOUNCE_AS_WFW:
9570 default_server_announce |= SV_TYPE_WFW;
9571 break;
9572 default:
9573 break;
9576 switch (lp_server_role()) {
9577 case ROLE_DOMAIN_MEMBER:
9578 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9579 break;
9580 case ROLE_DOMAIN_PDC:
9581 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9582 break;
9583 case ROLE_DOMAIN_BDC:
9584 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9585 break;
9586 case ROLE_STANDALONE:
9587 default:
9588 break;
9590 if (lp_time_server())
9591 default_server_announce |= SV_TYPE_TIME_SOURCE;
9593 if (lp_host_msdfs())
9594 default_server_announce |= SV_TYPE_DFS_SERVER;
9597 /***********************************************************
9598 If we are PDC then prefer us as DMB
9599 ************************************************************/
9601 bool lp_domain_master(void)
9603 if (Globals.iDomainMaster == Auto)
9604 return (lp_server_role() == ROLE_DOMAIN_PDC);
9606 return (bool)Globals.iDomainMaster;
9609 /***********************************************************
9610 If we are PDC then prefer us as DMB
9611 ************************************************************/
9613 bool lp_domain_master_true_or_auto(void)
9615 if (Globals.iDomainMaster) /* auto or yes */
9616 return true;
9618 return false;
9621 /***********************************************************
9622 If we are DMB then prefer us as LMB
9623 ************************************************************/
9625 bool lp_preferred_master(void)
9627 if (Globals.iPreferredMaster == Auto)
9628 return (lp_local_master() && lp_domain_master());
9630 return (bool)Globals.iPreferredMaster;
9633 /*******************************************************************
9634 Remove a service.
9635 ********************************************************************/
9637 void lp_remove_service(int snum)
9639 ServicePtrs[snum]->valid = False;
9640 invalid_services[num_invalid_services++] = snum;
9643 /*******************************************************************
9644 Copy a service.
9645 ********************************************************************/
9647 void lp_copy_service(int snum, const char *new_name)
9649 do_section(new_name, NULL);
9650 if (snum >= 0) {
9651 snum = lp_servicenumber(new_name);
9652 if (snum >= 0)
9653 lp_do_parameter(snum, "copy", lp_servicename(snum));
9658 /*******************************************************************
9659 Get the default server type we will announce as via nmbd.
9660 ********************************************************************/
9662 int lp_default_server_announce(void)
9664 return default_server_announce;
9667 /*******************************************************************
9668 Split the announce version into major and minor numbers.
9669 ********************************************************************/
9671 int lp_major_announce_version(void)
9673 static bool got_major = False;
9674 static int major_version = DEFAULT_MAJOR_VERSION;
9675 char *vers;
9676 char *p;
9678 if (got_major)
9679 return major_version;
9681 got_major = True;
9682 if ((vers = lp_announce_version()) == NULL)
9683 return major_version;
9685 if ((p = strchr_m(vers, '.')) == 0)
9686 return major_version;
9688 *p = '\0';
9689 major_version = atoi(vers);
9690 return major_version;
9693 int lp_minor_announce_version(void)
9695 static bool got_minor = False;
9696 static int minor_version = DEFAULT_MINOR_VERSION;
9697 char *vers;
9698 char *p;
9700 if (got_minor)
9701 return minor_version;
9703 got_minor = True;
9704 if ((vers = lp_announce_version()) == NULL)
9705 return minor_version;
9707 if ((p = strchr_m(vers, '.')) == 0)
9708 return minor_version;
9710 p++;
9711 minor_version = atoi(p);
9712 return minor_version;
9715 /***********************************************************
9716 Set the global name resolution order (used in smbclient).
9717 ************************************************************/
9719 void lp_set_name_resolve_order(const char *new_order)
9721 string_set(&Globals.szNameResolveOrder, new_order);
9724 const char *lp_printername(int snum)
9726 const char *ret = _lp_printername(snum);
9727 if (ret == NULL || (ret != NULL && *ret == '\0'))
9728 ret = lp_const_servicename(snum);
9730 return ret;
9734 /***********************************************************
9735 Allow daemons such as winbindd to fix their logfile name.
9736 ************************************************************/
9738 void lp_set_logfile(const char *name)
9740 string_set(&Globals.szLogFile, name);
9741 debug_set_logfile(name);
9744 /*******************************************************************
9745 Return the max print jobs per queue.
9746 ********************************************************************/
9748 int lp_maxprintjobs(int snum)
9750 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9751 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9752 maxjobs = PRINT_MAX_JOBID - 1;
9754 return maxjobs;
9757 const char *lp_printcapname(void)
9759 if ((Globals.szPrintcapname != NULL) &&
9760 (Globals.szPrintcapname[0] != '\0'))
9761 return Globals.szPrintcapname;
9763 if (sDefault.iPrinting == PRINT_CUPS) {
9764 #ifdef HAVE_CUPS
9765 return "cups";
9766 #else
9767 return "lpstat";
9768 #endif
9771 if (sDefault.iPrinting == PRINT_BSD)
9772 return "/etc/printcap";
9774 return PRINTCAP_NAME;
9777 static uint32 spoolss_state;
9779 bool lp_disable_spoolss( void )
9781 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9782 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9784 return spoolss_state == SVCCTL_STOPPED ? True : False;
9787 void lp_set_spoolss_state( uint32 state )
9789 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9791 spoolss_state = state;
9794 uint32 lp_get_spoolss_state( void )
9796 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9799 /*******************************************************************
9800 Ensure we don't use sendfile if server smb signing is active.
9801 ********************************************************************/
9803 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9805 bool sign_active = false;
9807 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9808 if (get_Protocol() < PROTOCOL_NT1) {
9809 return false;
9811 if (signing_state) {
9812 sign_active = smb_signing_is_active(signing_state);
9814 return (_lp_use_sendfile(snum) &&
9815 (get_remote_arch() != RA_WIN95) &&
9816 !sign_active);
9819 /*******************************************************************
9820 Turn off sendfile if we find the underlying OS doesn't support it.
9821 ********************************************************************/
9823 void set_use_sendfile(int snum, bool val)
9825 if (LP_SNUM_OK(snum))
9826 ServicePtrs[snum]->bUseSendfile = val;
9827 else
9828 sDefault.bUseSendfile = val;
9831 /*******************************************************************
9832 Turn off storing DOS attributes if this share doesn't support it.
9833 ********************************************************************/
9835 void set_store_dos_attributes(int snum, bool val)
9837 if (!LP_SNUM_OK(snum))
9838 return;
9839 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9842 void lp_set_mangling_method(const char *new_method)
9844 string_set(&Globals.szManglingMethod, new_method);
9847 /*******************************************************************
9848 Global state for POSIX pathname processing.
9849 ********************************************************************/
9851 static bool posix_pathnames;
9853 bool lp_posix_pathnames(void)
9855 return posix_pathnames;
9858 /*******************************************************************
9859 Change everything needed to ensure POSIX pathname processing (currently
9860 not much).
9861 ********************************************************************/
9863 void lp_set_posix_pathnames(void)
9865 posix_pathnames = True;
9868 /*******************************************************************
9869 Global state for POSIX lock processing - CIFS unix extensions.
9870 ********************************************************************/
9872 bool posix_default_lock_was_set;
9873 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9875 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9877 if (posix_default_lock_was_set) {
9878 return posix_cifsx_locktype;
9879 } else {
9880 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9884 /*******************************************************************
9885 ********************************************************************/
9887 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9889 posix_default_lock_was_set = True;
9890 posix_cifsx_locktype = val;
9893 int lp_min_receive_file_size(void)
9895 if (Globals.iminreceivefile < 0) {
9896 return 0;
9898 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9901 /*******************************************************************
9902 If socket address is an empty character string, it is necessary to
9903 define it as "0.0.0.0".
9904 ********************************************************************/
9906 const char *lp_socket_address(void)
9908 char *sock_addr = Globals.szSocketAddress;
9910 if (sock_addr[0] == '\0'){
9911 string_set(&Globals.szSocketAddress, "0.0.0.0");
9913 return Globals.szSocketAddress;
9916 void lp_set_passdb_backend(const char *backend)
9918 string_set(&Globals.szPassdbBackend, backend);
9921 /*******************************************************************
9922 Safe wide links checks.
9923 This helper function always verify the validity of wide links,
9924 even after a configuration file reload.
9925 ********************************************************************/
9927 static bool lp_widelinks_internal(int snum)
9929 return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9930 sDefault.bWidelinks);
9933 void widelinks_warning(int snum)
9935 if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9936 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9937 "These parameters are incompatible. "
9938 "Wide links will be disabled for this share.\n",
9939 lp_servicename(snum) ));
9943 bool lp_widelinks(int snum)
9945 /* wide links is always incompatible with unix extensions */
9946 if (lp_unix_extensions()) {
9947 return false;
9950 return lp_widelinks_internal(snum);
9953 bool lp_writeraw(void)
9955 if (lp_async_smb_echo_handler()) {
9956 return false;
9958 return _lp_writeraw();
9961 bool lp_readraw(void)
9963 if (lp_async_smb_echo_handler()) {
9964 return false;
9966 return _lp_readraw();