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