Fix bug #5944 - nmbd does not boot if socket adress = "" is defined in smb.conf
[kai/samba.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    Copyright (C) Michael Adam 2008
13    
14    This program is free software; you can redistribute it and/or modify
15    it under the terms of the GNU General Public License as published by
16    the Free Software Foundation; either version 3 of the License, or
17    (at your option) any later version.
18    
19    This program is distributed in the hope that it will be useful,
20    but WITHOUT ANY WARRANTY; without even the implied warranty of
21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22    GNU General Public License for more details.
23    
24    You should have received a copy of the GNU General Public License
25    along with this program.  If not, see <http://www.gnu.org/licenses/>.
26 */
27
28 /*
29  *  Load parameters.
30  *
31  *  This module provides suitable callback functions for the params
32  *  module. It builds the internal table of service details which is
33  *  then used by the rest of the server.
34  *
35  * To add a parameter:
36  *
37  * 1) add it to the global or service structure definition
38  * 2) add it to the parm_table
39  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40  * 4) If it's a global then initialise it in init_globals. If a local
41  *    (ie. service) parameter then initialise it in the sDefault structure
42  *  
43  *
44  * Notes:
45  *   The configuration file is processed sequentially for speed. It is NOT
46  *   accessed randomly as happens in 'real' Windows. For this reason, there
47  *   is a fair bit of sequence-dependent code here - ie., code which assumes
48  *   that certain things happen before others. In particular, the code which
49  *   happens at the boundary between sections is delicately poised, so be
50  *   careful!
51  *
52  */
53
54 #include "includes.h"
55 #include "printing.h"
56
57 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_nis_home_map_name, &Globals.szNISHomeMapName)
5067 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5068 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5069 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5070  * lp_passdb_backend() should be replace by the this macro again after
5071  * some releases.
5072  * */
5073 const char *lp_passdb_backend(void)
5074 {
5075         char *delim, *quote;
5076
5077         delim = strchr( Globals.szPassdbBackend, ' ');
5078         /* no space at all */
5079         if (delim == NULL) {
5080                 goto out;
5081         }
5082
5083         quote = strchr(Globals.szPassdbBackend, '"');
5084         /* no quote char or non in the first part */
5085         if (quote == NULL || quote > delim) {
5086                 *delim = '\0';
5087                 goto warn;
5088         }
5089
5090         quote = strchr(quote+1, '"');
5091         if (quote == NULL) {
5092                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5093                 goto out;
5094         } else if (*(quote+1) == '\0') {
5095                 /* space, fitting quote char, and one backend only */
5096                 goto out;
5097         } else {
5098                 /* terminate string after the fitting quote char */
5099                 *(quote+1) = '\0';
5100         }
5101
5102 warn:
5103         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
5104                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
5105                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
5106                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
5107
5108 out:
5109         return Globals.szPassdbBackend;
5110 }
5111 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5112 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5113 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5114 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5115 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5116
5117 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5118 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5119 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5120 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5121 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5122 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5123
5124 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5125
5126 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5127 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5128 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5129
5130 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5131
5132 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5133 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5134 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5135 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5136 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5137 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5138 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5139 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5140 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5141 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5142 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5143 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5144 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5145 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5146 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5147
5148 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5149 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5150 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5151 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5152 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5153 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5154
5155 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5156 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5157 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5158 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5159 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5160 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5161 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5162 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5163 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5164 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5165 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5166 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5167 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5168 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5169 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5170 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5171 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5172
5173 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5174
5175 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5176 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5177 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5178 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5179 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5180 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5181 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5182 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5183 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5184 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5185 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5186 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5187 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5188 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5189 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5190 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5191 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5192 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5193 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5194 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5195 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5196 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5197 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5198 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5199 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5200 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5201 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5202 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5203 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5204 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5205 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5206 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5207 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5208 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5209 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5210 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5211 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5212 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5213 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5214 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5215 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5216 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5217 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5218 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5219 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5220 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5221 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5222 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5223 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5224 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5225 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5226 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5227 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5228 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5229 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5230 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5231 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5232 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5233 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5234 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5235 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5236 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5237 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5238 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5239 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5240 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5241 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5242 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5243 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5244 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5245 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5246 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5247 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5248 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5249 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5250 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5251 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5252 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5253 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5254 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5255 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5256 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5257 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5258 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5259 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5260 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5261 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5262 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5263 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5264 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5265 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5266 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5267 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5268 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5269 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5270 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5271 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5272 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5273
5274 FN_LOCAL_STRING(lp_preexec, szPreExec)
5275 FN_LOCAL_STRING(lp_postexec, szPostExec)
5276 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5277 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5278 FN_LOCAL_STRING(lp_servicename, szService)
5279 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5280 FN_LOCAL_STRING(lp_pathname, szPath)
5281 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5282 FN_LOCAL_STRING(lp_username, szUsername)
5283 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5284 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5285 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5286 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5287 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5288 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5289 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5290 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5291 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5292 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5293 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5294 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5295 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5296 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5297 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5298 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5299 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5300 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5301 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5302 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5303 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5304 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5305 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5306 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5307 FN_LOCAL_STRING(lp_comment, comment)
5308 FN_LOCAL_STRING(lp_force_user, force_user)
5309 FN_LOCAL_STRING(lp_force_group, force_group)
5310 FN_LOCAL_LIST(lp_readlist, readlist)
5311 FN_LOCAL_LIST(lp_writelist, writelist)
5312 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5313 FN_LOCAL_STRING(lp_fstype, fstype)
5314 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5315 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5316 static FN_LOCAL_STRING(lp_volume, volume)
5317 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5318 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5319 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5320 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5321 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5322 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5323 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5324 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5325 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5326 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5327 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5328 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5329 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5330 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5331 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5332 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5333 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5334 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5335 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5336 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5337 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5338 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5339 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5340 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5341 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5342 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5343 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5344 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5345 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5346 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5347 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5348 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5349 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5350 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5351 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5352 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5353 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5354 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5355 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5356 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5357 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5358 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5359 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5360 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5361 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5362 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5363 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5364 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5365 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5366 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5367 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5368 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5369 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5370 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5371 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5372 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5373 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5374 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5375 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5376 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5377 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5378 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5379 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5380 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5381 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5382 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5383 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5384 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5385 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5386 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5387 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5388 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5389 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5390 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5391 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5392 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5393 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5394 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5395 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5396 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5397 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5398 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5399 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5400 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5401 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5402 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5403 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5404 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5405 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5406 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5407 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5408 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5409 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5410 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5411 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5412 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5413 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5414 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5415
5416 /* local prototypes */
5417
5418 static int map_parameter(const char *pszParmName);
5419 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5420 static const char *get_boolean(bool bool_value);
5421 static int getservicebyname(const char *pszServiceName,
5422                             struct service *pserviceDest);
5423 static void copy_service(struct service *pserviceDest,
5424                          struct service *pserviceSource,
5425                          struct bitmap *pcopymapDest);
5426 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5427                          void *userdata);
5428 static bool do_section(const char *pszSectionName, void *userdata);
5429 static void init_copymap(struct service *pservice);
5430 static bool hash_a_service(const char *name, int number);
5431 static void free_service_byindex(int iService);
5432 static void free_param_opts(struct param_opt_struct **popts);
5433 static char * canonicalize_servicename(const char *name);
5434 static void show_parameter(int parmIndex);
5435 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5436
5437 /*
5438  * This is a helper function for parametrical options support.  It returns a
5439  * pointer to parametrical option value if it exists or NULL otherwise. Actual
5440  * parametrical functions are quite simple
5441  */
5442 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5443                                                 const char *option)
5444 {
5445         bool global_section = False;
5446         char* param_key;
5447         struct param_opt_struct *data;
5448         
5449         if (snum >= iNumServices) return NULL;
5450         
5451         if (snum < 0) { 
5452                 data = Globals.param_opt;
5453                 global_section = True;
5454         } else {
5455                 data = ServicePtrs[snum]->param_opt;
5456         }
5457     
5458         if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5459                 DEBUG(0,("asprintf failed!\n"));
5460                 return NULL;
5461         }
5462
5463         while (data) {
5464                 if (strwicmp(data->key, param_key) == 0) {
5465                         string_free(&param_key);
5466                         return data;
5467                 }
5468                 data = data->next;
5469         }
5470
5471         if (!global_section) {
5472                 /* Try to fetch the same option but from globals */
5473                 /* but only if we are not already working with Globals */
5474                 data = Globals.param_opt;
5475                 while (data) {
5476                         if (strwicmp(data->key, param_key) == 0) {
5477                                 string_free(&param_key);
5478                                 return data;
5479                         }
5480                         data = data->next;
5481                 }
5482         }
5483
5484         string_free(&param_key);
5485         
5486         return NULL;
5487 }
5488
5489
5490 #define MISSING_PARAMETER(name) \
5491     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5492
5493 /*******************************************************************
5494 convenience routine to return int parameters.
5495 ********************************************************************/
5496 static int lp_int(const char *s)
5497 {
5498
5499         if (!s || !*s) {
5500                 MISSING_PARAMETER(lp_int);
5501                 return (-1);
5502         }
5503
5504         return (int)strtol(s, NULL, 0);
5505 }
5506
5507 /*******************************************************************
5508 convenience routine to return unsigned long parameters.
5509 ********************************************************************/
5510 static unsigned long lp_ulong(const char *s)
5511 {
5512
5513         if (!s || !*s) {
5514                 MISSING_PARAMETER(lp_ulong);
5515                 return (0);
5516         }
5517
5518         return strtoul(s, NULL, 0);
5519 }
5520
5521 /*******************************************************************
5522 convenience routine to return boolean parameters.
5523 ********************************************************************/
5524 static bool lp_bool(const char *s)
5525 {
5526         bool ret = False;
5527
5528         if (!s || !*s) {
5529                 MISSING_PARAMETER(lp_bool);
5530                 return False;
5531         }
5532         
5533         if (!set_boolean(s, &ret)) {
5534                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5535                 return False;
5536         }
5537
5538         return ret;
5539 }
5540
5541 /*******************************************************************
5542 convenience routine to return enum parameters.
5543 ********************************************************************/
5544 static int lp_enum(const char *s,const struct enum_list *_enum)
5545 {
5546         int i;
5547
5548         if (!s || !*s || !_enum) {
5549                 MISSING_PARAMETER(lp_enum);
5550                 return (-1);
5551         }
5552         
5553         for (i=0; _enum[i].name; i++) {
5554                 if (strequal(_enum[i].name,s))
5555                         return _enum[i].value;
5556         }
5557
5558         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5559         return (-1);
5560 }
5561
5562 #undef MISSING_PARAMETER
5563
5564 /* DO NOT USE lp_parm_string ANYMORE!!!!
5565  * use lp_parm_const_string or lp_parm_talloc_string
5566  *
5567  * lp_parm_string is only used to let old modules find this symbol
5568  */
5569 #undef lp_parm_string
5570  char *lp_parm_string(const char *servicename, const char *type, const char *option);
5571  char *lp_parm_string(const char *servicename, const char *type, const char *option)
5572 {
5573         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5574 }
5575
5576 /* Return parametric option from a given service. Type is a part of option before ':' */
5577 /* Parametric option has following syntax: 'Type: option = value' */
5578 /* the returned value is talloced on the talloc_tos() */
5579 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5580 {
5581         struct param_opt_struct *data = get_parametrics(snum, type, option);
5582         
5583         if (data == NULL||data->value==NULL) {
5584                 if (def) {
5585                         return lp_string(def);
5586                 } else {
5587                         return NULL;
5588                 }
5589         }
5590
5591         return lp_string(data->value);
5592 }
5593
5594 /* Return parametric option from a given service. Type is a part of option before ':' */
5595 /* Parametric option has following syntax: 'Type: option = value' */
5596 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5597 {
5598         struct param_opt_struct *data = get_parametrics(snum, type, option);
5599         
5600         if (data == NULL||data->value==NULL)
5601                 return def;
5602                 
5603         return data->value;
5604 }
5605
5606 /* Return parametric option from a given service. Type is a part of option before ':' */
5607 /* Parametric option has following syntax: 'Type: option = value' */
5608
5609 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5610 {
5611         struct param_opt_struct *data = get_parametrics(snum, type, option);
5612
5613         if (data == NULL||data->value==NULL)
5614                 return (const char **)def;
5615                 
5616         if (data->list==NULL) {
5617                 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5618         }
5619
5620         return (const char **)data->list;
5621 }
5622
5623 /* Return parametric option from a given service. Type is a part of option before ':' */
5624 /* Parametric option has following syntax: 'Type: option = value' */
5625
5626 int lp_parm_int(int snum, const char *type, const char *option, int def)
5627 {
5628         struct param_opt_struct *data = get_parametrics(snum, type, option);
5629         
5630         if (data && data->value && *data->value)
5631                 return lp_int(data->value);
5632
5633         return def;
5634 }
5635
5636 /* Return parametric option from a given service. Type is a part of option before ':' */
5637 /* Parametric option has following syntax: 'Type: option = value' */
5638
5639 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5640 {
5641         struct param_opt_struct *data = get_parametrics(snum, type, option);
5642         
5643         if (data && data->value && *data->value)
5644                 return lp_ulong(data->value);
5645
5646         return def;
5647 }
5648
5649 /* Return parametric option from a given service. Type is a part of option before ':' */
5650 /* Parametric option has following syntax: 'Type: option = value' */
5651
5652 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5653 {
5654         struct param_opt_struct *data = get_parametrics(snum, type, option);
5655         
5656         if (data && data->value && *data->value)
5657                 return lp_bool(data->value);
5658
5659         return def;
5660 }
5661
5662 /* Return parametric option from a given service. Type is a part of option before ':' */
5663 /* Parametric option has following syntax: 'Type: option = value' */
5664
5665 int lp_parm_enum(int snum, const char *type, const char *option,
5666                  const struct enum_list *_enum, int def)
5667 {
5668         struct param_opt_struct *data = get_parametrics(snum, type, option);
5669         
5670         if (data && data->value && *data->value && _enum)
5671                 return lp_enum(data->value, _enum);
5672
5673         return def;
5674 }
5675
5676
5677 /***************************************************************************
5678  Initialise a service to the defaults.
5679 ***************************************************************************/
5680
5681 static void init_service(struct service *pservice)
5682 {
5683         memset((char *)pservice, '\0', sizeof(struct service));
5684         copy_service(pservice, &sDefault, NULL);
5685 }
5686
5687
5688 /**
5689  * free a param_opts structure.
5690  * param_opts handling should be moved to talloc;
5691  * then this whole functions reduces to a TALLOC_FREE().
5692  */
5693
5694 static void free_param_opts(struct param_opt_struct **popts)
5695 {
5696         struct param_opt_struct *opt, *next_opt;
5697
5698         if (popts == NULL) {
5699                 return;
5700         }
5701
5702         if (*popts != NULL) {
5703                 DEBUG(5, ("Freeing parametrics:\n"));
5704         }
5705         opt = *popts;
5706         while (opt != NULL) {
5707                 string_free(&opt->key);
5708                 string_free(&opt->value);
5709                 TALLOC_FREE(opt->list);
5710                 next_opt = opt->next;
5711                 SAFE_FREE(opt);
5712                 opt = next_opt;
5713         }
5714         *popts = NULL;
5715 }
5716
5717 /***************************************************************************
5718  Free the dynamically allocated parts of a service struct.
5719 ***************************************************************************/
5720
5721 static void free_service(struct service *pservice)
5722 {
5723         if (!pservice)
5724                 return;
5725
5726         if (pservice->szService)
5727                 DEBUG(5, ("free_service: Freeing service %s\n",
5728                        pservice->szService));
5729
5730         free_parameters(getservicebyname(pservice->szService, NULL));
5731
5732         string_free(&pservice->szService);
5733         bitmap_free(pservice->copymap);
5734
5735         free_param_opts(&pservice->param_opt);
5736
5737         ZERO_STRUCTP(pservice);
5738 }
5739
5740
5741 /***************************************************************************
5742  remove a service indexed in the ServicePtrs array from the ServiceHash
5743  and free the dynamically allocated parts
5744 ***************************************************************************/
5745
5746 static void free_service_byindex(int idx)
5747 {
5748         if ( !LP_SNUM_OK(idx) ) 
5749                 return;
5750
5751         ServicePtrs[idx]->valid = False;
5752         invalid_services[num_invalid_services++] = idx;
5753
5754         /* we have to cleanup the hash record */
5755
5756         if (ServicePtrs[idx]->szService) {
5757                 char *canon_name = canonicalize_servicename(
5758                         ServicePtrs[idx]->szService );
5759                 
5760                 dbwrap_delete_bystring(ServiceHash, canon_name );
5761                 TALLOC_FREE(canon_name);
5762         }
5763
5764         free_service(ServicePtrs[idx]);
5765 }
5766
5767 /***************************************************************************
5768  Add a new service to the services array initialising it with the given 
5769  service. 
5770 ***************************************************************************/
5771
5772 static int add_a_service(const struct service *pservice, const char *name)
5773 {
5774         int i;
5775         struct service tservice;
5776         int num_to_alloc = iNumServices + 1;
5777
5778         tservice = *pservice;
5779
5780         /* it might already exist */
5781         if (name) {
5782                 i = getservicebyname(name, NULL);
5783                 if (i >= 0) {
5784                         /* Clean all parametric options for service */
5785                         /* They will be added during parsing again */
5786                         free_param_opts(&ServicePtrs[i]->param_opt);
5787                         return (i);
5788                 }
5789         }
5790
5791         /* find an invalid one */
5792         i = iNumServices;
5793         if (num_invalid_services > 0) {
5794                 i = invalid_services[--num_invalid_services];
5795         }
5796
5797         /* if not, then create one */
5798         if (i == iNumServices) {
5799                 struct service **tsp;
5800                 int *tinvalid;
5801                 
5802                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5803                 if (tsp == NULL) {
5804                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5805                         return (-1);
5806                 }
5807                 ServicePtrs = tsp;
5808                 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5809                 if (!ServicePtrs[iNumServices]) {
5810                         DEBUG(0,("add_a_service: out of memory!\n"));
5811                         return (-1);
5812                 }
5813                 iNumServices++;
5814
5815                 /* enlarge invalid_services here for now... */
5816                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5817                                              num_to_alloc);
5818                 if (tinvalid == NULL) {
5819                         DEBUG(0,("add_a_service: failed to enlarge "
5820                                  "invalid_services!\n"));
5821                         return (-1);
5822                 }
5823                 invalid_services = tinvalid;
5824         } else {
5825                 free_service_byindex(i);
5826         }
5827
5828         ServicePtrs[i]->valid = True;
5829
5830         init_service(ServicePtrs[i]);
5831         copy_service(ServicePtrs[i], &tservice, NULL);
5832         if (name)
5833                 string_set(&ServicePtrs[i]->szService, name);
5834                 
5835         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
5836                 i, ServicePtrs[i]->szService));
5837
5838         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5839                 return (-1);
5840         }
5841                 
5842         return (i);
5843 }
5844
5845 /***************************************************************************
5846   Convert a string to uppercase and remove whitespaces.
5847 ***************************************************************************/
5848
5849 static char *canonicalize_servicename(const char *src)
5850 {
5851         char *result;
5852
5853         if ( !src ) {
5854                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5855                 return NULL;
5856         }
5857
5858         result = talloc_strdup(talloc_tos(), src);
5859         SMB_ASSERT(result != NULL);
5860
5861         strlower_m(result);
5862         return result;
5863 }
5864
5865 /***************************************************************************
5866   Add a name/index pair for the services array to the hash table.
5867 ***************************************************************************/
5868
5869 static bool hash_a_service(const char *name, int idx)
5870 {
5871         char *canon_name;
5872
5873         if ( !ServiceHash ) {
5874                 DEBUG(10,("hash_a_service: creating servicehash\n"));
5875                 ServiceHash = db_open_rbt(NULL);
5876                 if ( !ServiceHash ) {
5877                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5878                         return False;
5879                 }
5880         }
5881
5882         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5883                 idx, name));
5884
5885         canon_name = canonicalize_servicename( name );
5886
5887         dbwrap_store_bystring(ServiceHash, canon_name,
5888                               make_tdb_data((uint8 *)&idx, sizeof(idx)),
5889                               TDB_REPLACE);
5890
5891         TALLOC_FREE(canon_name);
5892
5893         return True;
5894 }
5895
5896 /***************************************************************************
5897  Add a new home service, with the specified home directory, defaults coming
5898  from service ifrom.
5899 ***************************************************************************/
5900
5901 bool lp_add_home(const char *pszHomename, int iDefaultService,
5902                  const char *user, const char *pszHomedir)
5903 {
5904         int i;
5905
5906         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5907
5908         if (i < 0)
5909                 return (False);
5910
5911         if (!(*(ServicePtrs[iDefaultService]->szPath))
5912             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5913                 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5914         }
5915
5916         if (!(*(ServicePtrs[i]->comment))) {
5917                 char *comment = NULL;
5918                 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5919                         return false;
5920                 }
5921                 string_set(&ServicePtrs[i]->comment, comment);
5922                 SAFE_FREE(comment);
5923         }
5924
5925         /* set the browseable flag from the global default */
5926
5927         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5928
5929         ServicePtrs[i]->autoloaded = True;
5930
5931         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
5932                user, ServicePtrs[i]->szPath ));
5933
5934         return (True);
5935 }
5936
5937 /***************************************************************************
5938  Add a new service, based on an old one.
5939 ***************************************************************************/
5940
5941 int lp_add_service(const char *pszService, int iDefaultService)
5942 {
5943         if (iDefaultService < 0) {
5944                 return add_a_service(&sDefault, pszService);
5945         }
5946
5947         return (add_a_service(ServicePtrs[iDefaultService], pszService));
5948 }
5949
5950 /***************************************************************************
5951  Add the IPC service.
5952 ***************************************************************************/
5953
5954 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5955 {
5956         char *comment = NULL;
5957         int i = add_a_service(&sDefault, ipc_name);
5958
5959         if (i < 0)
5960                 return (False);
5961
5962         if (asprintf(&comment, "IPC Service (%s)",
5963                                 Globals.szServerString) < 0) {
5964                 return (False);
5965         }
5966
5967         string_set(&ServicePtrs[i]->szPath, tmpdir());
5968         string_set(&ServicePtrs[i]->szUsername, "");
5969         string_set(&ServicePtrs[i]->comment, comment);
5970         string_set(&ServicePtrs[i]->fstype, "IPC");
5971         ServicePtrs[i]->iMaxConnections = 0;
5972         ServicePtrs[i]->bAvailable = True;
5973         ServicePtrs[i]->bRead_only = True;
5974         ServicePtrs[i]->bGuest_only = False;
5975         ServicePtrs[i]->bAdministrative_share = True;
5976         ServicePtrs[i]->bGuest_ok = guest_ok;
5977         ServicePtrs[i]->bPrint_ok = False;
5978         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5979
5980         DEBUG(3, ("adding IPC service\n"));
5981
5982         SAFE_FREE(comment);
5983         return (True);
5984 }
5985
5986 /***************************************************************************
5987  Add a new printer service, with defaults coming from service iFrom.
5988 ***************************************************************************/
5989
5990 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5991 {
5992         const char *comment = "From Printcap";
5993         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5994
5995         if (i < 0)
5996                 return (False);
5997
5998         /* note that we do NOT default the availability flag to True - */
5999         /* we take it from the default service passed. This allows all */
6000         /* dynamic printers to be disabled by disabling the [printers] */
6001         /* entry (if/when the 'available' keyword is implemented!).    */
6002
6003         /* the printer name is set to the service name. */
6004         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6005         string_set(&ServicePtrs[i]->comment, comment);
6006
6007         /* set the browseable flag from the gloabl default */
6008         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6009
6010         /* Printers cannot be read_only. */
6011         ServicePtrs[i]->bRead_only = False;
6012         /* No share modes on printer services. */
6013         ServicePtrs[i]->bShareModes = False;
6014         /* No oplocks on printer services. */
6015         ServicePtrs[i]->bOpLocks = False;
6016         /* Printer services must be printable. */
6017         ServicePtrs[i]->bPrint_ok = True;
6018         
6019         DEBUG(3, ("adding printer service %s\n", pszPrintername));
6020
6021         return (True);
6022 }
6023
6024
6025 /***************************************************************************
6026  Check whether the given parameter name is valid.
6027  Parametric options (names containing a colon) are considered valid.
6028 ***************************************************************************/
6029
6030 bool lp_parameter_is_valid(const char *pszParmName)
6031 {
6032         return ((map_parameter(pszParmName) != -1) ||
6033                 (strchr(pszParmName, ':') != NULL));
6034 }
6035
6036 /***************************************************************************
6037  Check whether the given name is the name of a global parameter.
6038  Returns True for strings belonging to parameters of class
6039  P_GLOBAL, False for all other strings, also for parametric options
6040  and strings not belonging to any option.
6041 ***************************************************************************/
6042
6043 bool lp_parameter_is_global(const char *pszParmName)
6044 {
6045         int num = map_parameter(pszParmName);
6046
6047         if (num >= 0) {
6048                 return (parm_table[num].p_class == P_GLOBAL);
6049         }
6050
6051         return False;
6052 }
6053
6054 /**************************************************************************
6055  Check whether the given name is the canonical name of a parameter.
6056  Returns False if it is not a valid parameter Name.
6057  For parametric options, True is returned.
6058 **************************************************************************/
6059
6060 bool lp_parameter_is_canonical(const char *parm_name)
6061 {
6062         if (!lp_parameter_is_valid(parm_name)) {
6063                 return False;
6064         }
6065
6066         return (map_parameter(parm_name) ==
6067                 map_parameter_canonical(parm_name, NULL));
6068 }
6069
6070 /**************************************************************************
6071  Determine the canonical name for a parameter.
6072  Indicate when it is an inverse (boolean) synonym instead of a
6073  "usual" synonym.
6074 **************************************************************************/
6075
6076 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6077                                bool *inverse)
6078 {
6079         int num;
6080
6081         if (!lp_parameter_is_valid(parm_name)) {
6082                 *canon_parm = NULL;
6083                 return False;
6084         }
6085
6086         num = map_parameter_canonical(parm_name, inverse);
6087         if (num < 0) {
6088                 /* parametric option */
6089                 *canon_parm = parm_name;
6090         } else {
6091                 *canon_parm = parm_table[num].label;
6092         }
6093
6094         return True;
6095
6096 }
6097
6098 /**************************************************************************
6099  Determine the canonical name for a parameter.
6100  Turn the value given into the inverse boolean expression when
6101  the synonym is an invers boolean synonym.
6102
6103  Return True if parm_name is a valid parameter name and
6104  in case it is an invers boolean synonym, if the val string could
6105  successfully be converted to the reverse bool.
6106  Return false in all other cases.
6107 **************************************************************************/
6108
6109 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6110                                           const char *val,
6111                                           const char **canon_parm,
6112                                           const char **canon_val)
6113 {
6114         int num;
6115         bool inverse;
6116
6117         if (!lp_parameter_is_valid(parm_name)) {
6118                 *canon_parm = NULL;
6119                 *canon_val = NULL;
6120                 return False;
6121         }
6122
6123         num = map_parameter_canonical(parm_name, &inverse);
6124         if (num < 0) {
6125                 /* parametric option */
6126                 *canon_parm = parm_name;
6127                 *canon_val = val;
6128         } else {
6129                 *canon_parm = parm_table[num].label;
6130                 if (inverse) {
6131                         if (!lp_invert_boolean(val, canon_val)) {
6132                                 *canon_val = NULL;
6133                                 return False;
6134                         }
6135                 } else {
6136                         *canon_val = val;
6137                 }
6138         }
6139
6140         return True;
6141 }
6142
6143 /***************************************************************************
6144  Map a parameter's string representation to something we can use. 
6145  Returns False if the parameter string is not recognised, else TRUE.
6146 ***************************************************************************/
6147
6148 static int map_parameter(const char *pszParmName)
6149 {
6150         int iIndex;
6151
6152         if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6153                 return (-1);
6154
6155         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6156                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6157                         return (iIndex);
6158
6159         /* Warn only if it isn't parametric option */
6160         if (strchr(pszParmName, ':') == NULL)
6161                 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6162         /* We do return 'fail' for parametric options as well because they are
6163            stored in different storage
6164          */
6165         return (-1);
6166 }
6167
6168 /***************************************************************************
6169  Map a parameter's string representation to the index of the canonical
6170  form of the parameter (it might be a synonym).
6171  Returns -1 if the parameter string is not recognised.
6172 ***************************************************************************/
6173
6174 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6175 {
6176         int parm_num, canon_num;
6177         bool loc_inverse = False;
6178
6179         parm_num = map_parameter(pszParmName);
6180         if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6181                 /* invalid, parametric or no canidate for synonyms ... */
6182                 goto done;
6183         }
6184
6185         for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6186                 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6187                         parm_num = canon_num;
6188                         goto done;
6189                 }
6190         }
6191
6192 done:
6193         if (inverse != NULL) {
6194                 *inverse = loc_inverse;
6195         }
6196         return parm_num;
6197 }
6198
6199 /***************************************************************************
6200  return true if parameter number parm1 is a synonym of parameter
6201  number parm2 (parm2 being the principal name).
6202  set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6203  False otherwise.
6204 ***************************************************************************/
6205
6206 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6207 {
6208         if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6209             (parm_table[parm1].flags & FLAG_HIDE) &&
6210             !(parm_table[parm2].flags & FLAG_HIDE))
6211         {
6212                 if (inverse != NULL) {
6213                         if ((parm_table[parm1].type == P_BOOLREV) &&
6214                             (parm_table[parm2].type == P_BOOL))
6215                         {
6216                                 *inverse = True;
6217                         } else {
6218                                 *inverse = False;
6219                         }
6220                 }
6221                 return True;
6222         }
6223         return False;
6224 }
6225
6226 /***************************************************************************
6227  Show one parameter's name, type, [values,] and flags.
6228  (helper functions for show_parameter_list)
6229 ***************************************************************************/
6230
6231 static void show_parameter(int parmIndex)
6232 {
6233         int enumIndex, flagIndex;
6234         int parmIndex2;
6235         bool hadFlag;
6236         bool hadSyn;
6237         bool inverse;
6238         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6239                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6240                 "P_ENUM", "P_SEP"};
6241         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6242                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6243                 FLAG_HIDE, FLAG_DOS_STRING};
6244         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6245                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6246                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6247
6248         printf("%s=%s", parm_table[parmIndex].label,
6249                type[parm_table[parmIndex].type]);
6250         if (parm_table[parmIndex].type == P_ENUM) {
6251                 printf(",");
6252                 for (enumIndex=0;
6253                      parm_table[parmIndex].enum_list[enumIndex].name;
6254                      enumIndex++)
6255                 {
6256                         printf("%s%s",
6257                                enumIndex ? "|" : "",
6258                                parm_table[parmIndex].enum_list[enumIndex].name);
6259                 }
6260         }
6261         printf(",");
6262         hadFlag = False;
6263         for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6264                 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6265                         printf("%s%s",
6266                                 hadFlag ? "|" : "",
6267                                 flag_names[flagIndex]);
6268                         hadFlag = True;
6269                 }
6270         }
6271
6272         /* output synonyms */
6273         hadSyn = False;
6274         for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6275                 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6276                         printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6277                                parm_table[parmIndex2].label);
6278                 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6279                         if (!hadSyn) {
6280                                 printf(" (synonyms: ");
6281                                 hadSyn = True;
6282                         } else {
6283                                 printf(", ");
6284                         }
6285                         printf("%s%s", parm_table[parmIndex2].label,
6286                                inverse ? "[i]" : "");
6287                 }
6288         }
6289         if (hadSyn) {
6290                 printf(")");
6291         }
6292
6293         printf("\n");
6294 }
6295
6296 /***************************************************************************
6297  Show all parameter's name, type, [values,] and flags.
6298 ***************************************************************************/
6299
6300 void show_parameter_list(void)
6301 {
6302         int classIndex, parmIndex;
6303         const char *section_names[] = { "local", "global", NULL};
6304
6305         for (classIndex=0; section_names[classIndex]; classIndex++) {
6306                 printf("[%s]\n", section_names[classIndex]);
6307                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6308                         if (parm_table[parmIndex].p_class == classIndex) {
6309                                 show_parameter(parmIndex);
6310                         }
6311                 }
6312         }
6313 }
6314
6315 /***************************************************************************
6316  Check if a given string correctly represents a boolean value.
6317 ***************************************************************************/
6318
6319 bool lp_string_is_valid_boolean(const char *parm_value)
6320 {
6321         return set_boolean(parm_value, NULL);
6322 }
6323
6324 /***************************************************************************
6325  Get the standard string representation of a boolean value ("yes" or "no")
6326 ***************************************************************************/
6327
6328 static const char *get_boolean(bool bool_value)
6329 {
6330         static const char *yes_str = "yes";
6331         static const char *no_str = "no";
6332
6333         return (bool_value ? yes_str : no_str);
6334 }
6335
6336 /***************************************************************************
6337  Provide the string of the negated boolean value associated to the boolean
6338  given as a string. Returns False if the passed string does not correctly
6339  represent a boolean.
6340 ***************************************************************************/
6341
6342 bool lp_invert_boolean(const char *str, const char **inverse_str)
6343 {
6344         bool val;
6345
6346         if (!set_boolean(str, &val)) {
6347                 return False;
6348         }
6349
6350         *inverse_str = get_boolean(!val);
6351         return True;
6352 }
6353
6354 /***************************************************************************
6355  Provide the canonical string representation of a boolean value given
6356  as a string. Return True on success, False if the string given does
6357  not correctly represent a boolean.
6358 ***************************************************************************/
6359
6360 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6361 {
6362         bool val;
6363
6364         if (!set_boolean(str, &val)) {
6365                 return False;
6366         }
6367
6368         *canon_str = get_boolean(val);
6369         return True;
6370 }
6371
6372 /***************************************************************************
6373 Find a service by name. Otherwise works like get_service.
6374 ***************************************************************************/
6375
6376 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6377 {
6378         int iService = -1;
6379         char *canon_name;
6380         TDB_DATA data;
6381
6382         if (ServiceHash == NULL) {
6383                 return -1;
6384         }
6385
6386         canon_name = canonicalize_servicename(pszServiceName);
6387
6388         data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6389
6390         if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6391                 iService = *(int *)data.dptr;
6392         }
6393
6394         TALLOC_FREE(canon_name);
6395
6396         if ((iService != -1) && (LP_SNUM_OK(iService))
6397             && (pserviceDest != NULL)) {
6398                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6399         }
6400
6401         return (iService);
6402 }
6403
6404 /***************************************************************************
6405  Copy a service structure to another.
6406  If pcopymapDest is NULL then copy all fields
6407 ***************************************************************************/
6408
6409 /**
6410  * Add a parametric option to a param_opt_struct,
6411  * replacing old value, if already present.
6412  */
6413 static void set_param_opt(struct param_opt_struct **opt_list,
6414                           const char *opt_name,
6415                           const char *opt_value)
6416 {
6417         struct param_opt_struct *new_opt, *opt;
6418         bool not_added;
6419
6420         if (opt_list == NULL) {
6421                 return;
6422         }
6423
6424         opt = *opt_list;
6425         not_added = true;
6426
6427         /* Traverse destination */
6428         while (opt) {
6429                 /* If we already have same option, override it */
6430                 if (strwicmp(opt->key, opt_name) == 0) {
6431                         string_free(&opt->value);
6432                         TALLOC_FREE(opt->list);
6433                         opt->value = SMB_STRDUP(opt_value);
6434                         not_added = false;
6435                         break;
6436                 }
6437                 opt = opt->next;
6438         }
6439         if (not_added) {
6440             new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6441             new_opt->key = SMB_STRDUP(opt_name);
6442             new_opt->value = SMB_STRDUP(opt_value);
6443             new_opt->list = NULL;
6444             DLIST_ADD(*opt_list, new_opt);
6445         }
6446 }
6447
6448 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6449                          struct bitmap *pcopymapDest)
6450 {
6451         int i;
6452         bool bcopyall = (pcopymapDest == NULL);
6453         struct param_opt_struct *data;
6454
6455         for (i = 0; parm_table[i].label; i++)
6456                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6457                     (bcopyall || bitmap_query(pcopymapDest,i))) {
6458                         void *def_ptr = parm_table[i].ptr;
6459                         void *src_ptr =
6460                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6461                                                                     &sDefault);
6462                         void *dest_ptr =
6463                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6464                                                                   &sDefault);
6465
6466                         switch (parm_table[i].type) {
6467                                 case P_BOOL:
6468                                 case P_BOOLREV:
6469                                         *(bool *)dest_ptr = *(bool *)src_ptr;
6470                                         break;
6471
6472                                 case P_INTEGER:
6473                                 case P_ENUM:
6474                                 case P_OCTAL:
6475                                         *(int *)dest_ptr = *(int *)src_ptr;
6476                                         break;
6477
6478                                 case P_CHAR:
6479                                         *(char *)dest_ptr = *(char *)src_ptr;
6480                                         break;
6481
6482                                 case P_STRING:
6483                                         string_set((char **)dest_ptr,
6484                                                    *(char **)src_ptr);
6485                                         break;
6486
6487                                 case P_USTRING:
6488                                         string_set((char **)dest_ptr,
6489                                                    *(char **)src_ptr);
6490                                         strupper_m(*(char **)dest_ptr);
6491                                         break;
6492                                 case P_LIST:
6493                                         TALLOC_FREE(*((char ***)dest_ptr));
6494                                         *((char ***)dest_ptr) = str_list_copy(NULL, 
6495                                                       *(const char ***)src_ptr);
6496                                         break;
6497                                 default:
6498                                         break;
6499                         }
6500                 }
6501
6502         if (bcopyall) {
6503                 init_copymap(pserviceDest);
6504                 if (pserviceSource->copymap)
6505                         bitmap_copy(pserviceDest->copymap,
6506                                     pserviceSource->copymap);
6507         }
6508         
6509         data = pserviceSource->param_opt;
6510         while (data) {
6511                 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6512                 data = data->next;
6513         }
6514 }
6515
6516 /***************************************************************************
6517 Check a service for consistency. Return False if the service is in any way
6518 incomplete or faulty, else True.
6519 ***************************************************************************/
6520
6521 bool service_ok(int iService)
6522 {
6523         bool bRetval;
6524
6525         bRetval = True;
6526         if (ServicePtrs[iService]->szService[0] == '\0') {
6527                 DEBUG(0, ("The following message indicates an internal error:\n"));
6528                 DEBUG(0, ("No service name in service entry.\n"));
6529                 bRetval = False;
6530         }
6531
6532         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6533         /* I can't see why you'd want a non-printable printer service...        */
6534         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6535                 if (!ServicePtrs[iService]->bPrint_ok) {
6536                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6537                                ServicePtrs[iService]->szService));
6538                         ServicePtrs[iService]->bPrint_ok = True;
6539                 }
6540                 /* [printers] service must also be non-browsable. */
6541                 if (ServicePtrs[iService]->bBrowseable)
6542                         ServicePtrs[iService]->bBrowseable = False;
6543         }
6544
6545         if (ServicePtrs[iService]->szPath[0] == '\0' &&
6546             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6547             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6548             ) {
6549                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6550                         ServicePtrs[iService]->szService));
6551                 ServicePtrs[iService]->bAvailable = False;
6552         }
6553
6554         /* If a service is flagged unavailable, log the fact at level 1. */
6555         if (!ServicePtrs[iService]->bAvailable)
6556                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6557                           ServicePtrs[iService]->szService));
6558
6559         return (bRetval);
6560 }
6561
6562 static struct smbconf_ctx *lp_smbconf_ctx(void)
6563 {
6564         WERROR werr;
6565         static struct smbconf_ctx *conf_ctx = NULL;
6566
6567         if (conf_ctx == NULL) {
6568                 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6569                 if (!W_ERROR_IS_OK(werr)) {
6570                         DEBUG(1, ("error initializing registry configuration: "
6571                                   "%s\n", win_errstr(werr)));
6572                         conf_ctx = NULL;
6573                 }
6574         }
6575
6576         return conf_ctx;
6577 }
6578
6579 static bool process_smbconf_service(struct smbconf_service *service)
6580 {
6581         uint32_t count;
6582         bool ret;
6583
6584         if (service == NULL) {
6585                 return false;
6586         }
6587
6588         ret = do_section(service->name, NULL);
6589         if (ret != true) {
6590                 return false;
6591         }
6592         for (count = 0; count < service->num_params; count++) {
6593                 ret = do_parameter(service->param_names[count],
6594                                    service->param_values[count],
6595                                    NULL);
6596                 if (ret != true) {
6597                         return false;
6598                 }
6599         }
6600         return true;
6601 }
6602
6603 /*
6604  * process_registry_globals
6605  */
6606 static bool process_registry_globals(void)
6607 {
6608         WERROR werr;
6609         struct smbconf_service *service = NULL;
6610         TALLOC_CTX *mem_ctx = talloc_stackframe();
6611         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6612         bool ret = false;
6613
6614         if (conf_ctx == NULL) {
6615                 goto done;
6616         }
6617
6618         ret = do_parameter("registry shares", "yes", NULL);
6619         if (!ret) {
6620                 goto done;
6621         }
6622
6623         if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6624                 /* nothing to read from the registry yet but make sure lp_load
6625                  * doesn't return false */
6626                 ret = true;
6627                 goto done;
6628         }
6629
6630         werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6631         if (!W_ERROR_IS_OK(werr)) {
6632                 goto done;
6633         }
6634
6635         ret = process_smbconf_service(service);
6636         if (!ret) {
6637                 goto done;
6638         }
6639
6640         /* store the csn */
6641         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6642
6643 done:
6644         TALLOC_FREE(mem_ctx);
6645         return ret;
6646 }
6647
6648 static bool process_registry_shares(void)
6649 {
6650         WERROR werr;
6651         uint32_t count;
6652         struct smbconf_service **service = NULL;
6653         uint32_t num_shares = 0;
6654         TALLOC_CTX *mem_ctx = talloc_stackframe();
6655         struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6656         bool ret = false;
6657
6658         if (conf_ctx == NULL) {
6659                 goto done;
6660         }
6661
6662         werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6663         if (!W_ERROR_IS_OK(werr)) {
6664                 goto done;
6665         }
6666
6667         ret = true;
6668
6669         for (count = 0; count < num_shares; count++) {
6670                 if (strequal(service[count]->name, GLOBAL_NAME)) {
6671                         continue;
6672                 }
6673                 ret = process_smbconf_service(service[count]);
6674                 if (!ret) {
6675                         goto done;
6676                 }
6677         }
6678
6679         /* store the csn */
6680         smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6681
6682 done:
6683         TALLOC_FREE(mem_ctx);
6684         return ret;
6685 }
6686
6687 static struct file_lists {
6688         struct file_lists *next;
6689         char *name;
6690         char *subfname;
6691         time_t modtime;
6692 } *file_lists = NULL;
6693
6694 /*******************************************************************
6695  Keep a linked list of all config files so we know when one has changed 
6696  it's date and needs to be reloaded.
6697 ********************************************************************/
6698
6699 static void add_to_file_list(const char *fname, const char *subfname)
6700 {
6701         struct file_lists *f = file_lists;
6702
6703         while (f) {
6704                 if (f->name && !strcmp(f->name, fname))
6705                         break;
6706                 f = f->next;
6707         }
6708
6709         if (!f) {
6710                 f = SMB_MALLOC_P(struct file_lists);
6711                 if (!f)
6712                         return;
6713                 f->next = file_lists;
6714                 f->name = SMB_STRDUP(fname);
6715                 if (!f->name) {
6716                         SAFE_FREE(f);
6717                         return;
6718                 }
6719                 f->subfname = SMB_STRDUP(subfname);
6720                 if (!f->subfname) {
6721                         SAFE_FREE(f);
6722                         return;
6723                 }
6724                 file_lists = f;
6725                 f->modtime = file_modtime(subfname);
6726         } else {
6727                 time_t t = file_modtime(subfname);
6728                 if (t)
6729                         f->modtime = t;
6730         }
6731 }
6732
6733 /**
6734  * Utility function for outsiders to check if we're running on registry.
6735  */
6736 bool lp_config_backend_is_registry(void)
6737 {
6738         return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6739 }
6740
6741 /**
6742  * Utility function to check if the config backend is FILE.
6743  */
6744 bool lp_config_backend_is_file(void)
6745 {
6746         return (lp_config_backend() == CONFIG_BACKEND_FILE);
6747 }
6748
6749 /*******************************************************************
6750  Check if a config file has changed date.
6751 ********************************************************************/
6752
6753 bool lp_file_list_changed(void)
6754 {
6755         struct file_lists *f = file_lists;
6756
6757         DEBUG(6, ("lp_file_list_changed()\n"));
6758
6759         if (lp_config_backend_is_registry()) {
6760                 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6761
6762                 if (conf_ctx == NULL) {
6763                         return false;
6764                 }
6765                 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6766                         DEBUGADD(6, ("registry config changed\n"));
6767                         return true;
6768                 }
6769         }
6770
6771         while (f) {
6772                 char *n2 = NULL;
6773                 time_t mod_time;
6774
6775                 n2 = alloc_sub_basic(get_current_username(),
6776                                     current_user_info.domain,
6777                                     f->name);
6778                 if (!n2) {
6779                         return false;
6780                 }
6781                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
6782                              f->name, n2, ctime(&f->modtime)));
6783
6784                 mod_time = file_modtime(n2);
6785
6786                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6787                         DEBUGADD(6,
6788                                  ("file %s modified: %s\n", n2,
6789                                   ctime(&mod_time)));
6790                         f->modtime = mod_time;
6791                         SAFE_FREE(f->subfname);
6792                         f->subfname = n2; /* Passing ownership of
6793                                              return from alloc_sub_basic
6794                                              above. */
6795                         return true;
6796                 }
6797                 SAFE_FREE(n2);
6798                 f = f->next;
6799         }
6800         return (False);
6801 }
6802
6803
6804 /***************************************************************************
6805  Run standard_sub_basic on netbios name... needed because global_myname
6806  is not accessed through any lp_ macro.
6807  Note: We must *NOT* use string_set() here as ptr points to global_myname.
6808 ***************************************************************************/
6809
6810 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6811 {
6812         bool ret;
6813         char *netbios_name = alloc_sub_basic(get_current_username(),
6814                                         current_user_info.domain,
6815                                         pszParmValue);
6816
6817         ret = set_global_myname(netbios_name);
6818         SAFE_FREE(netbios_name);
6819         string_set(&Globals.szNetbiosName,global_myname());
6820
6821         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6822                global_myname()));
6823
6824         return ret;
6825 }
6826
6827 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6828 {
6829         if (strcmp(*ptr, pszParmValue) != 0) {
6830                 string_set(ptr, pszParmValue);
6831                 init_iconv();
6832         }
6833         return True;
6834 }
6835
6836
6837
6838 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6839 {
6840         bool ret;
6841         
6842         ret = set_global_myworkgroup(pszParmValue);
6843         string_set(&Globals.szWorkgroup,lp_workgroup());
6844         
6845         return ret;
6846 }
6847
6848 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6849 {
6850         bool ret;
6851         
6852         ret = set_global_scope(pszParmValue);
6853         string_set(&Globals.szNetbiosScope,global_scope());
6854
6855         return ret;
6856 }
6857
6858 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6859 {
6860         TALLOC_FREE(Globals.szNetbiosAliases);
6861         Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
6862         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6863 }
6864
6865 /***************************************************************************
6866  Handle the include operation.
6867 ***************************************************************************/
6868 static bool bAllowIncludeRegistry = true;
6869
6870 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6871 {
6872         char *fname;
6873
6874         if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6875                 if (!bAllowIncludeRegistry) {
6876                         return true;
6877                 }
6878                 if (bInGlobalSection) {
6879                         return process_registry_globals();
6880                 } else {
6881                         DEBUG(1, ("\"include = registry\" only effective "
6882                                   "in %s section\n", GLOBAL_NAME));
6883                         return false;
6884                 }
6885         }
6886
6887         fname = alloc_sub_basic(get_current_username(),
6888                                 current_user_info.domain,
6889                                 pszParmValue);
6890
6891         add_to_file_list(pszParmValue, fname);
6892
6893         string_set(ptr, fname);
6894
6895         if (file_exist(fname)) {
6896                 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6897                 SAFE_FREE(fname);
6898                 return ret;
6899         }
6900
6901         DEBUG(2, ("Can't find include file %s\n", fname));
6902         SAFE_FREE(fname);
6903         return true;
6904 }
6905
6906 /***************************************************************************
6907  Handle the interpretation of the copy parameter.
6908 ***************************************************************************/
6909
6910 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6911 {
6912         bool bRetval;
6913         int iTemp;
6914         struct service serviceTemp;
6915
6916         string_set(ptr, pszParmValue);
6917
6918         init_service(&serviceTemp);
6919
6920         bRetval = False;
6921
6922         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6923
6924         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6925                 if (iTemp == iServiceIndex) {
6926                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6927                 } else {
6928                         copy_service(ServicePtrs[iServiceIndex],
6929                                      &serviceTemp,
6930                                      ServicePtrs[iServiceIndex]->copymap);
6931                         bRetval = True;
6932                 }
6933         } else {
6934                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6935                 bRetval = False;
6936         }
6937
6938         free_service(&serviceTemp);
6939         return (bRetval);
6940 }
6941
6942 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6943 {
6944         Globals.ldap_debug_level = lp_int(pszParmValue);
6945         init_ldap_debugging();
6946         return true;
6947 }
6948
6949 /***************************************************************************
6950  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
6951  parameters is:
6952
6953  [global]
6954
6955         idmap uid = 1000-1999
6956         idmap gid = 700-899
6957
6958  We only do simple parsing checks here.  The strings are parsed into useful
6959  structures in the idmap daemon code.
6960
6961 ***************************************************************************/
6962
6963 /* Some lp_ routines to return idmap [ug]id information */
6964
6965 static uid_t idmap_uid_low, idmap_uid_high;
6966 static gid_t idmap_gid_low, idmap_gid_high;
6967
6968 bool lp_idmap_uid(uid_t *low, uid_t *high)
6969 {
6970         if (idmap_uid_low == 0 || idmap_uid_high == 0)
6971                 return False;
6972
6973         if (low)
6974                 *low = idmap_uid_low;
6975
6976         if (high)
6977                 *high = idmap_uid_high;
6978
6979         return True;
6980 }
6981
6982 bool lp_idmap_gid(gid_t *low, gid_t *high)
6983 {
6984         if (idmap_gid_low == 0 || idmap_gid_high == 0)
6985                 return False;
6986
6987         if (low)
6988                 *low = idmap_gid_low;
6989
6990         if (high)
6991                 *high = idmap_gid_high;
6992
6993         return True;
6994 }
6995
6996 /* Do some simple checks on "idmap [ug]id" parameter values */
6997
6998 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
6999 {
7000         uint32 low, high;
7001
7002         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7003                 return False;
7004
7005         /* Parse OK */
7006
7007         string_set(ptr, pszParmValue);
7008
7009         idmap_uid_low = low;
7010         idmap_uid_high = high;
7011
7012         return True;
7013 }
7014
7015 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7016 {
7017         uint32 low, high;
7018
7019         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7020                 return False;
7021
7022         /* Parse OK */
7023
7024         string_set(ptr, pszParmValue);
7025
7026         idmap_gid_low = low;
7027         idmap_gid_high = high;
7028
7029         return True;
7030 }
7031
7032 /***************************************************************************
7033  Handle the DEBUG level list.
7034 ***************************************************************************/
7035
7036 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7037 {
7038         string_set(ptr, pszParmValueIn);
7039         return debug_parse_levels(pszParmValueIn);
7040 }
7041
7042 /***************************************************************************
7043  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7044 ***************************************************************************/
7045
7046 static const char *append_ldap_suffix( const char *str )
7047 {
7048         const char *suffix_string;
7049
7050
7051         suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7052                                         Globals.szLdapSuffix );
7053         if ( !suffix_string ) {
7054                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7055                 return "";
7056         }
7057
7058         return suffix_string;
7059 }
7060
7061 const char *lp_ldap_machine_suffix(void)
7062 {
7063         if (Globals.szLdapMachineSuffix[0])
7064                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7065
7066         return lp_string(Globals.szLdapSuffix);
7067 }
7068
7069 const char *lp_ldap_user_suffix(void)
7070 {
7071         if (Globals.szLdapUserSuffix[0])
7072                 return append_ldap_suffix(Globals.szLdapUserSuffix);
7073
7074         return lp_string(Globals.szLdapSuffix);
7075 }
7076
7077 const char *lp_ldap_group_suffix(void)
7078 {
7079         if (Globals.szLdapGroupSuffix[0])
7080                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7081
7082         return lp_string(Globals.szLdapSuffix);
7083 }
7084
7085 const char *lp_ldap_idmap_suffix(void)
7086 {
7087         if (Globals.szLdapIdmapSuffix[0])
7088                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7089
7090         return lp_string(Globals.szLdapSuffix);
7091 }
7092
7093 /****************************************************************************
7094  set the value for a P_ENUM
7095  ***************************************************************************/
7096
7097 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7098                               int *ptr )
7099 {
7100         int i;
7101
7102         for (i = 0; parm->enum_list[i].name; i++) {
7103                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7104                         *ptr = parm->enum_list[i].value;
7105                         return;
7106                 }
7107         }
7108         DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7109                   pszParmValue, parm->label));
7110 }
7111
7112 /***************************************************************************
7113 ***************************************************************************/
7114
7115 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7116 {
7117         static int parm_num = -1;
7118         struct service *s;
7119
7120         if ( parm_num == -1 )
7121                 parm_num = map_parameter( "printing" );
7122
7123         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7124
7125         if ( snum < 0 )
7126                 s = &sDefault;
7127         else
7128                 s = ServicePtrs[snum];
7129
7130         init_printer_values( s );
7131
7132         return True;
7133 }
7134
7135
7136 /***************************************************************************
7137  Initialise a copymap.
7138 ***************************************************************************/
7139
7140 static void init_copymap(struct service *pservice)
7141 {
7142         int i;
7143         if (pservice->copymap) {
7144                 bitmap_free(pservice->copymap);
7145         }
7146         pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7147         if (!pservice->copymap)
7148                 DEBUG(0,
7149                       ("Couldn't allocate copymap!! (size %d)\n",
7150                        (int)NUMPARAMETERS));
7151         else
7152                 for (i = 0; i < NUMPARAMETERS; i++)
7153                         bitmap_set(pservice->copymap, i);
7154 }
7155
7156 /***************************************************************************
7157  Return the local pointer to a parameter given the service number and the 
7158  pointer into the default structure.
7159 ***************************************************************************/
7160
7161 void *lp_local_ptr(int snum, void *ptr)
7162 {
7163         return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7164 }
7165
7166 /***************************************************************************
7167  Process a parameter for a particular service number. If snum < 0
7168  then assume we are in the globals.
7169 ***************************************************************************/
7170
7171 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7172 {
7173         int parmnum, i;
7174         void *parm_ptr = NULL;  /* where we are going to store the result */
7175         void *def_ptr = NULL;
7176         struct param_opt_struct **opt_list;
7177
7178         parmnum = map_parameter(pszParmName);
7179
7180         if (parmnum < 0) {
7181                 if (strchr(pszParmName, ':') == NULL) {
7182                         DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7183                                   pszParmName));
7184                         return (True);
7185                 }
7186
7187                 /*
7188                  * We've got a parametric option
7189                  */
7190
7191                 opt_list = (snum < 0)
7192                         ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7193                 set_param_opt(opt_list, pszParmName, pszParmValue);
7194
7195                 return (True);
7196         }
7197
7198         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7199                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7200                           pszParmName));
7201         }
7202
7203         def_ptr = parm_table[parmnum].ptr;
7204
7205         /* we might point at a service, the default service or a global */
7206         if (snum < 0) {
7207                 parm_ptr = def_ptr;
7208         } else {
7209                 if (parm_table[parmnum].p_class == P_GLOBAL) {
7210                         DEBUG(0,
7211                               ("Global parameter %s found in service section!\n",
7212                                pszParmName));
7213                         return (True);
7214                 }
7215                 parm_ptr = lp_local_ptr(snum, def_ptr);
7216         }
7217
7218         if (snum >= 0) {
7219                 if (!ServicePtrs[snum]->copymap)
7220                         init_copymap(ServicePtrs[snum]);
7221
7222                 /* this handles the aliases - set the copymap for other entries with
7223                    the same data pointer */
7224                 for (i = 0; parm_table[i].label; i++)
7225                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
7226                                 bitmap_clear(ServicePtrs[snum]->copymap, i);
7227         }
7228
7229         /* if it is a special case then go ahead */
7230         if (parm_table[parmnum].special) {
7231                 return parm_table[parmnum].special(snum, pszParmValue,
7232                                                    (char **)parm_ptr);
7233         }
7234
7235         /* now switch on the type of variable it is */
7236         switch (parm_table[parmnum].type)
7237         {
7238                 case P_BOOL:
7239                         *(bool *)parm_ptr = lp_bool(pszParmValue);
7240                         break;
7241
7242                 case P_BOOLREV:
7243                         *(bool *)parm_ptr = !lp_bool(pszParmValue);
7244                         break;
7245
7246                 case P_INTEGER:
7247                         *(int *)parm_ptr = lp_int(pszParmValue);
7248                         break;
7249
7250                 case P_CHAR:
7251                         *(char *)parm_ptr = *pszParmValue;
7252                         break;
7253
7254                 case P_OCTAL:
7255                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7256                         if ( i != 1 ) {
7257                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7258                         }
7259                         break;
7260
7261                 case P_LIST:
7262                         TALLOC_FREE(*((char ***)parm_ptr));
7263                         *(char ***)parm_ptr = str_list_make_v3(
7264                                 talloc_autofree_context(), pszParmValue, NULL);
7265                         break;
7266
7267                 case P_STRING:
7268                         string_set((char **)parm_ptr, pszParmValue);
7269                         break;
7270
7271                 case P_USTRING:
7272                         string_set((char **)parm_ptr, pszParmValue);
7273                         strupper_m(*(char **)parm_ptr);
7274                         break;
7275
7276                 case P_ENUM:
7277                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7278                         break;
7279                 case P_SEP:
7280                         break;
7281         }
7282
7283         return (True);
7284 }
7285
7286 /***************************************************************************
7287  Process a parameter.
7288 ***************************************************************************/
7289
7290 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7291                          void *userdata)
7292 {
7293         if (!bInGlobalSection && bGlobalOnly)
7294                 return (True);
7295
7296         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7297
7298         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7299                                 pszParmName, pszParmValue));
7300 }
7301
7302 /***************************************************************************
7303  Print a parameter of the specified type.
7304 ***************************************************************************/
7305
7306 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7307 {
7308         int i;
7309         switch (p->type)
7310         {
7311                 case P_ENUM:
7312                         for (i = 0; p->enum_list[i].name; i++) {
7313                                 if (*(int *)ptr == p->enum_list[i].value) {
7314                                         fprintf(f, "%s",
7315                                                 p->enum_list[i].name);
7316                                         break;
7317                                 }
7318                         }
7319                         break;
7320
7321                 case P_BOOL:
7322                         fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7323                         break;
7324
7325                 case P_BOOLREV:
7326                         fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7327                         break;
7328
7329                 case P_INTEGER:
7330                         fprintf(f, "%d", *(int *)ptr);
7331                         break;
7332
7333                 case P_CHAR:
7334                         fprintf(f, "%c", *(char *)ptr);
7335                         break;
7336
7337                 case P_OCTAL: {
7338                         char *o = octal_string(*(int *)ptr);
7339                         fprintf(f, "%s", o);
7340                         TALLOC_FREE(o);
7341                         break;
7342                 }
7343
7344                 case P_LIST:
7345                         if ((char ***)ptr && *(char ***)ptr) {
7346                                 char **list = *(char ***)ptr;
7347                                 for (; *list; list++) {
7348                                         /* surround strings with whitespace in double quotes */
7349                                         if ( strchr_m( *list, ' ' ) )
7350                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7351                                         else
7352                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7353                                 }
7354                         }
7355                         break;
7356
7357                 case P_STRING:
7358                 case P_USTRING:
7359                         if (*(char **)ptr) {
7360                                 fprintf(f, "%s", *(char **)ptr);
7361                         }
7362                         break;
7363                 case P_SEP:
7364                         break;
7365         }
7366 }
7367
7368 /***************************************************************************
7369  Check if two parameters are equal.
7370 ***************************************************************************/
7371
7372 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7373 {
7374         switch (type) {
7375                 case P_BOOL:
7376                 case P_BOOLREV:
7377                         return (*((bool *)ptr1) == *((bool *)ptr2));
7378
7379                 case P_INTEGER:
7380                 case P_ENUM:
7381                 case P_OCTAL:
7382                         return (*((int *)ptr1) == *((int *)ptr2));
7383
7384                 case P_CHAR:
7385                         return (*((char *)ptr1) == *((char *)ptr2));
7386
7387                 case P_LIST:
7388                         return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7389
7390                 case P_STRING:
7391                 case P_USTRING:
7392                 {
7393                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7394                         if (p1 && !*p1)
7395                                 p1 = NULL;
7396                         if (p2 && !*p2)
7397                                 p2 = NULL;
7398                         return (p1 == p2 || strequal(p1, p2));
7399                 }
7400                 case P_SEP:
7401                         break;
7402         }
7403         return (False);
7404 }
7405
7406 /***************************************************************************
7407  Initialize any local varients in the sDefault table.
7408 ***************************************************************************/
7409
7410 void init_locals(void)
7411 {
7412         /* None as yet. */
7413 }
7414
7415 /***************************************************************************
7416  Process a new section (service). At this stage all sections are services.
7417  Later we'll have special sections that permit server parameters to be set.
7418  Returns True on success, False on failure. 
7419 ***************************************************************************/
7420
7421 static bool do_section(const char *pszSectionName, void *userdata)
7422 {
7423         bool bRetval;
7424         bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7425                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7426         bRetval = False;
7427
7428         /* if we were in a global section then do the local inits */
7429         if (bInGlobalSection && !isglobal)
7430                 init_locals();
7431
7432         /* if we've just struck a global section, note the fact. */
7433         bInGlobalSection = isglobal;
7434
7435         /* check for multiple global sections */
7436         if (bInGlobalSection) {
7437                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7438                 return (True);
7439         }
7440
7441         if (!bInGlobalSection && bGlobalOnly)
7442                 return (True);
7443
7444         /* if we have a current service, tidy it up before moving on */
7445         bRetval = True;
7446
7447         if (iServiceIndex >= 0)
7448                 bRetval = service_ok(iServiceIndex);
7449
7450         /* if all is still well, move to the next record in the services array */
7451         if (bRetval) {
7452                 /* We put this here to avoid an odd message order if messages are */
7453                 /* issued by the post-processing of a previous section. */
7454                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7455
7456                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7457                     < 0) {
7458                         DEBUG(0, ("Failed to add a new service\n"));
7459                         return (False);
7460                 }
7461         }
7462
7463         return (bRetval);
7464 }
7465
7466
7467 /***************************************************************************
7468  Determine if a partcular base parameter is currentl set to the default value.
7469 ***************************************************************************/
7470
7471 static bool is_default(int i)
7472 {
7473         if (!defaults_saved)
7474                 return False;
7475         switch (parm_table[i].type) {
7476                 case P_LIST:
7477                         return str_list_equal((const char **)parm_table[i].def.lvalue, 
7478                                                 *(const char ***)parm_table[i].ptr);
7479                 case P_STRING:
7480                 case P_USTRING:
7481                         return strequal(parm_table[i].def.svalue,
7482                                         *(char **)parm_table[i].ptr);
7483                 case P_BOOL:
7484                 case P_BOOLREV:
7485                         return parm_table[i].def.bvalue ==
7486                                 *(bool *)parm_table[i].ptr;
7487                 case P_CHAR:
7488                         return parm_table[i].def.cvalue ==
7489                                 *(char *)parm_table[i].ptr;
7490                 case P_INTEGER:
7491                 case P_OCTAL:
7492                 case P_ENUM:
7493                         return parm_table[i].def.ivalue ==
7494                                 *(int *)parm_table[i].ptr;
7495                 case P_SEP:
7496                         break;
7497         }
7498         return False;
7499 }
7500
7501 /***************************************************************************
7502 Display the contents of the global structure.
7503 ***************************************************************************/
7504
7505 static void dump_globals(FILE *f)
7506 {
7507         int i;
7508         struct param_opt_struct *data;
7509         
7510         fprintf(f, "[global]\n");
7511
7512         for (i = 0; parm_table[i].label; i++)
7513                 if (parm_table[i].p_class == P_GLOBAL &&
7514                     parm_table[i].ptr &&
7515                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7516                         if (defaults_saved && is_default(i))
7517                                 continue;
7518                         fprintf(f, "\t%s = ", parm_table[i].label);
7519                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
7520                         fprintf(f, "\n");
7521         }
7522         if (Globals.param_opt != NULL) {
7523                 data = Globals.param_opt;
7524                 while(data) {
7525                         fprintf(f, "\t%s = %s\n", data->key, data->value);
7526                         data = data->next;
7527                 }
7528         }
7529
7530 }
7531
7532 /***************************************************************************
7533  Return True if a local parameter is currently set to the global default.
7534 ***************************************************************************/
7535
7536 bool lp_is_default(int snum, struct parm_struct *parm)
7537 {
7538         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7539
7540         return equal_parameter(parm->type,
7541                                ((char *)ServicePtrs[snum]) + pdiff,
7542                                ((char *)&sDefault) + pdiff);
7543 }
7544
7545 /***************************************************************************
7546  Display the contents of a single services record.
7547 ***************************************************************************/
7548
7549 static void dump_a_service(struct service *pService, FILE * f)
7550 {
7551         int i;
7552         struct param_opt_struct *data;
7553         
7554         if (pService != &sDefault)
7555                 fprintf(f, "[%s]\n", pService->szService);
7556
7557         for (i = 0; parm_table[i].label; i++) {
7558
7559                 if (parm_table[i].p_class == P_LOCAL &&
7560                     parm_table[i].ptr &&
7561                     (*parm_table[i].label != '-') &&
7562                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7563                 {
7564                 
7565                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7566
7567                         if (pService == &sDefault) {
7568                                 if (defaults_saved && is_default(i))
7569                                         continue;
7570                         } else {
7571                                 if (equal_parameter(parm_table[i].type,
7572                                                     ((char *)pService) +
7573                                                     pdiff,
7574                                                     ((char *)&sDefault) +
7575                                                     pdiff))
7576                                         continue;
7577                         }
7578
7579                         fprintf(f, "\t%s = ", parm_table[i].label);
7580                         print_parameter(&parm_table[i],
7581                                         ((char *)pService) + pdiff, f);
7582                         fprintf(f, "\n");
7583                 }
7584         }
7585
7586                 if (pService->param_opt != NULL) {
7587                         data = pService->param_opt;
7588                         while(data) {
7589                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
7590                                 data = data->next;
7591                         }
7592                 }
7593 }
7594
7595 /***************************************************************************
7596  Display the contents of a parameter of a single services record.
7597 ***************************************************************************/
7598
7599 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7600 {
7601         int i;
7602         bool result = False;
7603         parm_class p_class;
7604         unsigned flag = 0;
7605         fstring local_parm_name;
7606         char *parm_opt;
7607         const char *parm_opt_value;
7608
7609         /* check for parametrical option */
7610         fstrcpy( local_parm_name, parm_name);
7611         parm_opt = strchr( local_parm_name, ':');
7612
7613         if (parm_opt) {
7614                 *parm_opt = '\0';
7615                 parm_opt++;
7616                 if (strlen(parm_opt)) {
7617                         parm_opt_value = lp_parm_const_string( snum,
7618                                 local_parm_name, parm_opt, NULL);
7619                         if (parm_opt_value) {
7620                                 printf( "%s\n", parm_opt_value);
7621                                 result = True;
7622                         }
7623                 }
7624                 return result;
7625         }
7626
7627         /* check for a key and print the value */
7628         if (isGlobal) {
7629                 p_class = P_GLOBAL;
7630                 flag = FLAG_GLOBAL;
7631         } else
7632                 p_class = P_LOCAL;
7633
7634         for (i = 0; parm_table[i].label; i++) {
7635                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7636                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7637                     parm_table[i].ptr &&
7638                     (*parm_table[i].label != '-') &&
7639                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
7640                 {
7641                         void *ptr;
7642
7643                         if (isGlobal) {
7644                                 ptr = parm_table[i].ptr;
7645                         } else {
7646                                 struct service *pService = ServicePtrs[snum];
7647                                 ptr = ((char *)pService) +
7648                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
7649                         }
7650
7651                         print_parameter(&parm_table[i],
7652                                         ptr, f);
7653                         fprintf(f, "\n");
7654                         result = True;
7655                         break;
7656                 }
7657         }
7658
7659         return result;
7660 }
7661
7662 /***************************************************************************
7663  Return info about the requested parameter (given as a string).
7664  Return NULL when the string is not a valid parameter name.
7665 ***************************************************************************/
7666
7667 struct parm_struct *lp_get_parameter(const char *param_name)
7668 {
7669         int num = map_parameter(param_name);
7670
7671         if (num < 0) {
7672                 return NULL;
7673         }
7674
7675         return &parm_table[num];
7676 }
7677
7678 /***************************************************************************
7679  Return info about the next parameter in a service.
7680  snum==GLOBAL_SECTION_SNUM gives the globals.
7681  Return NULL when out of parameters.
7682 ***************************************************************************/
7683
7684 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7685 {
7686         if (snum < 0) {
7687                 /* do the globals */
7688                 for (; parm_table[*i].label; (*i)++) {
7689                         if (parm_table[*i].p_class == P_SEPARATOR)
7690                                 return &parm_table[(*i)++];
7691
7692                         if (!parm_table[*i].ptr
7693                             || (*parm_table[*i].label == '-'))
7694                                 continue;
7695
7696                         if ((*i) > 0
7697                             && (parm_table[*i].ptr ==
7698                                 parm_table[(*i) - 1].ptr))
7699                                 continue;
7700                         
7701                         if (is_default(*i) && !allparameters)
7702                                 continue;
7703
7704                         return &parm_table[(*i)++];
7705                 }
7706         } else {
7707                 struct service *pService = ServicePtrs[snum];
7708
7709                 for (; parm_table[*i].label; (*i)++) {
7710                         if (parm_table[*i].p_class == P_SEPARATOR)
7711                                 return &parm_table[(*i)++];
7712
7713                         if (parm_table[*i].p_class == P_LOCAL &&
7714                             parm_table[*i].ptr &&
7715                             (*parm_table[*i].label != '-') &&
7716                             ((*i) == 0 ||
7717                              (parm_table[*i].ptr !=
7718                               parm_table[(*i) - 1].ptr)))
7719                         {
7720                                 int pdiff =
7721                                         PTR_DIFF(parm_table[*i].ptr,
7722                                                  &sDefault);
7723
7724                                 if (allparameters ||
7725                                     !equal_parameter(parm_table[*i].type,
7726                                                      ((char *)pService) +
7727                                                      pdiff,
7728                                                      ((char *)&sDefault) +
7729                                                      pdiff))
7730                                 {
7731                                         return &parm_table[(*i)++];
7732                                 }
7733                         }
7734                 }
7735         }
7736
7737         return NULL;
7738 }
7739
7740
7741 #if 0
7742 /***************************************************************************
7743  Display the contents of a single copy structure.
7744 ***************************************************************************/
7745 static void dump_copy_map(bool *pcopymap)
7746 {
7747         int i;
7748         if (!pcopymap)
7749                 return;
7750
7751         printf("\n\tNon-Copied parameters:\n");
7752
7753         for (i = 0; parm_table[i].label; i++)
7754                 if (parm_table[i].p_class == P_LOCAL &&
7755                     parm_table[i].ptr && !pcopymap[i] &&
7756                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7757                 {
7758                         printf("\t\t%s\n", parm_table[i].label);
7759                 }
7760 }
7761 #endif
7762
7763 /***************************************************************************
7764  Return TRUE if the passed service number is within range.
7765 ***************************************************************************/
7766
7767 bool lp_snum_ok(int iService)
7768 {
7769         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7770 }
7771
7772 /***************************************************************************
7773  Auto-load some home services.
7774 ***************************************************************************/
7775
7776 static void lp_add_auto_services(char *str)
7777 {
7778         char *s;
7779         char *p;
7780         int homes;
7781         char *saveptr;
7782
7783         if (!str)
7784                 return;
7785
7786         s = SMB_STRDUP(str);
7787         if (!s)
7788                 return;
7789
7790         homes = lp_servicenumber(HOMES_NAME);
7791
7792         for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7793              p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7794                 char *home;
7795
7796                 if (lp_servicenumber(p) >= 0)
7797                         continue;
7798
7799                 home = get_user_home_dir(talloc_tos(), p);
7800
7801                 if (home && homes >= 0)
7802                         lp_add_home(p, homes, p, home);
7803
7804                 TALLOC_FREE(home);
7805         }
7806         SAFE_FREE(s);
7807 }
7808
7809 /***************************************************************************
7810  Auto-load one printer.
7811 ***************************************************************************/
7812
7813 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7814 {
7815         int printers = lp_servicenumber(PRINTERS_NAME);
7816         int i;
7817
7818         if (lp_servicenumber(name) < 0) {
7819                 lp_add_printer(name, printers);
7820                 if ((i = lp_servicenumber(name)) >= 0) {
7821                         string_set(&ServicePtrs[i]->comment, comment);
7822                         ServicePtrs[i]->autoloaded = True;
7823                 }
7824         }
7825 }
7826
7827 /***************************************************************************
7828  Have we loaded a services file yet?
7829 ***************************************************************************/
7830
7831 bool lp_loaded(void)
7832 {
7833         return (bLoaded);
7834 }
7835
7836 /***************************************************************************
7837  Unload unused services.
7838 ***************************************************************************/
7839
7840 void lp_killunused(bool (*snumused) (int))
7841 {
7842         int i;
7843         for (i = 0; i < iNumServices; i++) {
7844                 if (!VALID(i))
7845                         continue;
7846
7847                 /* don't kill autoloaded or usershare services */
7848                 if ( ServicePtrs[i]->autoloaded ||
7849                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7850                         continue;
7851                 }
7852
7853                 if (!snumused || !snumused(i)) {
7854                         free_service_byindex(i);
7855                 }
7856         }
7857 }
7858
7859 /**
7860  * Kill all except autoloaded and usershare services - convenience wrapper
7861  */
7862 void lp_kill_all_services(void)
7863 {
7864         lp_killunused(NULL);
7865 }
7866
7867 /***************************************************************************
7868  Unload a service.
7869 ***************************************************************************/
7870
7871 void lp_killservice(int iServiceIn)
7872 {
7873         if (VALID(iServiceIn)) {
7874                 free_service_byindex(iServiceIn);
7875         }
7876 }
7877
7878 /***************************************************************************
7879  Save the curent values of all global and sDefault parameters into the 
7880  defaults union. This allows swat and testparm to show only the
7881  changed (ie. non-default) parameters.
7882 ***************************************************************************/
7883
7884 static void lp_save_defaults(void)
7885 {
7886         int i;
7887         for (i = 0; parm_table[i].label; i++) {
7888                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7889                         continue;
7890                 switch (parm_table[i].type) {
7891                         case P_LIST:
7892                                 parm_table[i].def.lvalue = str_list_copy(
7893                                         NULL, *(const char ***)parm_table[i].ptr);
7894                                 break;
7895                         case P_STRING:
7896                         case P_USTRING:
7897                                 if (parm_table[i].ptr) {
7898                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7899                                 } else {
7900                                         parm_table[i].def.svalue = NULL;
7901                                 }
7902                                 break;
7903                         case P_BOOL:
7904                         case P_BOOLREV:
7905                                 parm_table[i].def.bvalue =
7906                                         *(bool *)parm_table[i].ptr;
7907                                 break;
7908                         case P_CHAR:
7909                                 parm_table[i].def.cvalue =
7910                                         *(char *)parm_table[i].ptr;
7911                                 break;
7912                         case P_INTEGER:
7913                         case P_OCTAL:
7914                         case P_ENUM:
7915                                 parm_table[i].def.ivalue =
7916                                         *(int *)parm_table[i].ptr;
7917                                 break;
7918                         case P_SEP:
7919                                 break;
7920                 }
7921         }
7922         defaults_saved = True;
7923 }
7924
7925 /*******************************************************************
7926  Set the server type we will announce as via nmbd.
7927 ********************************************************************/
7928
7929 static const struct srv_role_tab {
7930         uint32 role;
7931         const char *role_str;
7932 } srv_role_tab [] = {
7933         { ROLE_STANDALONE, "ROLE_STANDALONE" },
7934         { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7935         { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7936         { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7937         { 0, NULL }
7938 };
7939
7940 const char* server_role_str(uint32 role)
7941 {
7942         int i = 0;
7943         for (i=0; srv_role_tab[i].role_str; i++) {
7944                 if (role == srv_role_tab[i].role) {
7945                         return srv_role_tab[i].role_str;
7946                 }
7947         }
7948         return NULL;
7949 }
7950
7951 static void set_server_role(void)
7952 {
7953         server_role = ROLE_STANDALONE;
7954
7955         switch (lp_security()) {
7956                 case SEC_SHARE:
7957                         if (lp_domain_logons())
7958                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7959                         break;
7960                 case SEC_SERVER:
7961                         if (lp_domain_logons())
7962                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
7963                         /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
7964                         server_role = ROLE_STANDALONE;
7965                         break;
7966                 case SEC_DOMAIN:
7967                         if (lp_domain_logons()) {
7968                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
7969                                 server_role = ROLE_DOMAIN_BDC;
7970                                 break;
7971                         }
7972                         server_role = ROLE_DOMAIN_MEMBER;
7973                         break;
7974                 case SEC_ADS:
7975                         if (lp_domain_logons()) {
7976                                 server_role = ROLE_DOMAIN_PDC;
7977                                 break;
7978                         }
7979                         server_role = ROLE_DOMAIN_MEMBER;
7980                         break;
7981                 case SEC_USER:
7982                         if (lp_domain_logons()) {
7983
7984                                 if (Globals.iDomainMaster) /* auto or yes */ 
7985                                         server_role = ROLE_DOMAIN_PDC;
7986                                 else
7987                                         server_role = ROLE_DOMAIN_BDC;
7988                         }
7989                         break;
7990                 default:
7991                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
7992                         break;
7993         }
7994
7995         DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
7996 }
7997
7998 /***********************************************************
7999  If we should send plaintext/LANMAN passwords in the clinet
8000 ************************************************************/
8001
8002 static void set_allowed_client_auth(void)
8003 {
8004         if (Globals.bClientNTLMv2Auth) {
8005                 Globals.bClientLanManAuth = False;
8006         }
8007         if (!Globals.bClientLanManAuth) {
8008                 Globals.bClientPlaintextAuth = False;
8009         }
8010 }
8011
8012 /***************************************************************************
8013  JRA.
8014  The following code allows smbd to read a user defined share file.
8015  Yes, this is my intent. Yes, I'm comfortable with that...
8016
8017  THE FOLLOWING IS SECURITY CRITICAL CODE.
8018
8019  It washes your clothes, it cleans your house, it guards you while you sleep...
8020  Do not f%^k with it....
8021 ***************************************************************************/
8022
8023 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8024
8025 /***************************************************************************
8026  Check allowed stat state of a usershare file.
8027  Ensure we print out who is dicking with us so the admin can
8028  get their sorry ass fired.
8029 ***************************************************************************/
8030
8031 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8032 {
8033         if (!S_ISREG(psbuf->st_mode)) {
8034                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8035                         "not a regular file\n",
8036                         fname, (unsigned int)psbuf->st_uid ));
8037                 return False;
8038         }
8039
8040         /* Ensure this doesn't have the other write bit set. */
8041         if (psbuf->st_mode & S_IWOTH) {
8042                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8043                         "public write. Refusing to allow as a usershare file.\n",
8044                         fname, (unsigned int)psbuf->st_uid ));
8045                 return False;
8046         }
8047
8048         /* Should be 10k or less. */
8049         if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8050                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8051                         "too large (%u) to be a user share file.\n",
8052                         fname, (unsigned int)psbuf->st_uid,
8053                         (unsigned int)psbuf->st_size ));
8054                 return False;
8055         }
8056
8057         return True;
8058 }
8059
8060 /***************************************************************************
8061  Parse the contents of a usershare file.
8062 ***************************************************************************/
8063
8064 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8065                         SMB_STRUCT_STAT *psbuf,
8066                         const char *servicename,
8067                         int snum,
8068                         char **lines,
8069                         int numlines,
8070                         char **pp_sharepath,
8071                         char **pp_comment,
8072                         SEC_DESC **ppsd,
8073                         bool *pallow_guest)
8074 {
8075         const char **prefixallowlist = lp_usershare_prefix_allow_list();
8076         const char **prefixdenylist = lp_usershare_prefix_deny_list();
8077         int us_vers;
8078         SMB_STRUCT_DIR *dp;
8079         SMB_STRUCT_STAT sbuf;
8080         char *sharepath = NULL;
8081         char *comment = NULL;
8082
8083         *pp_sharepath = NULL;
8084         *pp_comment = NULL;
8085
8086         *pallow_guest = False;
8087
8088         if (numlines < 4) {
8089                 return USERSHARE_MALFORMED_FILE;
8090         }
8091
8092         if (strcmp(lines[0], "#VERSION 1") == 0) {
8093                 us_vers = 1;
8094         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8095                 us_vers = 2;
8096                 if (numlines < 5) {
8097                         return USERSHARE_MALFORMED_FILE;
8098                 }
8099         } else {
8100                 return USERSHARE_BAD_VERSION;
8101         }
8102
8103         if (strncmp(lines[1], "path=", 5) != 0) {
8104                 return USERSHARE_MALFORMED_PATH;
8105         }
8106
8107         sharepath = talloc_strdup(ctx, &lines[1][5]);
8108         if (!sharepath) {
8109                 return USERSHARE_POSIX_ERR;
8110         }
8111         trim_string(sharepath, " ", " ");
8112
8113         if (strncmp(lines[2], "comment=", 8) != 0) {
8114                 return USERSHARE_MALFORMED_COMMENT_DEF;
8115         }
8116
8117         comment = talloc_strdup(ctx, &lines[2][8]);
8118         if (!comment) {
8119                 return USERSHARE_POSIX_ERR;
8120         }
8121         trim_string(comment, " ", " ");
8122         trim_char(comment, '"', '"');
8123
8124         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8125                 return USERSHARE_MALFORMED_ACL_DEF;
8126         }
8127
8128         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8129                 return USERSHARE_ACL_ERR;
8130         }
8131
8132         if (us_vers == 2) {
8133                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8134                         return USERSHARE_MALFORMED_ACL_DEF;
8135                 }
8136                 if (lines[4][9] == 'y') {
8137                         *pallow_guest = True;
8138                 }
8139         }
8140
8141         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8142                 /* Path didn't change, no checks needed. */
8143                 *pp_sharepath = sharepath;
8144                 *pp_comment = comment;
8145                 return USERSHARE_OK;
8146         }
8147
8148         /* The path *must* be absolute. */
8149         if (sharepath[0] != '/') {
8150                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8151                         servicename, sharepath));
8152                 return USERSHARE_PATH_NOT_ABSOLUTE;
8153         }
8154
8155         /* If there is a usershare prefix deny list ensure one of these paths
8156            doesn't match the start of the user given path. */
8157         if (prefixdenylist) {
8158                 int i;
8159                 for ( i=0; prefixdenylist[i]; i++ ) {
8160                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8161                                 servicename, i, prefixdenylist[i], sharepath ));
8162                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8163                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8164                                         "usershare prefix deny list entries.\n",
8165                                         servicename, sharepath));
8166                                 return USERSHARE_PATH_IS_DENIED;
8167                         }
8168                 }
8169         }
8170
8171         /* If there is a usershare prefix allow list ensure one of these paths
8172            does match the start of the user given path. */
8173
8174         if (prefixallowlist) {
8175                 int i;
8176                 for ( i=0; prefixallowlist[i]; i++ ) {
8177                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8178                                 servicename, i, prefixallowlist[i], sharepath ));
8179                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8180                                 break;
8181                         }
8182                 }
8183                 if (prefixallowlist[i] == NULL) {
8184                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8185                                 "usershare prefix allow list entries.\n",
8186                                 servicename, sharepath));
8187                         return USERSHARE_PATH_NOT_ALLOWED;
8188                 }
8189         }
8190
8191         /* Ensure this is pointing to a directory. */
8192         dp = sys_opendir(sharepath);
8193
8194         if (!dp) {
8195                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8196                         servicename, sharepath));
8197                 return USERSHARE_PATH_NOT_DIRECTORY;
8198         }
8199
8200         /* Ensure the owner of the usershare file has permission to share
8201            this directory. */
8202
8203         if (sys_stat(sharepath, &sbuf) == -1) {
8204                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8205                         servicename, sharepath, strerror(errno) ));
8206                 sys_closedir(dp);
8207                 return USERSHARE_POSIX_ERR;
8208         }
8209
8210         sys_closedir(dp);
8211
8212         if (!S_ISDIR(sbuf.st_mode)) {
8213                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8214                         servicename, sharepath ));
8215                 return USERSHARE_PATH_NOT_DIRECTORY;
8216         }
8217
8218         /* Check if sharing is restricted to owner-only. */
8219         /* psbuf is the stat of the usershare definition file,
8220            sbuf is the stat of the target directory to be shared. */
8221
8222         if (lp_usershare_owner_only()) {
8223                 /* root can share anything. */
8224                 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8225                         return USERSHARE_PATH_NOT_ALLOWED;
8226                 }
8227         }
8228
8229         *pp_sharepath = sharepath;
8230         *pp_comment = comment;
8231         return USERSHARE_OK;
8232 }
8233
8234 /***************************************************************************
8235  Deal with a usershare file.
8236  Returns:
8237         >= 0 - snum
8238         -1 - Bad name, invalid contents.
8239            - service name already existed and not a usershare, problem
8240             with permissions to share directory etc.
8241 ***************************************************************************/
8242
8243 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8244 {
8245         SMB_STRUCT_STAT sbuf;
8246         SMB_STRUCT_STAT lsbuf;
8247         char *fname = NULL;
8248         char *sharepath = NULL;
8249         char *comment = NULL;
8250         fstring service_name;
8251         char **lines = NULL;
8252         int numlines = 0;
8253         int fd = -1;
8254         int iService = -1;
8255         TALLOC_CTX *ctx = NULL;
8256         SEC_DESC *psd = NULL;
8257         bool guest_ok = False;
8258
8259         /* Ensure share name doesn't contain invalid characters. */
8260         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8261                 DEBUG(0,("process_usershare_file: share name %s contains "
8262                         "invalid characters (any of %s)\n",
8263                         file_name, INVALID_SHARENAME_CHARS ));
8264                 return -1;
8265         }
8266
8267         fstrcpy(service_name, file_name);
8268
8269         if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8270         }
8271
8272         /* Minimize the race condition by doing an lstat before we
8273            open and fstat. Ensure this isn't a symlink link. */
8274
8275         if (sys_lstat(fname, &lsbuf) != 0) {
8276                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8277                         fname, strerror(errno) ));
8278                 SAFE_FREE(fname);
8279                 return -1;
8280         }
8281
8282         /* This must be a regular file, not a symlink, directory or
8283            other strange filetype. */
8284         if (!check_usershare_stat(fname, &lsbuf)) {
8285                 SAFE_FREE(fname);
8286                 return -1;
8287         }
8288
8289         {
8290                 char *canon_name = canonicalize_servicename(service_name);
8291                 TDB_DATA data = dbwrap_fetch_bystring(
8292                         ServiceHash, canon_name, canon_name);
8293
8294                 iService = -1;
8295
8296                 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8297                         iService = *(int *)data.dptr;
8298                 }
8299                 TALLOC_FREE(canon_name);
8300         }
8301
8302         if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8303                 /* Nothing changed - Mark valid and return. */
8304                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8305                         service_name ));
8306                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8307                 SAFE_FREE(fname);
8308                 return iService;
8309         }
8310
8311         /* Try and open the file read only - no symlinks allowed. */
8312 #ifdef O_NOFOLLOW
8313         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8314 #else
8315         fd = sys_open(fname, O_RDONLY, 0);
8316 #endif
8317
8318         if (fd == -1) {
8319                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8320                         fname, strerror(errno) ));
8321                 SAFE_FREE(fname);
8322                 return -1;
8323         }
8324
8325         /* Now fstat to be *SURE* it's a regular file. */
8326         if (sys_fstat(fd, &sbuf) != 0) {
8327                 close(fd);
8328                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8329                         fname, strerror(errno) ));
8330                 SAFE_FREE(fname);
8331                 return -1;
8332         }
8333
8334         /* Is it the same dev/inode as was lstated ? */
8335         if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8336                 close(fd);
8337                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8338                         "Symlink spoofing going on ?\n", fname ));
8339                 SAFE_FREE(fname);
8340                 return -1;
8341         }
8342
8343         /* This must be a regular file, not a symlink, directory or
8344            other strange filetype. */
8345         if (!check_usershare_stat(fname, &sbuf)) {
8346                 SAFE_FREE(fname);
8347                 return -1;
8348         }
8349
8350         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8351
8352         close(fd);
8353         if (lines == NULL) {
8354                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8355                         fname, (unsigned int)sbuf.st_uid ));
8356                 SAFE_FREE(fname);
8357                 return -1;
8358         }
8359
8360         SAFE_FREE(fname);
8361
8362         /* Should we allow printers to be shared... ? */
8363         ctx = talloc_init("usershare_sd_xctx");
8364         if (!ctx) {
8365                 TALLOC_FREE(lines);
8366                 return 1;
8367         }
8368
8369         if (parse_usershare_file(ctx, &sbuf, service_name,
8370                         iService, lines, numlines, &sharepath,
8371                         &comment, &psd, &guest_ok) != USERSHARE_OK) {
8372                 talloc_destroy(ctx);
8373                 TALLOC_FREE(lines);
8374                 return -1;
8375         }
8376
8377         TALLOC_FREE(lines);
8378
8379         /* Everything ok - add the service possibly using a template. */
8380         if (iService < 0) {
8381                 const struct service *sp = &sDefault;
8382                 if (snum_template != -1) {
8383                         sp = ServicePtrs[snum_template];
8384                 }
8385
8386                 if ((iService = add_a_service(sp, service_name)) < 0) {
8387                         DEBUG(0, ("process_usershare_file: Failed to add "
8388                                 "new service %s\n", service_name));
8389                         talloc_destroy(ctx);
8390                         return -1;
8391                 }
8392
8393                 /* Read only is controlled by usershare ACL below. */
8394                 ServicePtrs[iService]->bRead_only = False;
8395         }
8396
8397         /* Write the ACL of the new/modified share. */
8398         if (!set_share_security(service_name, psd)) {
8399                  DEBUG(0, ("process_usershare_file: Failed to set share "
8400                         "security for user share %s\n",
8401                         service_name ));
8402                 lp_remove_service(iService);
8403                 talloc_destroy(ctx);
8404                 return -1;
8405         }
8406
8407         /* If from a template it may be marked invalid. */
8408         ServicePtrs[iService]->valid = True;
8409
8410         /* Set the service as a valid usershare. */
8411         ServicePtrs[iService]->usershare = USERSHARE_VALID;
8412
8413         /* Set guest access. */
8414         if (lp_usershare_allow_guests()) {
8415                 ServicePtrs[iService]->bGuest_ok = guest_ok;
8416         }
8417
8418         /* And note when it was loaded. */
8419         ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8420         string_set(&ServicePtrs[iService]->szPath, sharepath);
8421         string_set(&ServicePtrs[iService]->comment, comment);
8422
8423         talloc_destroy(ctx);
8424
8425         return iService;
8426 }
8427
8428 /***************************************************************************
8429  Checks if a usershare entry has been modified since last load.
8430 ***************************************************************************/
8431
8432 static bool usershare_exists(int iService, time_t *last_mod)
8433 {
8434         SMB_STRUCT_STAT lsbuf;
8435         const char *usersharepath = Globals.szUsersharePath;
8436         char *fname;
8437
8438         if (asprintf(&fname, "%s/%s",
8439                                 usersharepath,
8440                                 ServicePtrs[iService]->szService) < 0) {
8441                 return false;
8442         }
8443
8444         if (sys_lstat(fname, &lsbuf) != 0) {
8445                 SAFE_FREE(fname);
8446                 return false;
8447         }
8448
8449         if (!S_ISREG(lsbuf.st_mode)) {
8450                 SAFE_FREE(fname);
8451                 return false;
8452         }
8453
8454         SAFE_FREE(fname);
8455         *last_mod = lsbuf.st_mtime;
8456         return true;
8457 }
8458
8459 /***************************************************************************
8460  Load a usershare service by name. Returns a valid servicenumber or -1.
8461 ***************************************************************************/
8462
8463 int load_usershare_service(const char *servicename)
8464 {
8465         SMB_STRUCT_STAT sbuf;
8466         const char *usersharepath = Globals.szUsersharePath;
8467         int max_user_shares = Globals.iUsershareMaxShares;
8468         int snum_template = -1;
8469
8470         if (*usersharepath == 0 ||  max_user_shares == 0) {
8471                 return -1;
8472         }
8473
8474         if (sys_stat(usersharepath, &sbuf) != 0) {
8475                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8476                         usersharepath, strerror(errno) ));
8477                 return -1;
8478         }
8479
8480         if (!S_ISDIR(sbuf.st_mode)) {
8481                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8482                         usersharepath ));
8483                 return -1;
8484         }
8485
8486         /*
8487          * This directory must be owned by root, and have the 't' bit set.
8488          * It also must not be writable by "other".
8489          */
8490
8491 #ifdef S_ISVTX
8492         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8493 #else
8494         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8495 #endif
8496                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8497                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8498                         usersharepath ));
8499                 return -1;
8500         }
8501
8502         /* Ensure the template share exists if it's set. */
8503         if (Globals.szUsershareTemplateShare[0]) {
8504                 /* We can't use lp_servicenumber here as we are recommending that
8505                    template shares have -valid=False set. */
8506                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8507                         if (ServicePtrs[snum_template]->szService &&
8508                                         strequal(ServicePtrs[snum_template]->szService,
8509                                                 Globals.szUsershareTemplateShare)) {
8510                                 break;
8511                         }
8512                 }
8513
8514                 if (snum_template == -1) {
8515                         DEBUG(0,("load_usershare_service: usershare template share %s "
8516                                 "does not exist.\n",
8517                                 Globals.szUsershareTemplateShare ));
8518                         return -1;
8519                 }
8520         }
8521
8522         return process_usershare_file(usersharepath, servicename, snum_template);
8523 }
8524
8525 /***************************************************************************
8526  Load all user defined shares from the user share directory.
8527  We only do this if we're enumerating the share list.
8528  This is the function that can delete usershares that have
8529  been removed.
8530 ***************************************************************************/
8531
8532 int load_usershare_shares(void)
8533 {
8534         SMB_STRUCT_DIR *dp;
8535         SMB_STRUCT_STAT sbuf;
8536         SMB_STRUCT_DIRENT *de;
8537         int num_usershares = 0;
8538         int max_user_shares = Globals.iUsershareMaxShares;
8539         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8540         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8541         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8542         int iService;
8543         int snum_template = -1;
8544         const char *usersharepath = Globals.szUsersharePath;
8545         int ret = lp_numservices();
8546
8547         if (max_user_shares == 0 || *usersharepath == '\0') {
8548                 return lp_numservices();
8549         }
8550
8551         if (sys_stat(usersharepath, &sbuf) != 0) {
8552                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8553                         usersharepath, strerror(errno) ));
8554                 return ret;
8555         }
8556
8557         /*
8558          * This directory must be owned by root, and have the 't' bit set.
8559          * It also must not be writable by "other".
8560          */
8561
8562 #ifdef S_ISVTX
8563         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8564 #else
8565         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8566 #endif
8567                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8568                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
8569                         usersharepath ));
8570                 return ret;
8571         }
8572
8573         /* Ensure the template share exists if it's set. */
8574         if (Globals.szUsershareTemplateShare[0]) {
8575                 /* We can't use lp_servicenumber here as we are recommending that
8576                    template shares have -valid=False set. */
8577                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8578                         if (ServicePtrs[snum_template]->szService &&
8579                                         strequal(ServicePtrs[snum_template]->szService,
8580                                                 Globals.szUsershareTemplateShare)) {
8581                                 break;
8582                         }
8583                 }
8584
8585                 if (snum_template == -1) {
8586                         DEBUG(0,("load_usershare_shares: usershare template share %s "
8587                                 "does not exist.\n",
8588                                 Globals.szUsershareTemplateShare ));
8589                         return ret;
8590                 }
8591         }
8592
8593         /* Mark all existing usershares as pending delete. */
8594         for (iService = iNumServices - 1; iService >= 0; iService--) {
8595                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8596                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8597                 }
8598         }
8599
8600         dp = sys_opendir(usersharepath);
8601         if (!dp) {
8602                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8603                         usersharepath, strerror(errno) ));
8604                 return ret;
8605         }
8606
8607         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8608                         (de = sys_readdir(dp));
8609                         num_dir_entries++ ) {
8610                 int r;
8611                 const char *n = de->d_name;
8612
8613                 /* Ignore . and .. */
8614                 if (*n == '.') {
8615                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8616                                 continue;
8617                         }
8618                 }
8619
8620                 if (n[0] == ':') {
8621                         /* Temporary file used when creating a share. */
8622                         num_tmp_dir_entries++;
8623                 }
8624
8625                 /* Allow 20% tmp entries. */
8626                 if (num_tmp_dir_entries > allowed_tmp_entries) {
8627                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8628                                 "in directory %s\n",
8629                                 num_tmp_dir_entries, usersharepath));
8630                         break;
8631                 }
8632
8633                 r = process_usershare_file(usersharepath, n, snum_template);
8634                 if (r == 0) {
8635                         /* Update the services count. */
8636                         num_usershares++;
8637                         if (num_usershares >= max_user_shares) {
8638                                 DEBUG(0,("load_usershare_shares: max user shares reached "
8639                                         "on file %s in directory %s\n",
8640                                         n, usersharepath ));
8641                                 break;
8642                         }
8643                 } else if (r == -1) {
8644                         num_bad_dir_entries++;
8645                 }
8646
8647                 /* Allow 20% bad entries. */
8648                 if (num_bad_dir_entries > allowed_bad_entries) {
8649                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8650                                 "in directory %s\n",
8651                                 num_bad_dir_entries, usersharepath));
8652                         break;
8653                 }
8654
8655                 /* Allow 20% bad entries. */
8656                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8657                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8658                         "in directory %s\n",
8659                         num_dir_entries, usersharepath));
8660                         break;
8661                 }
8662         }
8663
8664         sys_closedir(dp);
8665
8666         /* Sweep through and delete any non-refreshed usershares that are
8667            not currently in use. */
8668         for (iService = iNumServices - 1; iService >= 0; iService--) {
8669                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8670                         if (conn_snum_used(iService)) {
8671                                 continue;
8672                         }
8673                         /* Remove from the share ACL db. */
8674                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8675                                 lp_servicename(iService) ));
8676                         delete_share_security(lp_servicename(iService));
8677                         free_service_byindex(iService);
8678                 }
8679         }
8680
8681         return lp_numservices();
8682 }
8683
8684 /********************************************************
8685  Destroy global resources allocated in this file
8686 ********************************************************/
8687
8688 void gfree_loadparm(void)
8689 {
8690         struct file_lists *f;
8691         struct file_lists *next;
8692         int i;
8693
8694         /* Free the file lists */
8695
8696         f = file_lists;
8697         while( f ) {
8698                 next = f->next;
8699                 SAFE_FREE( f->name );
8700                 SAFE_FREE( f->subfname );
8701                 SAFE_FREE( f );
8702                 f = next;
8703         }
8704         file_lists = NULL;
8705
8706         /* Free resources allocated to services */
8707
8708         for ( i = 0; i < iNumServices; i++ ) {
8709                 if ( VALID(i) ) {
8710                         free_service_byindex(i);
8711                 }
8712         }
8713
8714         SAFE_FREE( ServicePtrs );
8715         iNumServices = 0;
8716
8717         /* Now release all resources allocated to global
8718            parameters and the default service */
8719
8720         free_global_parameters();
8721 }
8722
8723
8724 /***************************************************************************
8725  Allow client apps to specify that they are a client
8726 ***************************************************************************/
8727 void lp_set_in_client(bool b)
8728 {
8729     in_client = b;
8730 }
8731
8732
8733 /***************************************************************************
8734  Determine if we're running in a client app
8735 ***************************************************************************/
8736 bool lp_is_in_client(void)
8737 {
8738     return in_client;
8739 }
8740
8741 /***************************************************************************
8742  Load the services array from the services file. Return True on success, 
8743  False on failure.
8744 ***************************************************************************/
8745
8746 bool lp_load_ex(const char *pszFname,
8747                 bool global_only,
8748                 bool save_defaults,
8749                 bool add_ipc,
8750                 bool initialize_globals,
8751                 bool allow_include_registry,
8752                 bool allow_registry_shares)
8753 {
8754         char *n2 = NULL;
8755         bool bRetval;
8756
8757         bRetval = False;
8758
8759         DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8760
8761         bInGlobalSection = True;
8762         bGlobalOnly = global_only;
8763         bAllowIncludeRegistry = allow_include_registry;
8764
8765         init_globals(! initialize_globals);
8766         debug_init();
8767
8768         if (save_defaults) {
8769                 init_locals();
8770                 lp_save_defaults();
8771         }
8772
8773         free_param_opts(&Globals.param_opt);
8774
8775         /* We get sections first, so have to start 'behind' to make up */
8776         iServiceIndex = -1;
8777
8778         if (lp_config_backend_is_file()) {
8779                 n2 = alloc_sub_basic(get_current_username(),
8780                                         current_user_info.domain,
8781                                         pszFname);
8782                 if (!n2) {
8783                         smb_panic("lp_load_ex: out of memory");
8784                 }
8785
8786                 add_to_file_list(pszFname, n2);
8787
8788                 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8789                 SAFE_FREE(n2);
8790
8791                 /* finish up the last section */
8792                 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8793                 if (bRetval) {
8794                         if (iServiceIndex >= 0) {
8795                                 bRetval = service_ok(iServiceIndex);
8796                         }
8797                 }
8798
8799                 if (lp_config_backend_is_registry()) {
8800                         /* config backend changed to registry in config file */
8801                         /*
8802                          * We need to use this extra global variable here to
8803                          * survive restart: init_globals uses this as a default
8804                          * for ConfigBackend. Otherwise, init_globals would
8805                          *  send us into an endless loop here.
8806                          */
8807                         config_backend = CONFIG_BACKEND_REGISTRY;
8808                         /* start over */
8809                         DEBUG(1, ("lp_load_ex: changing to config backend "
8810                                   "registry\n"));
8811                         init_globals(false);
8812                         lp_kill_all_services();
8813                         return lp_load_ex(pszFname, global_only, save_defaults,
8814                                           add_ipc, initialize_globals,
8815                                           allow_include_registry,
8816                                           allow_registry_shares);
8817                 }
8818         } else if (lp_config_backend_is_registry()) {
8819                 bRetval = process_registry_globals();
8820         } else {
8821                 DEBUG(0, ("Illegal config  backend given: %d\n",
8822                           lp_config_backend()));
8823                 bRetval = false;
8824         }
8825
8826         if (bRetval && lp_registry_shares() && allow_registry_shares) {
8827                 bRetval = process_registry_shares();
8828         }
8829
8830         lp_add_auto_services(lp_auto_services());
8831
8832         if (add_ipc) {
8833                 /* When 'restrict anonymous = 2' guest connections to ipc$
8834                    are denied */
8835                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8836                 if ( lp_enable_asu_support() ) {
8837                         lp_add_ipc("ADMIN$", false);
8838                 }
8839         }
8840
8841         set_server_role();
8842         set_default_server_announce_type();
8843         set_allowed_client_auth();
8844
8845         bLoaded = True;
8846
8847         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8848         /* if bWINSsupport is true and we are in the client            */
8849         if (lp_is_in_client() && Globals.bWINSsupport) {
8850                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8851         }
8852
8853         init_iconv();
8854
8855         bAllowIncludeRegistry = true;
8856
8857         return (bRetval);
8858 }
8859
8860 bool lp_load(const char *pszFname,
8861              bool global_only,
8862              bool save_defaults,
8863              bool add_ipc,
8864              bool initialize_globals)
8865 {
8866         return lp_load_ex(pszFname,
8867                           global_only,
8868                           save_defaults,
8869                           add_ipc,
8870                           initialize_globals,
8871                           true, false);
8872 }
8873
8874 bool lp_load_initial_only(const char *pszFname)
8875 {
8876         return lp_load_ex(pszFname,
8877                           true,
8878                           false,
8879                           false,
8880                           true,
8881                           false,
8882                           false);
8883 }
8884
8885 bool lp_load_with_registry_shares(const char *pszFname,
8886                                   bool global_only,
8887                                   bool save_defaults,
8888                                   bool add_ipc,
8889                                   bool initialize_globals)
8890 {
8891         return lp_load_ex(pszFname,
8892                           global_only,
8893                           save_defaults,
8894                           add_ipc,
8895                           initialize_globals,
8896                           true,
8897                           true);
8898 }
8899
8900 /***************************************************************************
8901  Return the max number of services.
8902 ***************************************************************************/
8903
8904 int lp_numservices(void)
8905 {
8906         return (iNumServices);
8907 }
8908
8909 /***************************************************************************
8910 Display the contents of the services array in human-readable form.
8911 ***************************************************************************/
8912
8913 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8914 {
8915         int iService;
8916
8917         if (show_defaults)
8918                 defaults_saved = False;
8919
8920         dump_globals(f);
8921
8922         dump_a_service(&sDefault, f);
8923
8924         for (iService = 0; iService < maxtoprint; iService++) {
8925                 fprintf(f,"\n");
8926                 lp_dump_one(f, show_defaults, iService);
8927         }
8928 }
8929
8930 /***************************************************************************
8931 Display the contents of one service in human-readable form.
8932 ***************************************************************************/
8933
8934 void lp_dump_one(FILE * f, bool show_defaults, int snum)
8935 {
8936         if (VALID(snum)) {
8937                 if (ServicePtrs[snum]->szService[0] == '\0')
8938                         return;
8939                 dump_a_service(ServicePtrs[snum], f);
8940         }
8941 }
8942
8943 /***************************************************************************
8944 Return the number of the service with the given name, or -1 if it doesn't
8945 exist. Note that this is a DIFFERENT ANIMAL from the internal function
8946 getservicebyname()! This works ONLY if all services have been loaded, and
8947 does not copy the found service.
8948 ***************************************************************************/
8949
8950 int lp_servicenumber(const char *pszServiceName)
8951 {
8952         int iService;
8953         fstring serviceName;
8954         
8955         if (!pszServiceName) {
8956                 return GLOBAL_SECTION_SNUM;
8957         }
8958         
8959         for (iService = iNumServices - 1; iService >= 0; iService--) {
8960                 if (VALID(iService) && ServicePtrs[iService]->szService) {
8961                         /*
8962                          * The substitution here is used to support %U is
8963                          * service names
8964                          */
8965                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
8966                         standard_sub_basic(get_current_username(),
8967                                            current_user_info.domain,
8968                                            serviceName,sizeof(serviceName));
8969                         if (strequal(serviceName, pszServiceName)) {
8970                                 break;
8971                         }
8972                 }
8973         }
8974
8975         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
8976                 time_t last_mod;
8977
8978                 if (!usershare_exists(iService, &last_mod)) {
8979                         /* Remove the share security tdb entry for it. */
8980                         delete_share_security(lp_servicename(iService));
8981                         /* Remove it from the array. */
8982                         free_service_byindex(iService);
8983                         /* Doesn't exist anymore. */
8984                         return GLOBAL_SECTION_SNUM;
8985                 }
8986
8987                 /* Has it been modified ? If so delete and reload. */
8988                 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
8989                         /* Remove it from the array. */
8990                         free_service_byindex(iService);
8991                         /* and now reload it. */
8992                         iService = load_usershare_service(pszServiceName);
8993                 }
8994         }
8995
8996         if (iService < 0) {
8997                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
8998                 return GLOBAL_SECTION_SNUM;
8999         }
9000
9001         return (iService);
9002 }
9003
9004 bool share_defined(const char *service_name)
9005 {
9006         return (lp_servicenumber(service_name) != -1);
9007 }
9008
9009 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9010                                       const char *sharename)
9011 {
9012         struct share_params *result;
9013         char *sname;
9014         int snum;
9015
9016         if (!(sname = SMB_STRDUP(sharename))) {
9017                 return NULL;
9018         }
9019
9020         snum = find_service(sname);
9021         SAFE_FREE(sname);
9022
9023         if (snum < 0) {
9024                 return NULL;
9025         }
9026
9027         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9028                 DEBUG(0, ("talloc failed\n"));
9029                 return NULL;
9030         }
9031
9032         result->service = snum;
9033         return result;
9034 }
9035
9036 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9037 {
9038         struct share_iterator *result;
9039
9040         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9041                 DEBUG(0, ("talloc failed\n"));
9042                 return NULL;
9043         }
9044
9045         result->next_id = 0;
9046         return result;
9047 }
9048
9049 struct share_params *next_share(struct share_iterator *list)
9050 {
9051         struct share_params *result;
9052
9053         while (!lp_snum_ok(list->next_id) &&
9054                (list->next_id < lp_numservices())) {
9055                 list->next_id += 1;
9056         }
9057
9058         if (list->next_id >= lp_numservices()) {
9059                 return NULL;
9060         }
9061
9062         if (!(result = TALLOC_P(list, struct share_params))) {
9063                 DEBUG(0, ("talloc failed\n"));
9064                 return NULL;
9065         }
9066
9067         result->service = list->next_id;
9068         list->next_id += 1;
9069         return result;
9070 }
9071
9072 struct share_params *next_printer(struct share_iterator *list)
9073 {
9074         struct share_params *result;
9075
9076         while ((result = next_share(list)) != NULL) {
9077                 if (lp_print_ok(result->service)) {
9078                         break;
9079                 }
9080         }
9081         return result;
9082 }
9083
9084 /*
9085  * This is a hack for a transition period until we transformed all code from
9086  * service numbers to struct share_params.
9087  */
9088
9089 struct share_params *snum2params_static(int snum)
9090 {
9091         static struct share_params result;
9092         result.service = snum;
9093         return &result;
9094 }
9095
9096 /*******************************************************************
9097  A useful volume label function. 
9098 ********************************************************************/
9099
9100 const char *volume_label(int snum)
9101 {
9102         char *ret;
9103         const char *label = lp_volume(snum);
9104         if (!*label) {
9105                 label = lp_servicename(snum);
9106         }
9107                 
9108         /* This returns a 33 byte guarenteed null terminated string. */
9109         ret = talloc_strndup(talloc_tos(), label, 32);
9110         if (!ret) {
9111                 return "";
9112         }               
9113         return ret;
9114 }
9115
9116 /*******************************************************************
9117  Set the server type we will announce as via nmbd.
9118 ********************************************************************/
9119
9120 static void set_default_server_announce_type(void)
9121 {
9122         default_server_announce = 0;
9123         default_server_announce |= SV_TYPE_WORKSTATION;
9124         default_server_announce |= SV_TYPE_SERVER;
9125         default_server_announce |= SV_TYPE_SERVER_UNIX;
9126
9127         /* note that the flag should be set only if we have a 
9128            printer service but nmbd doesn't actually load the 
9129            services so we can't tell   --jerry */
9130
9131         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9132
9133         switch (lp_announce_as()) {
9134                 case ANNOUNCE_AS_NT_SERVER:
9135                         default_server_announce |= SV_TYPE_SERVER_NT;
9136                         /* fall through... */
9137                 case ANNOUNCE_AS_NT_WORKSTATION:
9138                         default_server_announce |= SV_TYPE_NT;
9139                         break;
9140                 case ANNOUNCE_AS_WIN95:
9141                         default_server_announce |= SV_TYPE_WIN95_PLUS;
9142                         break;
9143                 case ANNOUNCE_AS_WFW:
9144                         default_server_announce |= SV_TYPE_WFW;
9145                         break;
9146                 default:
9147                         break;
9148         }
9149
9150         switch (lp_server_role()) {
9151                 case ROLE_DOMAIN_MEMBER:
9152                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9153                         break;
9154                 case ROLE_DOMAIN_PDC:
9155                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9156                         break;
9157                 case ROLE_DOMAIN_BDC:
9158                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9159                         break;
9160                 case ROLE_STANDALONE:
9161                 default:
9162                         break;
9163         }
9164         if (lp_time_server())
9165                 default_server_announce |= SV_TYPE_TIME_SOURCE;
9166
9167         if (lp_host_msdfs())
9168                 default_server_announce |= SV_TYPE_DFS_SERVER;
9169 }
9170
9171 /***********************************************************
9172  returns role of Samba server
9173 ************************************************************/
9174
9175 int lp_server_role(void)
9176 {
9177         return server_role;
9178 }
9179
9180 /***********************************************************
9181  If we are PDC then prefer us as DMB
9182 ************************************************************/
9183
9184 bool lp_domain_master(void)
9185 {
9186         if (Globals.iDomainMaster == Auto)
9187                 return (lp_server_role() == ROLE_DOMAIN_PDC);
9188
9189         return (bool)Globals.iDomainMaster;
9190 }
9191
9192 /***********************************************************
9193  If we are DMB then prefer us as LMB
9194 ************************************************************/
9195
9196 bool lp_preferred_master(void)
9197 {
9198         if (Globals.iPreferredMaster == Auto)
9199                 return (lp_local_master() && lp_domain_master());
9200
9201         return (bool)Globals.iPreferredMaster;
9202 }
9203
9204 /*******************************************************************
9205  Remove a service.
9206 ********************************************************************/
9207
9208 void lp_remove_service(int snum)
9209 {
9210         ServicePtrs[snum]->valid = False;
9211         invalid_services[num_invalid_services++] = snum;
9212 }
9213
9214 /*******************************************************************
9215  Copy a service.
9216 ********************************************************************/
9217
9218 void lp_copy_service(int snum, const char *new_name)
9219 {
9220         do_section(new_name, NULL);
9221         if (snum >= 0) {
9222                 snum = lp_servicenumber(new_name);
9223                 if (snum >= 0)
9224                         lp_do_parameter(snum, "copy", lp_servicename(snum));
9225         }
9226 }
9227
9228
9229 /*******************************************************************
9230  Get the default server type we will announce as via nmbd.
9231 ********************************************************************/
9232
9233 int lp_default_server_announce(void)
9234 {
9235         return default_server_announce;
9236 }
9237
9238 /*******************************************************************
9239  Split the announce version into major and minor numbers.
9240 ********************************************************************/
9241
9242 int lp_major_announce_version(void)
9243 {
9244         static bool got_major = False;
9245         static int major_version = DEFAULT_MAJOR_VERSION;
9246         char *vers;
9247         char *p;
9248
9249         if (got_major)
9250                 return major_version;
9251
9252         got_major = True;
9253         if ((vers = lp_announce_version()) == NULL)
9254                 return major_version;
9255
9256         if ((p = strchr_m(vers, '.')) == 0)
9257                 return major_version;
9258
9259         *p = '\0';
9260         major_version = atoi(vers);
9261         return major_version;
9262 }
9263
9264 int lp_minor_announce_version(void)
9265 {
9266         static bool got_minor = False;
9267         static int minor_version = DEFAULT_MINOR_VERSION;
9268         char *vers;
9269         char *p;
9270
9271         if (got_minor)
9272                 return minor_version;
9273
9274         got_minor = True;
9275         if ((vers = lp_announce_version()) == NULL)
9276                 return minor_version;
9277
9278         if ((p = strchr_m(vers, '.')) == 0)
9279                 return minor_version;
9280
9281         p++;
9282         minor_version = atoi(p);
9283         return minor_version;
9284 }
9285
9286 /***********************************************************
9287  Set the global name resolution order (used in smbclient).
9288 ************************************************************/
9289
9290 void lp_set_name_resolve_order(const char *new_order)
9291 {
9292         string_set(&Globals.szNameResolveOrder, new_order);
9293 }
9294
9295 const char *lp_printername(int snum)
9296 {
9297         const char *ret = _lp_printername(snum);
9298         if (ret == NULL || (ret != NULL && *ret == '\0'))
9299                 ret = lp_const_servicename(snum);
9300
9301         return ret;
9302 }
9303
9304
9305 /***********************************************************
9306  Allow daemons such as winbindd to fix their logfile name.
9307 ************************************************************/
9308
9309 void lp_set_logfile(const char *name)
9310 {
9311         string_set(&Globals.szLogFile, name);
9312         debug_set_logfile(name);
9313 }
9314
9315 /*******************************************************************
9316  Return the max print jobs per queue.
9317 ********************************************************************/
9318
9319 int lp_maxprintjobs(int snum)
9320 {
9321         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9322         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9323                 maxjobs = PRINT_MAX_JOBID - 1;
9324
9325         return maxjobs;
9326 }
9327
9328 const char *lp_printcapname(void)
9329 {
9330         if ((Globals.szPrintcapname != NULL) &&
9331             (Globals.szPrintcapname[0] != '\0'))
9332                 return Globals.szPrintcapname;
9333
9334         if (sDefault.iPrinting == PRINT_CUPS) {
9335 #ifdef HAVE_CUPS
9336                 return "cups";
9337 #else
9338                 return "lpstat";
9339 #endif
9340         }
9341
9342         if (sDefault.iPrinting == PRINT_BSD)
9343                 return "/etc/printcap";
9344
9345         return PRINTCAP_NAME;
9346 }
9347
9348 /*******************************************************************
9349  Ensure we don't use sendfile if server smb signing is active.
9350 ********************************************************************/
9351
9352 static uint32 spoolss_state;
9353
9354 bool lp_disable_spoolss( void )
9355 {
9356         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9357                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9358
9359         return spoolss_state == SVCCTL_STOPPED ? True : False;
9360 }
9361
9362 void lp_set_spoolss_state( uint32 state )
9363 {
9364         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9365
9366         spoolss_state = state;
9367 }
9368
9369 uint32 lp_get_spoolss_state( void )
9370 {
9371         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9372 }
9373
9374 /*******************************************************************
9375  Ensure we don't use sendfile if server smb signing is active.
9376 ********************************************************************/
9377
9378 bool lp_use_sendfile(int snum)
9379 {
9380         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9381         if (Protocol < PROTOCOL_NT1) {
9382                 return False;
9383         }
9384         return (_lp_use_sendfile(snum) &&
9385                         (get_remote_arch() != RA_WIN95) &&
9386                         !srv_is_signing_active());
9387 }
9388
9389 /*******************************************************************
9390  Turn off sendfile if we find the underlying OS doesn't support it.
9391 ********************************************************************/
9392
9393 void set_use_sendfile(int snum, bool val)
9394 {
9395         if (LP_SNUM_OK(snum))
9396                 ServicePtrs[snum]->bUseSendfile = val;
9397         else
9398                 sDefault.bUseSendfile = val;
9399 }
9400
9401 /*******************************************************************
9402  Turn off storing DOS attributes if this share doesn't support it.
9403 ********************************************************************/
9404
9405 void set_store_dos_attributes(int snum, bool val)
9406 {
9407         if (!LP_SNUM_OK(snum))
9408                 return;
9409         ServicePtrs[(snum)]->bStoreDosAttributes = val;
9410 }
9411
9412 void lp_set_mangling_method(const char *new_method)
9413 {
9414         string_set(&Globals.szManglingMethod, new_method);
9415 }
9416
9417 /*******************************************************************
9418  Global state for POSIX pathname processing.
9419 ********************************************************************/
9420
9421 static bool posix_pathnames;
9422
9423 bool lp_posix_pathnames(void)
9424 {
9425         return posix_pathnames;
9426 }
9427
9428 /*******************************************************************
9429  Change everything needed to ensure POSIX pathname processing (currently
9430  not much).
9431 ********************************************************************/
9432
9433 void lp_set_posix_pathnames(void)
9434 {
9435         posix_pathnames = True;
9436 }
9437
9438 /*******************************************************************
9439  Global state for POSIX lock processing - CIFS unix extensions.
9440 ********************************************************************/
9441
9442 bool posix_default_lock_was_set;
9443 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9444
9445 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9446 {
9447         if (posix_default_lock_was_set) {
9448                 return posix_cifsx_locktype;
9449         } else {
9450                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9451         }
9452 }
9453
9454 /*******************************************************************
9455 ********************************************************************/
9456
9457 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9458 {
9459         posix_default_lock_was_set = True;
9460         posix_cifsx_locktype = val;
9461 }
9462
9463 int lp_min_receive_file_size(void)
9464 {
9465         if (Globals.iminreceivefile < 0) {
9466                 return 0;
9467         }
9468         return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9469 }
9470
9471 /*******************************************************************
9472  If socket address is an empty character string, it is necessary to 
9473  define it as "0.0.0.0". 
9474 ********************************************************************/
9475
9476 const char *lp_socket_address(void)
9477 {
9478         char *sock_addr = Globals.szSocketAddress;
9479         
9480         if (sock_addr[0] == '\0'){
9481                 string_set(&Globals.szSocketAddress, "0.0.0.0");
9482         }
9483         return  Globals.szSocketAddress;
9484 }