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