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