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