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