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