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