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