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