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