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