Sequel to c10aad9f13: Ignore whitespaces in parametric options
[sfrench/samba-autobuild/.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 (strwicmp(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 (strwicmp(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 (strwicmp(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;
7117         void *parm_ptr = NULL;  /* where we are going to store the result */
7118         void *def_ptr = NULL;
7119         struct param_opt_struct *paramo, *data;
7120         bool not_added;
7121
7122         parmnum = map_parameter(pszParmName);
7123
7124         if (parmnum < 0) {
7125                 TALLOC_CTX *frame;
7126
7127                 if (strchr(pszParmName, ':') == NULL) {
7128                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7129                                   pszParmName));
7130                         return (True);
7131                 }
7132
7133                 /*
7134                  * We've got a parametric option
7135                  */
7136
7137                 frame = talloc_stackframe();
7138
7139                 not_added = True;
7140                 data = (snum < 0)
7141                         ? Globals.param_opt : ServicePtrs[snum]->param_opt;
7142                 /* Traverse destination */
7143                 while (data) {
7144                         /* If we already have same option, override it */
7145                         if (strwicmp(data->key, pszParmName) == 0) {
7146                                 string_free(&data->value);
7147                                 TALLOC_FREE(data->list);
7148                                 data->value = SMB_STRDUP(pszParmValue);
7149                                 not_added = False;
7150                                 break;
7151                         }
7152                         data = data->next;
7153                 }
7154                 if (not_added) {
7155                         paramo = SMB_XMALLOC_P(struct param_opt_struct);
7156                         paramo->key = SMB_STRDUP(pszParmName);
7157                         paramo->value = SMB_STRDUP(pszParmValue);
7158                         paramo->list = NULL;
7159                         if (snum < 0) {
7160                                 DLIST_ADD(Globals.param_opt, paramo);
7161                         } else {
7162                                 DLIST_ADD(ServicePtrs[snum]->param_opt,
7163                                           paramo);
7164                         }
7165                 }
7166
7167                 TALLOC_FREE(frame);
7168                 return (True);
7169         }
7170
7171         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7172                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7173                           pszParmName));
7174         }
7175
7176         def_ptr = parm_table[parmnum].ptr;
7177
7178         /* we might point at a service, the default service or a global */
7179         if (snum < 0) {
7180                 parm_ptr = def_ptr;
7181         } else {
7182                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7183                         DEBUG(0,
7184                               ("Global parameter %s found in service section!\n",
7185                                pszParmName));
7186                         return (True);
7187                 }
7188                 parm_ptr =
7189                         ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7190                                                             &sDefault);
7191         }
7192
7193         if (snum >= 0) {
7194                 if (!ServicePtrs[snum]->copymap)
7195                         init_copymap(ServicePtrs[snum]);
7196
7197                 /* this handles the aliases - set the copymap for other entries with
7198                    the same data pointer */
7199                 for (i = 0; parm_table[i].label; i++)
7200                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7201                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7202         }
7203
7204         /* if it is a special case then go ahead */
7205         if (parm_table[parmnum].special) {
7206                 return parm_table[parmnum].special(snum, pszParmValue,
7207                                                    (char **)parm_ptr);
7208         }
7209
7210         /* now switch on the type of variable it is */
7211         switch (parm_table[parmnum].type)
7212         {
7213                 case P_BOOL:
7214                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7215                         break;
7216
7217                 case P_BOOLREV:
7218                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7219                         break;
7220
7221                 case P_INTEGER:
7222                         *(int *)parm_ptr = lp_int(pszParmValue);
7223                         break;
7224
7225                 case P_CHAR:
7226                         *(char *)parm_ptr = *pszParmValue;
7227                         break;
7228
7229                 case P_OCTAL:
7230                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7231                         if ( i != 1 ) {
7232                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7233                         }
7234                         break;
7235
7236                 case P_LIST:
7237                         TALLOC_FREE(*((char ***)parm_ptr));
7238                         *(char ***)parm_ptr = str_list_make(
7239                                 NULL, pszParmValue, NULL);
7240                         break;
7241
7242                 case P_STRING:
7243                         string_set((char **)parm_ptr, pszParmValue);
7244                         break;
7245
7246                 case P_USTRING:
7247                         string_set((char **)parm_ptr, pszParmValue);
7248                         strupper_m(*(char **)parm_ptr);
7249                         break;
7250
7251                 case P_ENUM:
7252                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7253                         break;
7254                 case P_SEP:
7255                         break;
7256         }
7257
7258         return (True);
7259 }
7260
7261 /***************************************************************************
7262  Process a parameter.
7263 ***************************************************************************/
7264
7265 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7266                          void *userdata)
7267 {
7268         if (!bInGlobalSection && bGlobalOnly)
7269                 return (True);
7270
7271         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7272
7273         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7274                                 pszParmName, pszParmValue));
7275 }
7276
7277 /***************************************************************************
7278  Print a parameter of the specified type.
7279 ***************************************************************************/
7280
7281 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7282 {
7283         int i;
7284         switch (p->type)
7285         {
7286                 case P_ENUM:
7287                         for (i = 0; p->enum_list[i].name; i++) {
7288                                 if (*(int *)ptr == p->enum_list[i].value) {
7289                                         fprintf(f, "%s",
7290                                                 p->enum_list[i].name);
7291                                         break;
7292                                 }
7293                         }
7294                         break;
7295
7296                 case P_BOOL:
7297                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7298                         break;
7299
7300                 case P_BOOLREV:
7301                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7302                         break;
7303
7304                 case P_INTEGER:
7305                         fprintf(f, "%d", *(int *)ptr);
7306                         break;
7307
7308                 case P_CHAR:
7309                         fprintf(f, "%c", *(char *)ptr);
7310                         break;
7311
7312                 case P_OCTAL: {
7313                         char *o = octal_string(*(int *)ptr);
7314                         fprintf(f, "%s", o);
7315                         TALLOC_FREE(o);
7316                         break;
7317                 }
7318
7319                 case P_LIST:
7320                         if ((char ***)ptr && *(char ***)ptr) {
7321                                 char **list = *(char ***)ptr;
7322                                 for (; *list; list++) {
7323                                         /* surround strings with whitespace in double quotes */
7324                                         if ( strchr_m( *list, ' ' ) )
7325                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7326                                         else
7327                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7328                                 }
7329                         }
7330                         break;
7331
7332                 case P_STRING:
7333                 case P_USTRING:
7334                         if (*(char **)ptr) {
7335                                 fprintf(f, "%s", *(char **)ptr);
7336                         }
7337                         break;
7338                 case P_SEP:
7339                         break;
7340         }
7341 }
7342
7343 /***************************************************************************
7344  Check if two parameters are equal.
7345 ***************************************************************************/
7346
7347 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7348 {
7349         switch (type) {
7350                 case P_BOOL:
7351                 case P_BOOLREV:
7352                         return (*((bool *)ptr1) == *((bool *)ptr2));
7353
7354                 case P_INTEGER:
7355                 case P_ENUM:
7356                 case P_OCTAL:
7357                         return (*((int *)ptr1) == *((int *)ptr2));
7358
7359                 case P_CHAR:
7360                         return (*((char *)ptr1) == *((char *)ptr2));
7361
7362                 case P_LIST:
7363                         return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7364
7365                 case P_STRING:
7366                 case P_USTRING:
7367                 {
7368                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7369                         if (p1 && !*p1)
7370                                 p1 = NULL;
7371                         if (p2 && !*p2)
7372                                 p2 = NULL;
7373                         return (p1 == p2 || strequal(p1, p2));
7374                 }
7375                 case P_SEP:
7376                         break;
7377         }
7378         return (False);
7379 }
7380
7381 /***************************************************************************
7382  Initialize any local varients in the sDefault table.
7383 ***************************************************************************/
7384
7385 void init_locals(void)
7386 {
7387         /* None as yet. */
7388 }
7389
7390 /***************************************************************************
7391  Process a new section (service). At this stage all sections are services.
7392  Later we'll have special sections that permit server parameters to be set.
7393  Returns True on success, False on failure. 
7394 ***************************************************************************/
7395
7396 static bool do_section(const char *pszSectionName, void *userdata)
7397 {
7398         bool bRetval;
7399         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7400                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7401         bRetval = False;
7402
7403         /* if we were in a global section then do the local inits */
7404         if (bInGlobalSection && !isglobal)
7405                 init_locals();
7406
7407         /* if we've just struck a global section, note the fact. */
7408         bInGlobalSection = isglobal;
7409
7410         /* check for multiple global sections */
7411         if (bInGlobalSection) {
7412                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7413                 return (True);
7414         }
7415
7416         if (!bInGlobalSection && bGlobalOnly)
7417                 return (True);
7418
7419         /* if we have a current service, tidy it up before moving on */
7420         bRetval = True;
7421
7422         if (iServiceIndex >= 0)
7423                 bRetval = service_ok(iServiceIndex);
7424
7425         /* if all is still well, move to the next record in the services array */
7426         if (bRetval) {
7427                 /* We put this here to avoid an odd message order if messages are */
7428                 /* issued by the post-processing of a previous section. */
7429                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7430
7431                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7432                     < 0) {
7433                         DEBUG(0, ("Failed to add a new service\n"));
7434                         return (False);
7435                 }
7436         }
7437
7438         return (bRetval);
7439 }
7440
7441
7442 /***************************************************************************
7443  Determine if a partcular base parameter is currentl set to the default value.
7444 ***************************************************************************/
7445
7446 static bool is_default(int i)
7447 {
7448         if (!defaults_saved)
7449                 return False;
7450         switch (parm_table[i].type) {
7451                 case P_LIST:
7452                         return str_list_compare (parm_table[i].def.lvalue, 
7453                                                 *(char ***)parm_table[i].ptr);
7454                 case P_STRING:
7455                 case P_USTRING:
7456                         return strequal(parm_table[i].def.svalue,
7457                                         *(char **)parm_table[i].ptr);
7458                 case P_BOOL:
7459                 case P_BOOLREV:
7460                         return parm_table[i].def.bvalue ==
7461                                 *(bool *)parm_table[i].ptr;
7462                 case P_CHAR:
7463                         return parm_table[i].def.cvalue ==
7464                                 *(char *)parm_table[i].ptr;
7465                 case P_INTEGER:
7466                 case P_OCTAL:
7467                 case P_ENUM:
7468                         return parm_table[i].def.ivalue ==
7469                                 *(int *)parm_table[i].ptr;
7470                 case P_SEP:
7471                         break;
7472         }
7473         return False;
7474 }
7475
7476 /***************************************************************************
7477 Display the contents of the global structure.
7478 ***************************************************************************/
7479
7480 static void dump_globals(FILE *f)
7481 {
7482         int i;
7483         struct param_opt_struct *data;
7484         
7485         fprintf(f, "[global]\n");
7486
7487         for (i = 0; parm_table[i].label; i++)
7488                 if (parm_table[i].p_class == P_GLOBAL &&
7489                     parm_table[i].ptr &&
7490                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7491                         if (defaults_saved && is_default(i))
7492                                 continue;
7493                         fprintf(f, "\t%s = ", parm_table[i].label);
7494                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
7495                         fprintf(f, "\n");
7496         }
7497         if (Globals.param_opt != NULL) {
7498                 data = Globals.param_opt;
7499                 while(data) {
7500                         fprintf(f, "\t%s = %s\n", data->key, data->value);
7501                         data = data->next;
7502                 }
7503         }
7504
7505 }
7506
7507 /***************************************************************************
7508  Return True if a local parameter is currently set to the global default.
7509 ***************************************************************************/
7510
7511 bool lp_is_default(int snum, struct parm_struct *parm)
7512 {
7513         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7514
7515         return equal_parameter(parm->type,
7516                                ((char *)ServicePtrs[snum]) + pdiff,
7517                                ((char *)&sDefault) + pdiff);
7518 }
7519
7520 /***************************************************************************
7521  Display the contents of a single services record.
7522 ***************************************************************************/
7523
7524 static void dump_a_service(struct service *pService, FILE * f)
7525 {
7526         int i;
7527         struct param_opt_struct *data;
7528         
7529         if (pService != &sDefault)
7530                 fprintf(f, "[%s]\n", pService->szService);
7531
7532         for (i = 0; parm_table[i].label; i++) {
7533
7534                 if (parm_table[i].p_class == P_LOCAL &&
7535                     parm_table[i].ptr &&
7536                     (*parm_table[i].label != '-') &&
7537                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7538                 {
7539                 
7540                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7541
7542                         if (pService == &sDefault) {
7543                                 if (defaults_saved && is_default(i))
7544                                         continue;
7545                         } else {
7546                                 if (equal_parameter(parm_table[i].type,
7547                                                     ((char *)pService) +
7548                                                     pdiff,
7549                                                     ((char *)&sDefault) +
7550                                                     pdiff))
7551                                         continue;
7552                         }
7553
7554                         fprintf(f, "\t%s = ", parm_table[i].label);
7555                         print_parameter(&parm_table[i],
7556                                         ((char *)pService) + pdiff, f);
7557                         fprintf(f, "\n");
7558                 }
7559         }
7560
7561                 if (pService->param_opt != NULL) {
7562                         data = pService->param_opt;
7563                         while(data) {
7564                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
7565                                 data = data->next;
7566                         }
7567                 }
7568 }
7569
7570 /***************************************************************************
7571  Display the contents of a parameter of a single services record.
7572 ***************************************************************************/
7573
7574 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7575 {
7576         int i;
7577         bool result = False;
7578         parm_class p_class;
7579         unsigned flag = 0;
7580         fstring local_parm_name;
7581         char *parm_opt;
7582         const char *parm_opt_value;
7583
7584         /* check for parametrical option */
7585         fstrcpy( local_parm_name, parm_name);
7586         parm_opt = strchr( local_parm_name, ':');
7587
7588         if (parm_opt) {
7589                 *parm_opt = '\0';
7590                 parm_opt++;
7591                 if (strlen(parm_opt)) {
7592                         parm_opt_value = lp_parm_const_string( snum,
7593                                 local_parm_name, parm_opt, NULL);
7594                         if (parm_opt_value) {
7595                                 printf( "%s\n", parm_opt_value);
7596                                 result = True;
7597                         }
7598                 }
7599                 return result;
7600         }
7601
7602         /* check for a key and print the value */
7603         if (isGlobal) {
7604                 p_class = P_GLOBAL;
7605                 flag = FLAG_GLOBAL;
7606         } else
7607                 p_class = P_LOCAL;
7608
7609         for (i = 0; parm_table[i].label; i++) {
7610                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7611                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7612                     parm_table[i].ptr &&
7613                     (*parm_table[i].label != '-') &&
7614                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7615                 {
7616                         void *ptr;
7617
7618                         if (isGlobal) {
7619                                 ptr = parm_table[i].ptr;
7620                         } else {
7621                                 struct service *pService = ServicePtrs[snum];
7622                                 ptr = ((char *)pService) +
7623                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
7624                         }
7625
7626                         print_parameter(&parm_table[i],
7627                                         ptr, f);
7628                         fprintf(f, "\n");
7629                         result = True;
7630                         break;
7631                 }
7632         }
7633
7634         return result;
7635 }
7636
7637 /***************************************************************************
7638  Return info about the requested parameter (given as a string).
7639  Return NULL when the string is not a valid parameter name.
7640 ***************************************************************************/
7641
7642 struct parm_struct *lp_get_parameter(const char *param_name)
7643 {
7644         int num = map_parameter(param_name);
7645
7646         if (num < 0) {
7647                 return NULL;
7648         }
7649
7650         return &parm_table[num];
7651 }
7652
7653 /***************************************************************************
7654  Return info about the next parameter in a service.
7655  snum==GLOBAL_SECTION_SNUM gives the globals.
7656  Return NULL when out of parameters.
7657 ***************************************************************************/
7658
7659 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7660 {
7661         if (snum < 0) {
7662                 /* do the globals */
7663                 for (; parm_table[*i].label; (*i)++) {
7664                         if (parm_table[*i].p_class == P_SEPARATOR)
7665                                 return &parm_table[(*i)++];
7666
7667                         if (!parm_table[*i].ptr
7668                             || (*parm_table[*i].label == '-'))
7669                                 continue;
7670
7671                         if ((*i) > 0
7672                             && (parm_table[*i].ptr ==
7673                                 parm_table[(*i) - 1].ptr))
7674                                 continue;
7675                         
7676                         if (is_default(*i) && !allparameters)
7677                                 continue;
7678
7679                         return &parm_table[(*i)++];
7680                 }
7681         } else {
7682                 struct service *pService = ServicePtrs[snum];
7683
7684                 for (; parm_table[*i].label; (*i)++) {
7685                         if (parm_table[*i].p_class == P_SEPARATOR)
7686                                 return &parm_table[(*i)++];
7687
7688                         if (parm_table[*i].p_class == P_LOCAL &&
7689                             parm_table[*i].ptr &&
7690                             (*parm_table[*i].label != '-') &&
7691                             ((*i) == 0 ||
7692                              (parm_table[*i].ptr !=
7693                               parm_table[(*i) - 1].ptr)))
7694                         {
7695                                 int pdiff =
7696                                         PTR_DIFF(parm_table[*i].ptr,
7697                                                  &sDefault);
7698
7699                                 if (allparameters ||
7700                                     !equal_parameter(parm_table[*i].type,
7701                                                      ((char *)pService) +
7702                                                      pdiff,
7703                                                      ((char *)&sDefault) +
7704                                                      pdiff))
7705                                 {
7706                                         return &parm_table[(*i)++];
7707                                 }
7708                         }
7709                 }
7710         }
7711
7712         return NULL;
7713 }
7714
7715
7716 #if 0
7717 /***************************************************************************
7718  Display the contents of a single copy structure.
7719 ***************************************************************************/
7720 static void dump_copy_map(bool *pcopymap)
7721 {
7722         int i;
7723         if (!pcopymap)
7724                 return;
7725
7726         printf("\n\tNon-Copied parameters:\n");
7727
7728         for (i = 0; parm_table[i].label; i++)
7729                 if (parm_table[i].p_class == P_LOCAL &&
7730                     parm_table[i].ptr && !pcopymap[i] &&
7731                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7732                 {
7733                         printf("\t\t%s\n", parm_table[i].label);
7734                 }
7735 }
7736 #endif
7737
7738 /***************************************************************************
7739  Return TRUE if the passed service number is within range.
7740 ***************************************************************************/
7741
7742 bool lp_snum_ok(int iService)
7743 {
7744         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7745 }
7746
7747 /***************************************************************************
7748  Auto-load some home services.
7749 ***************************************************************************/
7750
7751 static void lp_add_auto_services(char *str)
7752 {
7753         char *s;
7754         char *p;
7755         int homes;
7756         char *saveptr;
7757
7758         if (!str)
7759                 return;
7760
7761         s = SMB_STRDUP(str);
7762         if (!s)
7763                 return;
7764
7765         homes = lp_servicenumber(HOMES_NAME);
7766
7767         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7768              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7769                 char *home;
7770
7771                 if (lp_servicenumber(p) >= 0)
7772                         continue;
7773
7774                 home = get_user_home_dir(talloc_tos(), p);
7775
7776                 if (home && homes >= 0)
7777                         lp_add_home(p, homes, p, home);
7778
7779                 TALLOC_FREE(home);
7780         }
7781         SAFE_FREE(s);
7782 }
7783
7784 /***************************************************************************
7785  Auto-load one printer.
7786 ***************************************************************************/
7787
7788 void lp_add_one_printer(char *name, char *comment)
7789 {
7790         int printers = lp_servicenumber(PRINTERS_NAME);
7791         int i;
7792
7793         if (lp_servicenumber(name) < 0) {
7794                 lp_add_printer(name, printers);
7795                 if ((i = lp_servicenumber(name)) >= 0) {
7796                         string_set(&ServicePtrs[i]->comment, comment);
7797                         ServicePtrs[i]->autoloaded = True;
7798                 }
7799         }
7800 }
7801
7802 /***************************************************************************
7803  Have we loaded a services file yet?
7804 ***************************************************************************/
7805
7806 bool lp_loaded(void)
7807 {
7808         return (bLoaded);
7809 }
7810
7811 /***************************************************************************
7812  Unload unused services.
7813 ***************************************************************************/
7814
7815 void lp_killunused(bool (*snumused) (int))
7816 {
7817         int i;
7818         for (i = 0; i < iNumServices; i++) {
7819                 if (!VALID(i))
7820                         continue;
7821
7822                 /* don't kill autoloaded or usershare services */
7823                 if ( ServicePtrs[i]->autoloaded ||
7824                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7825                         continue;
7826                 }
7827
7828                 if (!snumused || !snumused(i)) {
7829                         free_service_byindex(i);
7830                 }
7831         }
7832 }
7833
7834 /**
7835  * Kill all except autoloaded and usershare services - convenience wrapper
7836  */
7837 void lp_kill_all_services(void)
7838 {
7839         lp_killunused(NULL);
7840 }
7841
7842 /***************************************************************************
7843  Unload a service.
7844 ***************************************************************************/
7845
7846 void lp_killservice(int iServiceIn)
7847 {
7848         if (VALID(iServiceIn)) {
7849                 free_service_byindex(iServiceIn);
7850         }
7851 }
7852
7853 /***************************************************************************
7854  Save the curent values of all global and sDefault parameters into the 
7855  defaults union. This allows swat and testparm to show only the
7856  changed (ie. non-default) parameters.
7857 ***************************************************************************/
7858
7859 static void lp_save_defaults(void)
7860 {
7861         int i;
7862         for (i = 0; parm_table[i].label; i++) {
7863                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7864                         continue;
7865                 switch (parm_table[i].type) {
7866                         case P_LIST:
7867                                 str_list_copy(
7868                                         NULL, &(parm_table[i].def.lvalue),
7869                                         *(const char ***)parm_table[i].ptr);
7870                                 break;
7871                         case P_STRING:
7872                         case P_USTRING:
7873                                 if (parm_table[i].ptr) {
7874                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7875                                 } else {
7876                                         parm_table[i].def.svalue = NULL;
7877                                 }
7878                                 break;
7879                         case P_BOOL:
7880                         case P_BOOLREV:
7881                                 parm_table[i].def.bvalue =
7882                                         *(bool *)parm_table[i].ptr;
7883                                 break;
7884                         case P_CHAR:
7885                                 parm_table[i].def.cvalue =
7886                                         *(char *)parm_table[i].ptr;
7887                                 break;
7888                         case P_INTEGER:
7889                         case P_OCTAL:
7890                         case P_ENUM:
7891                                 parm_table[i].def.ivalue =
7892                                         *(int *)parm_table[i].ptr;
7893                                 break;
7894                         case P_SEP:
7895                                 break;
7896                 }
7897         }
7898         defaults_saved = True;
7899 }
7900
7901 /*******************************************************************
7902  Set the server type we will announce as via nmbd.
7903 ********************************************************************/
7904
7905 static const struct srv_role_tab {
7906         uint32 role;
7907         const char *role_str;
7908 } srv_role_tab [] = {
7909         { ROLE_STANDALONE, "ROLE_STANDALONE" },
7910         { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7911         { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7912         { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7913         { 0, NULL }
7914 };
7915
7916 const char* server_role_str(uint32 role)
7917 {
7918         int i = 0;
7919         for (i=0; srv_role_tab[i].role_str; i++) {
7920                 if (role == srv_role_tab[i].role) {
7921                         return srv_role_tab[i].role_str;
7922                 }
7923         }
7924         return NULL;
7925 }
7926
7927 static void set_server_role(void)
7928 {
7929         server_role = ROLE_STANDALONE;
7930
7931         switch (lp_security()) {
7932                 case SEC_SHARE:
7933                         if (lp_domain_logons())
7934                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7935                         break;
7936                 case SEC_SERVER:
7937                         if (lp_domain_logons())
7938                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7939                         /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7940                         server_role = ROLE_STANDALONE;
7941                         break;
7942                 case SEC_DOMAIN:
7943                         if (lp_domain_logons()) {
7944                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7945                                 server_role = ROLE_DOMAIN_BDC;
7946                                 break;
7947                         }
7948                         server_role = ROLE_DOMAIN_MEMBER;
7949                         break;
7950                 case SEC_ADS:
7951                         if (lp_domain_logons()) {
7952                                 server_role = ROLE_DOMAIN_PDC;
7953                                 break;
7954                         }
7955                         server_role = ROLE_DOMAIN_MEMBER;
7956                         break;
7957                 case SEC_USER:
7958                         if (lp_domain_logons()) {
7959
7960                                 if (Globals.iDomainMaster) /* auto or yes */ 
7961                                         server_role = ROLE_DOMAIN_PDC;
7962                                 else
7963                                         server_role = ROLE_DOMAIN_BDC;
7964                         }
7965                         break;
7966                 default:
7967                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7968                         break;
7969         }
7970
7971         DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7972 }
7973
7974 /***********************************************************
7975  If we should send plaintext/LANMAN passwords in the clinet
7976 ************************************************************/
7977
7978 static void set_allowed_client_auth(void)
7979 {
7980         if (Globals.bClientNTLMv2Auth) {
7981                 Globals.bClientLanManAuth = False;
7982         }
7983         if (!Globals.bClientLanManAuth) {
7984                 Globals.bClientPlaintextAuth = False;
7985         }
7986 }
7987
7988 /***************************************************************************
7989  JRA.
7990  The following code allows smbd to read a user defined share file.
7991  Yes, this is my intent. Yes, I'm comfortable with that...
7992
7993  THE FOLLOWING IS SECURITY CRITICAL CODE.
7994
7995  It washes your clothes, it cleans your house, it guards you while you sleep...
7996  Do not f%^k with it....
7997 ***************************************************************************/
7998
7999 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8000
8001 /***************************************************************************
8002  Check allowed stat state of a usershare file.
8003  Ensure we print out who is dicking with us so the admin can
8004  get their sorry ass fired.
8005 ***************************************************************************/
8006
8007 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8008 {
8009         if (!S_ISREG(psbuf->st_mode)) {
8010                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8011                         "not a regular file\n",
8012                         fname, (unsigned int)psbuf->st_uid ));
8013                 return False;
8014         }
8015
8016         /* Ensure this doesn't have the other write bit set. */
8017         if (psbuf->st_mode & S_IWOTH) {
8018                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8019                         "public write. Refusing to allow as a usershare file.\n",
8020                         fname, (unsigned int)psbuf->st_uid ));
8021                 return False;
8022         }
8023
8024         /* Should be 10k or less. */
8025         if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8026                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8027                         "too large (%u) to be a user share file.\n",
8028                         fname, (unsigned int)psbuf->st_uid,
8029                         (unsigned int)psbuf->st_size ));
8030                 return False;
8031         }
8032
8033         return True;
8034 }
8035
8036 /***************************************************************************
8037  Parse the contents of a usershare file.
8038 ***************************************************************************/
8039
8040 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8041                         SMB_STRUCT_STAT *psbuf,
8042                         const char *servicename,
8043                         int snum,
8044                         char **lines,
8045                         int numlines,
8046                         char **pp_sharepath,
8047                         char **pp_comment,
8048                         SEC_DESC **ppsd,
8049                         bool *pallow_guest)
8050 {
8051         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8052         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8053         int us_vers;
8054         SMB_STRUCT_DIR *dp;
8055         SMB_STRUCT_STAT sbuf;
8056         char *sharepath = NULL;
8057         char *comment = NULL;
8058
8059         *pp_sharepath = NULL;
8060         *pp_comment = NULL;
8061
8062         *pallow_guest = False;
8063
8064         if (numlines < 4) {
8065                 return USERSHARE_MALFORMED_FILE;
8066         }
8067
8068         if (strcmp(lines[0], "#VERSION 1") == 0) {
8069                 us_vers = 1;
8070         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8071                 us_vers = 2;
8072                 if (numlines < 5) {
8073                         return USERSHARE_MALFORMED_FILE;
8074                 }
8075         } else {
8076                 return USERSHARE_BAD_VERSION;
8077         }
8078
8079         if (strncmp(lines[1], "path=", 5) != 0) {
8080                 return USERSHARE_MALFORMED_PATH;
8081         }
8082
8083         sharepath = talloc_strdup(ctx, &lines[1][5]);
8084         if (!sharepath) {
8085                 return USERSHARE_POSIX_ERR;
8086         }
8087         trim_string(sharepath, " ", " ");
8088
8089         if (strncmp(lines[2], "comment=", 8) != 0) {
8090                 return USERSHARE_MALFORMED_COMMENT_DEF;
8091         }
8092
8093         comment = talloc_strdup(ctx, &lines[2][8]);
8094         if (!comment) {
8095                 return USERSHARE_POSIX_ERR;
8096         }
8097         trim_string(comment, " ", " ");
8098         trim_char(comment, '"', '"');
8099
8100         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8101                 return USERSHARE_MALFORMED_ACL_DEF;
8102         }
8103
8104         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8105                 return USERSHARE_ACL_ERR;
8106         }
8107
8108         if (us_vers == 2) {
8109                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8110                         return USERSHARE_MALFORMED_ACL_DEF;
8111                 }
8112                 if (lines[4][9] == 'y') {
8113                         *pallow_guest = True;
8114                 }
8115         }
8116
8117         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8118                 /* Path didn't change, no checks needed. */
8119                 *pp_sharepath = sharepath;
8120                 *pp_comment = comment;
8121                 return USERSHARE_OK;
8122         }
8123
8124         /* The path *must* be absolute. */
8125         if (sharepath[0] != '/') {
8126                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8127                         servicename, sharepath));
8128                 return USERSHARE_PATH_NOT_ABSOLUTE;
8129         }
8130
8131         /* If there is a usershare prefix deny list ensure one of these paths
8132            doesn't match the start of the user given path. */
8133         if (prefixdenylist) {
8134                 int i;
8135                 for ( i=0; prefixdenylist[i]; i++ ) {
8136                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8137                                 servicename, i, prefixdenylist[i], sharepath ));
8138                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8139                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8140                                         "usershare prefix deny list entries.\n",
8141                                         servicename, sharepath));
8142                                 return USERSHARE_PATH_IS_DENIED;
8143                         }
8144                 }
8145         }
8146
8147         /* If there is a usershare prefix allow list ensure one of these paths
8148            does match the start of the user given path. */
8149
8150         if (prefixallowlist) {
8151                 int i;
8152                 for ( i=0; prefixallowlist[i]; i++ ) {
8153                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8154                                 servicename, i, prefixallowlist[i], sharepath ));
8155                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8156                                 break;
8157                         }
8158                 }
8159                 if (prefixallowlist[i] == NULL) {
8160                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8161                                 "usershare prefix allow list entries.\n",
8162                                 servicename, sharepath));
8163                         return USERSHARE_PATH_NOT_ALLOWED;
8164                 }
8165         }
8166
8167         /* Ensure this is pointing to a directory. */
8168         dp = sys_opendir(sharepath);
8169
8170         if (!dp) {
8171                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8172                         servicename, sharepath));
8173                 return USERSHARE_PATH_NOT_DIRECTORY;
8174         }
8175
8176         /* Ensure the owner of the usershare file has permission to share
8177            this directory. */
8178
8179         if (sys_stat(sharepath, &sbuf) == -1) {
8180                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8181                         servicename, sharepath, strerror(errno) ));
8182                 sys_closedir(dp);
8183                 return USERSHARE_POSIX_ERR;
8184         }
8185
8186         sys_closedir(dp);
8187
8188         if (!S_ISDIR(sbuf.st_mode)) {
8189                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8190                         servicename, sharepath ));
8191                 return USERSHARE_PATH_NOT_DIRECTORY;
8192         }
8193
8194         /* Check if sharing is restricted to owner-only. */
8195         /* psbuf is the stat of the usershare definition file,
8196            sbuf is the stat of the target directory to be shared. */
8197
8198         if (lp_usershare_owner_only()) {
8199                 /* root can share anything. */
8200                 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8201                         return USERSHARE_PATH_NOT_ALLOWED;
8202                 }
8203         }
8204
8205         *pp_sharepath = sharepath;
8206         *pp_comment = comment;
8207         return USERSHARE_OK;
8208 }
8209
8210 /***************************************************************************
8211  Deal with a usershare file.
8212  Returns:
8213         >= 0 - snum
8214         -1 - Bad name, invalid contents.
8215            - service name already existed and not a usershare, problem
8216             with permissions to share directory etc.
8217 ***************************************************************************/
8218
8219 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8220 {
8221         SMB_STRUCT_STAT sbuf;
8222         SMB_STRUCT_STAT lsbuf;
8223         char *fname = NULL;
8224         char *sharepath = NULL;
8225         char *comment = NULL;
8226         fstring service_name;
8227         char **lines = NULL;
8228         int numlines = 0;
8229         int fd = -1;
8230         int iService = -1;
8231         TALLOC_CTX *ctx = NULL;
8232         SEC_DESC *psd = NULL;
8233         bool guest_ok = False;
8234
8235         /* Ensure share name doesn't contain invalid characters. */
8236         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8237                 DEBUG(0,("process_usershare_file: share name %s contains "
8238                         "invalid characters (any of %s)\n",
8239                         file_name, INVALID_SHARENAME_CHARS ));
8240                 return -1;
8241         }
8242
8243         fstrcpy(service_name, file_name);
8244
8245         if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8246         }
8247
8248         /* Minimize the race condition by doing an lstat before we
8249            open and fstat. Ensure this isn't a symlink link. */
8250
8251         if (sys_lstat(fname, &lsbuf) != 0) {
8252                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8253                         fname, strerror(errno) ));
8254                 SAFE_FREE(fname);
8255                 return -1;
8256         }
8257
8258         /* This must be a regular file, not a symlink, directory or
8259            other strange filetype. */
8260         if (!check_usershare_stat(fname, &lsbuf)) {
8261                 SAFE_FREE(fname);
8262                 return -1;
8263         }
8264
8265         {
8266                 char *canon_name = canonicalize_servicename(service_name);
8267                 TDB_DATA data = dbwrap_fetch_bystring(
8268                         ServiceHash, canon_name, canon_name);
8269
8270                 iService = -1;
8271
8272                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8273                         iService = *(int *)data.dptr;
8274                 }
8275                 TALLOC_FREE(canon_name);
8276         }
8277
8278         if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8279                 /* Nothing changed - Mark valid and return. */
8280                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8281                         service_name ));
8282                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8283                 SAFE_FREE(fname);
8284                 return iService;
8285         }
8286
8287         /* Try and open the file read only - no symlinks allowed. */
8288 #ifdef O_NOFOLLOW
8289         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8290 #else
8291         fd = sys_open(fname, O_RDONLY, 0);
8292 #endif
8293
8294         if (fd == -1) {
8295                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8296                         fname, strerror(errno) ));
8297                 SAFE_FREE(fname);
8298                 return -1;
8299         }
8300
8301         /* Now fstat to be *SURE* it's a regular file. */
8302         if (sys_fstat(fd, &sbuf) != 0) {
8303                 close(fd);
8304                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8305                         fname, strerror(errno) ));
8306                 SAFE_FREE(fname);
8307                 return -1;
8308         }
8309
8310         /* Is it the same dev/inode as was lstated ? */
8311         if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8312                 close(fd);
8313                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8314                         "Symlink spoofing going on ?\n", fname ));
8315                 SAFE_FREE(fname);
8316                 return -1;
8317         }
8318
8319         /* This must be a regular file, not a symlink, directory or
8320            other strange filetype. */
8321         if (!check_usershare_stat(fname, &sbuf)) {
8322                 SAFE_FREE(fname);
8323                 return -1;
8324         }
8325
8326         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8327
8328         close(fd);
8329         if (lines == NULL) {
8330                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8331                         fname, (unsigned int)sbuf.st_uid ));
8332                 SAFE_FREE(fname);
8333                 return -1;
8334         }
8335
8336         SAFE_FREE(fname);
8337
8338         /* Should we allow printers to be shared... ? */
8339         ctx = talloc_init("usershare_sd_xctx");
8340         if (!ctx) {
8341                 file_lines_free(lines);
8342                 return 1;
8343         }
8344
8345         if (parse_usershare_file(ctx, &sbuf, service_name,
8346                         iService, lines, numlines, &sharepath,
8347                         &comment, &psd, &guest_ok) != USERSHARE_OK) {
8348                 talloc_destroy(ctx);
8349                 file_lines_free(lines);
8350                 return -1;
8351         }
8352
8353         file_lines_free(lines);
8354
8355         /* Everything ok - add the service possibly using a template. */
8356         if (iService < 0) {
8357                 const struct service *sp = &sDefault;
8358                 if (snum_template != -1) {
8359                         sp = ServicePtrs[snum_template];
8360                 }
8361
8362                 if ((iService = add_a_service(sp, service_name)) < 0) {
8363                         DEBUG(0, ("process_usershare_file: Failed to add "
8364                                 "new service %s\n", service_name));
8365                         talloc_destroy(ctx);
8366                         return -1;
8367                 }
8368
8369                 /* Read only is controlled by usershare ACL below. */
8370                 ServicePtrs[iService]->bRead_only = False;
8371         }
8372
8373         /* Write the ACL of the new/modified share. */
8374         if (!set_share_security(service_name, psd)) {
8375                  DEBUG(0, ("process_usershare_file: Failed to set share "
8376                         "security for user share %s\n",
8377                         service_name ));
8378                 lp_remove_service(iService);
8379                 talloc_destroy(ctx);
8380                 return -1;
8381         }
8382
8383         /* If from a template it may be marked invalid. */
8384         ServicePtrs[iService]->valid = True;
8385
8386         /* Set the service as a valid usershare. */
8387         ServicePtrs[iService]->usershare = USERSHARE_VALID;
8388
8389         /* Set guest access. */
8390         if (lp_usershare_allow_guests()) {
8391                 ServicePtrs[iService]->bGuest_ok = guest_ok;
8392         }
8393
8394         /* And note when it was loaded. */
8395         ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8396         string_set(&ServicePtrs[iService]->szPath, sharepath);
8397         string_set(&ServicePtrs[iService]->comment, comment);
8398
8399         talloc_destroy(ctx);
8400
8401         return iService;
8402 }
8403
8404 /***************************************************************************
8405  Checks if a usershare entry has been modified since last load.
8406 ***************************************************************************/
8407
8408 static bool usershare_exists(int iService, time_t *last_mod)
8409 {
8410         SMB_STRUCT_STAT lsbuf;
8411         const char *usersharepath = Globals.szUsersharePath;
8412         char *fname;
8413
8414         if (asprintf(&fname, "%s/%s",
8415                                 usersharepath,
8416                                 ServicePtrs[iService]->szService) < 0) {
8417                 return false;
8418         }
8419
8420         if (sys_lstat(fname, &lsbuf) != 0) {
8421                 SAFE_FREE(fname);
8422                 return false;
8423         }
8424
8425         if (!S_ISREG(lsbuf.st_mode)) {
8426                 SAFE_FREE(fname);
8427                 return false;
8428         }
8429
8430         SAFE_FREE(fname);
8431         *last_mod = lsbuf.st_mtime;
8432         return true;
8433 }
8434
8435 /***************************************************************************
8436  Load a usershare service by name. Returns a valid servicenumber or -1.
8437 ***************************************************************************/
8438
8439 int load_usershare_service(const char *servicename)
8440 {
8441         SMB_STRUCT_STAT sbuf;
8442         const char *usersharepath = Globals.szUsersharePath;
8443         int max_user_shares = Globals.iUsershareMaxShares;
8444         int snum_template = -1;
8445
8446         if (*usersharepath == 0 ||  max_user_shares == 0) {
8447                 return -1;
8448         }
8449
8450         if (sys_stat(usersharepath, &sbuf) != 0) {
8451                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8452                         usersharepath, strerror(errno) ));
8453                 return -1;
8454         }
8455
8456         if (!S_ISDIR(sbuf.st_mode)) {
8457                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8458                         usersharepath ));
8459                 return -1;
8460         }
8461
8462         /*
8463          * This directory must be owned by root, and have the 't' bit set.
8464          * It also must not be writable by "other".
8465          */
8466
8467 #ifdef S_ISVTX
8468         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8469 #else
8470         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8471 #endif
8472                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8473                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8474                         usersharepath ));
8475                 return -1;
8476         }
8477
8478         /* Ensure the template share exists if it's set. */
8479         if (Globals.szUsershareTemplateShare[0]) {
8480                 /* We can't use lp_servicenumber here as we are recommending that
8481                    template shares have -valid=False set. */
8482                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8483                         if (ServicePtrs[snum_template]->szService &&
8484                                         strequal(ServicePtrs[snum_template]->szService,
8485                                                 Globals.szUsershareTemplateShare)) {
8486                                 break;
8487                         }
8488                 }
8489
8490                 if (snum_template == -1) {
8491                         DEBUG(0,("load_usershare_service: usershare template share %s "
8492                                 "does not exist.\n",
8493                                 Globals.szUsershareTemplateShare ));
8494                         return -1;
8495                 }
8496         }
8497
8498         return process_usershare_file(usersharepath, servicename, snum_template);
8499 }
8500
8501 /***************************************************************************
8502  Load all user defined shares from the user share directory.
8503  We only do this if we're enumerating the share list.
8504  This is the function that can delete usershares that have
8505  been removed.
8506 ***************************************************************************/
8507
8508 int load_usershare_shares(void)
8509 {
8510         SMB_STRUCT_DIR *dp;
8511         SMB_STRUCT_STAT sbuf;
8512         SMB_STRUCT_DIRENT *de;
8513         int num_usershares = 0;
8514         int max_user_shares = Globals.iUsershareMaxShares;
8515         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8516         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8517         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8518         int iService;
8519         int snum_template = -1;
8520         const char *usersharepath = Globals.szUsersharePath;
8521         int ret = lp_numservices();
8522
8523         if (max_user_shares == 0 || *usersharepath == '\0') {
8524                 return lp_numservices();
8525         }
8526
8527         if (sys_stat(usersharepath, &sbuf) != 0) {
8528                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8529                         usersharepath, strerror(errno) ));
8530                 return ret;
8531         }
8532
8533         /*
8534          * This directory must be owned by root, and have the 't' bit set.
8535          * It also must not be writable by "other".
8536          */
8537
8538 #ifdef S_ISVTX
8539         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8540 #else
8541         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8542 #endif
8543                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8544                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8545                         usersharepath ));
8546                 return ret;
8547         }
8548
8549         /* Ensure the template share exists if it's set. */
8550         if (Globals.szUsershareTemplateShare[0]) {
8551                 /* We can't use lp_servicenumber here as we are recommending that
8552                    template shares have -valid=False set. */
8553                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8554                         if (ServicePtrs[snum_template]->szService &&
8555                                         strequal(ServicePtrs[snum_template]->szService,
8556                                                 Globals.szUsershareTemplateShare)) {
8557                                 break;
8558                         }
8559                 }
8560
8561                 if (snum_template == -1) {
8562                         DEBUG(0,("load_usershare_shares: usershare template share %s "
8563                                 "does not exist.\n",
8564                                 Globals.szUsershareTemplateShare ));
8565                         return ret;
8566                 }
8567         }
8568
8569         /* Mark all existing usershares as pending delete. */
8570         for (iService = iNumServices - 1; iService >= 0; iService--) {
8571                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8572                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8573                 }
8574         }
8575
8576         dp = sys_opendir(usersharepath);
8577         if (!dp) {
8578                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8579                         usersharepath, strerror(errno) ));
8580                 return ret;
8581         }
8582
8583         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8584                         (de = sys_readdir(dp));
8585                         num_dir_entries++ ) {
8586                 int r;
8587                 const char *n = de->d_name;
8588
8589                 /* Ignore . and .. */
8590                 if (*n == '.') {
8591                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8592                                 continue;
8593                         }
8594                 }
8595
8596                 if (n[0] == ':') {
8597                         /* Temporary file used when creating a share. */
8598                         num_tmp_dir_entries++;
8599                 }
8600
8601                 /* Allow 20% tmp entries. */
8602                 if (num_tmp_dir_entries > allowed_tmp_entries) {
8603                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8604                                 "in directory %s\n",
8605                                 num_tmp_dir_entries, usersharepath));
8606                         break;
8607                 }
8608
8609                 r = process_usershare_file(usersharepath, n, snum_template);
8610                 if (r == 0) {
8611                         /* Update the services count. */
8612                         num_usershares++;
8613                         if (num_usershares >= max_user_shares) {
8614                                 DEBUG(0,("load_usershare_shares: max user shares reached "
8615                                         "on file %s in directory %s\n",
8616                                         n, usersharepath ));
8617                                 break;
8618                         }
8619                 } else if (r == -1) {
8620                         num_bad_dir_entries++;
8621                 }
8622
8623                 /* Allow 20% bad entries. */
8624                 if (num_bad_dir_entries > allowed_bad_entries) {
8625                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8626                                 "in directory %s\n",
8627                                 num_bad_dir_entries, usersharepath));
8628                         break;
8629                 }
8630
8631                 /* Allow 20% bad entries. */
8632                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8633                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8634                         "in directory %s\n",
8635                         num_dir_entries, usersharepath));
8636                         break;
8637                 }
8638         }
8639
8640         sys_closedir(dp);
8641
8642         /* Sweep through and delete any non-refreshed usershares that are
8643            not currently in use. */
8644         for (iService = iNumServices - 1; iService >= 0; iService--) {
8645                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8646                         if (conn_snum_used(iService)) {
8647                                 continue;
8648                         }
8649                         /* Remove from the share ACL db. */
8650                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8651                                 lp_servicename(iService) ));
8652                         delete_share_security(lp_servicename(iService));
8653                         free_service_byindex(iService);
8654                 }
8655         }
8656
8657         return lp_numservices();
8658 }
8659
8660 /********************************************************
8661  Destroy global resources allocated in this file
8662 ********************************************************/
8663
8664 void gfree_loadparm(void)
8665 {
8666         struct file_lists *f;
8667         struct file_lists *next;
8668         int i;
8669
8670         /* Free the file lists */
8671
8672         f = file_lists;
8673         while( f ) {
8674                 next = f->next;
8675                 SAFE_FREE( f->name );
8676                 SAFE_FREE( f->subfname );
8677                 SAFE_FREE( f );
8678                 f = next;
8679         }
8680
8681         /* Free resources allocated to services */
8682
8683         for ( i = 0; i < iNumServices; i++ ) {
8684                 if ( VALID(i) ) {
8685                         free_service_byindex(i);
8686                 }
8687         }
8688
8689         SAFE_FREE( ServicePtrs );
8690         iNumServices = 0;
8691
8692         /* Now release all resources allocated to global
8693            parameters and the default service */
8694
8695         for (i = 0; parm_table[i].label; i++) 
8696         {
8697                 if ( parm_table[i].type == P_STRING 
8698                         || parm_table[i].type == P_USTRING ) 
8699                 {
8700                         string_free( (char**)parm_table[i].ptr );
8701                 }
8702                 else if (parm_table[i].type == P_LIST) {
8703                         TALLOC_FREE( *((char***)parm_table[i].ptr) );
8704                 }
8705         }
8706 }
8707
8708
8709 /***************************************************************************
8710  Allow client apps to specify that they are a client
8711 ***************************************************************************/
8712 void lp_set_in_client(bool b)
8713 {
8714     in_client = b;
8715 }
8716
8717
8718 /***************************************************************************
8719  Determine if we're running in a client app
8720 ***************************************************************************/
8721 bool lp_is_in_client(void)
8722 {
8723     return in_client;
8724 }
8725
8726
8727
8728
8729 /***************************************************************************
8730  Load the services array from the services file. Return True on success, 
8731  False on failure.
8732 ***************************************************************************/
8733
8734 bool lp_load_ex(const char *pszFname,
8735                 bool global_only,
8736                 bool save_defaults,
8737                 bool add_ipc,
8738                 bool initialize_globals,
8739                 bool allow_include_registry,
8740                 bool allow_registry_shares)
8741 {
8742         char *n2 = NULL;
8743         bool bRetval;
8744         struct param_opt_struct *data, *pdata;
8745
8746         bRetval = False;
8747
8748         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8749
8750         bInGlobalSection = True;
8751         bGlobalOnly = global_only;
8752         bAllowIncludeRegistry = allow_include_registry;
8753
8754         init_globals(! initialize_globals);
8755         debug_init();
8756
8757         if (save_defaults) {
8758                 init_locals();
8759                 lp_save_defaults();
8760         }
8761
8762         /* We get sections first, so have to start 'behind' to make up */
8763         iServiceIndex = -1;
8764
8765         if (Globals.param_opt != NULL) {
8766                 data = Globals.param_opt;
8767                 while (data) {
8768                         string_free(&data->key);
8769                         string_free(&data->value);
8770                         TALLOC_FREE(data->list);
8771                         pdata = data->next;
8772                         SAFE_FREE(data);
8773                         data = pdata;
8774                 }
8775                 Globals.param_opt = NULL;
8776         }
8777
8778         if (lp_config_backend_is_file()) {
8779                 n2 = alloc_sub_basic(get_current_username(),
8780                                         current_user_info.domain,
8781                                         pszFname);
8782                 if (!n2) {
8783                         smb_panic("lp_load_ex: out of memory");
8784                 }
8785
8786                 add_to_file_list(pszFname, n2);
8787
8788                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8789                 SAFE_FREE(n2);
8790
8791                 /* finish up the last section */
8792                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8793                 if (bRetval) {
8794                         if (iServiceIndex >= 0) {
8795                                 bRetval = service_ok(iServiceIndex);
8796                         }
8797                 }
8798
8799                 if (lp_config_backend_is_registry()) {
8800                         /* config backend changed to registry in config file */
8801                         /*
8802                          * We need to use this extra global variable here to
8803                          * survive restart: init_globals uses this as a default
8804                          * for ConfigBackend. Otherwise, init_globals would
8805                          *  send us into an endless loop here.
8806                          */
8807                         config_backend = CONFIG_BACKEND_REGISTRY;
8808                         /* start over */
8809                         DEBUG(1, ("lp_load_ex: changing to config backend "
8810                                   "registry\n"));
8811                         init_globals(false);
8812                         lp_kill_all_services();
8813                         return lp_load_ex(pszFname, global_only, save_defaults,
8814                                           add_ipc, initialize_globals,
8815                                           allow_include_registry,
8816                                           allow_registry_shares);
8817                 }
8818         } else if (lp_config_backend_is_registry()) {
8819                 bRetval = process_registry_globals();
8820         } else {
8821                 DEBUG(0, ("Illegal config  backend given: %d\n",
8822                           lp_config_backend()));
8823                 bRetval = false;
8824         }
8825
8826         if (bRetval && lp_registry_shares() && allow_registry_shares) {
8827                 bRetval = process_registry_shares();
8828         }
8829
8830         lp_add_auto_services(lp_auto_services());
8831
8832         if (add_ipc) {
8833                 /* When 'restrict anonymous = 2' guest connections to ipc$
8834                    are denied */
8835                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8836                 if ( lp_enable_asu_support() ) {
8837                         lp_add_ipc("ADMIN$", false);
8838                 }
8839         }
8840
8841         set_server_role();
8842         set_default_server_announce_type();
8843         set_allowed_client_auth();
8844
8845         bLoaded = True;
8846
8847         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8848         /* if bWINSsupport is true and we are in the client            */
8849         if (lp_is_in_client() && Globals.bWINSsupport) {
8850                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8851         }
8852
8853         init_iconv();
8854
8855         bAllowIncludeRegistry = true;
8856
8857         return (bRetval);
8858 }
8859
8860 bool lp_load(const char *pszFname,
8861              bool global_only,
8862              bool save_defaults,
8863              bool add_ipc,
8864              bool initialize_globals)
8865 {
8866         return lp_load_ex(pszFname,
8867                           global_only,
8868                           save_defaults,
8869                           add_ipc,
8870                           initialize_globals,
8871                           true, false);
8872 }
8873
8874 bool lp_load_initial_only(const char *pszFname)
8875 {
8876         return lp_load_ex(pszFname,
8877                           true,
8878                           false,
8879                           false,
8880                           true,
8881                           false,
8882                           false);
8883 }
8884
8885 bool lp_load_with_registry_shares(const char *pszFname,
8886                                   bool global_only,
8887                                   bool save_defaults,
8888                                   bool add_ipc,
8889                                   bool initialize_globals)
8890 {
8891         return lp_load_ex(pszFname,
8892                           global_only,
8893                           save_defaults,
8894                           add_ipc,
8895                           initialize_globals,
8896                           true,
8897                           true);
8898 }
8899
8900 /***************************************************************************
8901  Return the max number of services.
8902 ***************************************************************************/
8903
8904 int lp_numservices(void)
8905 {
8906         return (iNumServices);
8907 }
8908
8909 /***************************************************************************
8910 Display the contents of the services array in human-readable form.
8911 ***************************************************************************/
8912
8913 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8914 {
8915         int iService;
8916
8917         if (show_defaults)
8918                 defaults_saved = False;
8919
8920         dump_globals(f);
8921
8922         dump_a_service(&sDefault, f);
8923
8924         for (iService = 0; iService < maxtoprint; iService++) {
8925                 fprintf(f,"\n");
8926                 lp_dump_one(f, show_defaults, iService);
8927         }
8928 }
8929
8930 /***************************************************************************
8931 Display the contents of one service in human-readable form.
8932 ***************************************************************************/
8933
8934 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8935 {
8936         if (VALID(snum)) {
8937                 if (ServicePtrs[snum]->szService[0] == '\0')
8938                         return;
8939                 dump_a_service(ServicePtrs[snum], f);
8940         }
8941 }
8942
8943 /***************************************************************************
8944 Return the number of the service with the given name, or -1 if it doesn't
8945 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8946 getservicebyname()! This works ONLY if all services have been loaded, and
8947 does not copy the found service.
8948 ***************************************************************************/
8949
8950 int lp_servicenumber(const char *pszServiceName)
8951 {
8952         int iService;
8953         fstring serviceName;
8954         
8955         if (!pszServiceName) {
8956                 return GLOBAL_SECTION_SNUM;
8957         }
8958         
8959         for (iService = iNumServices - 1; iService >= 0; iService--) {
8960                 if (VALID(iService) && ServicePtrs[iService]->szService) {
8961                         /*
8962                          * The substitution here is used to support %U is
8963                          * service names
8964                          */
8965                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
8966                         standard_sub_basic(get_current_username(),
8967                                            current_user_info.domain,
8968                                            serviceName,sizeof(serviceName));
8969                         if (strequal(serviceName, pszServiceName)) {
8970                                 break;
8971                         }
8972                 }
8973         }
8974
8975         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8976                 time_t last_mod;
8977
8978                 if (!usershare_exists(iService, &last_mod)) {
8979                         /* Remove the share security tdb entry for it. */
8980                         delete_share_security(lp_servicename(iService));
8981                         /* Remove it from the array. */
8982                         free_service_byindex(iService);
8983                         /* Doesn't exist anymore. */
8984                         return GLOBAL_SECTION_SNUM;
8985                 }
8986
8987                 /* Has it been modified ? If so delete and reload. */
8988                 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
8989                         /* Remove it from the array. */
8990                         free_service_byindex(iService);
8991                         /* and now reload it. */
8992                         iService = load_usershare_service(pszServiceName);
8993                 }
8994         }
8995
8996         if (iService < 0) {
8997                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
8998                 return GLOBAL_SECTION_SNUM;
8999         }
9000
9001         return (iService);
9002 }
9003
9004 bool share_defined(const char *service_name)
9005 {
9006         return (lp_servicenumber(service_name) != -1);
9007 }
9008
9009 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9010                                       const char *sharename)
9011 {
9012         struct share_params *result;
9013         char *sname;
9014         int snum;
9015
9016         if (!(sname = SMB_STRDUP(sharename))) {
9017                 return NULL;
9018         }
9019
9020         snum = find_service(sname);
9021         SAFE_FREE(sname);
9022
9023         if (snum < 0) {
9024                 return NULL;
9025         }
9026
9027         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9028                 DEBUG(0, ("talloc failed\n"));
9029                 return NULL;
9030         }
9031
9032         result->service = snum;
9033         return result;
9034 }
9035
9036 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9037 {
9038         struct share_iterator *result;
9039
9040         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9041                 DEBUG(0, ("talloc failed\n"));
9042                 return NULL;
9043         }
9044
9045         result->next_id = 0;
9046         return result;
9047 }
9048
9049 struct share_params *next_share(struct share_iterator *list)
9050 {
9051         struct share_params *result;
9052
9053         while (!lp_snum_ok(list->next_id) &&
9054                (list->next_id < lp_numservices())) {
9055                 list->next_id += 1;
9056         }
9057
9058         if (list->next_id >= lp_numservices()) {
9059                 return NULL;
9060         }
9061
9062         if (!(result = TALLOC_P(list, struct share_params))) {
9063                 DEBUG(0, ("talloc failed\n"));
9064                 return NULL;
9065         }
9066
9067         result->service = list->next_id;
9068         list->next_id += 1;
9069         return result;
9070 }
9071
9072 struct share_params *next_printer(struct share_iterator *list)
9073 {
9074         struct share_params *result;
9075
9076         while ((result = next_share(list)) != NULL) {
9077                 if (lp_print_ok(result->service)) {
9078                         break;
9079                 }
9080         }
9081         return result;
9082 }
9083
9084 /*
9085  * This is a hack for a transition period until we transformed all code from
9086  * service numbers to struct share_params.
9087  */
9088
9089 struct share_params *snum2params_static(int snum)
9090 {
9091         static struct share_params result;
9092         result.service = snum;
9093         return &result;
9094 }
9095
9096 /*******************************************************************
9097  A useful volume label function. 
9098 ********************************************************************/
9099
9100 const char *volume_label(int snum)
9101 {
9102         char *ret;
9103         const char *label = lp_volume(snum);
9104         if (!*label) {
9105                 label = lp_servicename(snum);
9106         }
9107                 
9108         /* This returns a 33 byte guarenteed null terminated string. */
9109         ret = talloc_strndup(talloc_tos(), label, 32);
9110         if (!ret) {
9111                 return "";
9112         }               
9113         return ret;
9114 }
9115
9116 /*******************************************************************
9117  Set the server type we will announce as via nmbd.
9118 ********************************************************************/
9119
9120 static void set_default_server_announce_type(void)
9121 {
9122         default_server_announce = 0;
9123         default_server_announce |= SV_TYPE_WORKSTATION;
9124         default_server_announce |= SV_TYPE_SERVER;
9125         default_server_announce |= SV_TYPE_SERVER_UNIX;
9126
9127         /* note that the flag should be set only if we have a 
9128            printer service but nmbd doesn't actually load the 
9129            services so we can't tell   --jerry */
9130
9131         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9132
9133         switch (lp_announce_as()) {
9134                 case ANNOUNCE_AS_NT_SERVER:
9135                         default_server_announce |= SV_TYPE_SERVER_NT;
9136                         /* fall through... */
9137                 case ANNOUNCE_AS_NT_WORKSTATION:
9138                         default_server_announce |= SV_TYPE_NT;
9139                         break;
9140                 case ANNOUNCE_AS_WIN95:
9141                         default_server_announce |= SV_TYPE_WIN95_PLUS;
9142                         break;
9143                 case ANNOUNCE_AS_WFW:
9144                         default_server_announce |= SV_TYPE_WFW;
9145                         break;
9146                 default:
9147                         break;
9148         }
9149
9150         switch (lp_server_role()) {
9151                 case ROLE_DOMAIN_MEMBER:
9152                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9153                         break;
9154                 case ROLE_DOMAIN_PDC:
9155                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9156                         break;
9157                 case ROLE_DOMAIN_BDC:
9158                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9159                         break;
9160                 case ROLE_STANDALONE:
9161                 default:
9162                         break;
9163         }
9164         if (lp_time_server())
9165                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9166
9167         if (lp_host_msdfs())
9168                 default_server_announce |= SV_TYPE_DFS_SERVER;
9169 }
9170
9171 /***********************************************************
9172  returns role of Samba server
9173 ************************************************************/
9174
9175 int lp_server_role(void)
9176 {
9177         return server_role;
9178 }
9179
9180 /***********************************************************
9181  If we are PDC then prefer us as DMB
9182 ************************************************************/
9183
9184 bool lp_domain_master(void)
9185 {
9186         if (Globals.iDomainMaster == Auto)
9187                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9188
9189         return (bool)Globals.iDomainMaster;
9190 }
9191
9192 /***********************************************************
9193  If we are DMB then prefer us as LMB
9194 ************************************************************/
9195
9196 bool lp_preferred_master(void)
9197 {
9198         if (Globals.iPreferredMaster == Auto)
9199                 return (lp_local_master() && lp_domain_master());
9200
9201         return (bool)Globals.iPreferredMaster;
9202 }
9203
9204 /*******************************************************************
9205  Remove a service.
9206 ********************************************************************/
9207
9208 void lp_remove_service(int snum)
9209 {
9210         ServicePtrs[snum]->valid = False;
9211         invalid_services[num_invalid_services++] = snum;
9212 }
9213
9214 /*******************************************************************
9215  Copy a service.
9216 ********************************************************************/
9217
9218 void lp_copy_service(int snum, const char *new_name)
9219 {
9220         do_section(new_name, NULL);
9221         if (snum >= 0) {
9222                 snum = lp_servicenumber(new_name);
9223                 if (snum >= 0)
9224                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9225         }
9226 }
9227
9228
9229 /*******************************************************************
9230  Get the default server type we will announce as via nmbd.
9231 ********************************************************************/
9232
9233 int lp_default_server_announce(void)
9234 {
9235         return default_server_announce;
9236 }
9237
9238 /*******************************************************************
9239  Split the announce version into major and minor numbers.
9240 ********************************************************************/
9241
9242 int lp_major_announce_version(void)
9243 {
9244         static bool got_major = False;
9245         static int major_version = DEFAULT_MAJOR_VERSION;
9246         char *vers;
9247         char *p;
9248
9249         if (got_major)
9250                 return major_version;
9251
9252         got_major = True;
9253         if ((vers = lp_announce_version()) == NULL)
9254                 return major_version;
9255
9256         if ((p = strchr_m(vers, '.')) == 0)
9257                 return major_version;
9258
9259         *p = '\0';
9260         major_version = atoi(vers);
9261         return major_version;
9262 }
9263
9264 int lp_minor_announce_version(void)
9265 {
9266         static bool got_minor = False;
9267         static int minor_version = DEFAULT_MINOR_VERSION;
9268         char *vers;
9269         char *p;
9270
9271         if (got_minor)
9272                 return minor_version;
9273
9274         got_minor = True;
9275         if ((vers = lp_announce_version()) == NULL)
9276                 return minor_version;
9277
9278         if ((p = strchr_m(vers, '.')) == 0)
9279                 return minor_version;
9280
9281         p++;
9282         minor_version = atoi(p);
9283         return minor_version;
9284 }
9285
9286 /***********************************************************
9287  Set the global name resolution order (used in smbclient).
9288 ************************************************************/
9289
9290 void lp_set_name_resolve_order(const char *new_order)
9291 {
9292         string_set(&Globals.szNameResolveOrder, new_order);
9293 }
9294
9295 const char *lp_printername(int snum)
9296 {
9297         const char *ret = _lp_printername(snum);
9298         if (ret == NULL || (ret != NULL && *ret == '\0'))
9299                 ret = lp_const_servicename(snum);
9300
9301         return ret;
9302 }
9303
9304
9305 /***********************************************************
9306  Allow daemons such as winbindd to fix their logfile name.
9307 ************************************************************/
9308
9309 void lp_set_logfile(const char *name)
9310 {
9311         string_set(&Globals.szLogFile, name);
9312         debug_set_logfile(name);
9313 }
9314
9315 /*******************************************************************
9316  Return the max print jobs per queue.
9317 ********************************************************************/
9318
9319 int lp_maxprintjobs(int snum)
9320 {
9321         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9322         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9323                 maxjobs = PRINT_MAX_JOBID - 1;
9324
9325         return maxjobs;
9326 }
9327
9328 const char *lp_printcapname(void)
9329 {
9330         if ((Globals.szPrintcapname != NULL) &&
9331             (Globals.szPrintcapname[0] != '\0'))
9332                 return Globals.szPrintcapname;
9333
9334         if (sDefault.iPrinting == PRINT_CUPS) {
9335 #ifdef HAVE_CUPS
9336                 return "cups";
9337 #else
9338                 return "lpstat";
9339 #endif
9340         }
9341
9342         if (sDefault.iPrinting == PRINT_BSD)
9343                 return "/etc/printcap";
9344
9345         return PRINTCAP_NAME;
9346 }
9347
9348 /*******************************************************************
9349  Ensure we don't use sendfile if server smb signing is active.
9350 ********************************************************************/
9351
9352 static uint32 spoolss_state;
9353
9354 bool lp_disable_spoolss( void )
9355 {
9356         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9357                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9358
9359         return spoolss_state == SVCCTL_STOPPED ? True : False;
9360 }
9361
9362 void lp_set_spoolss_state( uint32 state )
9363 {
9364         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9365
9366         spoolss_state = state;
9367 }
9368
9369 uint32 lp_get_spoolss_state( void )
9370 {
9371         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9372 }
9373
9374 /*******************************************************************
9375  Ensure we don't use sendfile if server smb signing is active.
9376 ********************************************************************/
9377
9378 bool lp_use_sendfile(int snum)
9379 {
9380         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9381         if (Protocol < PROTOCOL_NT1) {
9382                 return False;
9383         }
9384         return (_lp_use_sendfile(snum) &&
9385                         (get_remote_arch() != RA_WIN95) &&
9386                         !srv_is_signing_active());
9387 }
9388
9389 /*******************************************************************
9390  Turn off sendfile if we find the underlying OS doesn't support it.
9391 ********************************************************************/
9392
9393 void set_use_sendfile(int snum, bool val)
9394 {
9395         if (LP_SNUM_OK(snum))
9396                 ServicePtrs[snum]->bUseSendfile = val;
9397         else
9398                 sDefault.bUseSendfile = val;
9399 }
9400
9401 /*******************************************************************
9402  Turn off storing DOS attributes if this share doesn't support it.
9403 ********************************************************************/
9404
9405 void set_store_dos_attributes(int snum, bool val)
9406 {
9407         if (!LP_SNUM_OK(snum))
9408                 return;
9409         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9410 }
9411
9412 void lp_set_mangling_method(const char *new_method)
9413 {
9414         string_set(&Globals.szManglingMethod, new_method);
9415 }
9416
9417 /*******************************************************************
9418  Global state for POSIX pathname processing.
9419 ********************************************************************/
9420
9421 static bool posix_pathnames;
9422
9423 bool lp_posix_pathnames(void)
9424 {
9425         return posix_pathnames;
9426 }
9427
9428 /*******************************************************************
9429  Change everything needed to ensure POSIX pathname processing (currently
9430  not much).
9431 ********************************************************************/
9432
9433 void lp_set_posix_pathnames(void)
9434 {
9435         posix_pathnames = True;
9436 }
9437
9438 /*******************************************************************
9439  Global state for POSIX lock processing - CIFS unix extensions.
9440 ********************************************************************/
9441
9442 bool posix_default_lock_was_set;
9443 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9444
9445 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9446 {
9447         if (posix_default_lock_was_set) {
9448                 return posix_cifsx_locktype;
9449         } else {
9450                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9451         }
9452 }
9453
9454 /*******************************************************************
9455 ********************************************************************/
9456
9457 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9458 {
9459         posix_default_lock_was_set = True;
9460         posix_cifsx_locktype = val;
9461 }
9462
9463 int lp_min_receive_file_size(void)
9464 {
9465         if (Globals.iminreceivefile < 0) {
9466                 return 0;
9467         }
9468         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9469 }