s3:param: add "async smb echo handler" option
[kai/samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13
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.
18
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.
23
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/>.
26 */
27
28 /*
29  *  Load parameters.
30  *
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.
34  *
35  * To add a parameter:
36  *
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
42  *  
43  *
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!
51  *
52  */
53
54 #include "includes.h"
55 #include "printing.h"
56
57 #ifdef HAVE_SYS_SYSCTL_H
58 #include <sys/sysctl.h>
59 #endif
60
61 #ifdef HAVE_HTTPCONNECTENCRYPT
62 #include <cups/http.h>
63 #endif
64
65 bool bLoaded = False;
66
67 extern userdom_struct current_user_info;
68
69 #ifndef GLOBAL_NAME
70 #define GLOBAL_NAME "global"
71 #endif
72
73 #ifndef PRINTERS_NAME
74 #define PRINTERS_NAME "printers"
75 #endif
76
77 #ifndef HOMES_NAME
78 #define HOMES_NAME "homes"
79 #endif
80
81 /* the special value for the include parameter
82  * to be interpreted not as a file name but to
83  * trigger loading of the global smb.conf options
84  * from registry. */
85 #ifndef INCLUDE_REGISTRY_NAME
86 #define INCLUDE_REGISTRY_NAME "registry"
87 #endif
88
89 static bool in_client = False;          /* Not in the client by default */
90 static struct smbconf_csn conf_last_csn;
91
92 #define CONFIG_BACKEND_FILE 0
93 #define CONFIG_BACKEND_REGISTRY 1
94
95 static int config_backend = CONFIG_BACKEND_FILE;
96
97 /* some helpful bits */
98 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
99 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
100
101 #define USERSHARE_VALID 1
102 #define USERSHARE_PENDING_DELETE 2
103
104 static bool defaults_saved = False;
105
106 struct param_opt_struct {
107         struct param_opt_struct *prev, *next;
108         char *key;
109         char *value;
110         char **list;
111 };
112
113 /*
114  * This structure describes global (ie., server-wide) parameters.
115  */
116 struct global {
117         int ConfigBackend;
118         char *smb_ports;
119         char *dos_charset;
120         char *unix_charset;
121         char *display_charset;
122         char *szPrintcapname;
123         char *szAddPortCommand;
124         char *szEnumPortsCommand;
125         char *szAddPrinterCommand;
126         char *szDeletePrinterCommand;
127         char *szOs2DriverMap;
128         char *szLockDir;
129         char *szStateDir;
130         char *szCacheDir;
131         char *szPidDir;
132         char *szRootdir;
133         char *szDefaultService;
134         char *szGetQuota;
135         char *szSetQuota;
136         char *szMsgCommand;
137         char *szServerString;
138         char *szAutoServices;
139         char *szPasswdProgram;
140         char *szPasswdChat;
141         char *szLogFile;
142         char *szConfigFile;
143         char *szSMBPasswdFile;
144         char *szPrivateDir;
145         char *szPassdbBackend;
146         char **szPreloadModules;
147         char *szPasswordServer;
148         char *szSocketOptions;
149         char *szRealm;
150         char *szAfsUsernameMap;
151         int iAfsTokenLifetime;
152         char *szLogNtTokenCommand;
153         char *szUsernameMap;
154         char *szLogonScript;
155         char *szLogonPath;
156         char *szLogonDrive;
157         char *szLogonHome;
158         char **szWINSservers;
159         char **szInterfaces;
160         char *szRemoteAnnounce;
161         char *szRemoteBrowseSync;
162         char *szSocketAddress;
163         bool bNmbdBindExplicitBroadcast;
164         char *szNISHomeMapName;
165         char *szAnnounceVersion;        /* This is initialised in init_globals */
166         char *szWorkgroup;
167         char *szNetbiosName;
168         char **szNetbiosAliases;
169         char *szNetbiosScope;
170         char *szNameResolveOrder;
171         char *szPanicAction;
172         char *szAddUserScript;
173         char *szRenameUserScript;
174         char *szDelUserScript;
175         char *szAddGroupScript;
176         char *szDelGroupScript;
177         char *szAddUserToGroupScript;
178         char *szDelUserFromGroupScript;
179         char *szSetPrimaryGroupScript;
180         char *szAddMachineScript;
181         char *szShutdownScript;
182         char *szAbortShutdownScript;
183         char *szUsernameMapScript;
184         char *szCheckPasswordScript;
185         char *szWINSHook;
186         char *szUtmpDir;
187         char *szWtmpDir;
188         bool bUtmp;
189         char *szIdmapUID;
190         char *szIdmapGID;
191         bool bPassdbExpandExplicit;
192         int AlgorithmicRidBase;
193         char *szTemplateHomedir;
194         char *szTemplateShell;
195         char *szWinbindSeparator;
196         bool bWinbindEnumUsers;
197         bool bWinbindEnumGroups;
198         bool bWinbindUseDefaultDomain;
199         bool bWinbindTrustedDomainsOnly;
200         bool bWinbindNestedGroups;
201         int  winbind_expand_groups;
202         bool bWinbindRefreshTickets;
203         bool bWinbindOfflineLogon;
204         bool bWinbindNormalizeNames;
205         bool bWinbindRpcOnly;
206         bool bCreateKrb5Conf;
207         char *szIdmapBackend;
208         char *szIdmapAllocBackend;
209         char *szAddShareCommand;
210         char *szChangeShareCommand;
211         char *szDeleteShareCommand;
212         char **szEventLogs;
213         char *szGuestaccount;
214         char *szManglingMethod;
215         char **szServicesList;
216         char *szUsersharePath;
217         char *szUsershareTemplateShare;
218         char **szUsersharePrefixAllowList;
219         char **szUsersharePrefixDenyList;
220         int mangle_prefix;
221         int max_log_size;
222         char *szLogLevel;
223         int max_xmit;
224         int max_mux;
225         int max_open_files;
226         int open_files_db_hash_size;
227         int pwordlevel;
228         int unamelevel;
229         int deadtime;
230         bool getwd_cache;
231         int maxprotocol;
232         int minprotocol;
233         int security;
234         char **AuthMethods;
235         bool paranoid_server_security;
236         int maxdisksize;
237         int lpqcachetime;
238         int iMaxSmbdProcesses;
239         bool bDisableSpoolss;
240         int syslog;
241         int os_level;
242         bool enhanced_browsing;
243         int max_ttl;
244         int max_wins_ttl;
245         int min_wins_ttl;
246         int lm_announce;
247         int lm_interval;
248         int announce_as;        /* This is initialised in init_globals */
249         int machine_password_timeout;
250         int map_to_guest;
251         int oplock_break_wait_time;
252         int winbind_cache_time;
253         int winbind_reconnect_delay;
254         int winbind_max_idle_children;
255         char **szWinbindNssInfo;
256         int iLockSpinTime;
257         char *szLdapMachineSuffix;
258         char *szLdapUserSuffix;
259         char *szLdapIdmapSuffix;
260         char *szLdapGroupSuffix;
261         int ldap_ssl;
262         bool ldap_ssl_ads;
263         int ldap_deref;
264         int ldap_follow_referral;
265         char *szLdapSuffix;
266         char *szLdapAdminDn;
267         int ldap_debug_level;
268         int ldap_debug_threshold;
269         int iAclCompat;
270         char *szCupsServer;
271         int CupsEncrypt;
272         char *szIPrintServer;
273         char *ctdbdSocket;
274         char **szClusterAddresses;
275         bool clustering;
276         int ctdb_timeout;
277         int ldap_passwd_sync;
278         int ldap_replication_sleep;
279         int ldap_timeout; /* This is initialised in init_globals */
280         int ldap_connection_timeout;
281         int ldap_page_size;
282         bool ldap_delete_dn;
283         bool bMsAddPrinterWizard;
284         bool bDNSproxy;
285         bool bWINSsupport;
286         bool bWINSproxy;
287         bool bLocalMaster;
288         int  iPreferredMaster;
289         int iDomainMaster;
290         bool bDomainLogons;
291         char **szInitLogonDelayedHosts;
292         int InitLogonDelay;
293         bool bEncryptPasswords;
294         bool bUpdateEncrypt;
295         int  clientSchannel;
296         int  serverSchannel;
297         bool bNullPasswords;
298         bool bObeyPamRestrictions;
299         bool bLoadPrinters;
300         int PrintcapCacheTime;
301         bool bLargeReadwrite;
302         bool bReadRaw;
303         bool bWriteRaw;
304         bool bSyslogOnly;
305         bool bBrowseList;
306         bool bNISHomeMap;
307         bool bTimeServer;
308         bool bBindInterfacesOnly;
309         bool bPamPasswordChange;
310         bool bUnixPasswdSync;
311         bool bPasswdChatDebug;
312         int iPasswdChatTimeout;
313         bool bTimestampLogs;
314         bool bNTSmbSupport;
315         bool bNTPipeSupport;
316         bool bNTStatusSupport;
317         bool bStatCache;
318         int iMaxStatCacheSize;
319         bool bKernelOplocks;
320         bool bAllowTrustedDomains;
321         bool bLanmanAuth;
322         bool bNTLMAuth;
323         bool bUseSpnego;
324         bool bClientLanManAuth;
325         bool bClientNTLMv2Auth;
326         bool bClientPlaintextAuth;
327         bool bClientUseSpnego;
328         bool bDebugPrefixTimestamp;
329         bool bDebugHiresTimestamp;
330         bool bDebugPid;
331         bool bDebugUid;
332         bool bDebugClass;
333         bool bEnableCoreFiles;
334         bool bHostMSDfs;
335         bool bUseMmap;
336         bool bHostnameLookups;
337         bool bUnixExtensions;
338         bool bDisableNetbios;
339         char * szDedicatedKeytabFile;
340         int  iKerberosMethod;
341         bool bDeferSharingViolations;
342         bool bEnablePrivileges;
343         bool bASUSupport;
344         bool bUsershareOwnerOnly;
345         bool bUsershareAllowGuests;
346         bool bRegistryShares;
347         int restrict_anonymous;
348         int name_cache_timeout;
349         int client_signing;
350         int server_signing;
351         int client_ldap_sasl_wrapping;
352         int iUsershareMaxShares;
353         int iIdmapCacheTime;
354         int iIdmapNegativeCacheTime;
355         bool bResetOnZeroVC;
356         bool bLogWriteableFilesOnExit;
357         int iKeepalive;
358         int iminreceivefile;
359         struct param_opt_struct *param_opt;
360         int cups_connection_timeout;
361         char *szSMBPerfcountModule;
362         bool bMapUntrustedToDomain;
363         bool bAsyncSMBEchoHandler;
364 };
365
366 static struct global Globals;
367
368 /*
369  * This structure describes a single service.
370  */
371 struct service {
372         bool valid;
373         bool autoloaded;
374         int usershare;
375         struct timespec usershare_last_mod;
376         char *szService;
377         char *szPath;
378         char *szUsername;
379         char **szInvalidUsers;
380         char **szValidUsers;
381         char **szAdminUsers;
382         char *szCopy;
383         char *szInclude;
384         char *szPreExec;
385         char *szPostExec;
386         char *szRootPreExec;
387         char *szRootPostExec;
388         char *szCupsOptions;
389         char *szPrintcommand;
390         char *szLpqcommand;
391         char *szLprmcommand;
392         char *szLppausecommand;
393         char *szLpresumecommand;
394         char *szQueuepausecommand;
395         char *szQueueresumecommand;
396         char *szPrintername;
397         char *szPrintjobUsername;
398         char *szDontdescend;
399         char **szHostsallow;
400         char **szHostsdeny;
401         char *szMagicScript;
402         char *szMagicOutput;
403         char *szVetoFiles;
404         char *szHideFiles;
405         char *szVetoOplockFiles;
406         char *comment;
407         char *force_user;
408         char *force_group;
409         char **readlist;
410         char **writelist;
411         char **printer_admin;
412         char *volume;
413         char *fstype;
414         char **szVfsObjects;
415         char *szMSDfsProxy;
416         char *szAioWriteBehind;
417         char *szDfree;
418         int iMinPrintSpace;
419         int iMaxPrintJobs;
420         int iMaxReportedPrintJobs;
421         int iWriteCacheSize;
422         int iCreate_mask;
423         int iCreate_force_mode;
424         int iSecurity_mask;
425         int iSecurity_force_mode;
426         int iDir_mask;
427         int iDir_force_mode;
428         int iDir_Security_mask;
429         int iDir_Security_force_mode;
430         int iMaxConnections;
431         int iDefaultCase;
432         int iPrinting;
433         int iOplockContentionLimit;
434         int iCSCPolicy;
435         int iBlock_size;
436         int iDfreeCacheTime;
437         bool bPreexecClose;
438         bool bRootpreexecClose;
439         int  iCaseSensitive;
440         bool bCasePreserve;
441         bool bShortCasePreserve;
442         bool bHideDotFiles;
443         bool bHideSpecialFiles;
444         bool bHideUnReadable;
445         bool bHideUnWriteableFiles;
446         bool bBrowseable;
447         bool bAccessBasedShareEnum;
448         bool bAvailable;
449         bool bRead_only;
450         bool bNo_set_dir;
451         bool bGuest_only;
452         bool bAdministrative_share;
453         bool bGuest_ok;
454         bool bPrint_ok;
455         bool bMap_system;
456         bool bMap_hidden;
457         bool bMap_archive;
458         bool bStoreDosAttributes;
459         bool bDmapiSupport;
460         bool bLocking;
461         int iStrictLocking;
462         bool bPosixLocking;
463         bool bShareModes;
464         bool bOpLocks;
465         bool bLevel2OpLocks;
466         bool bOnlyUser;
467         bool bMangledNames;
468         bool bWidelinks;
469         bool bSymlinks;
470         bool bSyncAlways;
471         bool bStrictAllocate;
472         bool bStrictSync;
473         char magic_char;
474         struct bitmap *copymap;
475         bool bDeleteReadonly;
476         bool bFakeOplocks;
477         bool bDeleteVetoFiles;
478         bool bDosFilemode;
479         bool bDosFiletimes;
480         bool bDosFiletimeResolution;
481         bool bFakeDirCreateTimes;
482         bool bBlockingLocks;
483         bool bInheritPerms;
484         bool bInheritACLS;
485         bool bInheritOwner;
486         bool bMSDfsRoot;
487         bool bUseClientDriver;
488         bool bDefaultDevmode;
489         bool bForcePrintername;
490         bool bNTAclSupport;
491         bool bForceUnknownAclUser;
492         bool bUseSendfile;
493         bool bProfileAcls;
494         bool bMap_acl_inherit;
495         bool bAfs_Share;
496         bool bEASupport;
497         bool bAclCheckPermissions;
498         bool bAclMapFullControl;
499         bool bAclGroupControl;
500         bool bChangeNotify;
501         bool bKernelChangeNotify;
502         int iallocation_roundup_size;
503         int iAioReadSize;
504         int iAioWriteSize;
505         int iMap_readonly;
506         int iDirectoryNameCacheSize;
507         int ismb_encrypt;
508         struct param_opt_struct *param_opt;
509
510         char dummy[3];          /* for alignment */
511 };
512
513
514 /* This is a default service used to prime a services structure */
515 static struct service sDefault = {
516         True,                   /* valid */
517         False,                  /* not autoloaded */
518         0,                      /* not a usershare */
519         {0, },                  /* No last mod time */
520         NULL,                   /* szService */
521         NULL,                   /* szPath */
522         NULL,                   /* szUsername */
523         NULL,                   /* szInvalidUsers */
524         NULL,                   /* szValidUsers */
525         NULL,                   /* szAdminUsers */
526         NULL,                   /* szCopy */
527         NULL,                   /* szInclude */
528         NULL,                   /* szPreExec */
529         NULL,                   /* szPostExec */
530         NULL,                   /* szRootPreExec */
531         NULL,                   /* szRootPostExec */
532         NULL,                   /* szCupsOptions */
533         NULL,                   /* szPrintcommand */
534         NULL,                   /* szLpqcommand */
535         NULL,                   /* szLprmcommand */
536         NULL,                   /* szLppausecommand */
537         NULL,                   /* szLpresumecommand */
538         NULL,                   /* szQueuepausecommand */
539         NULL,                   /* szQueueresumecommand */
540         NULL,                   /* szPrintername */
541         NULL,                   /* szPrintjobUsername */
542         NULL,                   /* szDontdescend */
543         NULL,                   /* szHostsallow */
544         NULL,                   /* szHostsdeny */
545         NULL,                   /* szMagicScript */
546         NULL,                   /* szMagicOutput */
547         NULL,                   /* szVetoFiles */
548         NULL,                   /* szHideFiles */
549         NULL,                   /* szVetoOplockFiles */
550         NULL,                   /* comment */
551         NULL,                   /* force user */
552         NULL,                   /* force group */
553         NULL,                   /* readlist */
554         NULL,                   /* writelist */
555         NULL,                   /* printer admin */
556         NULL,                   /* volume */
557         NULL,                   /* fstype */
558         NULL,                   /* vfs objects */
559         NULL,                   /* szMSDfsProxy */
560         NULL,                   /* szAioWriteBehind */
561         NULL,                   /* szDfree */
562         0,                      /* iMinPrintSpace */
563         1000,                   /* iMaxPrintJobs */
564         0,                      /* iMaxReportedPrintJobs */
565         0,                      /* iWriteCacheSize */
566         0744,                   /* iCreate_mask */
567         0000,                   /* iCreate_force_mode */
568         0777,                   /* iSecurity_mask */
569         0,                      /* iSecurity_force_mode */
570         0755,                   /* iDir_mask */
571         0000,                   /* iDir_force_mode */
572         0777,                   /* iDir_Security_mask */
573         0,                      /* iDir_Security_force_mode */
574         0,                      /* iMaxConnections */
575         CASE_LOWER,             /* iDefaultCase */
576         DEFAULT_PRINTING,       /* iPrinting */
577         2,                      /* iOplockContentionLimit */
578         0,                      /* iCSCPolicy */
579         1024,                   /* iBlock_size */
580         0,                      /* iDfreeCacheTime */
581         False,                  /* bPreexecClose */
582         False,                  /* bRootpreexecClose */
583         Auto,                   /* case sensitive */
584         True,                   /* case preserve */
585         True,                   /* short case preserve */
586         True,                   /* bHideDotFiles */
587         False,                  /* bHideSpecialFiles */
588         False,                  /* bHideUnReadable */
589         False,                  /* bHideUnWriteableFiles */
590         True,                   /* bBrowseable */
591         False,                  /* bAccessBasedShareEnum */
592         True,                   /* bAvailable */
593         True,                   /* bRead_only */
594         True,                   /* bNo_set_dir */
595         False,                  /* bGuest_only */
596         False,                  /* bAdministrative_share */
597         False,                  /* bGuest_ok */
598         False,                  /* bPrint_ok */
599         False,                  /* bMap_system */
600         False,                  /* bMap_hidden */
601         True,                   /* bMap_archive */
602         False,                  /* bStoreDosAttributes */
603         False,                  /* bDmapiSupport */
604         True,                   /* bLocking */
605         Auto,                   /* iStrictLocking */
606         True,                   /* bPosixLocking */
607         True,                   /* bShareModes */
608         True,                   /* bOpLocks */
609         True,                   /* bLevel2OpLocks */
610         False,                  /* bOnlyUser */
611         True,                   /* bMangledNames */
612         false,                  /* bWidelinks */
613         True,                   /* bSymlinks */
614         False,                  /* bSyncAlways */
615         False,                  /* bStrictAllocate */
616         False,                  /* bStrictSync */
617         '~',                    /* magic char */
618         NULL,                   /* copymap */
619         False,                  /* bDeleteReadonly */
620         False,                  /* bFakeOplocks */
621         False,                  /* bDeleteVetoFiles */
622         False,                  /* bDosFilemode */
623         True,                   /* bDosFiletimes */
624         False,                  /* bDosFiletimeResolution */
625         False,                  /* bFakeDirCreateTimes */
626         True,                   /* bBlockingLocks */
627         False,                  /* bInheritPerms */
628         False,                  /* bInheritACLS */
629         False,                  /* bInheritOwner */
630         False,                  /* bMSDfsRoot */
631         False,                  /* bUseClientDriver */
632         True,                   /* bDefaultDevmode */
633         False,                  /* bForcePrintername */
634         True,                   /* bNTAclSupport */
635         False,                  /* bForceUnknownAclUser */
636         False,                  /* bUseSendfile */
637         False,                  /* bProfileAcls */
638         False,                  /* bMap_acl_inherit */
639         False,                  /* bAfs_Share */
640         False,                  /* bEASupport */
641         True,                   /* bAclCheckPermissions */
642         True,                   /* bAclMapFullControl */
643         False,                  /* bAclGroupControl */
644         True,                   /* bChangeNotify */
645         True,                   /* bKernelChangeNotify */
646         SMB_ROUNDUP_ALLOCATION_SIZE,            /* iallocation_roundup_size */
647         0,                      /* iAioReadSize */
648         0,                      /* iAioWriteSize */
649         MAP_READONLY_YES,       /* iMap_readonly */
650 #ifdef BROKEN_DIRECTORY_HANDLING
651         0,                      /* iDirectoryNameCacheSize */
652 #else
653         100,                    /* iDirectoryNameCacheSize */
654 #endif
655         Auto,                   /* ismb_encrypt */
656         NULL,                   /* Parametric options */
657
658         ""                      /* dummy */
659 };
660
661 /* local variables */
662 static struct service **ServicePtrs = NULL;
663 static int iNumServices = 0;
664 static int iServiceIndex = 0;
665 static struct db_context *ServiceHash;
666 static int *invalid_services = NULL;
667 static int num_invalid_services = 0;
668 static bool bInGlobalSection = True;
669 static bool bGlobalOnly = False;
670 static int server_role;
671 static int default_server_announce;
672
673 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
674
675 /* prototypes for the special type handlers */
676 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
677 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
678 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
679 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
680 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
681 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
682 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
683 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
684 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
685 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
686 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
687 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
688
689 static void set_server_role(void);
690 static void set_default_server_announce_type(void);
691 static void set_allowed_client_auth(void);
692
693 static void *lp_local_ptr(struct service *service, void *ptr);
694
695 static void add_to_file_list(const char *fname, const char *subfname);
696
697 static const struct enum_list enum_protocol[] = {
698         {PROTOCOL_SMB2, "SMB2"},
699         {PROTOCOL_NT1, "NT1"},
700         {PROTOCOL_LANMAN2, "LANMAN2"},
701         {PROTOCOL_LANMAN1, "LANMAN1"},
702         {PROTOCOL_CORE, "CORE"},
703         {PROTOCOL_COREPLUS, "COREPLUS"},
704         {PROTOCOL_COREPLUS, "CORE+"},
705         {-1, NULL}
706 };
707
708 static const struct enum_list enum_security[] = {
709         {SEC_SHARE, "SHARE"},
710         {SEC_USER, "USER"},
711         {SEC_SERVER, "SERVER"},
712         {SEC_DOMAIN, "DOMAIN"},
713 #ifdef HAVE_ADS
714         {SEC_ADS, "ADS"},
715 #endif
716         {-1, NULL}
717 };
718
719 static const struct enum_list enum_printing[] = {
720         {PRINT_SYSV, "sysv"},
721         {PRINT_AIX, "aix"},
722         {PRINT_HPUX, "hpux"},
723         {PRINT_BSD, "bsd"},
724         {PRINT_QNX, "qnx"},
725         {PRINT_PLP, "plp"},
726         {PRINT_LPRNG, "lprng"},
727         {PRINT_CUPS, "cups"},
728         {PRINT_IPRINT, "iprint"},
729         {PRINT_LPRNT, "nt"},
730         {PRINT_LPROS2, "os2"},
731 #ifdef DEVELOPER
732         {PRINT_TEST, "test"},
733         {PRINT_VLP, "vlp"},
734 #endif /* DEVELOPER */
735         {-1, NULL}
736 };
737
738 static const struct enum_list enum_ldap_sasl_wrapping[] = {
739         {0, "plain"},
740         {ADS_AUTH_SASL_SIGN, "sign"},
741         {ADS_AUTH_SASL_SEAL, "seal"},
742         {-1, NULL}
743 };
744
745 static const struct enum_list enum_ldap_ssl[] = {
746         {LDAP_SSL_OFF, "no"},
747         {LDAP_SSL_OFF, "off"},
748         {LDAP_SSL_START_TLS, "start tls"},
749         {LDAP_SSL_START_TLS, "start_tls"},
750         {-1, NULL}
751 };
752
753 /* LDAP Dereferencing Alias types */
754 #define SAMBA_LDAP_DEREF_NEVER          0
755 #define SAMBA_LDAP_DEREF_SEARCHING      1
756 #define SAMBA_LDAP_DEREF_FINDING        2
757 #define SAMBA_LDAP_DEREF_ALWAYS         3
758
759 static const struct enum_list enum_ldap_deref[] = {
760         {SAMBA_LDAP_DEREF_NEVER, "never"},
761         {SAMBA_LDAP_DEREF_SEARCHING, "searching"},
762         {SAMBA_LDAP_DEREF_FINDING, "finding"},
763         {SAMBA_LDAP_DEREF_ALWAYS, "always"},
764         {-1, "auto"}
765 };
766
767 static const struct enum_list enum_ldap_passwd_sync[] = {
768         {LDAP_PASSWD_SYNC_OFF, "no"},
769         {LDAP_PASSWD_SYNC_OFF, "off"},
770         {LDAP_PASSWD_SYNC_ON, "yes"},
771         {LDAP_PASSWD_SYNC_ON, "on"},
772         {LDAP_PASSWD_SYNC_ONLY, "only"},
773         {-1, NULL}
774 };
775
776 /* Types of machine we can announce as. */
777 #define ANNOUNCE_AS_NT_SERVER 1
778 #define ANNOUNCE_AS_WIN95 2
779 #define ANNOUNCE_AS_WFW 3
780 #define ANNOUNCE_AS_NT_WORKSTATION 4
781
782 static const struct enum_list enum_announce_as[] = {
783         {ANNOUNCE_AS_NT_SERVER, "NT"},
784         {ANNOUNCE_AS_NT_SERVER, "NT Server"},
785         {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
786         {ANNOUNCE_AS_WIN95, "win95"},
787         {ANNOUNCE_AS_WFW, "WfW"},
788         {-1, NULL}
789 };
790
791 static const struct enum_list enum_map_readonly[] = {
792         {MAP_READONLY_NO, "no"},
793         {MAP_READONLY_NO, "false"},
794         {MAP_READONLY_NO, "0"},
795         {MAP_READONLY_YES, "yes"},
796         {MAP_READONLY_YES, "true"},
797         {MAP_READONLY_YES, "1"},
798         {MAP_READONLY_PERMISSIONS, "permissions"},
799         {MAP_READONLY_PERMISSIONS, "perms"},
800         {-1, NULL}
801 };
802
803 static const struct enum_list enum_case[] = {
804         {CASE_LOWER, "lower"},
805         {CASE_UPPER, "upper"},
806         {-1, NULL}
807 };
808
809
810
811 static const struct enum_list enum_bool_auto[] = {
812         {False, "No"},
813         {False, "False"},
814         {False, "0"},
815         {True, "Yes"},
816         {True, "True"},
817         {True, "1"},
818         {Auto, "Auto"},
819         {-1, NULL}
820 };
821
822 /* Client-side offline caching policy types */
823 #define CSC_POLICY_MANUAL 0
824 #define CSC_POLICY_DOCUMENTS 1
825 #define CSC_POLICY_PROGRAMS 2
826 #define CSC_POLICY_DISABLE 3
827
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}
834 };
835
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}
855 };
856
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}
863 };
864
865 /* 
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
869
870    You have 3 choices in the setting of map_to_guest:
871
872    "Never" means session setups with an invalid password
873    are rejected. This is the default.
874
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
878
879    "Bad Password" means session setups with an invalid password
880    are treated as a guest login
881
882    Note that map_to_guest only has an effect in user or server
883    level security.
884 */
885
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}
892 };
893
894 /* Config backend options */
895
896 static const struct enum_list enum_config_backend[] = {
897         {CONFIG_BACKEND_FILE, "file"},
898         {CONFIG_BACKEND_REGISTRY, "registry"},
899         {-1, NULL}
900 };
901
902 /* ADS kerberos ticket verification options */
903
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}
911 };
912
913 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
914  *
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.
918  *
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.
923  *
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.
929  */
930
931 static struct parm_struct parm_table[] = {
932         {N_("Base Options"), P_SEP, P_SEPARATOR},
933
934         {
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
942         },
943         {
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
951         },
952         {
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
960         },
961         {
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
969         },
970         {
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,
978         },
979         {
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,
987         },
988         {
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,
996         },
997 #ifdef WITH_ADS
998         {
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,
1006         },
1007 #endif
1008         {
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,
1016         },
1017         {
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,
1025         },
1026         {
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,
1034         },
1035         {
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,
1043         },
1044         {
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,
1052         },
1053         {
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,
1061         },
1062         {
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,
1070         },
1071
1072         {N_("Security Options"), P_SEP, P_SEPARATOR},
1073
1074         {
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,
1082         },
1083         {
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,
1091         },
1092         {
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,
1100         },
1101         {
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,
1109         },
1110         {
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,
1118         },
1119         {
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,
1127         },
1128         {
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,
1136         },
1137         {
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,
1145         },
1146         {
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,
1154         },
1155         {
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,
1163         },
1164         {
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,
1172         },
1173         {
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,
1181         },
1182         {
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,
1190         },
1191         {
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,
1199         },
1200         {
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,
1208         },
1209         {
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,
1217         },
1218         {
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,
1226         },
1227         {
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,
1235         },
1236         {
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,
1244         },
1245         {
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,
1253         },
1254
1255         {
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,
1263         },
1264         {
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,
1272         },
1273         {
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,
1281         },
1282         {
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,
1290         },
1291         {
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,
1299         },
1300         {
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,
1308         },
1309         {
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,
1317         },
1318         {
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,
1326         },
1327         {
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,
1335         },
1336         {
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,
1344         },
1345         {
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,
1353         },
1354         {
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,
1362         },
1363         {
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,
1371         },
1372         {
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,
1380         },
1381         {
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,
1389         },
1390         {
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,
1398         },
1399         {
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,
1407         },
1408         {
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,
1416         },
1417         {
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,
1425         },
1426         {
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,
1434         },
1435         {
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,
1443         },
1444         {
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,
1452         },
1453         {
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,
1461         },
1462         {
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,
1470         },
1471         {
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,
1479         },
1480         {
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,
1488         },
1489         {
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,
1497         },
1498         {
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,
1506         },
1507         {
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,
1515         },
1516         {
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,
1524         },
1525         {
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,
1533         },
1534         {
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,
1542         },
1543         {
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,
1551         },
1552         {
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,
1560         },
1561         {
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,
1569         },
1570         {
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,
1578         },
1579         {
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,
1587         },
1588         {
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,
1596         },
1597         {
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,
1605         },
1606         {
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,
1614         },
1615         {
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,
1623         },
1624         {
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,
1632         },
1633         {
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,
1641         },
1642         {
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,
1650         },
1651         {
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,
1659         },
1660         {
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,
1668         },
1669         {
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,
1677         },
1678         {
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,
1686         },
1687         {
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,
1695         },
1696         {
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,
1704         },
1705         {
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,
1713         },
1714         {
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,
1722         },
1723
1724         {
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,
1732         },
1733         {
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,
1741         },
1742         {
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,
1750         },
1751         {
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,
1759         },
1760         {
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,
1768         },
1769         {
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,
1777         },
1778         {
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,
1786         },
1787         {
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,
1795         },
1796         {
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,
1804         },
1805         {
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,
1813         },
1814         {
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,
1822         },
1823
1824
1825         {N_("Logging Options"), P_SEP, P_SEPARATOR},
1826
1827         {
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,
1835         },
1836         {
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,
1844         },
1845         {
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,
1853         },
1854         {
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,
1862         },
1863         {
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,
1871         },
1872         {
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,
1880         },
1881         {
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,
1889         },
1890         {
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,
1898         },
1899         {
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,
1907         },
1908         {
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,
1916         },
1917         {
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,
1925         },
1926         {
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,
1934         },
1935         {
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,
1943         },
1944         {
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,
1952         },
1953
1954         {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1955
1956         {
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,
1964         },
1965         {
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,
1973         },
1974         {
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,
1982         },
1983         {
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,
1991         },
1992         {
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,
2000         },
2001         {
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,
2009         },
2010         {
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,
2018         },
2019         {
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,
2027         },
2028         {
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,
2036         },
2037         {
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,
2045         },
2046         {
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,
2054         },
2055         {
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,
2063         },
2064         {
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,
2072         },
2073         {
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,
2081         },
2082         {
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,
2090         },
2091         {
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,
2099         },
2100         {
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,
2108         },
2109         {
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,
2117         },
2118         {
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,
2126         },
2127         {
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,
2135         },
2136         {
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,
2144         },
2145         {
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,
2153         },
2154         {
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,
2162         },
2163         {
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,
2171         },
2172         {
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,
2180         },
2181         {
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,
2189         },
2190         {
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,
2198         },
2199         {
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,
2207         },
2208         {
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,
2216         },
2217         {
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,
2225         },
2226         {
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,
2234         },
2235         {
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,
2243         },
2244         {
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,
2252         },
2253         {
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,
2261         },
2262         {
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,
2270         },
2271         {
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,
2279         },
2280         {
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,
2288         },
2289         {
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,
2297         },
2298         {
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,
2306         },
2307         {
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,
2315         },
2316         {
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,
2324         },
2325         {
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,
2333         },
2334
2335         {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2336
2337         {
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,
2345         },
2346         {
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,
2354         },
2355         {
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,
2363         },
2364         {
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,
2372         },
2373         {
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,
2381         },
2382         {
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,
2390         },
2391         {
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,
2399         },
2400         {
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,
2408         },
2409         {
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,
2417         },
2418         {
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,
2426         },
2427         {
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,
2435         },
2436         {
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,
2444         },
2445         {
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,
2453         },
2454         {
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,
2462         },
2463         {
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,
2471         },
2472         {
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,
2480         },
2481         {
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,
2489         },
2490         {
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,
2498         },
2499         {
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,
2507         },
2508         {
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,
2516         },
2517         {
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,
2525         },
2526         {
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,
2534         },
2535         {
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,
2543         },
2544         {
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,
2552         },
2553         {
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,
2561         },
2562         {
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,
2570         },
2571         {
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,
2579         },
2580
2581         {N_("Printing Options"), P_SEP, P_SEPARATOR},
2582
2583         {
2584                 .label          = "max reported print jobs",
2585                 .type           = P_INTEGER,
2586                 .p_class        = P_LOCAL,
2587                 .ptr            = &sDefault.iMaxReportedPrintJobs,
2588                 .special        = NULL,
2589                 .enum_list      = NULL,
2590                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2591         },
2592         {
2593                 .label          = "max print jobs",
2594                 .type           = P_INTEGER,
2595                 .p_class        = P_LOCAL,
2596                 .ptr            = &sDefault.iMaxPrintJobs,
2597                 .special        = NULL,
2598                 .enum_list      = NULL,
2599                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2600         },
2601         {
2602                 .label          = "load printers",
2603                 .type           = P_BOOL,
2604                 .p_class        = P_GLOBAL,
2605                 .ptr            = &Globals.bLoadPrinters,
2606                 .special        = NULL,
2607                 .enum_list      = NULL,
2608                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2609         },
2610         {
2611                 .label          = "printcap cache time",
2612                 .type           = P_INTEGER,
2613                 .p_class        = P_GLOBAL,
2614                 .ptr            = &Globals.PrintcapCacheTime,
2615                 .special        = NULL,
2616                 .enum_list      = NULL,
2617                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2618         },
2619         {
2620                 .label          = "printcap name",
2621                 .type           = P_STRING,
2622                 .p_class        = P_GLOBAL,
2623                 .ptr            = &Globals.szPrintcapname,
2624                 .special        = NULL,
2625                 .enum_list      = NULL,
2626                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2627         },
2628         {
2629                 .label          = "printcap",
2630                 .type           = P_STRING,
2631                 .p_class        = P_GLOBAL,
2632                 .ptr            = &Globals.szPrintcapname,
2633                 .special        = NULL,
2634                 .enum_list      = NULL,
2635                 .flags          = FLAG_HIDE,
2636         },
2637         {
2638                 .label          = "printable",
2639                 .type           = P_BOOL,
2640                 .p_class        = P_LOCAL,
2641                 .ptr            = &sDefault.bPrint_ok,
2642                 .special        = NULL,
2643                 .enum_list      = NULL,
2644                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2645         },
2646         {
2647                 .label          = "print ok",
2648                 .type           = P_BOOL,
2649                 .p_class        = P_LOCAL,
2650                 .ptr            = &sDefault.bPrint_ok,
2651                 .special        = NULL,
2652                 .enum_list      = NULL,
2653                 .flags          = FLAG_HIDE,
2654         },
2655         {
2656                 .label          = "printing",
2657                 .type           = P_ENUM,
2658                 .p_class        = P_LOCAL,
2659                 .ptr            = &sDefault.iPrinting,
2660                 .special        = handle_printing,
2661                 .enum_list      = enum_printing,
2662                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2663         },
2664         {
2665                 .label          = "cups options",
2666                 .type           = P_STRING,
2667                 .p_class        = P_LOCAL,
2668                 .ptr            = &sDefault.szCupsOptions,
2669                 .special        = NULL,
2670                 .enum_list      = NULL,
2671                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2672         },
2673         {
2674                 .label          = "cups server",
2675                 .type           = P_STRING,
2676                 .p_class        = P_GLOBAL,
2677                 .ptr            = &Globals.szCupsServer,
2678                 .special        = NULL,
2679                 .enum_list      = NULL,
2680                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2681         },
2682         {
2683                 .label          = "cups encrypt",
2684                 .type           = P_ENUM,
2685                 .p_class        = P_GLOBAL,
2686                 .ptr            = &Globals.CupsEncrypt,
2687                 .special        = NULL,
2688                 .enum_list      = enum_bool_auto,
2689                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2690         },
2691         {
2692
2693                 .label          = "cups connection timeout",
2694                 .type           = P_INTEGER,
2695                 .p_class        = P_GLOBAL,
2696                 .ptr            = &Globals.cups_connection_timeout,
2697                 .special        = NULL,
2698                 .enum_list      = NULL,
2699                 .flags          = FLAG_ADVANCED,
2700         },
2701         {
2702                 .label          = "iprint server",
2703                 .type           = P_STRING,
2704                 .p_class        = P_GLOBAL,
2705                 .ptr            = &Globals.szIPrintServer,
2706                 .special        = NULL,
2707                 .enum_list      = NULL,
2708                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2709         },
2710         {
2711                 .label          = "print command",
2712                 .type           = P_STRING,
2713                 .p_class        = P_LOCAL,
2714                 .ptr            = &sDefault.szPrintcommand,
2715                 .special        = NULL,
2716                 .enum_list      = NULL,
2717                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2718         },
2719         {
2720                 .label          = "disable spoolss",
2721                 .type           = P_BOOL,
2722                 .p_class        = P_GLOBAL,
2723                 .ptr            = &Globals.bDisableSpoolss,
2724                 .special        = NULL,
2725                 .enum_list      = NULL,
2726                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2727         },
2728         {
2729                 .label          = "enable spoolss",
2730                 .type           = P_BOOLREV,
2731                 .p_class        = P_GLOBAL,
2732                 .ptr            = &Globals.bDisableSpoolss,
2733                 .special        = NULL,
2734                 .enum_list      = NULL,
2735                 .flags          = FLAG_HIDE,
2736         },
2737         {
2738                 .label          = "lpq command",
2739                 .type           = P_STRING,
2740                 .p_class        = P_LOCAL,
2741                 .ptr            = &sDefault.szLpqcommand,
2742                 .special        = NULL,
2743                 .enum_list      = NULL,
2744                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2745         },
2746         {
2747                 .label          = "lprm command",
2748                 .type           = P_STRING,
2749                 .p_class        = P_LOCAL,
2750                 .ptr            = &sDefault.szLprmcommand,
2751                 .special        = NULL,
2752                 .enum_list      = NULL,
2753                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2754         },
2755         {
2756                 .label          = "lppause command",
2757                 .type           = P_STRING,
2758                 .p_class        = P_LOCAL,
2759                 .ptr            = &sDefault.szLppausecommand,
2760                 .special        = NULL,
2761                 .enum_list      = NULL,
2762                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2763         },
2764         {
2765                 .label          = "lpresume command",
2766                 .type           = P_STRING,
2767                 .p_class        = P_LOCAL,
2768                 .ptr            = &sDefault.szLpresumecommand,
2769                 .special        = NULL,
2770                 .enum_list      = NULL,
2771                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2772         },
2773         {
2774                 .label          = "queuepause command",
2775                 .type           = P_STRING,
2776                 .p_class        = P_LOCAL,
2777                 .ptr            = &sDefault.szQueuepausecommand,
2778                 .special        = NULL,
2779                 .enum_list      = NULL,
2780                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2781         },
2782         {
2783                 .label          = "queueresume command",
2784                 .type           = P_STRING,
2785                 .p_class        = P_LOCAL,
2786                 .ptr            = &sDefault.szQueueresumecommand,
2787                 .special        = NULL,
2788                 .enum_list      = NULL,
2789                 .flags          = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2790         },
2791         {
2792                 .label          = "addport command",
2793                 .type           = P_STRING,
2794                 .p_class        = P_GLOBAL,
2795                 .ptr            = &Globals.szAddPortCommand,
2796                 .special        = NULL,
2797                 .enum_list      = NULL,
2798                 .flags          = FLAG_ADVANCED,
2799         },
2800         {
2801                 .label          = "enumports command",
2802                 .type           = P_STRING,
2803                 .p_class        = P_GLOBAL,
2804                 .ptr            = &Globals.szEnumPortsCommand,
2805                 .special        = NULL,
2806                 .enum_list      = NULL,
2807                 .flags          = FLAG_ADVANCED,
2808         },
2809         {
2810                 .label          = "addprinter command",
2811                 .type           = P_STRING,
2812                 .p_class        = P_GLOBAL,
2813                 .ptr            = &Globals.szAddPrinterCommand,
2814                 .special        = NULL,
2815                 .enum_list      = NULL,
2816                 .flags          = FLAG_ADVANCED,
2817         },
2818         {
2819                 .label          = "deleteprinter command",
2820                 .type           = P_STRING,
2821                 .p_class        = P_GLOBAL,
2822                 .ptr            = &Globals.szDeletePrinterCommand,
2823                 .special        = NULL,
2824                 .enum_list      = NULL,
2825                 .flags          = FLAG_ADVANCED,
2826         },
2827         {
2828                 .label          = "show add printer wizard",
2829                 .type           = P_BOOL,
2830                 .p_class        = P_GLOBAL,
2831                 .ptr            = &Globals.bMsAddPrinterWizard,
2832                 .special        = NULL,
2833                 .enum_list      = NULL,
2834                 .flags          = FLAG_ADVANCED,
2835         },
2836         {
2837                 .label          = "os2 driver map",
2838                 .type           = P_STRING,
2839                 .p_class        = P_GLOBAL,
2840                 .ptr            = &Globals.szOs2DriverMap,
2841                 .special        = NULL,
2842                 .enum_list      = NULL,
2843                 .flags          = FLAG_ADVANCED,
2844         },
2845
2846         {
2847                 .label          = "printer name",
2848                 .type           = P_STRING,
2849                 .p_class        = P_LOCAL,
2850                 .ptr            = &sDefault.szPrintername,
2851                 .special        = NULL,
2852                 .enum_list      = NULL,
2853                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2854         },
2855         {
2856                 .label          = "printer",
2857                 .type           = P_STRING,
2858                 .p_class        = P_LOCAL,
2859                 .ptr            = &sDefault.szPrintername,
2860                 .special        = NULL,
2861                 .enum_list      = NULL,
2862                 .flags          = FLAG_HIDE,
2863         },
2864         {
2865                 .label          = "use client driver",
2866                 .type           = P_BOOL,
2867                 .p_class        = P_LOCAL,
2868                 .ptr            = &sDefault.bUseClientDriver,
2869                 .special        = NULL,
2870                 .enum_list      = NULL,
2871                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2872         },
2873         {
2874                 .label          = "default devmode",
2875                 .type           = P_BOOL,
2876                 .p_class        = P_LOCAL,
2877                 .ptr            = &sDefault.bDefaultDevmode,
2878                 .special        = NULL,
2879                 .enum_list      = NULL,
2880                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2881         },
2882         {
2883                 .label          = "force printername",
2884                 .type           = P_BOOL,
2885                 .p_class        = P_LOCAL,
2886                 .ptr            = &sDefault.bForcePrintername,
2887                 .special        = NULL,
2888                 .enum_list      = NULL,
2889                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2890         },
2891         {
2892                 .label          = "printjob username",
2893                 .type           = P_STRING,
2894                 .p_class        = P_LOCAL,
2895                 .ptr            = &sDefault.szPrintjobUsername,
2896                 .special        = NULL,
2897                 .enum_list      = NULL,
2898                 .flags          = FLAG_ADVANCED | FLAG_PRINT,
2899         },
2900
2901         {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2902
2903         {
2904                 .label          = "mangling method",
2905                 .type           = P_STRING,
2906                 .p_class        = P_GLOBAL,
2907                 .ptr            = &Globals.szManglingMethod,
2908                 .special        = NULL,
2909                 .enum_list      = NULL,
2910                 .flags          = FLAG_ADVANCED,
2911         },
2912         {
2913                 .label          = "mangle prefix",
2914                 .type           = P_INTEGER,
2915                 .p_class        = P_GLOBAL,
2916                 .ptr            = &Globals.mangle_prefix,
2917                 .special        = NULL,
2918                 .enum_list      = NULL,
2919                 .flags          = FLAG_ADVANCED,
2920         },
2921
2922         {
2923                 .label          = "default case",
2924                 .type           = P_ENUM,
2925                 .p_class        = P_LOCAL,
2926                 .ptr            = &sDefault.iDefaultCase,
2927                 .special        = NULL,
2928                 .enum_list      = enum_case,
2929                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
2930         },
2931         {
2932                 .label          = "case sensitive",
2933                 .type           = P_ENUM,
2934                 .p_class        = P_LOCAL,
2935                 .ptr            = &sDefault.iCaseSensitive,
2936                 .special        = NULL,
2937                 .enum_list      = enum_bool_auto,
2938                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2939         },
2940         {
2941                 .label          = "casesignames",
2942                 .type           = P_ENUM,
2943                 .p_class        = P_LOCAL,
2944                 .ptr            = &sDefault.iCaseSensitive,
2945                 .special        = NULL,
2946                 .enum_list      = enum_bool_auto,
2947                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2948         },
2949         {
2950                 .label          = "preserve case",
2951                 .type           = P_BOOL,
2952                 .p_class        = P_LOCAL,
2953                 .ptr            = &sDefault.bCasePreserve,
2954                 .special        = NULL,
2955                 .enum_list      = NULL,
2956                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2957         },
2958         {
2959                 .label          = "short preserve case",
2960                 .type           = P_BOOL,
2961                 .p_class        = P_LOCAL,
2962                 .ptr            = &sDefault.bShortCasePreserve,
2963                 .special        = NULL,
2964                 .enum_list      = NULL,
2965                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2966         },
2967         {
2968                 .label          = "mangling char",
2969                 .type           = P_CHAR,
2970                 .p_class        = P_LOCAL,
2971                 .ptr            = &sDefault.magic_char,
2972                 .special        = NULL,
2973                 .enum_list      = NULL,
2974                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2975         },
2976         {
2977                 .label          = "hide dot files",
2978                 .type           = P_BOOL,
2979                 .p_class        = P_LOCAL,
2980                 .ptr            = &sDefault.bHideDotFiles,
2981                 .special        = NULL,
2982                 .enum_list      = NULL,
2983                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2984         },
2985         {
2986                 .label          = "hide special files",
2987                 .type           = P_BOOL,
2988                 .p_class        = P_LOCAL,
2989                 .ptr            = &sDefault.bHideSpecialFiles,
2990                 .special        = NULL,
2991                 .enum_list      = NULL,
2992                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2993         },
2994         {
2995                 .label          = "hide unreadable",
2996                 .type           = P_BOOL,
2997                 .p_class        = P_LOCAL,
2998                 .ptr            = &sDefault.bHideUnReadable,
2999                 .special        = NULL,
3000                 .enum_list      = NULL,
3001                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3002         },
3003         {
3004                 .label          = "hide unwriteable files",
3005                 .type           = P_BOOL,
3006                 .p_class        = P_LOCAL,
3007                 .ptr            = &sDefault.bHideUnWriteableFiles,
3008                 .special        = NULL,
3009                 .enum_list      = NULL,
3010                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3011         },
3012         {
3013                 .label          = "delete veto files",
3014                 .type           = P_BOOL,
3015                 .p_class        = P_LOCAL,
3016                 .ptr            = &sDefault.bDeleteVetoFiles,
3017                 .special        = NULL,
3018                 .enum_list      = NULL,
3019                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3020         },
3021         {
3022                 .label          = "veto files",
3023                 .type           = P_STRING,
3024                 .p_class        = P_LOCAL,
3025                 .ptr            = &sDefault.szVetoFiles,
3026                 .special        = NULL,
3027                 .enum_list      = NULL,
3028                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3029         },
3030         {
3031                 .label          = "hide files",
3032                 .type           = P_STRING,
3033                 .p_class        = P_LOCAL,
3034                 .ptr            = &sDefault.szHideFiles,
3035                 .special        = NULL,
3036                 .enum_list      = NULL,
3037                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3038         },
3039         {
3040                 .label          = "veto oplock files",
3041                 .type           = P_STRING,
3042                 .p_class        = P_LOCAL,
3043                 .ptr            = &sDefault.szVetoOplockFiles,
3044                 .special        = NULL,
3045                 .enum_list      = NULL,
3046                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3047         },
3048         {
3049                 .label          = "map archive",
3050                 .type           = P_BOOL,
3051                 .p_class        = P_LOCAL,
3052                 .ptr            = &sDefault.bMap_archive,
3053                 .special        = NULL,
3054                 .enum_list      = NULL,
3055                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3056         },
3057         {
3058                 .label          = "map hidden",
3059                 .type           = P_BOOL,
3060                 .p_class        = P_LOCAL,
3061                 .ptr            = &sDefault.bMap_hidden,
3062                 .special        = NULL,
3063                 .enum_list      = NULL,
3064                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3065         },
3066         {
3067                 .label          = "map system",
3068                 .type           = P_BOOL,
3069                 .p_class        = P_LOCAL,
3070                 .ptr            = &sDefault.bMap_system,
3071                 .special        = NULL,
3072                 .enum_list      = NULL,
3073                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3074         },
3075         {
3076                 .label          = "map readonly",
3077                 .type           = P_ENUM,
3078                 .p_class        = P_LOCAL,
3079                 .ptr            = &sDefault.iMap_readonly,
3080                 .special        = NULL,
3081                 .enum_list      = enum_map_readonly,
3082                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3083         },
3084         {
3085                 .label          = "mangled names",
3086                 .type           = P_BOOL,
3087                 .p_class        = P_LOCAL,
3088                 .ptr            = &sDefault.bMangledNames,
3089                 .special        = NULL,
3090                 .enum_list      = NULL,
3091                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3092         },
3093         {
3094                 .label          = "max stat cache size",
3095                 .type           = P_INTEGER,
3096                 .p_class        = P_GLOBAL,
3097                 .ptr            = &Globals.iMaxStatCacheSize,
3098                 .special        = NULL,
3099                 .enum_list      = NULL,
3100                 .flags          = FLAG_ADVANCED,
3101         },
3102         {
3103                 .label          = "stat cache",
3104                 .type           = P_BOOL,
3105                 .p_class        = P_GLOBAL,
3106                 .ptr            = &Globals.bStatCache,
3107                 .special        = NULL,
3108                 .enum_list      = NULL,
3109                 .flags          = FLAG_ADVANCED,
3110         },
3111         {
3112                 .label          = "store dos attributes",
3113                 .type           = P_BOOL,
3114                 .p_class        = P_LOCAL,
3115                 .ptr            = &sDefault.bStoreDosAttributes,
3116                 .special        = NULL,
3117                 .enum_list      = NULL,
3118                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3119         },
3120         {
3121                 .label          = "dmapi support",
3122                 .type           = P_BOOL,
3123                 .p_class        = P_LOCAL,
3124                 .ptr            = &sDefault.bDmapiSupport,
3125                 .special        = NULL,
3126                 .enum_list      = NULL,
3127                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3128         },
3129
3130
3131         {N_("Domain Options"), P_SEP, P_SEPARATOR},
3132
3133         {
3134                 .label          = "machine password timeout",
3135                 .type           = P_INTEGER,
3136                 .p_class        = P_GLOBAL,
3137                 .ptr            = &Globals.machine_password_timeout,
3138                 .special        = NULL,
3139                 .enum_list      = NULL,
3140                 .flags          = FLAG_ADVANCED | FLAG_WIZARD,
3141         },
3142
3143         {N_("Logon Options"), P_SEP, P_SEPARATOR},
3144
3145         {
3146                 .label          = "add user script",
3147                 .type           = P_STRING,
3148                 .p_class        = P_GLOBAL,
3149                 .ptr            = &Globals.szAddUserScript,
3150                 .special        = NULL,
3151                 .enum_list      = NULL,
3152                 .flags          = FLAG_ADVANCED,
3153         },
3154         {
3155                 .label          = "rename user script",
3156                 .type           = P_STRING,
3157                 .p_class        = P_GLOBAL,
3158                 .ptr            = &Globals.szRenameUserScript,
3159                 .special        = NULL,
3160                 .enum_list      = NULL,
3161                 .flags          = FLAG_ADVANCED,
3162         },
3163         {
3164                 .label          = "delete user script",
3165                 .type           = P_STRING,
3166                 .p_class        = P_GLOBAL,
3167                 .ptr            = &Globals.szDelUserScript,
3168                 .special        = NULL,
3169                 .enum_list      = NULL,
3170                 .flags          = FLAG_ADVANCED,
3171         },
3172         {
3173                 .label          = "add group script",
3174                 .type           = P_STRING,
3175                 .p_class        = P_GLOBAL,
3176                 .ptr            = &Globals.szAddGroupScript,
3177                 .special        = NULL,
3178                 .enum_list      = NULL,
3179                 .flags          = FLAG_ADVANCED,
3180         },
3181         {
3182                 .label          = "delete group script",
3183                 .type           = P_STRING,
3184                 .p_class        = P_GLOBAL,
3185                 .ptr            = &Globals.szDelGroupScript,
3186                 .special        = NULL,
3187                 .enum_list      = NULL,
3188                 .flags          = FLAG_ADVANCED,
3189         },
3190         {
3191                 .label          = "add user to group script",
3192                 .type           = P_STRING,
3193                 .p_class        = P_GLOBAL,
3194                 .ptr            = &Globals.szAddUserToGroupScript,
3195                 .special        = NULL,
3196                 .enum_list      = NULL,
3197                 .flags          = FLAG_ADVANCED,
3198         },
3199         {
3200                 .label          = "delete user from group script",
3201                 .type           = P_STRING,
3202                 .p_class        = P_GLOBAL,
3203                 .ptr            = &Globals.szDelUserFromGroupScript,
3204                 .special        = NULL,
3205                 .enum_list      = NULL,
3206                 .flags          = FLAG_ADVANCED,
3207         },
3208         {
3209                 .label          = "set primary group script",
3210                 .type           = P_STRING,
3211                 .p_class        = P_GLOBAL,
3212                 .ptr            = &Globals.szSetPrimaryGroupScript,
3213                 .special        = NULL,
3214                 .enum_list      = NULL,
3215                 .flags          = FLAG_ADVANCED,
3216         },
3217         {
3218                 .label          = "add machine script",
3219                 .type           = P_STRING,
3220                 .p_class        = P_GLOBAL,
3221                 .ptr            = &Globals.szAddMachineScript,
3222                 .special        = NULL,
3223                 .enum_list      = NULL,
3224                 .flags          = FLAG_ADVANCED,
3225         },
3226         {
3227                 .label          = "shutdown script",
3228                 .type           = P_STRING,
3229                 .p_class        = P_GLOBAL,
3230                 .ptr            = &Globals.szShutdownScript,
3231                 .special        = NULL,
3232                 .enum_list      = NULL,
3233                 .flags          = FLAG_ADVANCED,
3234         },
3235         {
3236                 .label          = "abort shutdown script",
3237                 .type           = P_STRING,
3238                 .p_class        = P_GLOBAL,
3239                 .ptr            = &Globals.szAbortShutdownScript,
3240                 .special        = NULL,
3241                 .enum_list      = NULL,
3242                 .flags          = FLAG_ADVANCED,
3243         },
3244         {
3245                 .label          = "username map script",
3246                 .type           = P_STRING,
3247                 .p_class        = P_GLOBAL,
3248                 .ptr            = &Globals.szUsernameMapScript,
3249                 .special        = NULL,
3250                 .enum_list      = NULL,
3251                 .flags          = FLAG_ADVANCED,
3252         },
3253         {
3254                 .label          = "logon script",
3255                 .type           = P_STRING,
3256                 .p_class        = P_GLOBAL,
3257                 .ptr            = &Globals.szLogonScript,
3258                 .special        = NULL,
3259                 .enum_list      = NULL,
3260                 .flags          = FLAG_ADVANCED,
3261         },
3262         {
3263                 .label          = "logon path",
3264                 .type           = P_STRING,
3265                 .p_class        = P_GLOBAL,
3266                 .ptr            = &Globals.szLogonPath,
3267                 .special        = NULL,
3268                 .enum_list      = NULL,
3269                 .flags          = FLAG_ADVANCED,
3270         },
3271         {
3272                 .label          = "logon drive",
3273                 .type           = P_STRING,
3274                 .p_class        = P_GLOBAL,
3275                 .ptr            = &Globals.szLogonDrive,
3276                 .special        = NULL,
3277                 .enum_list      = NULL,
3278                 .flags          = FLAG_ADVANCED,
3279         },
3280         {
3281                 .label          = "logon home",
3282                 .type           = P_STRING,
3283                 .p_class        = P_GLOBAL,
3284                 .ptr            = &Globals.szLogonHome,
3285                 .special        = NULL,
3286                 .enum_list      = NULL,
3287                 .flags          = FLAG_ADVANCED,
3288         },
3289         {
3290                 .label          = "domain logons",
3291                 .type           = P_BOOL,
3292                 .p_class        = P_GLOBAL,
3293                 .ptr            = &Globals.bDomainLogons,
3294                 .special        = NULL,
3295                 .enum_list      = NULL,
3296                 .flags          = FLAG_ADVANCED,
3297         },
3298
3299         {
3300                 .label          = "init logon delayed hosts",
3301                 .type           = P_LIST,
3302                 .p_class        = P_GLOBAL,
3303                 .ptr            = &Globals.szInitLogonDelayedHosts,
3304                 .special        = NULL,
3305                 .enum_list      = NULL,
3306                 .flags          = FLAG_ADVANCED,
3307         },
3308
3309         {
3310                 .label          = "init logon delay",
3311                 .type           = P_INTEGER,
3312                 .p_class        = P_GLOBAL,
3313                 .ptr            = &Globals.InitLogonDelay,
3314                 .special        = NULL,
3315                 .enum_list      = NULL,
3316                 .flags          = FLAG_ADVANCED,
3317
3318         },
3319
3320         {N_("Browse Options"), P_SEP, P_SEPARATOR},
3321
3322         {
3323                 .label          = "os level",
3324                 .type           = P_INTEGER,
3325                 .p_class        = P_GLOBAL,
3326                 .ptr            = &Globals.os_level,
3327                 .special        = NULL,
3328                 .enum_list      = NULL,
3329                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3330         },
3331         {
3332                 .label          = "lm announce",
3333                 .type           = P_ENUM,
3334                 .p_class        = P_GLOBAL,
3335                 .ptr            = &Globals.lm_announce,
3336                 .special        = NULL,
3337                 .enum_list      = enum_bool_auto,
3338                 .flags          = FLAG_ADVANCED,
3339         },
3340         {
3341                 .label          = "lm interval",
3342                 .type           = P_INTEGER,
3343                 .p_class        = P_GLOBAL,
3344                 .ptr            = &Globals.lm_interval,
3345                 .special        = NULL,
3346                 .enum_list      = NULL,
3347                 .flags          = FLAG_ADVANCED,
3348         },
3349         {
3350                 .label          = "preferred master",
3351                 .type           = P_ENUM,
3352                 .p_class        = P_GLOBAL,
3353                 .ptr            = &Globals.iPreferredMaster,
3354                 .special        = NULL,
3355                 .enum_list      = enum_bool_auto,
3356                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3357         },
3358         {
3359                 .label          = "prefered master",
3360                 .type           = P_ENUM,
3361                 .p_class        = P_GLOBAL,
3362                 .ptr            = &Globals.iPreferredMaster,
3363                 .special        = NULL,
3364                 .enum_list      = enum_bool_auto,
3365                 .flags          = FLAG_HIDE,
3366         },
3367         {
3368                 .label          = "local master",
3369                 .type           = P_BOOL,
3370                 .p_class        = P_GLOBAL,
3371                 .ptr            = &Globals.bLocalMaster,
3372                 .special        = NULL,
3373                 .enum_list      = NULL,
3374                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3375         },
3376         {
3377                 .label          = "domain master",
3378                 .type           = P_ENUM,
3379                 .p_class        = P_GLOBAL,
3380                 .ptr            = &Globals.iDomainMaster,
3381                 .special        = NULL,
3382                 .enum_list      = enum_bool_auto,
3383                 .flags          = FLAG_BASIC | FLAG_ADVANCED,
3384         },
3385         {
3386                 .label          = "browse list",
3387                 .type           = P_BOOL,
3388                 .p_class        = P_GLOBAL,
3389                 .ptr            = &Globals.bBrowseList,
3390                 .special        = NULL,
3391                 .enum_list      = NULL,
3392                 .flags          = FLAG_ADVANCED,
3393         },
3394         {
3395                 .label          = "browseable",
3396                 .type           = P_BOOL,
3397                 .p_class        = P_LOCAL,
3398                 .ptr            = &sDefault.bBrowseable,
3399                 .special        = NULL,
3400                 .enum_list      = NULL,
3401                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3402         },
3403         {
3404                 .label          = "browsable",
3405                 .type           = P_BOOL,
3406                 .p_class        = P_LOCAL,
3407                 .ptr            = &sDefault.bBrowseable,
3408                 .special        = NULL,
3409                 .enum_list      = NULL,
3410                 .flags          = FLAG_HIDE,
3411         },
3412         {
3413                 .label          = "access based share enum",
3414                 .type           = P_BOOL,
3415                 .p_class        = P_LOCAL,
3416                 .ptr            = &sDefault.bAccessBasedShareEnum,
3417                 .special        = NULL,
3418                 .enum_list      = NULL,
3419                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3420         },
3421         {
3422                 .label          = "enhanced browsing",
3423                 .type           = P_BOOL,
3424                 .p_class        = P_GLOBAL,
3425                 .ptr            = &Globals.enhanced_browsing,
3426                 .special        = NULL,
3427                 .enum_list      = NULL,
3428                 .flags          = FLAG_ADVANCED,
3429         },
3430
3431         {N_("WINS Options"), P_SEP, P_SEPARATOR},
3432
3433         {
3434                 .label          = "dns proxy",
3435                 .type           = P_BOOL,
3436                 .p_class        = P_GLOBAL,
3437                 .ptr            = &Globals.bDNSproxy,
3438                 .special        = NULL,
3439                 .enum_list      = NULL,
3440                 .flags          = FLAG_ADVANCED,
3441         },
3442         {
3443                 .label          = "wins proxy",
3444                 .type           = P_BOOL,
3445                 .p_class        = P_GLOBAL,
3446                 .ptr            = &Globals.bWINSproxy,
3447                 .special        = NULL,
3448                 .enum_list      = NULL,
3449                 .flags          = FLAG_ADVANCED,
3450         },
3451         {
3452                 .label          = "wins server",
3453                 .type           = P_LIST,
3454                 .p_class        = P_GLOBAL,
3455                 .ptr            = &Globals.szWINSservers,
3456                 .special        = NULL,
3457                 .enum_list      = NULL,
3458                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3459         },
3460         {
3461                 .label          = "wins support",
3462                 .type           = P_BOOL,
3463                 .p_class        = P_GLOBAL,
3464                 .ptr            = &Globals.bWINSsupport,
3465                 .special        = NULL,
3466                 .enum_list      = NULL,
3467                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3468         },
3469         {
3470                 .label          = "wins hook",
3471                 .type           = P_STRING,
3472                 .p_class        = P_GLOBAL,
3473                 .ptr            = &Globals.szWINSHook,
3474                 .special        = NULL,
3475                 .enum_list      = NULL,
3476                 .flags          = FLAG_ADVANCED,
3477         },
3478
3479         {N_("Locking Options"), P_SEP, P_SEPARATOR},
3480
3481         {
3482                 .label          = "blocking locks",
3483                 .type           = P_BOOL,
3484                 .p_class        = P_LOCAL,
3485                 .ptr            = &sDefault.bBlockingLocks,
3486                 .special        = NULL,
3487                 .enum_list      = NULL,
3488                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3489         },
3490         {
3491                 .label          = "csc policy",
3492                 .type           = P_ENUM,
3493                 .p_class        = P_LOCAL,
3494                 .ptr            = &sDefault.iCSCPolicy,
3495                 .special        = NULL,
3496                 .enum_list      = enum_csc_policy,
3497                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3498         },
3499         {
3500                 .label          = "fake oplocks",
3501                 .type           = P_BOOL,
3502                 .p_class        = P_LOCAL,
3503                 .ptr            = &sDefault.bFakeOplocks,
3504                 .special        = NULL,
3505                 .enum_list      = NULL,
3506                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
3507         },
3508         {
3509                 .label          = "kernel oplocks",
3510                 .type           = P_BOOL,
3511                 .p_class        = P_GLOBAL,
3512                 .ptr            = &Globals.bKernelOplocks,
3513                 .special        = NULL,
3514                 .enum_list      = NULL,
3515                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
3516         },
3517         {
3518                 .label          = "locking",
3519                 .type           = P_BOOL,
3520                 .p_class        = P_LOCAL,
3521                 .ptr            = &sDefault.bLocking,
3522                 .special        = NULL,
3523                 .enum_list      = NULL,
3524                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3525         },
3526         {
3527                 .label          = "lock spin time",
3528                 .type           = P_INTEGER,
3529                 .p_class        = P_GLOBAL,
3530                 .ptr            = &Globals.iLockSpinTime,
3531                 .special        = NULL,
3532                 .enum_list      = NULL,
3533                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
3534         },
3535         {
3536                 .label          = "oplocks",
3537                 .type           = P_BOOL,
3538                 .p_class        = P_LOCAL,
3539                 .ptr            = &sDefault.bOpLocks,
3540                 .special        = NULL,
3541                 .enum_list      = NULL,
3542                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3543         },
3544         {
3545                 .label          = "level2 oplocks",
3546                 .type           = P_BOOL,
3547                 .p_class        = P_LOCAL,
3548                 .ptr            = &sDefault.bLevel2OpLocks,
3549                 .special        = NULL,
3550                 .enum_list      = NULL,
3551                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3552         },
3553         {
3554                 .label          = "oplock break wait time",
3555                 .type           = P_INTEGER,
3556                 .p_class        = P_GLOBAL,
3557                 .ptr            = &Globals.oplock_break_wait_time,
3558                 .special        = NULL,
3559                 .enum_list      = NULL,
3560                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
3561         },
3562         {
3563                 .label          = "oplock contention limit",
3564                 .type           = P_INTEGER,
3565                 .p_class        = P_LOCAL,
3566                 .ptr            = &sDefault.iOplockContentionLimit,
3567                 .special        = NULL,
3568                 .enum_list      = NULL,
3569                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3570         },
3571         {
3572                 .label          = "posix locking",
3573                 .type           = P_BOOL,
3574                 .p_class        = P_LOCAL,
3575                 .ptr            = &sDefault.bPosixLocking,
3576                 .special        = NULL,
3577                 .enum_list      = NULL,
3578                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3579         },
3580         {
3581                 .label          = "strict locking",
3582                 .type           = P_ENUM,
3583                 .p_class        = P_LOCAL,
3584                 .ptr            = &sDefault.iStrictLocking,
3585                 .special        = NULL,
3586                 .enum_list      = enum_bool_auto,
3587                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3588         },
3589         {
3590                 .label          = "share modes",
3591                 .type           = P_BOOL,
3592                 .p_class        = P_LOCAL,
3593                 .ptr            = &sDefault.bShareModes,
3594                 .special        = NULL,
3595                 .enum_list      = NULL,
3596                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3597         },
3598
3599         {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3600
3601         {
3602                 .label          = "ldap admin dn",
3603                 .type           = P_STRING,
3604                 .p_class        = P_GLOBAL,
3605                 .ptr            = &Globals.szLdapAdminDn,
3606                 .special        = NULL,
3607                 .enum_list      = NULL,
3608                 .flags          = FLAG_ADVANCED,
3609         },
3610         {
3611                 .label          = "ldap delete dn",
3612                 .type           = P_BOOL,
3613                 .p_class        = P_GLOBAL,
3614                 .ptr            = &Globals.ldap_delete_dn,
3615                 .special        = NULL,
3616                 .enum_list      = NULL,
3617                 .flags          = FLAG_ADVANCED,
3618         },
3619         {
3620                 .label          = "ldap group suffix",
3621                 .type           = P_STRING,
3622                 .p_class        = P_GLOBAL,
3623                 .ptr            = &Globals.szLdapGroupSuffix,
3624                 .special        = NULL,
3625                 .enum_list      = NULL,
3626                 .flags          = FLAG_ADVANCED,
3627         },
3628         {
3629                 .label          = "ldap idmap suffix",
3630                 .type           = P_STRING,
3631                 .p_class        = P_GLOBAL,
3632                 .ptr            = &Globals.szLdapIdmapSuffix,
3633                 .special        = NULL,
3634                 .enum_list      = NULL,
3635                 .flags          = FLAG_ADVANCED,
3636         },
3637         {
3638                 .label          = "ldap machine suffix",
3639                 .type           = P_STRING,
3640                 .p_class        = P_GLOBAL,
3641                 .ptr            = &Globals.szLdapMachineSuffix,
3642                 .special        = NULL,
3643                 .enum_list      = NULL,
3644                 .flags          = FLAG_ADVANCED,
3645         },
3646         {
3647                 .label          = "ldap passwd sync",
3648                 .type           = P_ENUM,
3649                 .p_class        = P_GLOBAL,
3650                 .ptr            = &Globals.ldap_passwd_sync,
3651                 .special        = NULL,
3652                 .enum_list      = enum_ldap_passwd_sync,
3653                 .flags          = FLAG_ADVANCED,
3654         },
3655         {
3656                 .label          = "ldap password sync",
3657                 .type           = P_ENUM,
3658                 .p_class        = P_GLOBAL,
3659                 .ptr            = &Globals.ldap_passwd_sync,
3660                 .special        = NULL,
3661                 .enum_list      = enum_ldap_passwd_sync,
3662                 .flags          = FLAG_HIDE,
3663         },
3664         {
3665                 .label          = "ldap replication sleep",
3666                 .type           = P_INTEGER,
3667                 .p_class        = P_GLOBAL,
3668                 .ptr            = &Globals.ldap_replication_sleep,
3669                 .special        = NULL,
3670                 .enum_list      = NULL,
3671                 .flags          = FLAG_ADVANCED,
3672         },
3673         {
3674                 .label          = "ldap suffix",
3675                 .type           = P_STRING,
3676                 .p_class        = P_GLOBAL,
3677                 .ptr            = &Globals.szLdapSuffix,
3678                 .special        = NULL,
3679                 .enum_list      = NULL,
3680                 .flags          = FLAG_ADVANCED,
3681         },
3682         {
3683                 .label          = "ldap ssl",
3684                 .type           = P_ENUM,
3685                 .p_class        = P_GLOBAL,
3686                 .ptr            = &Globals.ldap_ssl,
3687                 .special        = NULL,
3688                 .enum_list      = enum_ldap_ssl,
3689                 .flags          = FLAG_ADVANCED,
3690         },
3691         {
3692                 .label          = "ldap ssl ads",
3693                 .type           = P_BOOL,
3694                 .p_class        = P_GLOBAL,
3695                 .ptr            = &Globals.ldap_ssl_ads,
3696                 .special        = NULL,
3697                 .enum_list      = NULL,
3698                 .flags          = FLAG_ADVANCED,
3699         },
3700         {
3701                 .label          = "ldap deref",
3702                 .type           = P_ENUM,
3703                 .p_class        = P_GLOBAL,
3704                 .ptr            = &Globals.ldap_deref,
3705                 .special        = NULL,
3706                 .enum_list      = enum_ldap_deref,
3707                 .flags          = FLAG_ADVANCED,
3708         },
3709         {
3710                 .label          = "ldap follow referral",
3711                 .type           = P_ENUM,
3712                 .p_class        = P_GLOBAL,
3713                 .ptr            = &Globals.ldap_follow_referral,
3714                 .special        = NULL,
3715                 .enum_list      = enum_bool_auto,
3716                 .flags          = FLAG_ADVANCED,
3717         },
3718         {
3719                 .label          = "ldap timeout",
3720                 .type           = P_INTEGER,
3721                 .p_class        = P_GLOBAL,
3722                 .ptr            = &Globals.ldap_timeout,
3723                 .special        = NULL,
3724                 .enum_list      = NULL,
3725                 .flags          = FLAG_ADVANCED,
3726         },
3727         {
3728                 .label          = "ldap connection timeout",
3729                 .type           = P_INTEGER,
3730                 .p_class        = P_GLOBAL,
3731                 .ptr            = &Globals.ldap_connection_timeout,
3732                 .special        = NULL,
3733                 .enum_list      = NULL,
3734                 .flags          = FLAG_ADVANCED,
3735         },
3736         {
3737                 .label          = "ldap page size",
3738                 .type           = P_INTEGER,
3739                 .p_class        = P_GLOBAL,
3740                 .ptr            = &Globals.ldap_page_size,
3741                 .special        = NULL,
3742                 .enum_list      = NULL,
3743                 .flags          = FLAG_ADVANCED,
3744         },
3745         {
3746                 .label          = "ldap user suffix",
3747                 .type           = P_STRING,
3748                 .p_class        = P_GLOBAL,
3749                 .ptr            = &Globals.szLdapUserSuffix,
3750                 .special        = NULL,
3751                 .enum_list      = NULL,
3752                 .flags          = FLAG_ADVANCED,
3753         },
3754         {
3755                 .label          = "ldap debug level",
3756                 .type           = P_INTEGER,
3757                 .p_class        = P_GLOBAL,
3758                 .ptr            = &Globals.ldap_debug_level,
3759                 .special        = handle_ldap_debug_level,
3760                 .enum_list      = NULL,
3761                 .flags          = FLAG_ADVANCED,
3762         },
3763         {
3764                 .label          = "ldap debug threshold",
3765                 .type           = P_INTEGER,
3766                 .p_class        = P_GLOBAL,
3767                 .ptr            = &Globals.ldap_debug_threshold,
3768                 .special        = NULL,
3769                 .enum_list      = NULL,
3770                 .flags          = FLAG_ADVANCED,
3771         },
3772
3773         {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3774
3775         {
3776                 .label          = "eventlog list",
3777                 .type           = P_LIST,
3778                 .p_class        = P_GLOBAL,
3779                 .ptr            = &Globals.szEventLogs,
3780                 .special        = NULL,
3781                 .enum_list      = NULL,
3782                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3783         },
3784
3785         {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3786
3787         {
3788                 .label          = "add share command",
3789                 .type           = P_STRING,
3790                 .p_class        = P_GLOBAL,
3791                 .ptr            = &Globals.szAddShareCommand,
3792                 .special        = NULL,
3793                 .enum_list      = NULL,
3794                 .flags          = FLAG_ADVANCED,
3795         },
3796         {
3797                 .label          = "change share command",
3798                 .type           = P_STRING,
3799                 .p_class        = P_GLOBAL,
3800                 .ptr            = &Globals.szChangeShareCommand,
3801                 .special        = NULL,
3802                 .enum_list      = NULL,
3803                 .flags          = FLAG_ADVANCED,
3804         },
3805         {
3806                 .label          = "delete share command",
3807                 .type           = P_STRING,
3808                 .p_class        = P_GLOBAL,
3809                 .ptr            = &Globals.szDeleteShareCommand,
3810                 .special        = NULL,
3811                 .enum_list      = NULL,
3812                 .flags          = FLAG_ADVANCED,
3813         },
3814         {
3815                 .label          = "config file",
3816                 .type           = P_STRING,
3817                 .p_class        = P_GLOBAL,
3818                 .ptr            = &Globals.szConfigFile,
3819                 .special        = NULL,
3820                 .enum_list      = NULL,
3821                 .flags          = FLAG_HIDE|FLAG_META,
3822         },
3823         {
3824                 .label          = "preload",
3825                 .type           = P_STRING,
3826                 .p_class        = P_GLOBAL,
3827                 .ptr            = &Globals.szAutoServices,
3828                 .special        = NULL,
3829                 .enum_list      = NULL,
3830                 .flags          = FLAG_ADVANCED,
3831         },
3832         {
3833                 .label          = "auto services",
3834                 .type           = P_STRING,
3835                 .p_class        = P_GLOBAL,
3836                 .ptr            = &Globals.szAutoServices,
3837                 .special        = NULL,
3838                 .enum_list      = NULL,
3839                 .flags          = FLAG_ADVANCED,
3840         },
3841         {
3842                 .label          = "lock directory",
3843                 .type           = P_STRING,
3844                 .p_class        = P_GLOBAL,
3845                 .ptr            = &Globals.szLockDir,
3846                 .special        = NULL,
3847                 .enum_list      = NULL,
3848                 .flags          = FLAG_ADVANCED,
3849         },
3850         {
3851                 .label          = "lock dir",
3852                 .type           = P_STRING,
3853                 .p_class        = P_GLOBAL,
3854                 .ptr            = &Globals.szLockDir,
3855                 .special        = NULL,
3856                 .enum_list      = NULL,
3857                 .flags          = FLAG_HIDE,
3858         },
3859         {
3860                 .label          = "state directory",
3861                 .type           = P_STRING,
3862                 .p_class        = P_GLOBAL,
3863                 .ptr            = &Globals.szStateDir,
3864                 .special        = NULL,
3865                 .enum_list      = NULL,
3866                 .flags          = FLAG_ADVANCED,
3867         },
3868         {
3869                 .label          = "cache directory",
3870                 .type           = P_STRING,
3871                 .p_class        = P_GLOBAL,
3872                 .ptr            = &Globals.szCacheDir,
3873                 .special        = NULL,
3874                 .enum_list      = NULL,
3875                 .flags          = FLAG_ADVANCED,
3876         },
3877         {
3878                 .label          = "pid directory",
3879                 .type           = P_STRING,
3880                 .p_class        = P_GLOBAL,
3881                 .ptr            = &Globals.szPidDir,
3882                 .special        = NULL,
3883                 .enum_list      = NULL,
3884                 .flags          = FLAG_ADVANCED,
3885         },
3886 #ifdef WITH_UTMP
3887         {
3888                 .label          = "utmp directory",
3889                 .type           = P_STRING,
3890                 .p_class        = P_GLOBAL,
3891                 .ptr            = &Globals.szUtmpDir,
3892                 .special        = NULL,
3893                 .enum_list      = NULL,
3894                 .flags          = FLAG_ADVANCED,
3895         },
3896         {
3897                 .label          = "wtmp directory",
3898                 .type           = P_STRING,
3899                 .p_class        = P_GLOBAL,
3900                 .ptr            = &Globals.szWtmpDir,
3901                 .special        = NULL,
3902                 .enum_list      = NULL,
3903                 .flags          = FLAG_ADVANCED,
3904         },
3905         {
3906                 .label          = "utmp",
3907                 .type           = P_BOOL,
3908                 .p_class        = P_GLOBAL,
3909                 .ptr            = &Globals.bUtmp,
3910                 .special        = NULL,
3911                 .enum_list      = NULL,
3912                 .flags          = FLAG_ADVANCED,
3913         },
3914 #endif
3915         {
3916                 .label          = "default service",
3917                 .type           = P_STRING,
3918                 .p_class        = P_GLOBAL,
3919                 .ptr            = &Globals.szDefaultService,
3920                 .special        = NULL,
3921                 .enum_list      = NULL,
3922                 .flags          = FLAG_ADVANCED,
3923         },
3924         {
3925                 .label          = "default",
3926                 .type           = P_STRING,
3927                 .p_class        = P_GLOBAL,
3928                 .ptr            = &Globals.szDefaultService,
3929                 .special        = NULL,
3930                 .enum_list      = NULL,
3931                 .flags          = FLAG_ADVANCED,
3932         },
3933         {
3934                 .label          = "message command",
3935                 .type           = P_STRING,
3936                 .p_class        = P_GLOBAL,
3937                 .ptr            = &Globals.szMsgCommand,
3938                 .special        = NULL,
3939                 .enum_list      = NULL,
3940                 .flags          = FLAG_ADVANCED,
3941         },
3942         {
3943                 .label          = "dfree cache time",
3944                 .type           = P_INTEGER,
3945                 .p_class        = P_LOCAL,
3946                 .ptr            = &sDefault.iDfreeCacheTime,
3947                 .special        = NULL,
3948                 .enum_list      = NULL,
3949                 .flags          = FLAG_ADVANCED,
3950         },
3951         {
3952                 .label          = "dfree command",
3953                 .type           = P_STRING,
3954                 .p_class        = P_LOCAL,
3955                 .ptr            = &sDefault.szDfree,
3956                 .special        = NULL,
3957                 .enum_list      = NULL,
3958                 .flags          = FLAG_ADVANCED,
3959         },
3960         {
3961                 .label          = "get quota command",
3962                 .type           = P_STRING,
3963                 .p_class        = P_GLOBAL,
3964                 .ptr            = &Globals.szGetQuota,
3965                 .special        = NULL,
3966                 .enum_list      = NULL,
3967                 .flags          = FLAG_ADVANCED,
3968         },
3969         {
3970                 .label          = "set quota command",
3971                 .type           = P_STRING,
3972                 .p_class        = P_GLOBAL,
3973                 .ptr            = &Globals.szSetQuota,
3974                 .special        = NULL,
3975                 .enum_list      = NULL,
3976                 .flags          = FLAG_ADVANCED,
3977         },
3978         {
3979                 .label          = "remote announce",
3980                 .type           = P_STRING,
3981                 .p_class        = P_GLOBAL,
3982                 .ptr            = &Globals.szRemoteAnnounce,
3983                 .special        = NULL,
3984                 .enum_list      = NULL,
3985                 .flags          = FLAG_ADVANCED,
3986         },
3987         {
3988                 .label          = "remote browse sync",
3989                 .type           = P_STRING,
3990                 .p_class        = P_GLOBAL,
3991                 .ptr            = &Globals.szRemoteBrowseSync,
3992                 .special        = NULL,
3993                 .enum_list      = NULL,
3994                 .flags          = FLAG_ADVANCED,
3995         },
3996         {
3997                 .label          = "socket address",
3998                 .type           = P_STRING,
3999                 .p_class        = P_GLOBAL,
4000                 .ptr            = &Globals.szSocketAddress,
4001                 .special        = NULL,
4002                 .enum_list      = NULL,
4003                 .flags          = FLAG_ADVANCED,
4004         },
4005         {
4006                 .label          = "nmbd bind explicit broadcast",
4007                 .type           = P_BOOL,
4008                 .p_class        = P_GLOBAL,
4009                 .ptr            = &Globals.bNmbdBindExplicitBroadcast,
4010                 .special        = NULL,
4011                 .enum_list      = NULL,
4012                 .flags          = FLAG_ADVANCED,
4013         },
4014         {
4015                 .label          = "homedir map",
4016                 .type           = P_STRING,
4017                 .p_class        = P_GLOBAL,
4018                 .ptr            = &Globals.szNISHomeMapName,
4019                 .special        = NULL,
4020                 .enum_list      = NULL,
4021                 .flags          = FLAG_ADVANCED,
4022         },
4023         {
4024                 .label          = "afs username map",
4025                 .type           = P_STRING,
4026                 .p_class        = P_GLOBAL,
4027                 .ptr            = &Globals.szAfsUsernameMap,
4028                 .special        = NULL,
4029                 .enum_list      = NULL,
4030                 .flags          = FLAG_ADVANCED,
4031         },
4032         {
4033                 .label          = "afs token lifetime",
4034                 .type           = P_INTEGER,
4035                 .p_class        = P_GLOBAL,
4036                 .ptr            = &Globals.iAfsTokenLifetime,
4037                 .special        = NULL,
4038                 .enum_list      = NULL,
4039                 .flags          = FLAG_ADVANCED,
4040         },
4041         {
4042                 .label          = "log nt token command",
4043                 .type           = P_STRING,
4044                 .p_class        = P_GLOBAL,
4045                 .ptr            = &Globals.szLogNtTokenCommand,
4046                 .special        = NULL,
4047                 .enum_list      = NULL,
4048                 .flags          = FLAG_ADVANCED,
4049         },
4050         {
4051                 .label          = "time offset",
4052                 .type           = P_INTEGER,
4053                 .p_class        = P_GLOBAL,
4054                 .ptr            = &extra_time_offset,
4055                 .special        = NULL,
4056                 .enum_list      = NULL,
4057                 .flags          = FLAG_ADVANCED,
4058         },
4059         {
4060                 .label          = "NIS homedir",
4061                 .type           = P_BOOL,
4062                 .p_class        = P_GLOBAL,
4063                 .ptr            = &Globals.bNISHomeMap,
4064                 .special        = NULL,
4065                 .enum_list      = NULL,
4066                 .flags          = FLAG_ADVANCED,
4067         },
4068         {
4069                 .label          = "-valid",
4070                 .type           = P_BOOL,
4071                 .p_class        = P_LOCAL,
4072                 .ptr            = &sDefault.valid,
4073                 .special        = NULL,
4074                 .enum_list      = NULL,
4075                 .flags          = FLAG_HIDE,
4076         },
4077         {
4078                 .label          = "copy",
4079                 .type           = P_STRING,
4080                 .p_class        = P_LOCAL,
4081                 .ptr            = &sDefault.szCopy,
4082                 .special        = handle_copy,
4083                 .enum_list      = NULL,
4084                 .flags          = FLAG_HIDE,
4085         },
4086         {
4087                 .label          = "include",
4088                 .type           = P_STRING,
4089                 .p_class        = P_LOCAL,
4090                 .ptr            = &sDefault.szInclude,
4091                 .special        = handle_include,
4092                 .enum_list      = NULL,
4093                 .flags          = FLAG_HIDE|FLAG_META,
4094         },
4095         {
4096                 .label          = "preexec",
4097                 .type           = P_STRING,
4098                 .p_class        = P_LOCAL,
4099                 .ptr            = &sDefault.szPreExec,
4100                 .special        = NULL,
4101                 .enum_list      = NULL,
4102                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4103         },
4104         {
4105                 .label          = "exec",
4106                 .type           = P_STRING,
4107                 .p_class        = P_LOCAL,
4108                 .ptr            = &sDefault.szPreExec,
4109                 .special        = NULL,
4110                 .enum_list      = NULL,
4111                 .flags          = FLAG_ADVANCED,
4112         },
4113         {
4114                 .label          = "preexec close",
4115                 .type           = P_BOOL,
4116                 .p_class        = P_LOCAL,
4117                 .ptr            = &sDefault.bPreexecClose,
4118                 .special        = NULL,
4119                 .enum_list      = NULL,
4120                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4121         },
4122         {
4123                 .label          = "postexec",
4124                 .type           = P_STRING,
4125                 .p_class        = P_LOCAL,
4126                 .ptr            = &sDefault.szPostExec,
4127                 .special        = NULL,
4128                 .enum_list      = NULL,
4129                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4130         },
4131         {
4132                 .label          = "root preexec",
4133                 .type           = P_STRING,
4134                 .p_class        = P_LOCAL,
4135                 .ptr            = &sDefault.szRootPreExec,
4136                 .special        = NULL,
4137                 .enum_list      = NULL,
4138                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4139         },
4140         {
4141                 .label          = "root preexec close",
4142                 .type           = P_BOOL,
4143                 .p_class        = P_LOCAL,
4144                 .ptr            = &sDefault.bRootpreexecClose,
4145                 .special        = NULL,
4146                 .enum_list      = NULL,
4147                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4148         },
4149         {
4150                 .label          = "root postexec",
4151                 .type           = P_STRING,
4152                 .p_class        = P_LOCAL,
4153                 .ptr            = &sDefault.szRootPostExec,
4154                 .special        = NULL,
4155                 .enum_list      = NULL,
4156                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4157         },
4158         {
4159                 .label          = "available",
4160                 .type           = P_BOOL,
4161                 .p_class        = P_LOCAL,
4162                 .ptr            = &sDefault.bAvailable,
4163                 .special        = NULL,
4164                 .enum_list      = NULL,
4165                 .flags          = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4166         },
4167         {
4168                 .label          = "registry shares",
4169                 .type           = P_BOOL,
4170                 .p_class        = P_GLOBAL,
4171                 .ptr            = &Globals.bRegistryShares,
4172                 .special        = NULL,
4173                 .enum_list      = NULL,
4174                 .flags          = FLAG_ADVANCED,
4175         },
4176         {
4177                 .label          = "usershare allow guests",
4178                 .type           = P_BOOL,
4179                 .p_class        = P_GLOBAL,
4180                 .ptr            = &Globals.bUsershareAllowGuests,
4181                 .special        = NULL,
4182                 .enum_list      = NULL,
4183                 .flags          = FLAG_ADVANCED,
4184         },
4185         {
4186                 .label          = "usershare max shares",
4187                 .type           = P_INTEGER,
4188                 .p_class        = P_GLOBAL,
4189                 .ptr            = &Globals.iUsershareMaxShares,
4190                 .special        = NULL,
4191                 .enum_list      = NULL,
4192                 .flags          = FLAG_ADVANCED,
4193         },
4194         {
4195                 .label          = "usershare owner only",
4196                 .type           = P_BOOL,
4197                 .p_class        = P_GLOBAL,
4198                 .ptr            = &Globals.bUsershareOwnerOnly,
4199                 .special        = NULL,
4200                 .enum_list      = NULL,
4201                 .flags          = FLAG_ADVANCED,
4202         },
4203         {
4204                 .label          = "usershare path",
4205                 .type           = P_STRING,
4206                 .p_class        = P_GLOBAL,
4207                 .ptr            = &Globals.szUsersharePath,
4208                 .special        = NULL,
4209                 .enum_list      = NULL,
4210                 .flags          = FLAG_ADVANCED,
4211         },
4212         {
4213                 .label          = "usershare prefix allow list",
4214                 .type           = P_LIST,
4215                 .p_class        = P_GLOBAL,
4216                 .ptr            = &Globals.szUsersharePrefixAllowList,
4217                 .special        = NULL,
4218                 .enum_list      = NULL,
4219                 .flags          = FLAG_ADVANCED,
4220         },
4221         {
4222                 .label          = "usershare prefix deny list",
4223                 .type           = P_LIST,
4224                 .p_class        = P_GLOBAL,
4225                 .ptr            = &Globals.szUsersharePrefixDenyList,
4226                 .special        = NULL,
4227                 .enum_list      = NULL,
4228                 .flags          = FLAG_ADVANCED,
4229         },
4230         {
4231                 .label          = "usershare template share",
4232                 .type           = P_STRING,
4233                 .p_class        = P_GLOBAL,
4234                 .ptr            = &Globals.szUsershareTemplateShare,
4235                 .special        = NULL,
4236                 .enum_list      = NULL,
4237                 .flags          = FLAG_ADVANCED,
4238         },
4239         {
4240                 .label          = "volume",
4241                 .type           = P_STRING,
4242                 .p_class        = P_LOCAL,
4243                 .ptr            = &sDefault.volume,
4244                 .special        = NULL,
4245                 .enum_list      = NULL,
4246                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4247         },
4248         {
4249                 .label          = "fstype",
4250                 .type           = P_STRING,
4251                 .p_class        = P_LOCAL,
4252                 .ptr            = &sDefault.fstype,
4253                 .special        = NULL,
4254                 .enum_list      = NULL,
4255                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4256         },
4257         {
4258                 .label          = "set directory",
4259                 .type           = P_BOOLREV,
4260                 .p_class        = P_LOCAL,
4261                 .ptr            = &sDefault.bNo_set_dir,
4262                 .special        = NULL,
4263                 .enum_list      = NULL,
4264                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4265         },
4266         {
4267                 .label          = "wide links",
4268                 .type           = P_BOOL,
4269                 .p_class        = P_LOCAL,
4270                 .ptr            = &sDefault.bWidelinks,
4271                 .special        = NULL,
4272                 .enum_list      = NULL,
4273                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4274         },
4275         {
4276                 .label          = "follow symlinks",
4277                 .type           = P_BOOL,
4278                 .p_class        = P_LOCAL,
4279                 .ptr            = &sDefault.bSymlinks,
4280                 .special        = NULL,
4281                 .enum_list      = NULL,
4282                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4283         },
4284         {
4285                 .label          = "dont descend",
4286                 .type           = P_STRING,
4287                 .p_class        = P_LOCAL,
4288                 .ptr            = &sDefault.szDontdescend,
4289                 .special        = NULL,
4290                 .enum_list      = NULL,
4291                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4292         },
4293         {
4294                 .label          = "magic script",
4295                 .type           = P_STRING,
4296                 .p_class        = P_LOCAL,
4297                 .ptr            = &sDefault.szMagicScript,
4298                 .special        = NULL,
4299                 .enum_list      = NULL,
4300                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4301         },
4302         {
4303                 .label          = "magic output",
4304                 .type           = P_STRING,
4305                 .p_class        = P_LOCAL,
4306                 .ptr            = &sDefault.szMagicOutput,
4307                 .special        = NULL,
4308                 .enum_list      = NULL,
4309                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4310         },
4311         {
4312                 .label          = "delete readonly",
4313                 .type           = P_BOOL,
4314                 .p_class        = P_LOCAL,
4315                 .ptr            = &sDefault.bDeleteReadonly,
4316                 .special        = NULL,
4317                 .enum_list      = NULL,
4318                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4319         },
4320         {
4321                 .label          = "dos filemode",
4322                 .type           = P_BOOL,
4323                 .p_class        = P_LOCAL,
4324                 .ptr            = &sDefault.bDosFilemode,
4325                 .special        = NULL,
4326                 .enum_list      = NULL,
4327                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4328         },
4329         {
4330                 .label          = "dos filetimes",
4331                 .type           = P_BOOL,
4332                 .p_class        = P_LOCAL,
4333                 .ptr            = &sDefault.bDosFiletimes,
4334                 .special        = NULL,
4335                 .enum_list      = NULL,
4336                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4337         },
4338         {
4339                 .label          = "dos filetime resolution",
4340                 .type           = P_BOOL,
4341                 .p_class        = P_LOCAL,
4342                 .ptr            = &sDefault.bDosFiletimeResolution,
4343                 .special        = NULL,
4344                 .enum_list      = NULL,
4345                 .flags          = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4346         },
4347         {
4348                 .label          = "fake directory create times",
4349                 .type           = P_BOOL,
4350                 .p_class        = P_LOCAL,
4351                 .ptr            = &sDefault.bFakeDirCreateTimes,
4352                 .special        = NULL,
4353                 .enum_list      = NULL,
4354                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
4355         },
4356         {
4357                 .label          = "async smb echo handler",
4358                 .type           = P_BOOL,
4359                 .p_class        = P_GLOBAL,
4360                 .ptr            = &Globals.bAsyncSMBEchoHandler,
4361                 .special        = NULL,
4362                 .enum_list      = NULL,
4363                 .flags          = FLAG_ADVANCED | FLAG_GLOBAL,
4364         },
4365         {
4366                 .label          = "panic action",
4367                 .type           = P_STRING,
4368                 .p_class        = P_GLOBAL,
4369                 .ptr            = &Globals.szPanicAction,
4370                 .special        = NULL,
4371                 .enum_list      = NULL,
4372                 .flags          = FLAG_ADVANCED,
4373         },
4374         {
4375                 .label          = "perfcount module",
4376                 .type           = P_STRING,
4377                 .p_class        = P_GLOBAL,
4378                 .ptr            = &Globals.szSMBPerfcountModule,
4379                 .special        = NULL,
4380                 .enum_list      = NULL,
4381                 .flags          = FLAG_ADVANCED,
4382         },
4383
4384         {N_("VFS module options"), P_SEP, P_SEPARATOR},
4385
4386         {
4387                 .label          = "vfs objects",
4388                 .type           = P_LIST,
4389                 .p_class        = P_LOCAL,
4390                 .ptr            = &sDefault.szVfsObjects,
4391                 .special        = NULL,
4392                 .enum_list      = NULL,
4393                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4394         },
4395         {
4396                 .label          = "vfs object",
4397                 .type           = P_LIST,
4398                 .p_class        = P_LOCAL,
4399                 .ptr            = &sDefault.szVfsObjects,
4400                 .special        = NULL,
4401                 .enum_list      = NULL,
4402                 .flags          = FLAG_HIDE,
4403         },
4404
4405
4406         {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4407
4408         {
4409                 .label          = "msdfs root",
4410                 .type           = P_BOOL,
4411                 .p_class        = P_LOCAL,
4412                 .ptr            = &sDefault.bMSDfsRoot,
4413                 .special        = NULL,
4414                 .enum_list      = NULL,
4415                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4416         },
4417         {
4418                 .label          = "msdfs proxy",
4419                 .type           = P_STRING,
4420                 .p_class        = P_LOCAL,
4421                 .ptr            = &sDefault.szMSDfsProxy,
4422                 .special        = NULL,
4423                 .enum_list      = NULL,
4424                 .flags          = FLAG_ADVANCED | FLAG_SHARE,
4425         },
4426         {
4427                 .label          = "host msdfs",
4428                 .type           = P_BOOL,
4429                 .p_class        = P_GLOBAL,
4430                 .ptr            = &Globals.bHostMSDfs,
4431                 .special        = NULL,
4432                 .enum_list      = NULL,
4433                 .flags          = FLAG_ADVANCED,
4434         },
4435
4436         {N_("Winbind options"), P_SEP, P_SEPARATOR},
4437
4438         {
4439                 .label          = "passdb expand explicit",
4440                 .type           = P_BOOL,
4441                 .p_class        = P_GLOBAL,
4442                 .ptr            = &Globals.bPassdbExpandExplicit,
4443                 .special        = NULL,
4444                 .enum_list      = NULL,
4445                 .flags          = FLAG_ADVANCED,
4446         },
4447         {
4448                 .label          = "idmap backend",
4449                 .type           = P_STRING,
4450                 .p_class        = P_GLOBAL,
4451                 .ptr            = &Globals.szIdmapBackend,
4452                 .special        = NULL,
4453                 .enum_list      = NULL,
4454                 .flags          = FLAG_ADVANCED,
4455         },
4456         {
4457                 .label          = "idmap alloc backend",
4458                 .type           = P_STRING,
4459                 .p_class        = P_GLOBAL,
4460                 .ptr            = &Globals.szIdmapAllocBackend,
4461                 .special        = NULL,
4462                 .enum_list      = NULL,
4463                 .flags          = FLAG_ADVANCED,
4464         },
4465         {
4466                 .label          = "idmap cache time",
4467                 .type           = P_INTEGER,
4468                 .p_class        = P_GLOBAL,
4469                 .ptr            = &Globals.iIdmapCacheTime,
4470                 .special        = NULL,
4471                 .enum_list      = NULL,
4472                 .flags          = FLAG_ADVANCED,
4473         },
4474         {
4475                 .label          = "idmap negative cache time",
4476                 .type           = P_INTEGER,
4477                 .p_class        = P_GLOBAL,
4478                 .ptr            = &Globals.iIdmapNegativeCacheTime,
4479                 .special        = NULL,
4480                 .enum_list      = NULL,
4481                 .flags          = FLAG_ADVANCED,
4482         },
4483         {
4484                 .label          = "idmap uid",
4485                 .type           = P_STRING,
4486                 .p_class        = P_GLOBAL,
4487                 .ptr            = &Globals.szIdmapUID,
4488                 .special        = handle_idmap_uid,
4489                 .enum_list      = NULL,
4490                 .flags          = FLAG_ADVANCED,
4491         },
4492         {
4493                 .label          = "winbind uid",
4494                 .type           = P_STRING,
4495                 .p_class        = P_GLOBAL,
4496                 .ptr            = &Globals.szIdmapUID,
4497                 .special        = handle_idmap_uid,
4498                 .enum_list      = NULL,
4499                 .flags          = FLAG_HIDE,
4500         },
4501         {
4502                 .label          = "idmap gid",
4503                 .type           = P_STRING,
4504                 .p_class        = P_GLOBAL,
4505                 .ptr            = &Globals.szIdmapGID,
4506                 .special        = handle_idmap_gid,
4507                 .enum_list      = NULL,
4508                 .flags          = FLAG_ADVANCED,
4509         },
4510         {
4511                 .label          = "winbind gid",
4512                 .type           = P_STRING,
4513                 .p_class        = P_GLOBAL,
4514                 .ptr            = &Globals.szIdmapGID,
4515                 .special        = handle_idmap_gid,
4516                 .enum_list      = NULL,
4517                 .flags          = FLAG_HIDE,
4518         },
4519         {
4520                 .label          = "template homedir",
4521                 .type           = P_STRING,
4522                 .p_class        = P_GLOBAL,
4523                 .ptr            = &Globals.szTemplateHomedir,
4524                 .special        = NULL,
4525                 .enum_list      = NULL,
4526                 .flags          = FLAG_ADVANCED,
4527         },
4528         {
4529                 .label          = "template shell",
4530                 .type           = P_STRING,
4531                 .p_class        = P_GLOBAL,
4532                 .ptr            = &Globals.szTemplateShell,
4533                 .special        = NULL,
4534                 .enum_list      = NULL,
4535                 .flags          = FLAG_ADVANCED,
4536         },
4537         {
4538                 .label          = "winbind separator",
4539                 .type           = P_STRING,
4540                 .p_class        = P_GLOBAL,
4541                 .ptr            = &Globals.szWinbindSeparator,
4542                 .special        = NULL,
4543                 .enum_list      = NULL,
4544                 .flags          = FLAG_ADVANCED,
4545         },
4546         {
4547                 .label          = "winbind cache time",
4548                 .type           = P_INTEGER,
4549                 .p_class        = P_GLOBAL,
4550                 .ptr            = &Globals.winbind_cache_time,
4551                 .special        = NULL,
4552                 .enum_list      = NULL,
4553                 .flags          = FLAG_ADVANCED,
4554         },
4555         {
4556                 .label          = "winbind reconnect delay",
4557                 .type           = P_INTEGER,
4558                 .p_class        = P_GLOBAL,
4559                 .ptr            = &Globals.winbind_reconnect_delay,
4560                 .special        = NULL,
4561                 .enum_list      = NULL,
4562                 .flags          = FLAG_ADVANCED,
4563         },
4564         {
4565                 .label          = "winbind enum users",
4566                 .type           = P_BOOL,
4567                 .p_class        = P_GLOBAL,
4568                 .ptr            = &Globals.bWinbindEnumUsers,
4569                 .special        = NULL,
4570                 .enum_list      = NULL,
4571                 .flags          = FLAG_ADVANCED,
4572         },
4573         {
4574                 .label          = "winbind enum groups",
4575                 .type           = P_BOOL,
4576                 .p_class        = P_GLOBAL,
4577                 .ptr            = &Globals.bWinbindEnumGroups,
4578                 .special        = NULL,
4579                 .enum_list      = NULL,
4580                 .flags          = FLAG_ADVANCED,
4581         },
4582         {
4583                 .label          = "winbind use default domain",
4584                 .type           = P_BOOL,
4585                 .p_class        = P_GLOBAL,
4586                 .ptr            = &Globals.bWinbindUseDefaultDomain,
4587                 .special        = NULL,
4588                 .enum_list      = NULL,
4589                 .flags          = FLAG_ADVANCED,
4590         },
4591         {
4592                 .label          = "winbind trusted domains only",
4593                 .type           = P_BOOL,
4594                 .p_class        = P_GLOBAL,
4595                 .ptr            = &Globals.bWinbindTrustedDomainsOnly,
4596                 .special        = NULL,
4597                 .enum_list      = NULL,
4598                 .flags          = FLAG_ADVANCED,
4599         },
4600         {
4601                 .label          = "winbind nested groups",
4602                 .type           = P_BOOL,
4603                 .p_class        = P_GLOBAL,
4604                 .ptr            = &Globals.bWinbindNestedGroups,
4605                 .special        = NULL,
4606                 .enum_list      = NULL,
4607                 .flags          = FLAG_ADVANCED,
4608         },
4609         {
4610                 .label          = "winbind expand groups",
4611                 .type           = P_INTEGER,
4612                 .p_class        = P_GLOBAL,
4613                 .ptr            = &Globals.winbind_expand_groups,
4614                 .special        = NULL,
4615                 .enum_list      = NULL,
4616                 .flags          = FLAG_ADVANCED,
4617         },
4618         {
4619                 .label          = "winbind nss info",
4620                 .type           = P_LIST,
4621                 .p_class        = P_GLOBAL,
4622                 .ptr            = &Globals.szWinbindNssInfo,
4623                 .special        = NULL,
4624                 .enum_list      = NULL,
4625                 .flags          = FLAG_ADVANCED,
4626         },
4627         {
4628                 .label          = "winbind refresh tickets",
4629                 .type           = P_BOOL,
4630                 .p_class        = P_GLOBAL,
4631                 .ptr            = &Globals.bWinbindRefreshTickets,
4632                 .special        = NULL,
4633                 .enum_list      = NULL,
4634                 .flags          = FLAG_ADVANCED,
4635         },
4636         {
4637                 .label          = "winbind offline logon",
4638                 .type           = P_BOOL,
4639                 .p_class        = P_GLOBAL,
4640                 .ptr            = &Globals.bWinbindOfflineLogon,
4641                 .special        = NULL,
4642                 .enum_list      = NULL,
4643                 .flags          = FLAG_ADVANCED,
4644         },
4645         {
4646                 .label          = "winbind normalize names",
4647                 .type           = P_BOOL,
4648                 .p_class        = P_GLOBAL,
4649                 .ptr            = &Globals.bWinbindNormalizeNames,
4650                 .special        = NULL,
4651                 .enum_list      = NULL,
4652                 .flags          = FLAG_ADVANCED,
4653         },
4654         {
4655                 .label          = "winbind rpc only",
4656                 .type           = P_BOOL,
4657                 .p_class        = P_GLOBAL,
4658                 .ptr            = &Globals.bWinbindRpcOnly,
4659                 .special        = NULL,
4660                 .enum_list      = NULL,
4661                 .flags          = FLAG_ADVANCED,
4662         },
4663         {
4664                 .label          = "create krb5 conf",
4665                 .type           = P_BOOL,
4666                 .p_class        = P_GLOBAL,
4667                 .ptr            = &Globals.bCreateKrb5Conf,
4668                 .special        = NULL,
4669                 .enum_list      = NULL,
4670                 .flags          = FLAG_ADVANCED,
4671         },
4672
4673         {NULL,  P_BOOL,  P_NONE,  NULL,  NULL,  NULL,  0}
4674 };
4675
4676 /***************************************************************************
4677  Initialise the sDefault parameter structure for the printer values.
4678 ***************************************************************************/
4679
4680 static void init_printer_values(struct service *pService)
4681 {
4682         /* choose defaults depending on the type of printing */
4683         switch (pService->iPrinting) {
4684                 case PRINT_BSD:
4685                 case PRINT_AIX:
4686                 case PRINT_LPRNT:
4687                 case PRINT_LPROS2:
4688                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4689                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4690                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4691                         break;
4692
4693                 case PRINT_LPRNG:
4694                 case PRINT_PLP:
4695                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4696                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4697                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4698                         string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4699                         string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4700                         string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4701                         string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4702                         break;
4703
4704                 case PRINT_CUPS:
4705                 case PRINT_IPRINT:
4706 #ifdef HAVE_CUPS
4707                         /* set the lpq command to contain the destination printer
4708                            name only.  This is used by cups_queue_get() */
4709                         string_set(&pService->szLpqcommand, "%p");
4710                         string_set(&pService->szLprmcommand, "");
4711                         string_set(&pService->szPrintcommand, "");
4712                         string_set(&pService->szLppausecommand, "");
4713                         string_set(&pService->szLpresumecommand, "");
4714                         string_set(&pService->szQueuepausecommand, "");
4715                         string_set(&pService->szQueueresumecommand, "");
4716 #else
4717                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
4718                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4719                         string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4720                         string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4721                         string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4722                         string_set(&pService->szQueuepausecommand, "disable '%p'");
4723                         string_set(&pService->szQueueresumecommand, "enable '%p'");
4724 #endif /* HAVE_CUPS */
4725                         break;
4726
4727                 case PRINT_SYSV:
4728                 case PRINT_HPUX:
4729                         string_set(&pService->szLpqcommand, "lpstat -o%p");
4730                         string_set(&pService->szLprmcommand, "cancel %p-%j");
4731                         string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4732                         string_set(&pService->szQueuepausecommand, "disable %p");
4733                         string_set(&pService->szQueueresumecommand, "enable %p");
4734 #ifndef HPUX
4735                         string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4736                         string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4737 #endif /* HPUX */
4738                         break;
4739
4740                 case PRINT_QNX:
4741                         string_set(&pService->szLpqcommand, "lpq -P%p");
4742                         string_set(&pService->szLprmcommand, "lprm -P%p %j");
4743                         string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4744                         break;
4745
4746 #ifdef DEVELOPER
4747         case PRINT_TEST:
4748         case PRINT_VLP:
4749                 string_set(&pService->szPrintcommand, "vlp print %p %s");
4750                 string_set(&pService->szLpqcommand, "vlp lpq %p");
4751                 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4752                 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4753                 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4754                 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4755                 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4756                 break;
4757 #endif /* DEVELOPER */
4758
4759         }
4760 }
4761 /**
4762  *  Function to return the default value for the maximum number of open
4763  *  file descriptors permitted.  This function tries to consult the
4764  *  kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4765  *  the smaller of those.
4766  */
4767 static int max_open_files(void)
4768 {
4769         int sysctl_max = MAX_OPEN_FILES;
4770         int rlimit_max = MAX_OPEN_FILES;
4771
4772 #ifdef HAVE_SYSCTLBYNAME
4773         {
4774                 size_t size = sizeof(sysctl_max);
4775                 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4776                              0);
4777         }
4778 #endif
4779
4780 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4781         {
4782                 struct rlimit rl;
4783
4784                 ZERO_STRUCT(rl);
4785
4786                 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4787                         rlimit_max = rl.rlim_cur;
4788
4789 #if defined(RLIM_INFINITY)
4790                 if(rl.rlim_cur == RLIM_INFINITY)
4791                         rlimit_max = MAX_OPEN_FILES;
4792         }
4793 #endif
4794 #endif
4795
4796         if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4797                 DEBUG(2,("max_open_files: sysctl_max (%d) below "
4798                         "minimum Windows limit (%d)\n",
4799                         sysctl_max,
4800                         MIN_OPEN_FILES_WINDOWS));
4801                 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4802         }
4803
4804         if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4805                 DEBUG(2,("rlimit_max: rlimit_max (%d) below "
4806                         "minimum Windows limit (%d)\n",
4807                         rlimit_max,
4808                         MIN_OPEN_FILES_WINDOWS));
4809                 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4810         }
4811
4812         return MIN(sysctl_max, rlimit_max);
4813 }
4814
4815 /**
4816  * Common part of freeing allocated data for one parameter.
4817  */
4818 static void free_one_parameter_common(void *parm_ptr,
4819                                       struct parm_struct parm)
4820 {
4821         if ((parm.type == P_STRING) ||
4822             (parm.type == P_USTRING))
4823         {
4824                 string_free((char**)parm_ptr);
4825         } else if (parm.type == P_LIST) {
4826                 TALLOC_FREE(*((char***)parm_ptr));
4827         }
4828 }
4829
4830 /**
4831  * Free the allocated data for one parameter for a share
4832  * given as a service struct.
4833  */
4834 static void free_one_parameter(struct service *service,
4835                                struct parm_struct parm)
4836 {
4837         void *parm_ptr;
4838
4839         if (parm.p_class != P_LOCAL) {
4840                 return;
4841         }
4842
4843         parm_ptr = lp_local_ptr(service, parm.ptr);
4844
4845         free_one_parameter_common(parm_ptr, parm);
4846 }
4847
4848 /**
4849  * Free the allocated parameter data of a share given
4850  * as a service struct.
4851  */
4852 static void free_parameters(struct service *service)
4853 {
4854         uint32_t i;
4855
4856         for (i=0; parm_table[i].label; i++) {
4857                 free_one_parameter(service, parm_table[i]);
4858         }
4859 }
4860
4861 /**
4862  * Free the allocated data for one parameter for a given share
4863  * specified by an snum.
4864  */
4865 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4866 {
4867         void *parm_ptr;
4868
4869         if (parm.ptr == NULL) {
4870                 return;
4871         }
4872
4873         if (snum < 0) {
4874                 parm_ptr = parm.ptr;
4875         } else if (parm.p_class != P_LOCAL) {
4876                 return;
4877         } else {
4878                 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4879         }
4880
4881         free_one_parameter_common(parm_ptr, parm);
4882 }
4883
4884 /**
4885  * Free the allocated parameter data for a share specified
4886  * by an snum.
4887  */
4888 static void free_parameters_by_snum(int snum)
4889 {
4890         uint32_t i;
4891
4892         for (i=0; parm_table[i].label; i++) {
4893                 free_one_parameter_by_snum(snum, parm_table[i]);
4894         }
4895 }
4896
4897 /**
4898  * Free the allocated global parameters.
4899  */
4900 static void free_global_parameters(void)
4901 {
4902         free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4903 }
4904
4905 /***************************************************************************
4906  Initialise the global parameter structure.
4907 ***************************************************************************/
4908
4909 static void init_globals(bool first_time_only)
4910 {
4911         static bool done_init = False;
4912         char *s = NULL;
4913         int i;
4914
4915         /* If requested to initialize only once and we've already done it... */
4916         if (first_time_only && done_init) {
4917                 /* ... then we have nothing more to do */
4918                 return;
4919         }
4920
4921         if (!done_init) {
4922                 /* The logfile can be set before this is invoked. Free it if so. */
4923                 if (Globals.szLogFile != NULL) {
4924                         string_free(&Globals.szLogFile);
4925                         Globals.szLogFile = NULL;
4926                 }
4927                 done_init = True;
4928         } else {
4929                 free_global_parameters();
4930         }
4931
4932         memset((void *)&Globals, '\0', sizeof(Globals));
4933
4934         for (i = 0; parm_table[i].label; i++) {
4935                 if ((parm_table[i].type == P_STRING ||
4936                      parm_table[i].type == P_USTRING) &&
4937                     parm_table[i].ptr)
4938                 {
4939                         string_set((char **)parm_table[i].ptr, "");
4940                 }
4941         }
4942
4943         string_set(&sDefault.fstype, FSTYPE_STRING);
4944         string_set(&sDefault.szPrintjobUsername, "%U");
4945
4946         init_printer_values(&sDefault);
4947
4948
4949         DEBUG(3, ("Initialising global parameters\n"));
4950
4951         string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4952         string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4953
4954         /* use the new 'hash2' method by default, with a prefix of 1 */
4955         string_set(&Globals.szManglingMethod, "hash2");
4956         Globals.mangle_prefix = 1;
4957
4958         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4959
4960         /* using UTF8 by default allows us to support all chars */
4961         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4962
4963 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4964         /* If the system supports nl_langinfo(), try to grab the value
4965            from the user's locale */
4966         string_set(&Globals.display_charset, "LOCALE");
4967 #else
4968         string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4969 #endif
4970
4971         /* Use codepage 850 as a default for the dos character set */
4972         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4973
4974         /*
4975          * Allow the default PASSWD_CHAT to be overridden in local.h.
4976          */
4977         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4978
4979         set_global_myname(myhostname());
4980         string_set(&Globals.szNetbiosName,global_myname());
4981
4982         set_global_myworkgroup(WORKGROUP);
4983         string_set(&Globals.szWorkgroup, lp_workgroup());
4984
4985         string_set(&Globals.szPasswdProgram, "");
4986         string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4987         string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4988         string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4989         string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4990         string_set(&Globals.szSocketAddress, "0.0.0.0");
4991         /*
4992          * By default support explicit binding to broadcast
4993          * addresses.
4994          */
4995         Globals.bNmbdBindExplicitBroadcast = true;
4996
4997         if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4998                 smb_panic("init_globals: ENOMEM");
4999         }
5000         string_set(&Globals.szServerString, s);
5001         SAFE_FREE(s);
5002         if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
5003                         DEFAULT_MINOR_VERSION) < 0) {
5004                 smb_panic("init_globals: ENOMEM");
5005         }
5006         string_set(&Globals.szAnnounceVersion, s);
5007         SAFE_FREE(s);
5008 #ifdef DEVELOPER
5009         string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
5010 #endif
5011
5012         string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
5013
5014         string_set(&Globals.szLogonDrive, "");
5015         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
5016         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
5017         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
5018
5019         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
5020         string_set(&Globals.szPasswordServer, "*");
5021
5022         Globals.AlgorithmicRidBase = BASE_RID;
5023
5024         Globals.bLoadPrinters = True;
5025         Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
5026
5027         Globals.ConfigBackend = config_backend;
5028
5029         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
5030         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
5031         Globals.max_xmit = 0x4104;
5032         Globals.max_mux = 50;   /* This is *needed* for profile support. */
5033         Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
5034         Globals.bDisableSpoolss = False;
5035         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
5036         Globals.pwordlevel = 0;
5037         Globals.unamelevel = 0;
5038         Globals.deadtime = 0;
5039         Globals.getwd_cache = true;
5040         Globals.bLargeReadwrite = True;
5041         Globals.max_log_size = 5000;
5042         Globals.max_open_files = max_open_files();
5043         Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
5044         Globals.maxprotocol = PROTOCOL_NT1;
5045         Globals.minprotocol = PROTOCOL_CORE;
5046         Globals.security = SEC_USER;
5047         Globals.paranoid_server_security = True;
5048         Globals.bEncryptPasswords = True;
5049         Globals.bUpdateEncrypt = False;
5050         Globals.clientSchannel = Auto;
5051         Globals.serverSchannel = Auto;
5052         Globals.bReadRaw = True;
5053         Globals.bWriteRaw = True;
5054         Globals.bNullPasswords = False;
5055         Globals.bObeyPamRestrictions = False;
5056         Globals.syslog = 1;
5057         Globals.bSyslogOnly = False;
5058         Globals.bTimestampLogs = True;
5059         string_set(&Globals.szLogLevel, "0");
5060         Globals.bDebugPrefixTimestamp = False;
5061         Globals.bDebugHiresTimestamp = true;
5062         Globals.bDebugPid = False;
5063         Globals.bDebugUid = False;
5064         Globals.bDebugClass = False;
5065         Globals.bEnableCoreFiles = True;
5066         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
5067         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
5068         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
5069         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
5070         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
5071         Globals.lm_interval = 60;
5072         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
5073 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
5074         Globals.bNISHomeMap = False;
5075 #ifdef WITH_NISPLUS_HOME
5076         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
5077 #else
5078         string_set(&Globals.szNISHomeMapName, "auto.home");
5079 #endif
5080 #endif
5081         Globals.bTimeServer = False;
5082         Globals.bBindInterfacesOnly = False;
5083         Globals.bUnixPasswdSync = False;
5084         Globals.bPamPasswordChange = False;
5085         Globals.bPasswdChatDebug = False;
5086         Globals.iPasswdChatTimeout = 2; /* 2 second default. */
5087         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
5088         Globals.bNTStatusSupport = True; /* Use NT status by default. */
5089         Globals.bStatCache = True;      /* use stat cache by default */
5090         Globals.iMaxStatCacheSize = 256; /* 256k by default */
5091         Globals.restrict_anonymous = 0;
5092         Globals.bClientLanManAuth = False;      /* Do NOT use the LanMan hash if it is available */
5093         Globals.bClientPlaintextAuth = False;   /* Do NOT use a plaintext password even if is requested by the server */
5094         Globals.bLanmanAuth = False;    /* Do NOT use the LanMan hash, even if it is supplied */
5095         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
5096         Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
5097         /* Note, that we will use NTLM2 session security (which is different), if it is available */
5098
5099         Globals.map_to_guest = 0;       /* By Default, "Never" */
5100         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
5101         Globals.enhanced_browsing = true;
5102         Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
5103 #ifdef MMAP_BLACKLIST
5104         Globals.bUseMmap = False;
5105 #else
5106         Globals.bUseMmap = True;
5107 #endif
5108         Globals.bUnixExtensions = True;
5109         Globals.bResetOnZeroVC = False;
5110         Globals.bLogWriteableFilesOnExit = False;
5111         Globals.bCreateKrb5Conf = true;
5112
5113         /* hostname lookups can be very expensive and are broken on
5114            a large number of sites (tridge) */
5115         Globals.bHostnameLookups = False;
5116
5117         string_set(&Globals.szPassdbBackend, "tdbsam");
5118         string_set(&Globals.szLdapSuffix, "");
5119         string_set(&Globals.szLdapMachineSuffix, "");
5120         string_set(&Globals.szLdapUserSuffix, "");
5121         string_set(&Globals.szLdapGroupSuffix, "");
5122         string_set(&Globals.szLdapIdmapSuffix, "");
5123
5124         string_set(&Globals.szLdapAdminDn, "");
5125         Globals.ldap_ssl = LDAP_SSL_START_TLS;
5126         Globals.ldap_ssl_ads = False;
5127         Globals.ldap_deref = -1;
5128         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5129         Globals.ldap_delete_dn = False;
5130         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5131         Globals.ldap_follow_referral = Auto;
5132         Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5133         Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5134         Globals.ldap_page_size = LDAP_PAGE_SIZE;
5135
5136         Globals.ldap_debug_level = 0;
5137         Globals.ldap_debug_threshold = 10;
5138
5139         /* This is what we tell the afs client. in reality we set the token 
5140          * to never expire, though, when this runs out the afs client will 
5141          * forget the token. Set to 0 to get NEVERDATE.*/
5142         Globals.iAfsTokenLifetime = 604800;
5143         Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5144
5145 /* these parameters are set to defaults that are more appropriate
5146    for the increasing samba install base:
5147
5148    as a member of the workgroup, that will possibly become a
5149    _local_ master browser (lm = True).  this is opposed to a forced
5150    local master browser startup (pm = True).
5151
5152    doesn't provide WINS server service by default (wsupp = False),
5153    and doesn't provide domain master browser services by default, either.
5154
5155 */
5156
5157         Globals.bMsAddPrinterWizard = True;
5158         Globals.os_level = 20;
5159         Globals.bLocalMaster = True;
5160         Globals.iDomainMaster = Auto;   /* depending on bDomainLogons */
5161         Globals.bDomainLogons = False;
5162         Globals.bBrowseList = True;
5163         Globals.bWINSsupport = False;
5164         Globals.bWINSproxy = False;
5165
5166         TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5167         Globals.InitLogonDelay = 100; /* 100 ms default delay */
5168
5169         Globals.bDNSproxy = True;
5170
5171         /* this just means to use them if they exist */
5172         Globals.bKernelOplocks = True;
5173
5174         Globals.bAllowTrustedDomains = True;
5175         string_set(&Globals.szIdmapBackend, "tdb");
5176
5177         string_set(&Globals.szTemplateShell, "/bin/false");
5178         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5179         string_set(&Globals.szWinbindSeparator, "\\");
5180
5181         string_set(&Globals.szCupsServer, "");
5182         string_set(&Globals.szIPrintServer, "");
5183
5184         string_set(&Globals.ctdbdSocket, "");
5185         Globals.szClusterAddresses = NULL;
5186         Globals.clustering = False;
5187         Globals.ctdb_timeout = 0;
5188
5189         Globals.winbind_cache_time = 300;       /* 5 minutes */
5190         Globals.winbind_reconnect_delay = 30;   /* 30 seconds */
5191         Globals.bWinbindEnumUsers = False;
5192         Globals.bWinbindEnumGroups = False;
5193         Globals.bWinbindUseDefaultDomain = False;
5194         Globals.bWinbindTrustedDomainsOnly = False;
5195         Globals.bWinbindNestedGroups = True;
5196         Globals.winbind_expand_groups = 1;
5197         Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5198         Globals.bWinbindRefreshTickets = False;
5199         Globals.bWinbindOfflineLogon = False;
5200
5201         Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5202         Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5203
5204         Globals.bPassdbExpandExplicit = False;
5205
5206         Globals.name_cache_timeout = 660; /* In seconds */
5207
5208         Globals.bUseSpnego = True;
5209         Globals.bClientUseSpnego = True;
5210
5211         Globals.client_signing = Auto;
5212         Globals.server_signing = False;
5213
5214         Globals.bDeferSharingViolations = True;
5215         string_set(&Globals.smb_ports, SMB_PORTS);
5216
5217         Globals.bEnablePrivileges = True;
5218         Globals.bHostMSDfs        = True;
5219         Globals.bASUSupport       = False;
5220
5221         /* User defined shares. */
5222         if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5223                 smb_panic("init_globals: ENOMEM");
5224         }
5225         string_set(&Globals.szUsersharePath, s);
5226         SAFE_FREE(s);
5227         string_set(&Globals.szUsershareTemplateShare, "");
5228         Globals.iUsershareMaxShares = 0;
5229         /* By default disallow sharing of directories not owned by the sharer. */
5230         Globals.bUsershareOwnerOnly = True;
5231         /* By default disallow guest access to usershares. */
5232         Globals.bUsershareAllowGuests = False;
5233
5234         Globals.iKeepalive = DEFAULT_KEEPALIVE;
5235
5236         /* By default no shares out of the registry */
5237         Globals.bRegistryShares = False;
5238
5239         Globals.iminreceivefile = 0;
5240
5241         Globals.bMapUntrustedToDomain = false;
5242 }
5243
5244 /*******************************************************************
5245  Convenience routine to grab string parameters into temporary memory
5246  and run standard_sub_basic on them. The buffers can be written to by
5247  callers without affecting the source string.
5248 ********************************************************************/
5249
5250 static char *lp_string(const char *s)
5251 {
5252         char *ret;
5253         TALLOC_CTX *ctx = talloc_tos();
5254
5255         /* The follow debug is useful for tracking down memory problems
5256            especially if you have an inner loop that is calling a lp_*()
5257            function that returns a string.  Perhaps this debug should be
5258            present all the time? */
5259
5260 #if 0
5261         DEBUG(10, ("lp_string(%s)\n", s));
5262 #endif
5263         if (!s) {
5264                 return NULL;
5265         }
5266
5267         ret = talloc_sub_basic(ctx,
5268                         get_current_username(),
5269                         current_user_info.domain,
5270                         s);
5271         if (trim_char(ret, '\"', '\"')) {
5272                 if (strchr(ret,'\"') != NULL) {
5273                         TALLOC_FREE(ret);
5274                         ret = talloc_sub_basic(ctx,
5275                                         get_current_username(),
5276                                         current_user_info.domain,
5277                                         s);
5278                 }
5279         }
5280         return ret;
5281 }
5282
5283 /*
5284    In this section all the functions that are used to access the
5285    parameters from the rest of the program are defined
5286 */
5287
5288 #define FN_GLOBAL_STRING(fn_name,ptr) \
5289  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5290 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5291  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5292 #define FN_GLOBAL_LIST(fn_name,ptr) \
5293  const char **fn_name(void) {return(*(const char ***)(ptr));}
5294 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5295  bool fn_name(void) {return(*(bool *)(ptr));}
5296 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5297  char fn_name(void) {return(*(char *)(ptr));}
5298 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5299  int fn_name(void) {return(*(int *)(ptr));}
5300
5301 #define FN_LOCAL_STRING(fn_name,val) \
5302  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5303 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5304  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5305 #define FN_LOCAL_LIST(fn_name,val) \
5306  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5307 #define FN_LOCAL_BOOL(fn_name,val) \
5308  bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5309 #define FN_LOCAL_INTEGER(fn_name,val) \
5310  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5311
5312 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5313  bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5314 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5315  int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5316 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5317  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));}
5318 #define FN_LOCAL_CHAR(fn_name,val) \
5319  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5320
5321 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5322 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5323 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5324 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5325 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5326 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5327 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5328 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5329 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5330 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5331 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5332 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5333 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5334 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5335 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5336 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5337 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5338  * build process or in smb.conf, we use that value.  Otherwise they
5339  * default to the value of lp_lockdir(). */
5340 char *lp_statedir(void) {
5341         if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5342             (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5343                 return(lp_string(*(char **)(&Globals.szStateDir) ?
5344                     *(char **)(&Globals.szStateDir) : ""));
5345         else
5346                 return(lp_string(*(char **)(&Globals.szLockDir) ?
5347                     *(char **)(&Globals.szLockDir) : ""));
5348 }
5349 char *lp_cachedir(void) {
5350         if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5351             (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5352                 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5353                     *(char **)(&Globals.szCacheDir) : ""));
5354         else
5355                 return(lp_string(*(char **)(&Globals.szLockDir) ?
5356                     *(char **)(&Globals.szLockDir) : ""));
5357 }
5358 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5359 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5360 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5361 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5362 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5363 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5364 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5365 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5366 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5367 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5368 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5369 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5370 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5371 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5372 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5373 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5374 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5375 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5376 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5377 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5378 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5379 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5380 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5381 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5382 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5383 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5384 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5385 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5386 FN_GLOBAL_BOOL(lp_nmbd_bind_explicit_broadcast, &Globals.bNmbdBindExplicitBroadcast)
5387 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5388 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5389 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5390 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5391 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5392 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5393  * lp_passdb_backend() should be replace by the this macro again after
5394  * some releases.
5395  * */
5396 const char *lp_passdb_backend(void)
5397 {
5398         char *delim, *quote;
5399
5400         delim = strchr( Globals.szPassdbBackend, ' ');
5401         /* no space at all */
5402         if (delim == NULL) {
5403                 goto out;
5404         }
5405
5406         quote = strchr(Globals.szPassdbBackend, '"');
5407         /* no quote char or non in the first part */
5408         if (quote == NULL || quote > delim) {
5409                 *delim = '\0';
5410                 goto warn;
5411         }
5412
5413         quote = strchr(quote+1, '"');
5414         if (quote == NULL) {
5415                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5416                 goto out;
5417         } else if (*(quote+1) == '\0') {
5418                 /* space, fitting quote char, and one backend only */
5419                 goto out;
5420         } else {
5421                 /* terminate string after the fitting quote char */
5422                 *(quote+1) = '\0';
5423         }
5424
5425 warn:
5426         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
5427                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
5428                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
5429                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
5430
5431 out:
5432         return Globals.szPassdbBackend;
5433 }
5434 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5435 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5436 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5437 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5438 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5439
5440 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5441 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5442 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5443 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5444 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5445 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5446
5447 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5448
5449 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5450 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5451 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5452
5453 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5454
5455 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5456 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5457 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5458 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5459 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5460 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5461 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5462 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5463 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5464 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5465 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5466 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5467 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5468 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5469 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5470 FN_GLOBAL_BOOL(lp_create_krb5_conf, &Globals.bCreateKrb5Conf)
5471
5472 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5473 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5474 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5475 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5476 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5477 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5478
5479 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5480 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5481 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5482 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5483 FN_GLOBAL_INTEGER(lp_ldap_deref, &Globals.ldap_deref)
5484 FN_GLOBAL_INTEGER(lp_ldap_follow_referral, &Globals.ldap_follow_referral)
5485 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5486 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5487 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5488 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5489 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5490 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5491 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5492 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5493 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5494 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5495 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5496 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5497 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5498 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5499
5500 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5501
5502 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5503 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5504 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5505 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5506 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5507 FN_GLOBAL_BOOL(lp_log_writeable_files_on_exit,
5508                &Globals.bLogWriteableFilesOnExit)
5509 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5510 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5511 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5512 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5513 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5514 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5515 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5516 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5517 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5518 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5519 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5520 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5521 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5522 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5523 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5524 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5525 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5526 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5527 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5528 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5529 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5530 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5531 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5532 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5533 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5534 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5535 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5536 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5537 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5538 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5539 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5540 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5541 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5542 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5543 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5544 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5545 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5546 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5547 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5548 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5549 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5550 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5551 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5552 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5553 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5554 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5555 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5556 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5557 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5558 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5559 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5560 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5561 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5562 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5563 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5564 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5565 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5566 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5567 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5568 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5569 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5570 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5571 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5572 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5573 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5574 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5575 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5576 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5577 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5578 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5579 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5580 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5581 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5582 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5583 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5584 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5585 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5586 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5587 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5588 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5589 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5590 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5591 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5592 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5593 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5594 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5595 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5596 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5597 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5598 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5599 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5600 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5601 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5602 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5603 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5604
5605 FN_LOCAL_STRING(lp_preexec, szPreExec)
5606 FN_LOCAL_STRING(lp_postexec, szPostExec)
5607 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5608 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5609 FN_LOCAL_STRING(lp_servicename, szService)
5610 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5611 FN_LOCAL_STRING(lp_pathname, szPath)
5612 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5613 FN_LOCAL_STRING(lp_username, szUsername)
5614 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5615 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5616 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5617 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5618 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5619 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5620 int lp_cups_encrypt(void)
5621 {
5622 #ifdef HAVE_HTTPCONNECTENCRYPT
5623         switch (Globals.CupsEncrypt) {
5624                 case Auto:
5625                         Globals.CupsEncrypt = HTTP_ENCRYPT_REQUIRED;
5626                         break;
5627                 case True:
5628                         Globals.CupsEncrypt = HTTP_ENCRYPT_ALWAYS;
5629                         break;
5630                 case False:
5631                         Globals.CupsEncrypt = HTTP_ENCRYPT_NEVER;
5632                         break;
5633         }
5634 #endif
5635         return Globals.CupsEncrypt;
5636 }
5637 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5638 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5639 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5640 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5641 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5642 FN_GLOBAL_INTEGER(lp_ctdb_timeout, &Globals.ctdb_timeout)
5643 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5644 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5645 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5646 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5647 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5648 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5649 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5650 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5651 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5652 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5653 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5654 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5655 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5656 FN_LOCAL_STRING(lp_comment, comment)
5657 FN_LOCAL_STRING(lp_force_user, force_user)
5658 FN_LOCAL_STRING(lp_force_group, force_group)
5659 FN_LOCAL_LIST(lp_readlist, readlist)
5660 FN_LOCAL_LIST(lp_writelist, writelist)
5661 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5662 FN_LOCAL_STRING(lp_fstype, fstype)
5663 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5664 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5665 static FN_LOCAL_STRING(lp_volume, volume)
5666 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5667 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5668 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5669 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5670 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5671 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5672 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5673 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5674 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5675 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5676 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5677 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5678 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5679 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5680 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5681 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5682 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5683 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5684 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5685 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5686 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5687 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5688 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5689 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5690 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5691 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5692 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5693 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5694 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5695 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5696 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5697 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5698 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5699 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5700 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5701 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5702 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5703 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5704 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5705 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5706 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5707 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5708 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5709 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5710 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5711 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5712 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5713 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5714 FN_GLOBAL_BOOL(lp_async_smb_echo_handler, &Globals.bAsyncSMBEchoHandler)
5715 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5716 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5717 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5718 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5719 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5720 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5721 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5722 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5723 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5724 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5725 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5726 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5727 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5728 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5729 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5730 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5731 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5732 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5733 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5734 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5735 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5736 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5737 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5738 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5739 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5740 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5741 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5742 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5743 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5744 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5745 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5746 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5747 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5748 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5749 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5750 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5751 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5752 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5753 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5754 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5755 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5756 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5757 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5758 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5759 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5760 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5761 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5762 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5763 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5764 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5765
5766 /* local prototypes */
5767
5768 static int map_parameter(const char *pszParmName);
5769 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5770 static const char *get_boolean(bool bool_value);
5771 static int getservicebyname(const char *pszServiceName,
5772                             struct service *pserviceDest);
5773 static void copy_service(struct service *pserviceDest,
5774                          struct service *pserviceSource,
5775                          struct bitmap *pcopymapDest);
5776 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5777                          void *userdata);
5778 static bool do_section(const char *pszSectionName, void *userdata);
5779 static void init_copymap(struct service *pservice);
5780 static bool hash_a_service(const char *name, int number);
5781 static void free_service_byindex(int iService);
5782 static void free_param_opts(struct param_opt_struct **popts);
5783 static char * canonicalize_servicename(const char *name);
5784 static void show_parameter(int parmIndex);
5785 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5786
5787 /*
5788  * This is a helper function for parametrical options support.  It returns a
5789  * pointer to parametrical option value if it exists or NULL otherwise. Actual
5790  * parametrical functions are quite simple
5791  */
5792 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5793                                                 const char *option)
5794 {
5795         bool global_section = False;
5796         char* param_key;
5797         struct param_opt_struct *data;
5798
5799         if (snum >= iNumServices) return NULL;
5800
5801         if (snum < 0) { 
5802                 data = Globals.param_opt;
5803                 global_section = True;
5804         } else {
5805                 data = ServicePtrs[snum]->param_opt;
5806         }
5807
5808         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5809                 DEBUG(0,("asprintf failed!\n"));
5810                 return NULL;
5811         }
5812
5813         while (data) {
5814                 if (strwicmp(data->key, param_key) == 0) {
5815                         string_free(&param_key);
5816                         return data;
5817                 }
5818                 data = data->next;
5819         }
5820
5821         if (!global_section) {
5822                 /* Try to fetch the same option but from globals */
5823                 /* but only if we are not already working with Globals */
5824                 data = Globals.param_opt;
5825                 while (data) {
5826                         if (strwicmp(data->key, param_key) == 0) {
5827                                 string_free(&param_key);
5828                                 return data;
5829                         }
5830                         data = data->next;
5831                 }
5832         }
5833
5834         string_free(&param_key);
5835
5836         return NULL;
5837 }
5838
5839
5840 #define MISSING_PARAMETER(name) \
5841     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5842
5843 /*******************************************************************
5844 convenience routine to return int parameters.
5845 ********************************************************************/
5846 static int lp_int(const char *s)
5847 {
5848
5849         if (!s || !*s) {
5850                 MISSING_PARAMETER(lp_int);
5851                 return (-1);
5852         }
5853
5854         return (int)strtol(s, NULL, 0);
5855 }
5856
5857 /*******************************************************************
5858 convenience routine to return unsigned long parameters.
5859 ********************************************************************/
5860 static unsigned long lp_ulong(const char *s)
5861 {
5862
5863         if (!s || !*s) {
5864                 MISSING_PARAMETER(lp_ulong);
5865                 return (0);
5866         }
5867
5868         return strtoul(s, NULL, 0);
5869 }
5870
5871 /*******************************************************************
5872 convenience routine to return boolean parameters.
5873 ********************************************************************/
5874 static bool lp_bool(const char *s)
5875 {
5876         bool ret = False;
5877
5878         if (!s || !*s) {
5879                 MISSING_PARAMETER(lp_bool);
5880                 return False;
5881         }
5882
5883         if (!set_boolean(s, &ret)) {
5884                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5885                 return False;
5886         }
5887
5888         return ret;
5889 }
5890
5891 /*******************************************************************
5892 convenience routine to return enum parameters.
5893 ********************************************************************/
5894 static int lp_enum(const char *s,const struct enum_list *_enum)
5895 {
5896         int i;
5897
5898         if (!s || !*s || !_enum) {
5899                 MISSING_PARAMETER(lp_enum);
5900                 return (-1);
5901         }
5902
5903         for (i=0; _enum[i].name; i++) {
5904                 if (strequal(_enum[i].name,s))
5905                         return _enum[i].value;
5906         }
5907
5908         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5909         return (-1);
5910 }
5911
5912 #undef MISSING_PARAMETER
5913
5914 /* DO NOT USE lp_parm_string ANYMORE!!!!
5915  * use lp_parm_const_string or lp_parm_talloc_string
5916  *
5917  * lp_parm_string is only used to let old modules find this symbol
5918  */
5919 #undef lp_parm_string
5920  char *lp_parm_string(const char *servicename, const char *type, const char *option);
5921  char *lp_parm_string(const char *servicename, const char *type, const char *option)
5922 {
5923         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5924 }
5925
5926 /* Return parametric option from a given service. Type is a part of option before ':' */
5927 /* Parametric option has following syntax: 'Type: option = value' */
5928 /* the returned value is talloced on the talloc_tos() */
5929 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5930 {
5931         struct param_opt_struct *data = get_parametrics(snum, type, option);
5932
5933         if (data == NULL||data->value==NULL) {
5934                 if (def) {
5935                         return lp_string(def);
5936                 } else {
5937                         return NULL;
5938                 }
5939         }
5940
5941         return lp_string(data->value);
5942 }
5943
5944 /* Return parametric option from a given service. Type is a part of option before ':' */
5945 /* Parametric option has following syntax: 'Type: option = value' */
5946 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5947 {
5948         struct param_opt_struct *data = get_parametrics(snum, type, option);
5949
5950         if (data == NULL||data->value==NULL)
5951                 return def;
5952
5953         return data->value;
5954 }
5955
5956 /* Return parametric option from a given service. Type is a part of option before ':' */
5957 /* Parametric option has following syntax: 'Type: option = value' */
5958
5959 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5960 {
5961         struct param_opt_struct *data = get_parametrics(snum, type, option);
5962
5963         if (data == NULL||data->value==NULL)
5964                 return (const char **)def;
5965
5966         if (data->list==NULL) {
5967                 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5968         }
5969
5970         return (const char **)data->list;
5971 }
5972
5973 /* Return parametric option from a given service. Type is a part of option before ':' */
5974 /* Parametric option has following syntax: 'Type: option = value' */
5975
5976 int lp_parm_int(int snum, const char *type, const char *option, int def)
5977 {
5978         struct param_opt_struct *data = get_parametrics(snum, type, option);
5979
5980         if (data && data->value && *data->value)
5981                 return lp_int(data->value);
5982
5983         return def;
5984 }
5985
5986 /* Return parametric option from a given service. Type is a part of option before ':' */
5987 /* Parametric option has following syntax: 'Type: option = value' */
5988
5989 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5990 {
5991         struct param_opt_struct *data = get_parametrics(snum, type, option);
5992
5993         if (data && data->value && *data->value)
5994                 return lp_ulong(data->value);
5995
5996         return def;
5997 }
5998
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
6002 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
6003 {
6004         struct param_opt_struct *data = get_parametrics(snum, type, option);
6005
6006         if (data && data->value && *data->value)
6007                 return lp_bool(data->value);
6008
6009         return def;
6010 }
6011
6012 /* Return parametric option from a given service. Type is a part of option before ':' */
6013 /* Parametric option has following syntax: 'Type: option = value' */
6014
6015 int lp_parm_enum(int snum, const char *type, const char *option,
6016                  const struct enum_list *_enum, int def)
6017 {
6018         struct param_opt_struct *data = get_parametrics(snum, type, option);
6019
6020         if (data && data->value && *data->value && _enum)
6021                 return lp_enum(data->value, _enum);
6022
6023         return def;
6024 }
6025
6026
6027 /***************************************************************************
6028  Initialise a service to the defaults.
6029 ***************************************************************************/
6030
6031 static void init_service(struct service *pservice)
6032 {
6033         memset((char *)pservice, '\0', sizeof(struct service));
6034         copy_service(pservice, &sDefault, NULL);
6035 }
6036
6037
6038 /**
6039  * free a param_opts structure.
6040  * param_opts handling should be moved to talloc;
6041  * then this whole functions reduces to a TALLOC_FREE().
6042  */
6043
6044 static void free_param_opts(struct param_opt_struct **popts)
6045 {
6046         struct param_opt_struct *opt, *next_opt;
6047
6048         if (popts == NULL) {
6049                 return;
6050         }
6051
6052         if (*popts != NULL) {
6053                 DEBUG(5, ("Freeing parametrics:\n"));
6054         }
6055         opt = *popts;
6056         while (opt != NULL) {
6057                 string_free(&opt->key);
6058                 string_free(&opt->value);
6059                 TALLOC_FREE(opt->list);
6060                 next_opt = opt->next;
6061                 SAFE_FREE(opt);
6062                 opt = next_opt;
6063         }
6064         *popts = NULL;
6065 }
6066
6067 /***************************************************************************
6068  Free the dynamically allocated parts of a service struct.
6069 ***************************************************************************/
6070
6071 static void free_service(struct service *pservice)
6072 {
6073         if (!pservice)
6074                 return;
6075
6076         if (pservice->szService)
6077                 DEBUG(5, ("free_service: Freeing service %s\n",
6078                        pservice->szService));
6079
6080         free_parameters(pservice);
6081
6082         string_free(&pservice->szService);
6083         bitmap_free(pservice->copymap);
6084
6085         free_param_opts(&pservice->param_opt);
6086
6087         ZERO_STRUCTP(pservice);
6088 }
6089
6090
6091 /***************************************************************************
6092  remove a service indexed in the ServicePtrs array from the ServiceHash
6093  and free the dynamically allocated parts
6094 ***************************************************************************/
6095
6096 static void free_service_byindex(int idx)
6097 {
6098         if ( !LP_SNUM_OK(idx) ) 
6099                 return;
6100
6101         ServicePtrs[idx]->valid = False;
6102         invalid_services[num_invalid_services++] = idx;
6103
6104         /* we have to cleanup the hash record */
6105
6106         if (ServicePtrs[idx]->szService) {
6107                 char *canon_name = canonicalize_servicename(
6108                         ServicePtrs[idx]->szService );
6109
6110                 dbwrap_delete_bystring(ServiceHash, canon_name );
6111                 TALLOC_FREE(canon_name);
6112         }
6113
6114         free_service(ServicePtrs[idx]);
6115 }
6116
6117 /***************************************************************************
6118  Add a new service to the services array initialising it with the given 
6119  service. 
6120 ***************************************************************************/
6121
6122 static int add_a_service(const struct service *pservice, const char *name)
6123 {
6124         int i;
6125         struct service tservice;
6126         int num_to_alloc = iNumServices + 1;
6127
6128         tservice = *pservice;
6129
6130         /* it might already exist */
6131         if (name) {
6132                 i = getservicebyname(name, NULL);
6133                 if (i >= 0) {
6134                         /* Clean all parametric options for service */
6135                         /* They will be added during parsing again */
6136                         free_param_opts(&ServicePtrs[i]->param_opt);
6137                         return (i);
6138                 }
6139         }
6140
6141         /* find an invalid one */
6142         i = iNumServices;
6143         if (num_invalid_services > 0) {
6144                 i = invalid_services[--num_invalid_services];
6145         }
6146
6147         /* if not, then create one */
6148         if (i == iNumServices) {
6149                 struct service **tsp;
6150                 int *tinvalid;
6151
6152                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6153                 if (tsp == NULL) {
6154                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6155                         return (-1);
6156                 }
6157                 ServicePtrs = tsp;
6158                 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6159                 if (!ServicePtrs[iNumServices]) {
6160                         DEBUG(0,("add_a_service: out of memory!\n"));
6161                         return (-1);
6162                 }
6163                 iNumServices++;
6164
6165                 /* enlarge invalid_services here for now... */
6166                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6167                                              num_to_alloc);
6168                 if (tinvalid == NULL) {
6169                         DEBUG(0,("add_a_service: failed to enlarge "
6170                                  "invalid_services!\n"));
6171                         return (-1);
6172                 }
6173                 invalid_services = tinvalid;
6174         } else {
6175                 free_service_byindex(i);
6176         }
6177
6178         ServicePtrs[i]->valid = True;
6179
6180         init_service(ServicePtrs[i]);
6181         copy_service(ServicePtrs[i], &tservice, NULL);
6182         if (name)
6183                 string_set(&ServicePtrs[i]->szService, name);
6184
6185         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
6186                 i, ServicePtrs[i]->szService));
6187
6188         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6189                 return (-1);
6190         }
6191
6192         return (i);
6193 }
6194
6195 /***************************************************************************
6196   Convert a string to uppercase and remove whitespaces.
6197 ***************************************************************************/
6198
6199 static char *canonicalize_servicename(const char *src)
6200 {
6201         char *result;
6202
6203         if ( !src ) {
6204                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6205                 return NULL;
6206         }
6207
6208         result = talloc_strdup(talloc_tos(), src);
6209         SMB_ASSERT(result != NULL);
6210
6211         strlower_m(result);
6212         return result;
6213 }
6214
6215 /***************************************************************************
6216   Add a name/index pair for the services array to the hash table.
6217 ***************************************************************************/
6218
6219 static bool hash_a_service(const char *name, int idx)
6220 {
6221         char *canon_name;
6222
6223         if ( !ServiceHash ) {
6224                 DEBUG(10,("hash_a_service: creating servicehash\n"));
6225                 ServiceHash = db_open_rbt(NULL);
6226                 if ( !ServiceHash ) {
6227                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6228                         return False;
6229                 }
6230         }
6231
6232         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6233                 idx, name));
6234
6235         canon_name = canonicalize_servicename( name );
6236
6237         dbwrap_store_bystring(ServiceHash, canon_name,
6238                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
6239                               TDB_REPLACE);
6240
6241         TALLOC_FREE(canon_name);
6242
6243         return True;
6244 }
6245
6246 /***************************************************************************
6247  Add a new home service, with the specified home directory, defaults coming
6248  from service ifrom.
6249 ***************************************************************************/
6250
6251 bool lp_add_home(const char *pszHomename, int iDefaultService,
6252                  const char *user, const char *pszHomedir)
6253 {
6254         int i;
6255
6256         if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6257                         pszHomedir[0] == '\0') {
6258                 return false;
6259         }
6260
6261         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6262
6263         if (i < 0)
6264                 return (False);
6265
6266         if (!(*(ServicePtrs[iDefaultService]->szPath))
6267             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6268                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6269         }
6270
6271         if (!(*(ServicePtrs[i]->comment))) {
6272                 char *comment = NULL;
6273                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6274                         return false;
6275                 }
6276                 string_set(&ServicePtrs[i]->comment, comment);
6277                 SAFE_FREE(comment);
6278         }
6279
6280         /* set the browseable flag from the global default */
6281
6282         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6283         ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6284
6285         ServicePtrs[i]->autoloaded = True;
6286
6287         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
6288                user, ServicePtrs[i]->szPath ));
6289
6290         return (True);
6291 }
6292
6293 /***************************************************************************
6294  Add a new service, based on an old one.
6295 ***************************************************************************/
6296
6297 int lp_add_service(const char *pszService, int iDefaultService)
6298 {
6299         if (iDefaultService < 0) {
6300                 return add_a_service(&sDefault, pszService);
6301         }
6302
6303         return (add_a_service(ServicePtrs[iDefaultService], pszService));
6304 }
6305
6306 /***************************************************************************
6307  Add the IPC service.
6308 ***************************************************************************/
6309
6310 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6311 {
6312         char *comment = NULL;
6313         int i = add_a_service(&sDefault, ipc_name);
6314
6315         if (i < 0)
6316                 return (False);
6317
6318         if (asprintf(&comment, "IPC Service (%s)",
6319                                 Globals.szServerString) < 0) {
6320                 return (False);
6321         }
6322
6323         string_set(&ServicePtrs[i]->szPath, tmpdir());
6324         string_set(&ServicePtrs[i]->szUsername, "");
6325         string_set(&ServicePtrs[i]->comment, comment);
6326         string_set(&ServicePtrs[i]->fstype, "IPC");
6327         ServicePtrs[i]->iMaxConnections = 0;
6328         ServicePtrs[i]->bAvailable = True;
6329         ServicePtrs[i]->bRead_only = True;
6330         ServicePtrs[i]->bGuest_only = False;
6331         ServicePtrs[i]->bAdministrative_share = True;
6332         ServicePtrs[i]->bGuest_ok = guest_ok;
6333         ServicePtrs[i]->bPrint_ok = False;
6334         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6335
6336         DEBUG(3, ("adding IPC service\n"));
6337
6338         SAFE_FREE(comment);
6339         return (True);
6340 }
6341
6342 /***************************************************************************
6343  Add a new printer service, with defaults coming from service iFrom.
6344 ***************************************************************************/
6345
6346 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6347 {
6348         const char *comment = "From Printcap";
6349         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6350
6351         if (i < 0)
6352                 return (False);
6353
6354         /* note that we do NOT default the availability flag to True - */
6355         /* we take it from the default service passed. This allows all */
6356         /* dynamic printers to be disabled by disabling the [printers] */
6357         /* entry (if/when the 'available' keyword is implemented!).    */
6358
6359         /* the printer name is set to the service name. */
6360         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6361         string_set(&ServicePtrs[i]->comment, comment);
6362
6363         /* set the browseable flag from the gloabl default */
6364         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6365
6366         /* Printers cannot be read_only. */
6367         ServicePtrs[i]->bRead_only = False;
6368         /* No share modes on printer services. */
6369         ServicePtrs[i]->bShareModes = False;
6370         /* No oplocks on printer services. */
6371         ServicePtrs[i]->bOpLocks = False;
6372         /* Printer services must be printable. */
6373         ServicePtrs[i]->bPrint_ok = True;
6374
6375         DEBUG(3, ("adding printer service %s\n", pszPrintername));
6376
6377         return (True);
6378 }
6379
6380
6381 /***************************************************************************
6382  Check whether the given parameter name is valid.
6383  Parametric options (names containing a colon) are considered valid.
6384 ***************************************************************************/
6385
6386 bool lp_parameter_is_valid(const char *pszParmName)
6387 {
6388         return ((map_parameter(pszParmName) != -1) ||
6389                 (strchr(pszParmName, ':') != NULL));
6390 }
6391
6392 /***************************************************************************
6393  Check whether the given name is the name of a global parameter.
6394  Returns True for strings belonging to parameters of class
6395  P_GLOBAL, False for all other strings, also for parametric options
6396  and strings not belonging to any option.
6397 ***************************************************************************/
6398
6399 bool lp_parameter_is_global(const char *pszParmName)
6400 {
6401         int num = map_parameter(pszParmName);
6402
6403         if (num >= 0) {
6404                 return (parm_table[num].p_class == P_GLOBAL);
6405         }
6406
6407         return False;
6408 }
6409
6410 /**************************************************************************
6411  Check whether the given name is the canonical name of a parameter.
6412  Returns False if it is not a valid parameter Name.
6413  For parametric options, True is returned.
6414 **************************************************************************/
6415
6416 bool lp_parameter_is_canonical(const char *parm_name)
6417 {
6418         if (!lp_parameter_is_valid(parm_name)) {
6419                 return False;
6420         }
6421
6422         return (map_parameter(parm_name) ==
6423                 map_parameter_canonical(parm_name, NULL));
6424 }
6425
6426 /**************************************************************************
6427  Determine the canonical name for a parameter.
6428  Indicate when it is an inverse (boolean) synonym instead of a
6429  "usual" synonym.
6430 **************************************************************************/
6431
6432 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6433                                bool *inverse)
6434 {
6435         int num;
6436
6437         if (!lp_parameter_is_valid(parm_name)) {
6438                 *canon_parm = NULL;
6439                 return False;
6440         }
6441
6442         num = map_parameter_canonical(parm_name, inverse);
6443         if (num < 0) {
6444                 /* parametric option */
6445                 *canon_parm = parm_name;
6446         } else {
6447                 *canon_parm = parm_table[num].label;
6448         }
6449
6450         return True;
6451
6452 }
6453
6454 /**************************************************************************
6455  Determine the canonical name for a parameter.
6456  Turn the value given into the inverse boolean expression when
6457  the synonym is an invers boolean synonym.
6458
6459  Return True if parm_name is a valid parameter name and
6460  in case it is an invers boolean synonym, if the val string could
6461  successfully be converted to the reverse bool.
6462  Return false in all other cases.
6463 **************************************************************************/
6464
6465 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6466                                           const char *val,
6467                                           const char **canon_parm,
6468                                           const char **canon_val)
6469 {
6470         int num;
6471         bool inverse;
6472
6473         if (!lp_parameter_is_valid(parm_name)) {
6474                 *canon_parm = NULL;
6475                 *canon_val = NULL;
6476                 return False;
6477         }
6478
6479         num = map_parameter_canonical(parm_name, &inverse);
6480         if (num < 0) {
6481                 /* parametric option */
6482                 *canon_parm = parm_name;
6483                 *canon_val = val;
6484         } else {
6485                 *canon_parm = parm_table[num].label;
6486                 if (inverse) {
6487                         if (!lp_invert_boolean(val, canon_val)) {
6488                                 *canon_val = NULL;
6489                                 return False;
6490                         }
6491                 } else {
6492                         *canon_val = val;
6493                 }
6494         }
6495
6496         return True;
6497 }
6498
6499 /***************************************************************************
6500  Map a parameter's string representation to something we can use. 
6501  Returns False if the parameter string is not recognised, else TRUE.
6502 ***************************************************************************/
6503
6504 static int map_parameter(const char *pszParmName)
6505 {
6506         int iIndex;
6507
6508         if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6509                 return (-1);
6510
6511         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6512                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6513                         return (iIndex);
6514
6515         /* Warn only if it isn't parametric option */
6516         if (strchr(pszParmName, ':') == NULL)
6517                 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6518         /* We do return 'fail' for parametric options as well because they are
6519            stored in different storage
6520          */
6521         return (-1);
6522 }
6523
6524 /***************************************************************************
6525  Map a parameter's string representation to the index of the canonical
6526  form of the parameter (it might be a synonym).
6527  Returns -1 if the parameter string is not recognised.
6528 ***************************************************************************/
6529
6530 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6531 {
6532         int parm_num, canon_num;
6533         bool loc_inverse = False;
6534
6535         parm_num = map_parameter(pszParmName);
6536         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6537                 /* invalid, parametric or no canidate for synonyms ... */
6538                 goto done;
6539         }
6540
6541         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6542                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6543                         parm_num = canon_num;
6544                         goto done;
6545                 }
6546         }
6547
6548 done:
6549         if (inverse != NULL) {
6550                 *inverse = loc_inverse;
6551         }
6552         return parm_num;
6553 }
6554
6555 /***************************************************************************
6556  return true if parameter number parm1 is a synonym of parameter
6557  number parm2 (parm2 being the principal name).
6558  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6559  False otherwise.
6560 ***************************************************************************/
6561
6562 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6563 {
6564         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6565             (parm_table[parm1].flags & FLAG_HIDE) &&
6566             !(parm_table[parm2].flags & FLAG_HIDE))
6567         {
6568                 if (inverse != NULL) {
6569                         if ((parm_table[parm1].type == P_BOOLREV) &&
6570                             (parm_table[parm2].type == P_BOOL))
6571                         {
6572                                 *inverse = True;
6573                         } else {
6574                                 *inverse = False;
6575                         }
6576                 }
6577                 return True;
6578         }
6579         return False;
6580 }
6581
6582 /***************************************************************************
6583  Show one parameter's name, type, [values,] and flags.
6584  (helper functions for show_parameter_list)
6585 ***************************************************************************/
6586
6587 static void show_parameter(int parmIndex)
6588 {
6589         int enumIndex, flagIndex;
6590         int parmIndex2;
6591         bool hadFlag;
6592         bool hadSyn;
6593         bool inverse;
6594         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6595                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6596                 "P_ENUM", "P_SEP"};
6597         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6598                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6599                 FLAG_HIDE, FLAG_DOS_STRING};
6600         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6601                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6602                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6603
6604         printf("%s=%s", parm_table[parmIndex].label,
6605                type[parm_table[parmIndex].type]);
6606         if (parm_table[parmIndex].type == P_ENUM) {
6607                 printf(",");
6608                 for (enumIndex=0;
6609                      parm_table[parmIndex].enum_list[enumIndex].name;
6610                      enumIndex++)
6611                 {
6612                         printf("%s%s",
6613                                enumIndex ? "|" : "",
6614                                parm_table[parmIndex].enum_list[enumIndex].name);
6615                 }
6616         }
6617         printf(",");
6618         hadFlag = False;
6619         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6620                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6621                         printf("%s%s",
6622                                 hadFlag ? "|" : "",
6623                                 flag_names[flagIndex]);
6624                         hadFlag = True;
6625                 }
6626         }
6627
6628         /* output synonyms */
6629         hadSyn = False;
6630         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6631                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6632                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6633                                parm_table[parmIndex2].label);
6634                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6635                         if (!hadSyn) {
6636                                 printf(" (synonyms: ");
6637                                 hadSyn = True;
6638                         } else {
6639                                 printf(", ");
6640                         }
6641                         printf("%s%s", parm_table[parmIndex2].label,
6642                                inverse ? "[i]" : "");
6643                 }
6644         }
6645         if (hadSyn) {
6646                 printf(")");
6647         }
6648
6649         printf("\n");
6650 }
6651
6652 /***************************************************************************
6653  Show all parameter's name, type, [values,] and flags.
6654 ***************************************************************************/
6655
6656 void show_parameter_list(void)
6657 {
6658         int classIndex, parmIndex;
6659         const char *section_names[] = { "local", "global", NULL};
6660
6661         for (classIndex=0; section_names[classIndex]; classIndex++) {
6662                 printf("[%s]\n", section_names[classIndex]);
6663                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6664                         if (parm_table[parmIndex].p_class == classIndex) {
6665                                 show_parameter(parmIndex);
6666                         }
6667                 }
6668         }
6669 }
6670
6671 /***************************************************************************
6672  Check if a given string correctly represents a boolean value.
6673 ***************************************************************************/
6674
6675 bool lp_string_is_valid_boolean(const char *parm_value)
6676 {
6677         return set_boolean(parm_value, NULL);
6678 }
6679
6680 /***************************************************************************
6681  Get the standard string representation of a boolean value ("yes" or "no")
6682 ***************************************************************************/
6683
6684 static const char *get_boolean(bool bool_value)
6685 {
6686         static const char *yes_str = "yes";
6687         static const char *no_str = "no";
6688
6689         return (bool_value ? yes_str : no_str);
6690 }
6691
6692 /***************************************************************************
6693  Provide the string of the negated boolean value associated to the boolean
6694  given as a string. Returns False if the passed string does not correctly
6695  represent a boolean.
6696 ***************************************************************************/
6697
6698 bool lp_invert_boolean(const char *str, const char **inverse_str)
6699 {
6700         bool val;
6701
6702         if (!set_boolean(str, &val)) {
6703                 return False;
6704         }
6705
6706         *inverse_str = get_boolean(!val);
6707         return True;
6708 }
6709
6710 /***************************************************************************
6711  Provide the canonical string representation of a boolean value given
6712  as a string. Return True on success, False if the string given does
6713  not correctly represent a boolean.
6714 ***************************************************************************/
6715
6716 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6717 {
6718         bool val;
6719
6720         if (!set_boolean(str, &val)) {
6721                 return False;
6722         }
6723
6724         *canon_str = get_boolean(val);
6725         return True;
6726 }
6727
6728 /***************************************************************************
6729 Find a service by name. Otherwise works like get_service.
6730 ***************************************************************************/
6731
6732 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6733 {
6734         int iService = -1;
6735         char *canon_name;
6736         TDB_DATA data;
6737
6738         if (ServiceHash == NULL) {
6739                 return -1;
6740         }
6741
6742         canon_name = canonicalize_servicename(pszServiceName);
6743
6744         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6745
6746         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6747                 iService = *(int *)data.dptr;
6748         }
6749
6750         TALLOC_FREE(canon_name);
6751
6752         if ((iService != -1) && (LP_SNUM_OK(iService))
6753             && (pserviceDest != NULL)) {
6754                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6755         }
6756
6757         return (iService);
6758 }
6759
6760 /***************************************************************************
6761  Copy a service structure to another.
6762  If pcopymapDest is NULL then copy all fields
6763 ***************************************************************************/
6764
6765 /**
6766  * Add a parametric option to a param_opt_struct,
6767  * replacing old value, if already present.
6768  */
6769 static void set_param_opt(struct param_opt_struct **opt_list,
6770                           const char *opt_name,
6771                           const char *opt_value)
6772 {
6773         struct param_opt_struct *new_opt, *opt;
6774         bool not_added;
6775
6776         if (opt_list == NULL) {
6777                 return;
6778         }
6779
6780         opt = *opt_list;
6781         not_added = true;
6782
6783         /* Traverse destination */
6784         while (opt) {
6785                 /* If we already have same option, override it */
6786                 if (strwicmp(opt->key, opt_name) == 0) {
6787                         string_free(&opt->value);
6788                         TALLOC_FREE(opt->list);
6789                         opt->value = SMB_STRDUP(opt_value);
6790                         not_added = false;
6791                         break;
6792                 }
6793                 opt = opt->next;
6794         }
6795         if (not_added) {
6796             new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6797             new_opt->key = SMB_STRDUP(opt_name);
6798             new_opt->value = SMB_STRDUP(opt_value);
6799             new_opt->list = NULL;
6800             DLIST_ADD(*opt_list, new_opt);
6801         }
6802 }
6803
6804 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6805                          struct bitmap *pcopymapDest)
6806 {
6807         int i;
6808         bool bcopyall = (pcopymapDest == NULL);
6809         struct param_opt_struct *data;
6810
6811         for (i = 0; parm_table[i].label; i++)
6812                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6813                     (bcopyall || bitmap_query(pcopymapDest,i))) {
6814                         void *def_ptr = parm_table[i].ptr;
6815                         void *src_ptr =
6816                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6817                                                                     &sDefault);
6818                         void *dest_ptr =
6819                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6820                                                                   &sDefault);
6821
6822                         switch (parm_table[i].type) {
6823                                 case P_BOOL:
6824                                 case P_BOOLREV:
6825                                         *(bool *)dest_ptr = *(bool *)src_ptr;
6826                                         break;
6827
6828                                 case P_INTEGER:
6829                                 case P_ENUM:
6830                                 case P_OCTAL:
6831                                         *(int *)dest_ptr = *(int *)src_ptr;
6832                                         break;
6833
6834                                 case P_CHAR:
6835                                         *(char *)dest_ptr = *(char *)src_ptr;
6836                                         break;
6837
6838                                 case P_STRING:
6839                                         string_set((char **)dest_ptr,
6840                                                    *(char **)src_ptr);
6841                                         break;
6842
6843                                 case P_USTRING:
6844                                         string_set((char **)dest_ptr,
6845                                                    *(char **)src_ptr);
6846                                         strupper_m(*(char **)dest_ptr);
6847                                         break;
6848                                 case P_LIST:
6849                                         TALLOC_FREE(*((char ***)dest_ptr));
6850                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
6851                                                       *(const char ***)src_ptr);
6852                                         break;
6853                                 default:
6854                                         break;
6855                         }
6856                 }
6857
6858         if (bcopyall) {
6859                 init_copymap(pserviceDest);
6860                 if (pserviceSource->copymap)
6861                         bitmap_copy(pserviceDest->copymap,
6862                                     pserviceSource->copymap);
6863         }
6864
6865         data = pserviceSource->param_opt;
6866         while (data) {
6867                 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6868                 data = data->next;
6869         }
6870 }
6871
6872 /***************************************************************************
6873 Check a service for consistency. Return False if the service is in any way
6874 incomplete or faulty, else True.
6875 ***************************************************************************/
6876
6877 bool service_ok(int iService)
6878 {
6879         bool bRetval;
6880
6881         bRetval = True;
6882         if (ServicePtrs[iService]->szService[0] == '\0') {
6883                 DEBUG(0, ("The following message indicates an internal error:\n"));
6884                 DEBUG(0, ("No service name in service entry.\n"));
6885                 bRetval = False;
6886         }
6887
6888         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6889         /* I can't see why you'd want a non-printable printer service...        */
6890         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6891                 if (!ServicePtrs[iService]->bPrint_ok) {
6892                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6893                                ServicePtrs[iService]->szService));
6894                         ServicePtrs[iService]->bPrint_ok = True;
6895                 }
6896                 /* [printers] service must also be non-browsable. */
6897                 if (ServicePtrs[iService]->bBrowseable)
6898                         ServicePtrs[iService]->bBrowseable = False;
6899         }
6900
6901         if (ServicePtrs[iService]->szPath[0] == '\0' &&
6902             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6903             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6904             ) {
6905                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6906                         ServicePtrs[iService]->szService));
6907                 ServicePtrs[iService]->bAvailable = False;
6908         }
6909
6910         /* If a service is flagged unavailable, log the fact at level 1. */
6911         if (!ServicePtrs[iService]->bAvailable)
6912                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6913                           ServicePtrs[iService]->szService));
6914
6915         return (bRetval);
6916 }
6917
6918 static struct smbconf_ctx *lp_smbconf_ctx(void)
6919 {
6920         WERROR werr;
6921         static struct smbconf_ctx *conf_ctx = NULL;
6922
6923         if (conf_ctx == NULL) {
6924                 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6925                 if (!W_ERROR_IS_OK(werr)) {
6926                         DEBUG(1, ("error initializing registry configuration: "
6927                                   "%s\n", win_errstr(werr)));
6928                         conf_ctx = NULL;
6929                 }
6930         }
6931
6932         return conf_ctx;
6933 }
6934
6935 static bool process_smbconf_service(struct smbconf_service *service)
6936 {
6937         uint32_t count;
6938         bool ret;
6939
6940         if (service == NULL) {
6941                 return false;
6942         }
6943
6944         ret = do_section(service->name, NULL);
6945         if (ret != true) {
6946                 return false;
6947         }
6948         for (count = 0; count < service->num_params; count++) {
6949                 ret = do_parameter(service->param_names[count],
6950                                    service->param_values[count],
6951                                    NULL);
6952                 if (ret != true) {
6953                         return false;
6954                 }
6955         }
6956         if (iServiceIndex >= 0) {
6957                 return service_ok(iServiceIndex);
6958         }
6959         return true;
6960 }
6961
6962 /**
6963  * load a service from registry and activate it
6964  */
6965 bool process_registry_service(const char *service_name)
6966 {
6967         WERROR werr;
6968         struct smbconf_service *service = NULL;
6969         TALLOC_CTX *mem_ctx = talloc_stackframe();
6970         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6971         bool ret = false;
6972
6973         if (conf_ctx == NULL) {
6974                 goto done;
6975         }
6976
6977         DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6978
6979         if (!smbconf_share_exists(conf_ctx, service_name)) {
6980                 /*
6981                  * Registry does not contain data for this service (yet),
6982                  * but make sure lp_load doesn't return false.
6983                  */
6984                 ret = true;
6985                 goto done;
6986         }
6987
6988         werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6989         if (!W_ERROR_IS_OK(werr)) {
6990                 goto done;
6991         }
6992
6993         ret = process_smbconf_service(service);
6994         if (!ret) {
6995                 goto done;
6996         }
6997
6998         /* store the csn */
6999         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7000
7001 done:
7002         TALLOC_FREE(mem_ctx);
7003         return ret;
7004 }
7005
7006 /*
7007  * process_registry_globals
7008  */
7009 static bool process_registry_globals(void)
7010 {
7011         bool ret;
7012
7013         add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
7014
7015         ret = do_parameter("registry shares", "yes", NULL);
7016         if (!ret) {
7017                 return ret;
7018         }
7019
7020         return process_registry_service(GLOBAL_NAME);
7021 }
7022
7023 bool process_registry_shares(void)
7024 {
7025         WERROR werr;
7026         uint32_t count;
7027         struct smbconf_service **service = NULL;
7028         uint32_t num_shares = 0;
7029         TALLOC_CTX *mem_ctx = talloc_stackframe();
7030         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7031         bool ret = false;
7032
7033         if (conf_ctx == NULL) {
7034                 goto done;
7035         }
7036
7037         werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
7038         if (!W_ERROR_IS_OK(werr)) {
7039                 goto done;
7040         }
7041
7042         ret = true;
7043
7044         for (count = 0; count < num_shares; count++) {
7045                 if (strequal(service[count]->name, GLOBAL_NAME)) {
7046                         continue;
7047                 }
7048                 ret = process_smbconf_service(service[count]);
7049                 if (!ret) {
7050                         goto done;
7051                 }
7052         }
7053
7054         /* store the csn */
7055         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
7056
7057 done:
7058         TALLOC_FREE(mem_ctx);
7059         return ret;
7060 }
7061
7062 #define MAX_INCLUDE_DEPTH 100
7063
7064 static uint8_t include_depth;
7065
7066 static struct file_lists {
7067         struct file_lists *next;
7068         char *name;
7069         char *subfname;
7070         time_t modtime;
7071 } *file_lists = NULL;
7072
7073 /*******************************************************************
7074  Keep a linked list of all config files so we know when one has changed 
7075  it's date and needs to be reloaded.
7076 ********************************************************************/
7077
7078 static void add_to_file_list(const char *fname, const char *subfname)
7079 {
7080         struct file_lists *f = file_lists;
7081
7082         while (f) {
7083                 if (f->name && !strcmp(f->name, fname))
7084                         break;
7085                 f = f->next;
7086         }
7087
7088         if (!f) {
7089                 f = SMB_MALLOC_P(struct file_lists);
7090                 if (!f)
7091                         return;
7092                 f->next = file_lists;
7093                 f->name = SMB_STRDUP(fname);
7094                 if (!f->name) {
7095                         SAFE_FREE(f);
7096                         return;
7097                 }
7098                 f->subfname = SMB_STRDUP(subfname);
7099                 if (!f->subfname) {
7100                         SAFE_FREE(f->name);
7101                         SAFE_FREE(f);
7102                         return;
7103                 }
7104                 file_lists = f;
7105                 f->modtime = file_modtime(subfname);
7106         } else {
7107                 time_t t = file_modtime(subfname);
7108                 if (t)
7109                         f->modtime = t;
7110         }
7111         return;
7112 }
7113
7114 /**
7115  * Free the file lists
7116  */
7117 static void free_file_list(void)
7118 {
7119         struct file_lists *f;
7120         struct file_lists *next;
7121
7122         f = file_lists;
7123         while( f ) {
7124                 next = f->next;
7125                 SAFE_FREE( f->name );
7126                 SAFE_FREE( f->subfname );
7127                 SAFE_FREE( f );
7128                 f = next;
7129         }
7130         file_lists = NULL;
7131 }
7132
7133
7134 /**
7135  * Utility function for outsiders to check if we're running on registry.
7136  */
7137 bool lp_config_backend_is_registry(void)
7138 {
7139         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7140 }
7141
7142 /**
7143  * Utility function to check if the config backend is FILE.
7144  */
7145 bool lp_config_backend_is_file(void)
7146 {
7147         return (lp_config_backend() == CONFIG_BACKEND_FILE);
7148 }
7149
7150 /*******************************************************************
7151  Check if a config file has changed date.
7152 ********************************************************************/
7153
7154 bool lp_file_list_changed(void)
7155 {
7156         struct file_lists *f = file_lists;
7157
7158         DEBUG(6, ("lp_file_list_changed()\n"));
7159
7160         while (f) {
7161                 time_t mod_time;
7162
7163                 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7164                         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7165
7166                         if (conf_ctx == NULL) {
7167                                 return false;
7168                         }
7169                         if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7170                                             NULL))
7171                         {
7172                                 DEBUGADD(6, ("registry config changed\n"));
7173                                 return true;
7174                         }
7175                 } else {
7176                         char *n2 = NULL;
7177                         n2 = talloc_sub_basic(talloc_tos(),
7178                                               get_current_username(),
7179                                               current_user_info.domain,
7180                                               f->name);
7181                         if (!n2) {
7182                                 return false;
7183                         }
7184                         DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
7185                                      f->name, n2, ctime(&f->modtime)));
7186
7187                         mod_time = file_modtime(n2);
7188
7189                         if (mod_time &&
7190                             ((f->modtime != mod_time) ||
7191                              (f->subfname == NULL) ||
7192                              (strcmp(n2, f->subfname) != 0)))
7193                         {
7194                                 DEBUGADD(6,
7195                                          ("file %s modified: %s\n", n2,
7196                                           ctime(&mod_time)));
7197                                 f->modtime = mod_time;
7198                                 SAFE_FREE(f->subfname);
7199                                 f->subfname = SMB_STRDUP(n2);
7200                                 TALLOC_FREE(n2);
7201                                 return true;
7202                         }
7203                         TALLOC_FREE(n2);
7204                 }
7205                 f = f->next;
7206         }
7207         return (False);
7208 }
7209
7210
7211 /***************************************************************************
7212  Run standard_sub_basic on netbios name... needed because global_myname
7213  is not accessed through any lp_ macro.
7214  Note: We must *NOT* use string_set() here as ptr points to global_myname.
7215 ***************************************************************************/
7216
7217 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7218 {
7219         bool ret;
7220         char *netbios_name = talloc_sub_basic(
7221                 talloc_tos(), get_current_username(), current_user_info.domain,
7222                 pszParmValue);
7223
7224         ret = set_global_myname(netbios_name);
7225         TALLOC_FREE(netbios_name);
7226         string_set(&Globals.szNetbiosName,global_myname());
7227
7228         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7229                global_myname()));
7230
7231         return ret;
7232 }
7233
7234 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7235 {
7236         if (strcmp(*ptr, pszParmValue) != 0) {
7237                 string_set(ptr, pszParmValue);
7238                 init_iconv();
7239         }
7240         return True;
7241 }
7242
7243
7244
7245 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7246 {
7247         bool ret;
7248
7249         ret = set_global_myworkgroup(pszParmValue);
7250         string_set(&Globals.szWorkgroup,lp_workgroup());
7251
7252         return ret;
7253 }
7254
7255 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7256 {
7257         bool ret;
7258
7259         ret = set_global_scope(pszParmValue);
7260         string_set(&Globals.szNetbiosScope,global_scope());
7261
7262         return ret;
7263 }
7264
7265 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7266 {
7267         TALLOC_FREE(Globals.szNetbiosAliases);
7268         Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7269         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7270 }
7271
7272 /***************************************************************************
7273  Handle the include operation.
7274 ***************************************************************************/
7275 static bool bAllowIncludeRegistry = true;
7276
7277 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7278 {
7279         char *fname;
7280
7281         if (include_depth >= MAX_INCLUDE_DEPTH) {
7282                 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7283                           include_depth));
7284                 return false;
7285         }
7286
7287         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7288                 if (!bAllowIncludeRegistry) {
7289                         return true;
7290                 }
7291                 if (bInGlobalSection) {
7292                         bool ret;
7293                         include_depth++;
7294                         ret = process_registry_globals();
7295                         include_depth--;
7296                         return ret;
7297                 } else {
7298                         DEBUG(1, ("\"include = registry\" only effective "
7299                                   "in %s section\n", GLOBAL_NAME));
7300                         return false;
7301                 }
7302         }
7303
7304         fname = talloc_sub_basic(talloc_tos(), get_current_username(),
7305                                  current_user_info.domain,
7306                                  pszParmValue);
7307
7308         add_to_file_list(pszParmValue, fname);
7309
7310         string_set(ptr, fname);
7311
7312         if (file_exist(fname)) {
7313                 bool ret;
7314                 include_depth++;
7315                 ret = pm_process(fname, do_section, do_parameter, NULL);
7316                 include_depth--;
7317                 TALLOC_FREE(fname);
7318                 return ret;
7319         }
7320
7321         DEBUG(2, ("Can't find include file %s\n", fname));
7322         TALLOC_FREE(fname);
7323         return true;
7324 }
7325
7326 /***************************************************************************
7327  Handle the interpretation of the copy parameter.
7328 ***************************************************************************/
7329
7330 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7331 {
7332         bool bRetval;
7333         int iTemp;
7334         struct service serviceTemp;
7335
7336         string_set(ptr, pszParmValue);
7337
7338         init_service(&serviceTemp);
7339
7340         bRetval = False;
7341
7342         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7343
7344         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7345                 if (iTemp == iServiceIndex) {
7346                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7347                 } else {
7348                         copy_service(ServicePtrs[iServiceIndex],
7349                                      &serviceTemp,
7350                                      ServicePtrs[iServiceIndex]->copymap);
7351                         bRetval = True;
7352                 }
7353         } else {
7354                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7355                 bRetval = False;
7356         }
7357
7358         free_service(&serviceTemp);
7359         return (bRetval);
7360 }
7361
7362 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7363 {
7364         Globals.ldap_debug_level = lp_int(pszParmValue);
7365         init_ldap_debugging();
7366         return true;
7367 }
7368
7369 /***************************************************************************
7370  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
7371  parameters is:
7372
7373  [global]
7374
7375         idmap uid = 1000-1999
7376         idmap gid = 700-899
7377
7378  We only do simple parsing checks here.  The strings are parsed into useful
7379  structures in the idmap daemon code.
7380
7381 ***************************************************************************/
7382
7383 /* Some lp_ routines to return idmap [ug]id information */
7384
7385 static uid_t idmap_uid_low, idmap_uid_high;
7386 static gid_t idmap_gid_low, idmap_gid_high;
7387
7388 bool lp_idmap_uid(uid_t *low, uid_t *high)
7389 {
7390         if (idmap_uid_low == 0 || idmap_uid_high == 0)
7391                 return False;
7392
7393         if (low)
7394                 *low = idmap_uid_low;
7395
7396         if (high)
7397                 *high = idmap_uid_high;
7398
7399         return True;
7400 }
7401
7402 bool lp_idmap_gid(gid_t *low, gid_t *high)
7403 {
7404         if (idmap_gid_low == 0 || idmap_gid_high == 0)
7405                 return False;
7406
7407         if (low)
7408                 *low = idmap_gid_low;
7409
7410         if (high)
7411                 *high = idmap_gid_high;
7412
7413         return True;
7414 }
7415
7416 /* Do some simple checks on "idmap [ug]id" parameter values */
7417
7418 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7419 {
7420         uint32 low, high;
7421
7422         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7423                 return False;
7424
7425         /* Parse OK */
7426
7427         string_set(ptr, pszParmValue);
7428
7429         idmap_uid_low = low;
7430         idmap_uid_high = high;
7431
7432         return True;
7433 }
7434
7435 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7436 {
7437         uint32 low, high;
7438
7439         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7440                 return False;
7441
7442         /* Parse OK */
7443
7444         string_set(ptr, pszParmValue);
7445
7446         idmap_gid_low = low;
7447         idmap_gid_high = high;
7448
7449         return True;
7450 }
7451
7452 /***************************************************************************
7453  Handle the DEBUG level list.
7454 ***************************************************************************/
7455
7456 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7457 {
7458         string_set(ptr, pszParmValueIn);
7459         return debug_parse_levels(pszParmValueIn);
7460 }
7461
7462 /***************************************************************************
7463  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7464 ***************************************************************************/
7465
7466 static const char *append_ldap_suffix( const char *str )
7467 {
7468         const char *suffix_string;
7469
7470
7471         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7472                                         Globals.szLdapSuffix );
7473         if ( !suffix_string ) {
7474                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7475                 return "";
7476         }
7477
7478         return suffix_string;
7479 }
7480
7481 const char *lp_ldap_machine_suffix(void)
7482 {
7483         if (Globals.szLdapMachineSuffix[0])
7484                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7485
7486         return lp_string(Globals.szLdapSuffix);
7487 }
7488
7489 const char *lp_ldap_user_suffix(void)
7490 {
7491         if (Globals.szLdapUserSuffix[0])
7492                 return append_ldap_suffix(Globals.szLdapUserSuffix);
7493
7494         return lp_string(Globals.szLdapSuffix);
7495 }
7496
7497 const char *lp_ldap_group_suffix(void)
7498 {
7499         if (Globals.szLdapGroupSuffix[0])
7500                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7501
7502         return lp_string(Globals.szLdapSuffix);
7503 }
7504
7505 const char *lp_ldap_idmap_suffix(void)
7506 {
7507         if (Globals.szLdapIdmapSuffix[0])
7508                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7509
7510         return lp_string(Globals.szLdapSuffix);
7511 }
7512
7513 /****************************************************************************
7514  set the value for a P_ENUM
7515  ***************************************************************************/
7516
7517 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7518                               int *ptr )
7519 {
7520         int i;
7521
7522         for (i = 0; parm->enum_list[i].name; i++) {
7523                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7524                         *ptr = parm->enum_list[i].value;
7525                         return;
7526                 }
7527         }
7528         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7529                   pszParmValue, parm->label));
7530 }
7531
7532 /***************************************************************************
7533 ***************************************************************************/
7534
7535 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7536 {
7537         static int parm_num = -1;
7538         struct service *s;
7539
7540         if ( parm_num == -1 )
7541                 parm_num = map_parameter( "printing" );
7542
7543         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7544
7545         if ( snum < 0 )
7546                 s = &sDefault;
7547         else
7548                 s = ServicePtrs[snum];
7549
7550         init_printer_values( s );
7551
7552         return True;
7553 }
7554
7555
7556 /***************************************************************************
7557  Initialise a copymap.
7558 ***************************************************************************/
7559
7560 static void init_copymap(struct service *pservice)
7561 {
7562         int i;
7563         if (pservice->copymap) {
7564                 bitmap_free(pservice->copymap);
7565         }
7566         pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7567         if (!pservice->copymap)
7568                 DEBUG(0,
7569                       ("Couldn't allocate copymap!! (size %d)\n",
7570                        (int)NUMPARAMETERS));
7571         else
7572                 for (i = 0; i < NUMPARAMETERS; i++)
7573                         bitmap_set(pservice->copymap, i);
7574 }
7575
7576 /***************************************************************************
7577  Return the local pointer to a parameter given a service struct and the
7578  pointer into the default structure.
7579 ***************************************************************************/
7580
7581 static void *lp_local_ptr(struct service *service, void *ptr)
7582 {
7583         return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7584 }
7585
7586 /***************************************************************************
7587  Return the local pointer to a parameter given the service number and the 
7588  pointer into the default structure.
7589 ***************************************************************************/
7590
7591 void *lp_local_ptr_by_snum(int snum, void *ptr)
7592 {
7593         return lp_local_ptr(ServicePtrs[snum], ptr);
7594 }
7595
7596 /***************************************************************************
7597  Process a parameter for a particular service number. If snum < 0
7598  then assume we are in the globals.
7599 ***************************************************************************/
7600
7601 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7602 {
7603         int parmnum, i;
7604         void *parm_ptr = NULL;  /* where we are going to store the result */
7605         void *def_ptr = NULL;
7606         struct param_opt_struct **opt_list;
7607
7608         parmnum = map_parameter(pszParmName);
7609
7610         if (parmnum < 0) {
7611                 if (strchr(pszParmName, ':') == NULL) {
7612                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7613                                   pszParmName));
7614                         return (True);
7615                 }
7616
7617                 /*
7618                  * We've got a parametric option
7619                  */
7620
7621                 opt_list = (snum < 0)
7622                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7623                 set_param_opt(opt_list, pszParmName, pszParmValue);
7624
7625                 return (True);
7626         }
7627
7628         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7629                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7630                           pszParmName));
7631         }
7632
7633         def_ptr = parm_table[parmnum].ptr;
7634
7635         /* we might point at a service, the default service or a global */
7636         if (snum < 0) {
7637                 parm_ptr = def_ptr;
7638         } else {
7639                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7640                         DEBUG(0,
7641                               ("Global parameter %s found in service section!\n",
7642                                pszParmName));
7643                         return (True);
7644                 }
7645                 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7646         }
7647
7648         if (snum >= 0) {
7649                 if (!ServicePtrs[snum]->copymap)
7650                         init_copymap(ServicePtrs[snum]);
7651
7652                 /* this handles the aliases - set the copymap for other entries with
7653                    the same data pointer */
7654                 for (i = 0; parm_table[i].label; i++)
7655                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7656                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7657         }
7658
7659         /* if it is a special case then go ahead */
7660         if (parm_table[parmnum].special) {
7661                 return parm_table[parmnum].special(snum, pszParmValue,
7662                                                    (char **)parm_ptr);
7663         }
7664
7665         /* now switch on the type of variable it is */
7666         switch (parm_table[parmnum].type)
7667         {
7668                 case P_BOOL:
7669                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7670                         break;
7671
7672                 case P_BOOLREV:
7673                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7674                         break;
7675
7676                 case P_INTEGER:
7677                         *(int *)parm_ptr = lp_int(pszParmValue);
7678                         break;
7679
7680                 case P_CHAR:
7681                         *(char *)parm_ptr = *pszParmValue;
7682                         break;
7683
7684                 case P_OCTAL:
7685                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7686                         if ( i != 1 ) {
7687                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7688                         }
7689                         break;
7690
7691                 case P_LIST:
7692                         TALLOC_FREE(*((char ***)parm_ptr));
7693                         *(char ***)parm_ptr = str_list_make_v3(
7694                                 talloc_autofree_context(), pszParmValue, NULL);
7695                         break;
7696
7697                 case P_STRING:
7698                         string_set((char **)parm_ptr, pszParmValue);
7699                         break;
7700
7701                 case P_USTRING:
7702                         string_set((char **)parm_ptr, pszParmValue);
7703                         strupper_m(*(char **)parm_ptr);
7704                         break;
7705
7706                 case P_ENUM:
7707                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7708                         break;
7709                 case P_SEP:
7710                         break;
7711         }
7712
7713         return (True);
7714 }
7715
7716 /***************************************************************************
7717  Process a parameter.
7718 ***************************************************************************/
7719
7720 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7721                          void *userdata)
7722 {
7723         if (!bInGlobalSection && bGlobalOnly)
7724                 return (True);
7725
7726         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7727
7728         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7729                                 pszParmName, pszParmValue));
7730 }
7731
7732 /***************************************************************************
7733  Print a parameter of the specified type.
7734 ***************************************************************************/
7735
7736 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7737 {
7738         int i;
7739         switch (p->type)
7740         {
7741                 case P_ENUM:
7742                         for (i = 0; p->enum_list[i].name; i++) {
7743                                 if (*(int *)ptr == p->enum_list[i].value) {
7744                                         fprintf(f, "%s",
7745                                                 p->enum_list[i].name);
7746                                         break;
7747                                 }
7748                         }
7749                         break;
7750
7751                 case P_BOOL:
7752                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7753                         break;
7754
7755                 case P_BOOLREV:
7756                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7757                         break;
7758
7759                 case P_INTEGER:
7760                         fprintf(f, "%d", *(int *)ptr);
7761                         break;
7762
7763                 case P_CHAR:
7764                         fprintf(f, "%c", *(char *)ptr);
7765                         break;
7766
7767                 case P_OCTAL: {
7768                         char *o = octal_string(*(int *)ptr);
7769                         fprintf(f, "%s", o);
7770                         TALLOC_FREE(o);
7771                         break;
7772                 }
7773
7774                 case P_LIST:
7775                         if ((char ***)ptr && *(char ***)ptr) {
7776                                 char **list = *(char ***)ptr;
7777                                 for (; *list; list++) {
7778                                         /* surround strings with whitespace in double quotes */
7779                                         if ( strchr_m( *list, ' ' ) )
7780                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7781                                         else
7782                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7783                                 }
7784                         }
7785                         break;
7786
7787                 case P_STRING:
7788                 case P_USTRING:
7789                         if (*(char **)ptr) {
7790                                 fprintf(f, "%s", *(char **)ptr);
7791                         }
7792                         break;
7793                 case P_SEP:
7794                         break;
7795         }
7796 }
7797
7798 /***************************************************************************
7799  Check if two parameters are equal.
7800 ***************************************************************************/
7801
7802 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7803 {
7804         switch (type) {
7805                 case P_BOOL:
7806                 case P_BOOLREV:
7807                         return (*((bool *)ptr1) == *((bool *)ptr2));
7808
7809                 case P_INTEGER:
7810                 case P_ENUM:
7811                 case P_OCTAL:
7812                         return (*((int *)ptr1) == *((int *)ptr2));
7813
7814                 case P_CHAR:
7815                         return (*((char *)ptr1) == *((char *)ptr2));
7816
7817                 case P_LIST:
7818                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7819
7820                 case P_STRING:
7821                 case P_USTRING:
7822                 {
7823                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7824                         if (p1 && !*p1)
7825                                 p1 = NULL;
7826                         if (p2 && !*p2)
7827                                 p2 = NULL;
7828                         return (p1 == p2 || strequal(p1, p2));
7829                 }
7830                 case P_SEP:
7831                         break;
7832         }
7833         return (False);
7834 }
7835
7836 /***************************************************************************
7837  Initialize any local varients in the sDefault table.
7838 ***************************************************************************/
7839
7840 void init_locals(void)
7841 {
7842         /* None as yet. */
7843 }
7844
7845 /***************************************************************************
7846  Process a new section (service). At this stage all sections are services.
7847  Later we'll have special sections that permit server parameters to be set.
7848  Returns True on success, False on failure. 
7849 ***************************************************************************/
7850
7851 static bool do_section(const char *pszSectionName, void *userdata)
7852 {
7853         bool bRetval;
7854         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7855                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7856         bRetval = False;
7857
7858         /* if we were in a global section then do the local inits */
7859         if (bInGlobalSection && !isglobal)
7860                 init_locals();
7861
7862         /* if we've just struck a global section, note the fact. */
7863         bInGlobalSection = isglobal;
7864
7865         /* check for multiple global sections */
7866         if (bInGlobalSection) {
7867                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7868                 return (True);
7869         }
7870
7871         if (!bInGlobalSection && bGlobalOnly)
7872                 return (True);
7873
7874         /* if we have a current service, tidy it up before moving on */
7875         bRetval = True;
7876
7877         if (iServiceIndex >= 0)
7878                 bRetval = service_ok(iServiceIndex);
7879
7880         /* if all is still well, move to the next record in the services array */
7881         if (bRetval) {
7882                 /* We put this here to avoid an odd message order if messages are */
7883                 /* issued by the post-processing of a previous section. */
7884                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7885
7886                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7887                     < 0) {
7888                         DEBUG(0, ("Failed to add a new service\n"));
7889                         return (False);
7890                 }
7891         }
7892
7893         return (bRetval);
7894 }
7895
7896
7897 /***************************************************************************
7898  Determine if a partcular base parameter is currentl set to the default value.
7899 ***************************************************************************/
7900
7901 static bool is_default(int i)
7902 {
7903         if (!defaults_saved)
7904                 return False;
7905         switch (parm_table[i].type) {
7906                 case P_LIST:
7907                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
7908                                                 *(const char ***)parm_table[i].ptr);
7909                 case P_STRING:
7910                 case P_USTRING:
7911                         return strequal(parm_table[i].def.svalue,
7912                                         *(char **)parm_table[i].ptr);
7913                 case P_BOOL:
7914                 case P_BOOLREV:
7915                         return parm_table[i].def.bvalue ==
7916                                 *(bool *)parm_table[i].ptr;
7917                 case P_CHAR:
7918                         return parm_table[i].def.cvalue ==
7919                                 *(char *)parm_table[i].ptr;
7920                 case P_INTEGER:
7921                 case P_OCTAL:
7922                 case P_ENUM:
7923                         return parm_table[i].def.ivalue ==
7924                                 *(int *)parm_table[i].ptr;
7925                 case P_SEP:
7926                         break;
7927         }
7928         return False;
7929 }
7930
7931 /***************************************************************************
7932 Display the contents of the global structure.
7933 ***************************************************************************/
7934
7935 static void dump_globals(FILE *f)
7936 {
7937         int i;
7938         struct param_opt_struct *data;
7939
7940         fprintf(f, "[global]\n");
7941
7942         for (i = 0; parm_table[i].label; i++)
7943                 if (parm_table[i].p_class == P_GLOBAL &&
7944                     !(parm_table[i].flags & FLAG_META) &&
7945                     parm_table[i].ptr &&
7946                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7947                         if (defaults_saved && is_default(i))
7948                                 continue;
7949                         fprintf(f, "\t%s = ", parm_table[i].label);
7950                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
7951                         fprintf(f, "\n");
7952         }
7953         if (Globals.param_opt != NULL) {
7954                 data = Globals.param_opt;
7955                 while(data) {
7956                         fprintf(f, "\t%s = %s\n", data->key, data->value);
7957                         data = data->next;
7958                 }
7959         }
7960
7961 }
7962
7963 /***************************************************************************
7964  Return True if a local parameter is currently set to the global default.
7965 ***************************************************************************/
7966
7967 bool lp_is_default(int snum, struct parm_struct *parm)
7968 {
7969         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7970
7971         return equal_parameter(parm->type,
7972                                ((char *)ServicePtrs[snum]) + pdiff,
7973                                ((char *)&sDefault) + pdiff);
7974 }
7975
7976 /***************************************************************************
7977  Display the contents of a single services record.
7978 ***************************************************************************/
7979
7980 static void dump_a_service(struct service *pService, FILE * f)
7981 {
7982         int i;
7983         struct param_opt_struct *data;
7984
7985         if (pService != &sDefault)
7986                 fprintf(f, "[%s]\n", pService->szService);
7987
7988         for (i = 0; parm_table[i].label; i++) {
7989
7990                 if (parm_table[i].p_class == P_LOCAL &&
7991                     !(parm_table[i].flags & FLAG_META) &&
7992                     parm_table[i].ptr &&
7993                     (*parm_table[i].label != '-') &&
7994                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7995                 {
7996                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7997
7998                         if (pService == &sDefault) {
7999                                 if (defaults_saved && is_default(i))
8000                                         continue;
8001                         } else {
8002                                 if (equal_parameter(parm_table[i].type,
8003                                                     ((char *)pService) +
8004                                                     pdiff,
8005                                                     ((char *)&sDefault) +
8006                                                     pdiff))
8007                                         continue;
8008                         }
8009
8010                         fprintf(f, "\t%s = ", parm_table[i].label);
8011                         print_parameter(&parm_table[i],
8012                                         ((char *)pService) + pdiff, f);
8013                         fprintf(f, "\n");
8014                 }
8015         }
8016
8017                 if (pService->param_opt != NULL) {
8018                         data = pService->param_opt;
8019                         while(data) {
8020                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
8021                                 data = data->next;
8022                         }
8023                 }
8024 }
8025
8026 /***************************************************************************
8027  Display the contents of a parameter of a single services record.
8028 ***************************************************************************/
8029
8030 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
8031 {
8032         int i;
8033         bool result = False;
8034         parm_class p_class;
8035         unsigned flag = 0;
8036         fstring local_parm_name;
8037         char *parm_opt;
8038         const char *parm_opt_value;
8039
8040         /* check for parametrical option */
8041         fstrcpy( local_parm_name, parm_name);
8042         parm_opt = strchr( local_parm_name, ':');
8043
8044         if (parm_opt) {
8045                 *parm_opt = '\0';
8046                 parm_opt++;
8047                 if (strlen(parm_opt)) {
8048                         parm_opt_value = lp_parm_const_string( snum,
8049                                 local_parm_name, parm_opt, NULL);
8050                         if (parm_opt_value) {
8051                                 printf( "%s\n", parm_opt_value);
8052                                 result = True;
8053                         }
8054                 }
8055                 return result;
8056         }
8057
8058         /* check for a key and print the value */
8059         if (isGlobal) {
8060                 p_class = P_GLOBAL;
8061                 flag = FLAG_GLOBAL;
8062         } else
8063                 p_class = P_LOCAL;
8064
8065         for (i = 0; parm_table[i].label; i++) {
8066                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
8067                     !(parm_table[i].flags & FLAG_META) &&
8068                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
8069                     parm_table[i].ptr &&
8070                     (*parm_table[i].label != '-') &&
8071                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
8072                 {
8073                         void *ptr;
8074
8075                         if (isGlobal) {
8076                                 ptr = parm_table[i].ptr;
8077                         } else {
8078                                 struct service *pService = ServicePtrs[snum];
8079                                 ptr = ((char *)pService) +
8080                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
8081                         }
8082
8083                         print_parameter(&parm_table[i],
8084                                         ptr, f);
8085                         fprintf(f, "\n");
8086                         result = True;
8087                         break;
8088                 }
8089         }
8090
8091         return result;
8092 }
8093
8094 /***************************************************************************
8095  Return info about the requested parameter (given as a string).
8096  Return NULL when the string is not a valid parameter name.
8097 ***************************************************************************/
8098
8099 struct parm_struct *lp_get_parameter(const char *param_name)
8100 {
8101         int num = map_parameter(param_name);
8102
8103         if (num < 0) {
8104                 return NULL;
8105         }
8106
8107         return &parm_table[num];
8108 }
8109
8110 /***************************************************************************
8111  Return info about the next parameter in a service.
8112  snum==GLOBAL_SECTION_SNUM gives the globals.
8113  Return NULL when out of parameters.
8114 ***************************************************************************/
8115
8116 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
8117 {
8118         if (snum < 0) {
8119                 /* do the globals */
8120                 for (; parm_table[*i].label; (*i)++) {
8121                         if (parm_table[*i].p_class == P_SEPARATOR)
8122                                 return &parm_table[(*i)++];
8123
8124                         if (!parm_table[*i].ptr
8125                             || (*parm_table[*i].label == '-'))
8126                                 continue;
8127
8128                         if ((*i) > 0
8129                             && (parm_table[*i].ptr ==
8130                                 parm_table[(*i) - 1].ptr))
8131                                 continue;
8132
8133                         if (is_default(*i) && !allparameters)
8134                                 continue;
8135
8136                         return &parm_table[(*i)++];
8137                 }
8138         } else {
8139                 struct service *pService = ServicePtrs[snum];
8140
8141                 for (; parm_table[*i].label; (*i)++) {
8142                         if (parm_table[*i].p_class == P_SEPARATOR)
8143                                 return &parm_table[(*i)++];
8144
8145                         if (parm_table[*i].p_class == P_LOCAL &&
8146                             parm_table[*i].ptr &&
8147                             (*parm_table[*i].label != '-') &&
8148                             ((*i) == 0 ||
8149                              (parm_table[*i].ptr !=
8150                               parm_table[(*i) - 1].ptr)))
8151                         {
8152                                 int pdiff =
8153                                         PTR_DIFF(parm_table[*i].ptr,
8154                                                  &sDefault);
8155
8156                                 if (allparameters ||
8157                                     !equal_parameter(parm_table[*i].type,
8158                                                      ((char *)pService) +
8159                                                      pdiff,
8160                                                      ((char *)&sDefault) +
8161                                                      pdiff))
8162                                 {
8163                                         return &parm_table[(*i)++];
8164                                 }
8165                         }
8166                 }
8167         }
8168
8169         return NULL;
8170 }
8171
8172
8173 #if 0
8174 /***************************************************************************
8175  Display the contents of a single copy structure.
8176 ***************************************************************************/
8177 static void dump_copy_map(bool *pcopymap)
8178 {
8179         int i;
8180         if (!pcopymap)
8181                 return;
8182
8183         printf("\n\tNon-Copied parameters:\n");
8184
8185         for (i = 0; parm_table[i].label; i++)
8186                 if (parm_table[i].p_class == P_LOCAL &&
8187                     parm_table[i].ptr && !pcopymap[i] &&
8188                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8189                 {
8190                         printf("\t\t%s\n", parm_table[i].label);
8191                 }
8192 }
8193 #endif
8194
8195 /***************************************************************************
8196  Return TRUE if the passed service number is within range.
8197 ***************************************************************************/
8198
8199 bool lp_snum_ok(int iService)
8200 {
8201         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8202 }
8203
8204 /***************************************************************************
8205  Auto-load some home services.
8206 ***************************************************************************/
8207
8208 static void lp_add_auto_services(char *str)
8209 {
8210         char *s;
8211         char *p;
8212         int homes;
8213         char *saveptr;
8214
8215         if (!str)
8216                 return;
8217
8218         s = SMB_STRDUP(str);
8219         if (!s)
8220                 return;
8221
8222         homes = lp_servicenumber(HOMES_NAME);
8223
8224         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8225              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8226                 char *home;
8227
8228                 if (lp_servicenumber(p) >= 0)
8229                         continue;
8230
8231                 home = get_user_home_dir(talloc_tos(), p);
8232
8233                 if (home && home[0] && homes >= 0)
8234                         lp_add_home(p, homes, p, home);
8235
8236                 TALLOC_FREE(home);
8237         }
8238         SAFE_FREE(s);
8239 }
8240
8241 /***************************************************************************
8242  Auto-load one printer.
8243 ***************************************************************************/
8244
8245 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8246 {
8247         int printers = lp_servicenumber(PRINTERS_NAME);
8248         int i;
8249
8250         if (lp_servicenumber(name) < 0) {
8251                 lp_add_printer(name, printers);
8252                 if ((i = lp_servicenumber(name)) >= 0) {
8253                         string_set(&ServicePtrs[i]->comment, comment);
8254                         ServicePtrs[i]->autoloaded = True;
8255                 }
8256         }
8257 }
8258
8259 /***************************************************************************
8260  Have we loaded a services file yet?
8261 ***************************************************************************/
8262
8263 bool lp_loaded(void)
8264 {
8265         return (bLoaded);
8266 }
8267
8268 /***************************************************************************
8269  Unload unused services.
8270 ***************************************************************************/
8271
8272 void lp_killunused(bool (*snumused) (int))
8273 {
8274         int i;
8275         for (i = 0; i < iNumServices; i++) {
8276                 if (!VALID(i))
8277                         continue;
8278
8279                 /* don't kill autoloaded or usershare services */
8280                 if ( ServicePtrs[i]->autoloaded ||
8281                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8282                         continue;
8283                 }
8284
8285                 if (!snumused || !snumused(i)) {
8286                         free_service_byindex(i);
8287                 }
8288         }
8289 }
8290
8291 /**
8292  * Kill all except autoloaded and usershare services - convenience wrapper
8293  */
8294 void lp_kill_all_services(void)
8295 {
8296         lp_killunused(NULL);
8297 }
8298
8299 /***************************************************************************
8300  Unload a service.
8301 ***************************************************************************/
8302
8303 void lp_killservice(int iServiceIn)
8304 {
8305         if (VALID(iServiceIn)) {
8306                 free_service_byindex(iServiceIn);
8307         }
8308 }
8309
8310 /***************************************************************************
8311  Save the curent values of all global and sDefault parameters into the 
8312  defaults union. This allows swat and testparm to show only the
8313  changed (ie. non-default) parameters.
8314 ***************************************************************************/
8315
8316 static void lp_save_defaults(void)
8317 {
8318         int i;
8319         for (i = 0; parm_table[i].label; i++) {
8320                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8321                         continue;
8322                 switch (parm_table[i].type) {
8323                         case P_LIST:
8324                                 parm_table[i].def.lvalue = str_list_copy(
8325                                         NULL, *(const char ***)parm_table[i].ptr);
8326                                 break;
8327                         case P_STRING:
8328                         case P_USTRING:
8329                                 if (parm_table[i].ptr) {
8330                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8331                                 } else {
8332                                         parm_table[i].def.svalue = NULL;
8333                                 }
8334                                 break;
8335                         case P_BOOL:
8336                         case P_BOOLREV:
8337                                 parm_table[i].def.bvalue =
8338                                         *(bool *)parm_table[i].ptr;
8339                                 break;
8340                         case P_CHAR:
8341                                 parm_table[i].def.cvalue =
8342                                         *(char *)parm_table[i].ptr;
8343                                 break;
8344                         case P_INTEGER:
8345                         case P_OCTAL:
8346                         case P_ENUM:
8347                                 parm_table[i].def.ivalue =
8348                                         *(int *)parm_table[i].ptr;
8349                                 break;
8350                         case P_SEP:
8351                                 break;
8352                 }
8353         }
8354         defaults_saved = True;
8355 }
8356
8357 /*******************************************************************
8358  Set the server type we will announce as via nmbd.
8359 ********************************************************************/
8360
8361 static const struct srv_role_tab {
8362         uint32 role;
8363         const char *role_str;
8364 } srv_role_tab [] = {
8365         { ROLE_STANDALONE, "ROLE_STANDALONE" },
8366         { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8367         { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8368         { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8369         { 0, NULL }
8370 };
8371
8372 const char* server_role_str(uint32 role)
8373 {
8374         int i = 0;
8375         for (i=0; srv_role_tab[i].role_str; i++) {
8376                 if (role == srv_role_tab[i].role) {
8377                         return srv_role_tab[i].role_str;
8378                 }
8379         }
8380         return NULL;
8381 }
8382
8383 static void set_server_role(void)
8384 {
8385         server_role = ROLE_STANDALONE;
8386
8387         switch (lp_security()) {
8388                 case SEC_SHARE:
8389                         if (lp_domain_logons())
8390                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8391                         break;
8392                 case SEC_SERVER:
8393                         if (lp_domain_logons())
8394                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8395                         /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8396                         server_role = ROLE_STANDALONE;
8397                         break;
8398                 case SEC_DOMAIN:
8399                         if (lp_domain_logons()) {
8400                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8401                                 server_role = ROLE_DOMAIN_BDC;
8402                                 break;
8403                         }
8404                         server_role = ROLE_DOMAIN_MEMBER;
8405                         break;
8406                 case SEC_ADS:
8407                         if (lp_domain_logons()) {
8408                                 server_role = ROLE_DOMAIN_PDC;
8409                                 break;
8410                         }
8411                         server_role = ROLE_DOMAIN_MEMBER;
8412                         break;
8413                 case SEC_USER:
8414                         if (lp_domain_logons()) {
8415
8416                                 if (Globals.iDomainMaster) /* auto or yes */ 
8417                                         server_role = ROLE_DOMAIN_PDC;
8418                                 else
8419                                         server_role = ROLE_DOMAIN_BDC;
8420                         }
8421                         break;
8422                 default:
8423                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8424                         break;
8425         }
8426
8427         DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8428 }
8429
8430 /***********************************************************
8431  If we should send plaintext/LANMAN passwords in the clinet
8432 ************************************************************/
8433
8434 static void set_allowed_client_auth(void)
8435 {
8436         if (Globals.bClientNTLMv2Auth) {
8437                 Globals.bClientLanManAuth = False;
8438         }
8439         if (!Globals.bClientLanManAuth) {
8440                 Globals.bClientPlaintextAuth = False;
8441         }
8442 }
8443
8444 /***************************************************************************
8445  JRA.
8446  The following code allows smbd to read a user defined share file.
8447  Yes, this is my intent. Yes, I'm comfortable with that...
8448
8449  THE FOLLOWING IS SECURITY CRITICAL CODE.
8450
8451  It washes your clothes, it cleans your house, it guards you while you sleep...
8452  Do not f%^k with it....
8453 ***************************************************************************/
8454
8455 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8456
8457 /***************************************************************************
8458  Check allowed stat state of a usershare file.
8459  Ensure we print out who is dicking with us so the admin can
8460  get their sorry ass fired.
8461 ***************************************************************************/
8462
8463 static bool check_usershare_stat(const char *fname,
8464                                  const SMB_STRUCT_STAT *psbuf)
8465 {
8466         if (!S_ISREG(psbuf->st_ex_mode)) {
8467                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8468                         "not a regular file\n",
8469                         fname, (unsigned int)psbuf->st_ex_uid ));
8470                 return False;
8471         }
8472
8473         /* Ensure this doesn't have the other write bit set. */
8474         if (psbuf->st_ex_mode & S_IWOTH) {
8475                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8476                         "public write. Refusing to allow as a usershare file.\n",
8477                         fname, (unsigned int)psbuf->st_ex_uid ));
8478                 return False;
8479         }
8480
8481         /* Should be 10k or less. */
8482         if (psbuf->st_ex_size > MAX_USERSHARE_FILE_SIZE) {
8483                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8484                         "too large (%u) to be a user share file.\n",
8485                         fname, (unsigned int)psbuf->st_ex_uid,
8486                         (unsigned int)psbuf->st_ex_size ));
8487                 return False;
8488         }
8489
8490         return True;
8491 }
8492
8493 /***************************************************************************
8494  Parse the contents of a usershare file.
8495 ***************************************************************************/
8496
8497 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8498                         SMB_STRUCT_STAT *psbuf,
8499                         const char *servicename,
8500                         int snum,
8501                         char **lines,
8502                         int numlines,
8503                         char **pp_sharepath,
8504                         char **pp_comment,
8505                         SEC_DESC **ppsd,
8506                         bool *pallow_guest)
8507 {
8508         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8509         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8510         int us_vers;
8511         SMB_STRUCT_DIR *dp;
8512         SMB_STRUCT_STAT sbuf;
8513         char *sharepath = NULL;
8514         char *comment = NULL;
8515
8516         *pp_sharepath = NULL;
8517         *pp_comment = NULL;
8518
8519         *pallow_guest = False;
8520
8521         if (numlines < 4) {
8522                 return USERSHARE_MALFORMED_FILE;
8523         }
8524
8525         if (strcmp(lines[0], "#VERSION 1") == 0) {
8526                 us_vers = 1;
8527         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8528                 us_vers = 2;
8529                 if (numlines < 5) {
8530                         return USERSHARE_MALFORMED_FILE;
8531                 }
8532         } else {
8533                 return USERSHARE_BAD_VERSION;
8534         }
8535
8536         if (strncmp(lines[1], "path=", 5) != 0) {
8537                 return USERSHARE_MALFORMED_PATH;
8538         }
8539
8540         sharepath = talloc_strdup(ctx, &lines[1][5]);
8541         if (!sharepath) {
8542                 return USERSHARE_POSIX_ERR;
8543         }
8544         trim_string(sharepath, " ", " ");
8545
8546         if (strncmp(lines[2], "comment=", 8) != 0) {
8547                 return USERSHARE_MALFORMED_COMMENT_DEF;
8548         }
8549
8550         comment = talloc_strdup(ctx, &lines[2][8]);
8551         if (!comment) {
8552                 return USERSHARE_POSIX_ERR;
8553         }
8554         trim_string(comment, " ", " ");
8555         trim_char(comment, '"', '"');
8556
8557         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8558                 return USERSHARE_MALFORMED_ACL_DEF;
8559         }
8560
8561         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8562                 return USERSHARE_ACL_ERR;
8563         }
8564
8565         if (us_vers == 2) {
8566                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8567                         return USERSHARE_MALFORMED_ACL_DEF;
8568                 }
8569                 if (lines[4][9] == 'y') {
8570                         *pallow_guest = True;
8571                 }
8572         }
8573
8574         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8575                 /* Path didn't change, no checks needed. */
8576                 *pp_sharepath = sharepath;
8577                 *pp_comment = comment;
8578                 return USERSHARE_OK;
8579         }
8580
8581         /* The path *must* be absolute. */
8582         if (sharepath[0] != '/') {
8583                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8584                         servicename, sharepath));
8585                 return USERSHARE_PATH_NOT_ABSOLUTE;
8586         }
8587
8588         /* If there is a usershare prefix deny list ensure one of these paths
8589            doesn't match the start of the user given path. */
8590         if (prefixdenylist) {
8591                 int i;
8592                 for ( i=0; prefixdenylist[i]; i++ ) {
8593                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8594                                 servicename, i, prefixdenylist[i], sharepath ));
8595                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8596                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8597                                         "usershare prefix deny list entries.\n",
8598                                         servicename, sharepath));
8599                                 return USERSHARE_PATH_IS_DENIED;
8600                         }
8601                 }
8602         }
8603
8604         /* If there is a usershare prefix allow list ensure one of these paths
8605            does match the start of the user given path. */
8606
8607         if (prefixallowlist) {
8608                 int i;
8609                 for ( i=0; prefixallowlist[i]; i++ ) {
8610                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8611                                 servicename, i, prefixallowlist[i], sharepath ));
8612                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8613                                 break;
8614                         }
8615                 }
8616                 if (prefixallowlist[i] == NULL) {
8617                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8618                                 "usershare prefix allow list entries.\n",
8619                                 servicename, sharepath));
8620                         return USERSHARE_PATH_NOT_ALLOWED;
8621                 }
8622         }
8623
8624         /* Ensure this is pointing to a directory. */
8625         dp = sys_opendir(sharepath);
8626
8627         if (!dp) {
8628                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8629                         servicename, sharepath));
8630                 return USERSHARE_PATH_NOT_DIRECTORY;
8631         }
8632
8633         /* Ensure the owner of the usershare file has permission to share
8634            this directory. */
8635
8636         if (sys_stat(sharepath, &sbuf, false) == -1) {
8637                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8638                         servicename, sharepath, strerror(errno) ));
8639                 sys_closedir(dp);
8640                 return USERSHARE_POSIX_ERR;
8641         }
8642
8643         sys_closedir(dp);
8644
8645         if (!S_ISDIR(sbuf.st_ex_mode)) {
8646                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8647                         servicename, sharepath ));
8648                 return USERSHARE_PATH_NOT_DIRECTORY;
8649         }
8650
8651         /* Check if sharing is restricted to owner-only. */
8652         /* psbuf is the stat of the usershare definition file,
8653            sbuf is the stat of the target directory to be shared. */
8654
8655         if (lp_usershare_owner_only()) {
8656                 /* root can share anything. */
8657                 if ((psbuf->st_ex_uid != 0) && (sbuf.st_ex_uid != psbuf->st_ex_uid)) {
8658                         return USERSHARE_PATH_NOT_ALLOWED;
8659                 }
8660         }
8661
8662         *pp_sharepath = sharepath;
8663         *pp_comment = comment;
8664         return USERSHARE_OK;
8665 }
8666
8667 /***************************************************************************
8668  Deal with a usershare file.
8669  Returns:
8670         >= 0 - snum
8671         -1 - Bad name, invalid contents.
8672            - service name already existed and not a usershare, problem
8673             with permissions to share directory etc.
8674 ***************************************************************************/
8675
8676 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8677 {
8678         SMB_STRUCT_STAT sbuf;
8679         SMB_STRUCT_STAT lsbuf;
8680         char *fname = NULL;
8681         char *sharepath = NULL;
8682         char *comment = NULL;
8683         fstring service_name;
8684         char **lines = NULL;
8685         int numlines = 0;
8686         int fd = -1;
8687         int iService = -1;
8688         TALLOC_CTX *ctx = NULL;
8689         SEC_DESC *psd = NULL;
8690         bool guest_ok = False;
8691
8692         /* Ensure share name doesn't contain invalid characters. */
8693         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8694                 DEBUG(0,("process_usershare_file: share name %s contains "
8695                         "invalid characters (any of %s)\n",
8696                         file_name, INVALID_SHARENAME_CHARS ));
8697                 return -1;
8698         }
8699
8700         fstrcpy(service_name, file_name);
8701
8702         if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8703         }
8704
8705         /* Minimize the race condition by doing an lstat before we
8706            open and fstat. Ensure this isn't a symlink link. */
8707
8708         if (sys_lstat(fname, &lsbuf, false) != 0) {
8709                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8710                         fname, strerror(errno) ));
8711                 SAFE_FREE(fname);
8712                 return -1;
8713         }
8714
8715         /* This must be a regular file, not a symlink, directory or
8716            other strange filetype. */
8717         if (!check_usershare_stat(fname, &lsbuf)) {
8718                 SAFE_FREE(fname);
8719                 return -1;
8720         }
8721
8722         {
8723                 char *canon_name = canonicalize_servicename(service_name);
8724                 TDB_DATA data = dbwrap_fetch_bystring(
8725                         ServiceHash, canon_name, canon_name);
8726
8727                 iService = -1;
8728
8729                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8730                         iService = *(int *)data.dptr;
8731                 }
8732                 TALLOC_FREE(canon_name);
8733         }
8734
8735         if (iService != -1 &&
8736             timespec_compare(&ServicePtrs[iService]->usershare_last_mod,
8737                              &lsbuf.st_ex_mtime) == 0) {
8738                 /* Nothing changed - Mark valid and return. */
8739                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8740                         service_name ));
8741                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8742                 SAFE_FREE(fname);
8743                 return iService;
8744         }
8745
8746         /* Try and open the file read only - no symlinks allowed. */
8747 #ifdef O_NOFOLLOW
8748         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8749 #else
8750         fd = sys_open(fname, O_RDONLY, 0);
8751 #endif
8752
8753         if (fd == -1) {
8754                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8755                         fname, strerror(errno) ));
8756                 SAFE_FREE(fname);
8757                 return -1;
8758         }
8759
8760         /* Now fstat to be *SURE* it's a regular file. */
8761         if (sys_fstat(fd, &sbuf, false) != 0) {
8762                 close(fd);
8763                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8764                         fname, strerror(errno) ));
8765                 SAFE_FREE(fname);
8766                 return -1;
8767         }
8768
8769         /* Is it the same dev/inode as was lstated ? */
8770         if (lsbuf.st_ex_dev != sbuf.st_ex_dev || lsbuf.st_ex_ino != sbuf.st_ex_ino) {
8771                 close(fd);
8772                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8773                         "Symlink spoofing going on ?\n", fname ));
8774                 SAFE_FREE(fname);
8775                 return -1;
8776         }
8777
8778         /* This must be a regular file, not a symlink, directory or
8779            other strange filetype. */
8780         if (!check_usershare_stat(fname, &sbuf)) {
8781                 SAFE_FREE(fname);
8782                 return -1;
8783         }
8784
8785         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8786
8787         close(fd);
8788         if (lines == NULL) {
8789                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8790                         fname, (unsigned int)sbuf.st_ex_uid ));
8791                 SAFE_FREE(fname);
8792                 return -1;
8793         }
8794
8795         SAFE_FREE(fname);
8796
8797         /* Should we allow printers to be shared... ? */
8798         ctx = talloc_init("usershare_sd_xctx");
8799         if (!ctx) {
8800                 TALLOC_FREE(lines);
8801                 return 1;
8802         }
8803
8804         if (parse_usershare_file(ctx, &sbuf, service_name,
8805                         iService, lines, numlines, &sharepath,
8806                         &comment, &psd, &guest_ok) != USERSHARE_OK) {
8807                 talloc_destroy(ctx);
8808                 TALLOC_FREE(lines);
8809                 return -1;
8810         }
8811
8812         TALLOC_FREE(lines);
8813
8814         /* Everything ok - add the service possibly using a template. */
8815         if (iService < 0) {
8816                 const struct service *sp = &sDefault;
8817                 if (snum_template != -1) {
8818                         sp = ServicePtrs[snum_template];
8819                 }
8820
8821                 if ((iService = add_a_service(sp, service_name)) < 0) {
8822                         DEBUG(0, ("process_usershare_file: Failed to add "
8823                                 "new service %s\n", service_name));
8824                         talloc_destroy(ctx);
8825                         return -1;
8826                 }
8827
8828                 /* Read only is controlled by usershare ACL below. */
8829                 ServicePtrs[iService]->bRead_only = False;
8830         }
8831
8832         /* Write the ACL of the new/modified share. */
8833         if (!set_share_security(service_name, psd)) {
8834                  DEBUG(0, ("process_usershare_file: Failed to set share "
8835                         "security for user share %s\n",
8836                         service_name ));
8837                 lp_remove_service(iService);
8838                 talloc_destroy(ctx);
8839                 return -1;
8840         }
8841
8842         /* If from a template it may be marked invalid. */
8843         ServicePtrs[iService]->valid = True;
8844
8845         /* Set the service as a valid usershare. */
8846         ServicePtrs[iService]->usershare = USERSHARE_VALID;
8847
8848         /* Set guest access. */
8849         if (lp_usershare_allow_guests()) {
8850                 ServicePtrs[iService]->bGuest_ok = guest_ok;
8851         }
8852
8853         /* And note when it was loaded. */
8854         ServicePtrs[iService]->usershare_last_mod = sbuf.st_ex_mtime;
8855         string_set(&ServicePtrs[iService]->szPath, sharepath);
8856         string_set(&ServicePtrs[iService]->comment, comment);
8857
8858         talloc_destroy(ctx);
8859
8860         return iService;
8861 }
8862
8863 /***************************************************************************
8864  Checks if a usershare entry has been modified since last load.
8865 ***************************************************************************/
8866
8867 static bool usershare_exists(int iService, struct timespec *last_mod)
8868 {
8869         SMB_STRUCT_STAT lsbuf;
8870         const char *usersharepath = Globals.szUsersharePath;
8871         char *fname;
8872
8873         if (asprintf(&fname, "%s/%s",
8874                                 usersharepath,
8875                                 ServicePtrs[iService]->szService) < 0) {
8876                 return false;
8877         }
8878
8879         if (sys_lstat(fname, &lsbuf, false) != 0) {
8880                 SAFE_FREE(fname);
8881                 return false;
8882         }
8883
8884         if (!S_ISREG(lsbuf.st_ex_mode)) {
8885                 SAFE_FREE(fname);
8886                 return false;
8887         }
8888
8889         SAFE_FREE(fname);
8890         *last_mod = lsbuf.st_ex_mtime;
8891         return true;
8892 }
8893
8894 /***************************************************************************
8895  Load a usershare service by name. Returns a valid servicenumber or -1.
8896 ***************************************************************************/
8897
8898 int load_usershare_service(const char *servicename)
8899 {
8900         SMB_STRUCT_STAT sbuf;
8901         const char *usersharepath = Globals.szUsersharePath;
8902         int max_user_shares = Globals.iUsershareMaxShares;
8903         int snum_template = -1;
8904
8905         if (*usersharepath == 0 ||  max_user_shares == 0) {
8906                 return -1;
8907         }
8908
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;
8913         }
8914
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;
8919         }
8920
8921         /*
8922          * This directory must be owned by root, and have the 't' bit set.
8923          * It also must not be writable by "other".
8924          */
8925
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;
8935         }
8936
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;
8946                         }
8947                 }
8948
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;
8954                 }
8955         }
8956
8957         return process_usershare_file(usersharepath, servicename, snum_template);
8958 }
8959
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 ***************************************************************************/
8966
8967 int load_usershare_shares(void)
8968 {
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();
8981
8982         if (max_user_shares == 0 || *usersharepath == '\0') {
8983                 return lp_numservices();
8984         }
8985
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;
8990         }
8991
8992         /*
8993          * This directory must be owned by root, and have the 't' bit set.
8994          * It also must not be writable by "other".
8995          */
8996
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;
9006         }
9007
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;
9017                         }
9018                 }
9019
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;
9025                 }
9026         }
9027
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;
9032                 }
9033         }
9034
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;
9040         }
9041
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;
9047
9048                 /* Ignore . and .. */
9049                 if (*n == '.') {
9050                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
9051                                 continue;
9052                         }
9053                 }
9054
9055                 if (n[0] == ':') {
9056                         /* Temporary file used when creating a share. */
9057                         num_tmp_dir_entries++;
9058                 }
9059
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;
9066                 }
9067
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;
9077                         }
9078                 } else if (r == -1) {
9079                         num_bad_dir_entries++;
9080                 }
9081
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;
9088                 }
9089
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;
9096                 }
9097         }
9098
9099         sys_closedir(dp);
9100
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;
9107                         }
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);
9113                 }
9114         }
9115
9116         return lp_numservices();
9117 }
9118
9119 /********************************************************
9120  Destroy global resources allocated in this file
9121 ********************************************************/
9122
9123 void gfree_loadparm(void)
9124 {
9125         int i;
9126
9127         free_file_list();
9128
9129         /* Free resources allocated to services */
9130
9131         for ( i = 0; i < iNumServices; i++ ) {
9132                 if ( VALID(i) ) {
9133                         free_service_byindex(i);
9134                 }
9135         }
9136
9137         SAFE_FREE( ServicePtrs );
9138         iNumServices = 0;
9139
9140         /* Now release all resources allocated to global
9141            parameters and the default service */
9142
9143         free_global_parameters();
9144 }
9145
9146
9147 /***************************************************************************
9148  Allow client apps to specify that they are a client
9149 ***************************************************************************/
9150 void lp_set_in_client(bool b)
9151 {
9152     in_client = b;
9153 }
9154
9155
9156 /***************************************************************************
9157  Determine if we're running in a client app
9158 ***************************************************************************/
9159 bool lp_is_in_client(void)
9160 {
9161     return in_client;
9162 }
9163
9164 /***************************************************************************
9165  Load the services array from the services file. Return True on success, 
9166  False on failure.
9167 ***************************************************************************/
9168
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)
9176 {
9177         char *n2 = NULL;
9178         bool bRetval;
9179
9180         bRetval = False;
9181
9182         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9183
9184         bInGlobalSection = True;
9185         bGlobalOnly = global_only;
9186         bAllowIncludeRegistry = allow_include_registry;
9187
9188         init_globals(! initialize_globals);
9189         debug_init();
9190
9191         free_file_list();
9192
9193         if (save_defaults) {
9194                 init_locals();
9195                 lp_save_defaults();
9196         }
9197
9198         free_param_opts(&Globals.param_opt);
9199
9200         /* We get sections first, so have to start 'behind' to make up */
9201         iServiceIndex = -1;
9202
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");
9209                 }
9210
9211                 add_to_file_list(pszFname, n2);
9212
9213                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9214                 TALLOC_FREE(n2);
9215
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);
9221                         }
9222                 }
9223
9224                 if (lp_config_backend_is_registry()) {
9225                         /* config backend changed to registry in config file */
9226                         /*
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.
9231                          */
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);
9242                 }
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;
9249         }
9250
9251         if (bRetval && lp_registry_shares() && allow_registry_shares) {
9252                 bRetval = process_registry_shares();
9253         }
9254
9255         lp_add_auto_services(lp_auto_services());
9256
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);
9263                 }
9264         }
9265
9266         set_server_role();
9267         set_default_server_announce_type();
9268         set_allowed_client_auth();
9269
9270         bLoaded = True;
9271
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");
9276         }
9277
9278         init_iconv();
9279
9280         bAllowIncludeRegistry = true;
9281
9282         return (bRetval);
9283 }
9284
9285 bool lp_load(const char *pszFname,
9286              bool global_only,
9287              bool save_defaults,
9288              bool add_ipc,
9289              bool initialize_globals)
9290 {
9291         return lp_load_ex(pszFname,
9292                           global_only,
9293                           save_defaults,
9294                           add_ipc,
9295                           initialize_globals,
9296                           true, false);
9297 }
9298
9299 bool lp_load_initial_only(const char *pszFname)
9300 {
9301         return lp_load_ex(pszFname,
9302                           true,
9303                           false,
9304                           false,
9305                           true,
9306                           false,
9307                           false);
9308 }
9309
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)
9315 {
9316         return lp_load_ex(pszFname,
9317                           global_only,
9318                           save_defaults,
9319                           add_ipc,
9320                           initialize_globals,
9321                           true,
9322                           true);
9323 }
9324
9325 /***************************************************************************
9326  Return the max number of services.
9327 ***************************************************************************/
9328
9329 int lp_numservices(void)
9330 {
9331         return (iNumServices);
9332 }
9333
9334 /***************************************************************************
9335 Display the contents of the services array in human-readable form.
9336 ***************************************************************************/
9337
9338 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9339 {
9340         int iService;
9341
9342         if (show_defaults)
9343                 defaults_saved = False;
9344
9345         dump_globals(f);
9346
9347         dump_a_service(&sDefault, f);
9348
9349         for (iService = 0; iService < maxtoprint; iService++) {
9350                 fprintf(f,"\n");
9351                 lp_dump_one(f, show_defaults, iService);
9352         }
9353 }
9354
9355 /***************************************************************************
9356 Display the contents of one service in human-readable form.
9357 ***************************************************************************/
9358
9359 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9360 {
9361         if (VALID(snum)) {
9362                 if (ServicePtrs[snum]->szService[0] == '\0')
9363                         return;
9364                 dump_a_service(ServicePtrs[snum], f);
9365         }
9366 }
9367
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 ***************************************************************************/
9374
9375 int lp_servicenumber(const char *pszServiceName)
9376 {
9377         int iService;
9378         fstring serviceName;
9379
9380         if (!pszServiceName) {
9381                 return GLOBAL_SECTION_SNUM;
9382         }
9383
9384         for (iService = iNumServices - 1; iService >= 0; iService--) {
9385                 if (VALID(iService) && ServicePtrs[iService]->szService) {
9386                         /*
9387                          * The substitution here is used to support %U is
9388                          * service names
9389                          */
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;
9396                         }
9397                 }
9398         }
9399
9400         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9401                 struct timespec last_mod;
9402
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;
9410                 }
9411
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);
9419                 }
9420         }
9421
9422         if (iService < 0) {
9423                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9424                 return GLOBAL_SECTION_SNUM;
9425         }
9426
9427         return (iService);
9428 }
9429
9430 bool share_defined(const char *service_name)
9431 {
9432         return (lp_servicenumber(service_name) != -1);
9433 }
9434
9435 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9436                                       const char *sharename)
9437 {
9438         struct share_params *result;
9439         char *sname;
9440         int snum;
9441
9442         if (!(sname = SMB_STRDUP(sharename))) {
9443                 return NULL;
9444         }
9445
9446         snum = find_service(sname);
9447         SAFE_FREE(sname);
9448
9449         if (snum < 0) {
9450                 return NULL;
9451         }
9452
9453         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9454                 DEBUG(0, ("talloc failed\n"));
9455                 return NULL;
9456         }
9457
9458         result->service = snum;
9459         return result;
9460 }
9461
9462 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9463 {
9464         struct share_iterator *result;
9465
9466         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9467                 DEBUG(0, ("talloc failed\n"));
9468                 return NULL;
9469         }
9470
9471         result->next_id = 0;
9472         return result;
9473 }
9474
9475 struct share_params *next_share(struct share_iterator *list)
9476 {
9477         struct share_params *result;
9478
9479         while (!lp_snum_ok(list->next_id) &&
9480                (list->next_id < lp_numservices())) {
9481                 list->next_id += 1;
9482         }
9483
9484         if (list->next_id >= lp_numservices()) {
9485                 return NULL;
9486         }
9487
9488         if (!(result = TALLOC_P(list, struct share_params))) {
9489                 DEBUG(0, ("talloc failed\n"));
9490                 return NULL;
9491         }
9492
9493         result->service = list->next_id;
9494         list->next_id += 1;
9495         return result;
9496 }
9497
9498 struct share_params *next_printer(struct share_iterator *list)
9499 {
9500         struct share_params *result;
9501
9502         while ((result = next_share(list)) != NULL) {
9503                 if (lp_print_ok(result->service)) {
9504                         break;
9505                 }
9506         }
9507         return result;
9508 }
9509
9510 /*
9511  * This is a hack for a transition period until we transformed all code from
9512  * service numbers to struct share_params.
9513  */
9514
9515 struct share_params *snum2params_static(int snum)
9516 {
9517         static struct share_params result;
9518         result.service = snum;
9519         return &result;
9520 }
9521
9522 /*******************************************************************
9523  A useful volume label function. 
9524 ********************************************************************/
9525
9526 const char *volume_label(int snum)
9527 {
9528         char *ret;
9529         const char *label = lp_volume(snum);
9530         if (!*label) {
9531                 label = lp_servicename(snum);
9532         }
9533
9534         /* This returns a 33 byte guarenteed null terminated string. */
9535         ret = talloc_strndup(talloc_tos(), label, 32);
9536         if (!ret) {
9537                 return "";
9538         }               
9539         return ret;
9540 }
9541
9542 /*******************************************************************
9543  Set the server type we will announce as via nmbd.
9544 ********************************************************************/
9545
9546 static void set_default_server_announce_type(void)
9547 {
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;
9552
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 */
9556
9557         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9558
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;
9574         }
9575
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;
9589         }
9590         if (lp_time_server())
9591                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9592
9593         if (lp_host_msdfs())
9594                 default_server_announce |= SV_TYPE_DFS_SERVER;
9595 }
9596
9597 /***********************************************************
9598  returns role of Samba server
9599 ************************************************************/
9600
9601 int lp_server_role(void)
9602 {
9603         return server_role;
9604 }
9605
9606 /***********************************************************
9607  If we are PDC then prefer us as DMB
9608 ************************************************************/
9609
9610 bool lp_domain_master(void)
9611 {
9612         if (Globals.iDomainMaster == Auto)
9613                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9614
9615         return (bool)Globals.iDomainMaster;
9616 }
9617
9618 /***********************************************************
9619  If we are DMB then prefer us as LMB
9620 ************************************************************/
9621
9622 bool lp_preferred_master(void)
9623 {
9624         if (Globals.iPreferredMaster == Auto)
9625                 return (lp_local_master() && lp_domain_master());
9626
9627         return (bool)Globals.iPreferredMaster;
9628 }
9629
9630 /*******************************************************************
9631  Remove a service.
9632 ********************************************************************/
9633
9634 void lp_remove_service(int snum)
9635 {
9636         ServicePtrs[snum]->valid = False;
9637         invalid_services[num_invalid_services++] = snum;
9638 }
9639
9640 /*******************************************************************
9641  Copy a service.
9642 ********************************************************************/
9643
9644 void lp_copy_service(int snum, const char *new_name)
9645 {
9646         do_section(new_name, NULL);
9647         if (snum >= 0) {
9648                 snum = lp_servicenumber(new_name);
9649                 if (snum >= 0)
9650                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9651         }
9652 }
9653
9654
9655 /*******************************************************************
9656  Get the default server type we will announce as via nmbd.
9657 ********************************************************************/
9658
9659 int lp_default_server_announce(void)
9660 {
9661         return default_server_announce;
9662 }
9663
9664 /*******************************************************************
9665  Split the announce version into major and minor numbers.
9666 ********************************************************************/
9667
9668 int lp_major_announce_version(void)
9669 {
9670         static bool got_major = False;
9671         static int major_version = DEFAULT_MAJOR_VERSION;
9672         char *vers;
9673         char *p;
9674
9675         if (got_major)
9676                 return major_version;
9677
9678         got_major = True;
9679         if ((vers = lp_announce_version()) == NULL)
9680                 return major_version;
9681
9682         if ((p = strchr_m(vers, '.')) == 0)
9683                 return major_version;
9684
9685         *p = '\0';
9686         major_version = atoi(vers);
9687         return major_version;
9688 }
9689
9690 int lp_minor_announce_version(void)
9691 {
9692         static bool got_minor = False;
9693         static int minor_version = DEFAULT_MINOR_VERSION;
9694         char *vers;
9695         char *p;
9696
9697         if (got_minor)
9698                 return minor_version;
9699
9700         got_minor = True;
9701         if ((vers = lp_announce_version()) == NULL)
9702                 return minor_version;
9703
9704         if ((p = strchr_m(vers, '.')) == 0)
9705                 return minor_version;
9706
9707         p++;
9708         minor_version = atoi(p);
9709         return minor_version;
9710 }
9711
9712 /***********************************************************
9713  Set the global name resolution order (used in smbclient).
9714 ************************************************************/
9715
9716 void lp_set_name_resolve_order(const char *new_order)
9717 {
9718         string_set(&Globals.szNameResolveOrder, new_order);
9719 }
9720
9721 const char *lp_printername(int snum)
9722 {
9723         const char *ret = _lp_printername(snum);
9724         if (ret == NULL || (ret != NULL && *ret == '\0'))
9725                 ret = lp_const_servicename(snum);
9726
9727         return ret;
9728 }
9729
9730
9731 /***********************************************************
9732  Allow daemons such as winbindd to fix their logfile name.
9733 ************************************************************/
9734
9735 void lp_set_logfile(const char *name)
9736 {
9737         string_set(&Globals.szLogFile, name);
9738         debug_set_logfile(name);
9739 }
9740
9741 /*******************************************************************
9742  Return the max print jobs per queue.
9743 ********************************************************************/
9744
9745 int lp_maxprintjobs(int snum)
9746 {
9747         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9748         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9749                 maxjobs = PRINT_MAX_JOBID - 1;
9750
9751         return maxjobs;
9752 }
9753
9754 const char *lp_printcapname(void)
9755 {
9756         if ((Globals.szPrintcapname != NULL) &&
9757             (Globals.szPrintcapname[0] != '\0'))
9758                 return Globals.szPrintcapname;
9759
9760         if (sDefault.iPrinting == PRINT_CUPS) {
9761 #ifdef HAVE_CUPS
9762                 return "cups";
9763 #else
9764                 return "lpstat";
9765 #endif
9766         }
9767
9768         if (sDefault.iPrinting == PRINT_BSD)
9769                 return "/etc/printcap";
9770
9771         return PRINTCAP_NAME;
9772 }
9773
9774 static uint32 spoolss_state;
9775
9776 bool lp_disable_spoolss( void )
9777 {
9778         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9779                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9780
9781         return spoolss_state == SVCCTL_STOPPED ? True : False;
9782 }
9783
9784 void lp_set_spoolss_state( uint32 state )
9785 {
9786         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9787
9788         spoolss_state = state;
9789 }
9790
9791 uint32 lp_get_spoolss_state( void )
9792 {
9793         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9794 }
9795
9796 /*******************************************************************
9797  Ensure we don't use sendfile if server smb signing is active.
9798 ********************************************************************/
9799
9800 bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state)
9801 {
9802         bool sign_active = false;
9803
9804         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9805         if (get_Protocol() < PROTOCOL_NT1) {
9806                 return false;
9807         }
9808         if (signing_state) {
9809                 sign_active = smb_signing_is_active(signing_state);
9810         }
9811         return (_lp_use_sendfile(snum) &&
9812                         (get_remote_arch() != RA_WIN95) &&
9813                         !sign_active);
9814 }
9815
9816 /*******************************************************************
9817  Turn off sendfile if we find the underlying OS doesn't support it.
9818 ********************************************************************/
9819
9820 void set_use_sendfile(int snum, bool val)
9821 {
9822         if (LP_SNUM_OK(snum))
9823                 ServicePtrs[snum]->bUseSendfile = val;
9824         else
9825                 sDefault.bUseSendfile = val;
9826 }
9827
9828 /*******************************************************************
9829  Turn off storing DOS attributes if this share doesn't support it.
9830 ********************************************************************/
9831
9832 void set_store_dos_attributes(int snum, bool val)
9833 {
9834         if (!LP_SNUM_OK(snum))
9835                 return;
9836         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9837 }
9838
9839 void lp_set_mangling_method(const char *new_method)
9840 {
9841         string_set(&Globals.szManglingMethod, new_method);
9842 }
9843
9844 /*******************************************************************
9845  Global state for POSIX pathname processing.
9846 ********************************************************************/
9847
9848 static bool posix_pathnames;
9849
9850 bool lp_posix_pathnames(void)
9851 {
9852         return posix_pathnames;
9853 }
9854
9855 /*******************************************************************
9856  Change everything needed to ensure POSIX pathname processing (currently
9857  not much).
9858 ********************************************************************/
9859
9860 void lp_set_posix_pathnames(void)
9861 {
9862         posix_pathnames = True;
9863 }
9864
9865 /*******************************************************************
9866  Global state for POSIX lock processing - CIFS unix extensions.
9867 ********************************************************************/
9868
9869 bool posix_default_lock_was_set;
9870 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9871
9872 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9873 {
9874         if (posix_default_lock_was_set) {
9875                 return posix_cifsx_locktype;
9876         } else {
9877                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9878         }
9879 }
9880
9881 /*******************************************************************
9882 ********************************************************************/
9883
9884 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9885 {
9886         posix_default_lock_was_set = True;
9887         posix_cifsx_locktype = val;
9888 }
9889
9890 int lp_min_receive_file_size(void)
9891 {
9892         if (Globals.iminreceivefile < 0) {
9893                 return 0;
9894         }
9895         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9896 }
9897
9898 /*******************************************************************
9899  If socket address is an empty character string, it is necessary to 
9900  define it as "0.0.0.0". 
9901 ********************************************************************/
9902
9903 const char *lp_socket_address(void)
9904 {
9905         char *sock_addr = Globals.szSocketAddress;
9906
9907         if (sock_addr[0] == '\0'){
9908                 string_set(&Globals.szSocketAddress, "0.0.0.0");
9909         }
9910         return  Globals.szSocketAddress;
9911 }
9912
9913 void lp_set_passdb_backend(const char *backend)
9914 {
9915         string_set(&Globals.szPassdbBackend, backend);
9916 }
9917
9918 /*******************************************************************
9919  Safe wide links checks.
9920  This helper function always verify the validity of wide links,
9921  even after a configuration file reload.
9922 ********************************************************************/
9923
9924 static bool lp_widelinks_internal(int snum)
9925 {
9926         return (bool)(LP_SNUM_OK(snum)? ServicePtrs[(snum)]->bWidelinks :
9927                         sDefault.bWidelinks);
9928 }
9929
9930 void widelinks_warning(int snum)
9931 {
9932         if (lp_unix_extensions() && lp_widelinks_internal(snum)) {
9933                 DEBUG(0,("Share '%s' has wide links and unix extensions enabled. "
9934                         "These parameters are incompatible. "
9935                         "Wide links will be disabled for this share.\n",
9936                         lp_servicename(snum) ));
9937         }
9938 }
9939
9940 bool lp_widelinks(int snum)
9941 {
9942         /* wide links is always incompatible with unix extensions */
9943         if (lp_unix_extensions()) {
9944                 return false;
9945         }
9946
9947         return lp_widelinks_internal(snum);
9948 }