r15631: Add a new option "enable core files". Administrators can use this to
[ira/wip.git] / source3 / param / loadparm.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Parameter loading functions
4    Copyright (C) Karl Auer 1993-1998
5
6    Largely re-written by Andrew Tridgell, September 1994
7
8    Copyright (C) Simo Sorce 2001
9    Copyright (C) Alexander Bokovoy 2002
10    Copyright (C) Stefan (metze) Metzmacher 2002
11    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12    
13    This program is free software; you can redistribute it and/or modify
14    it under the terms of the GNU General Public License as published by
15    the Free Software Foundation; either version 2 of the License, or
16    (at your option) any later version.
17    
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License for more details.
22    
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28 /*
29  *  Load parameters.
30  *
31  *  This module provides suitable callback functions for the params
32  *  module. It builds the internal table of service details which is
33  *  then used by the rest of the server.
34  *
35  * To add a parameter:
36  *
37  * 1) add it to the global or service structure definition
38  * 2) add it to the parm_table
39  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40  * 4) If it's a global then initialise it in init_globals. If a local
41  *    (ie. service) parameter then initialise it in the sDefault structure
42  *  
43  *
44  * Notes:
45  *   The configuration file is processed sequentially for speed. It is NOT
46  *   accessed randomly as happens in 'real' Windows. For this reason, there
47  *   is a fair bit of sequence-dependent code here - ie., code which assumes
48  *   that certain things happen before others. In particular, the code which
49  *   happens at the boundary between sections is delicately poised, so be
50  *   careful!
51  *
52  */
53
54 #include "includes.h"
55
56 BOOL in_client = False;         /* Not in the client by default */
57 BOOL bLoaded = False;
58
59 extern pstring user_socket_options;
60 extern enum protocol_types Protocol;
61
62 #ifndef GLOBAL_NAME
63 #define GLOBAL_NAME "global"
64 #endif
65
66 #ifndef PRINTERS_NAME
67 #define PRINTERS_NAME "printers"
68 #endif
69
70 #ifndef HOMES_NAME
71 #define HOMES_NAME "homes"
72 #endif
73
74 /* some helpful bits */
75 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
76 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
77
78 #define USERSHARE_VALID 1
79 #define USERSHARE_PENDING_DELETE 2
80
81 int keepalive = DEFAULT_KEEPALIVE;
82 BOOL use_getwd_cache = True;
83
84 extern int extra_time_offset;
85
86 static BOOL defaults_saved = False;
87
88 typedef struct _param_opt_struct param_opt_struct;
89 struct _param_opt_struct {
90         param_opt_struct *prev, *next;
91         char *key;
92         char *value;
93         char **list;
94 };
95
96 /* 
97  * This structure describes global (ie., server-wide) parameters.
98  */
99 typedef struct {
100         char *smb_ports;
101         char *dos_charset;
102         char *unix_charset;
103         char *display_charset;
104         char *szPrintcapname;
105         char *szAddPortCommand;
106         char *szEnumPortsCommand;
107         char *szAddPrinterCommand;
108         char *szDeletePrinterCommand;
109         char *szOs2DriverMap;
110         char *szLockDir;
111         char *szPidDir;
112         char *szRootdir;
113         char *szDefaultService;
114         char *szGetQuota;
115         char *szSetQuota;
116         char *szMsgCommand;
117         char *szServerString;
118         char *szAutoServices;
119         char *szPasswdProgram;
120         char *szPasswdChat;
121         char *szLogFile;
122         char *szConfigFile;
123         char *szSMBPasswdFile;
124         char *szPrivateDir;
125         char *szPassdbBackend;
126         char **szPreloadModules;
127         char *szPasswordServer;
128         char *szSocketOptions;
129         char *szRealm;
130         char *szAfsUsernameMap;
131         int iAfsTokenLifetime;
132         char *szLogNtTokenCommand;
133         char *szUsernameMap;
134         char *szLogonScript;
135         char *szLogonPath;
136         char *szLogonDrive;
137         char *szLogonHome;
138         char **szWINSservers;
139         char **szInterfaces;
140         char *szRemoteAnnounce;
141         char *szRemoteBrowseSync;
142         char *szSocketAddress;
143         char *szNISHomeMapName;
144         char *szAnnounceVersion;        /* This is initialised in init_globals */
145         char *szWorkgroup;
146         char *szNetbiosName;
147         char **szNetbiosAliases;
148         char *szNetbiosScope;
149         char *szNameResolveOrder;
150         char *szPanicAction;
151         char *szAddUserScript;
152         char *szRenameUserScript;
153         char *szDelUserScript;
154         char *szAddGroupScript;
155         char *szDelGroupScript;
156         char *szAddUserToGroupScript;
157         char *szDelUserFromGroupScript;
158         char *szSetPrimaryGroupScript;
159         char *szAddMachineScript;
160         char *szShutdownScript;
161         char *szAbortShutdownScript;
162         char *szUsernameMapScript;
163         char *szCheckPasswordScript;
164         char *szWINSHook;
165         char *szUtmpDir;
166         char *szWtmpDir;
167         BOOL bUtmp;
168         char *szIdmapUID;
169         char *szIdmapGID;
170         BOOL bPassdbExpandExplicit;
171         int AlgorithmicRidBase;
172         char *szTemplateHomedir;
173         char *szTemplateShell;
174         char *szWinbindSeparator;
175         BOOL bWinbindEnumUsers;
176         BOOL bWinbindEnumGroups;
177         BOOL bWinbindUseDefaultDomain;
178         BOOL bWinbindTrustedDomainsOnly;
179         BOOL bWinbindNestedGroups;
180         BOOL bWinbindRefreshTickets;
181         BOOL bWinbindOfflineLogon;
182         char **szIdmapBackend;
183         char *szAddShareCommand;
184         char *szChangeShareCommand;
185         char *szDeleteShareCommand;
186         char **szEventLogs;
187         char *szGuestaccount;
188         char *szManglingMethod;
189         char **szServicesList;
190         char *szUsersharePath;
191         char *szUsershareTemplateShare;
192         char **szUsersharePrefixAllowList;
193         char **szUsersharePrefixDenyList;
194         int mangle_prefix;
195         int max_log_size;
196         char *szLogLevel;
197         int max_xmit;
198         int max_mux;
199         int max_open_files;
200         int open_files_db_hash_size;
201         int pwordlevel;
202         int unamelevel;
203         int deadtime;
204         int maxprotocol;
205         int minprotocol;
206         int security;
207         char **AuthMethods;
208         BOOL paranoid_server_security;
209         int maxdisksize;
210         int lpqcachetime;
211         int iMaxSmbdProcesses;
212         BOOL bDisableSpoolss;
213         int syslog;
214         int os_level;
215         int enhanced_browsing;
216         int max_ttl;
217         int max_wins_ttl;
218         int min_wins_ttl;
219         int lm_announce;
220         int lm_interval;
221         int announce_as;        /* This is initialised in init_globals */
222         int machine_password_timeout;
223         int map_to_guest;
224         int oplock_break_wait_time;
225         int winbind_cache_time;
226         int winbind_max_idle_children;
227         char **szWinbindNssInfo;
228         int iLockSpinCount;
229         int iLockSpinTime;
230         char *szLdapMachineSuffix;
231         char *szLdapUserSuffix;
232         char *szLdapIdmapSuffix;
233         char *szLdapGroupSuffix;
234         int ldap_ssl;
235         char *szLdapSuffix;
236         char *szLdapAdminDn;
237         char *szAclCompat;
238         char *szCupsServer;
239         char *szIPrintServer;
240         int ldap_passwd_sync; 
241         int ldap_replication_sleep;
242         int ldap_timeout; /* This is initialised in init_globals */
243         int ldap_page_size;
244         BOOL ldap_delete_dn;
245         BOOL bMsAddPrinterWizard;
246         BOOL bDNSproxy;
247         BOOL bWINSsupport;
248         BOOL bWINSproxy;
249         BOOL bLocalMaster;
250         BOOL bPreferredMaster;
251         BOOL bDomainMaster;
252         BOOL bDomainLogons;
253         BOOL bEncryptPasswords;
254         BOOL bUpdateEncrypt;
255         int  clientSchannel;
256         int  serverSchannel;
257         BOOL bNullPasswords;
258         BOOL bObeyPamRestrictions;
259         BOOL bLoadPrinters;
260         int PrintcapCacheTime;
261         BOOL bLargeReadwrite;
262         BOOL bReadRaw;
263         BOOL bWriteRaw;
264         BOOL bReadbmpx;
265         BOOL bSyslogOnly;
266         BOOL bBrowseList;
267         BOOL bNISHomeMap;
268         BOOL bTimeServer;
269         BOOL bBindInterfacesOnly;
270         BOOL bPamPasswordChange;
271         BOOL bUnixPasswdSync;
272         BOOL bPasswdChatDebug;
273         int iPasswdChatTimeout;
274         BOOL bTimestampLogs;
275         BOOL bNTSmbSupport;
276         BOOL bNTPipeSupport;
277         BOOL bNTStatusSupport;
278         BOOL bStatCache;
279         int iMaxStatCacheSize;
280         BOOL bKernelOplocks;
281         BOOL bAllowTrustedDomains;
282         BOOL bLanmanAuth;
283         BOOL bNTLMAuth;
284         BOOL bUseSpnego;
285         BOOL bClientLanManAuth;
286         BOOL bClientNTLMv2Auth;
287         BOOL bClientPlaintextAuth;
288         BOOL bClientUseSpnego;
289         BOOL bDebugHiresTimestamp;
290         BOOL bDebugPid;
291         BOOL bDebugUid;
292         BOOL bEnableCoreFiles;
293         BOOL bHostMSDfs;
294         BOOL bUseMmap;
295         BOOL bHostnameLookups;
296         BOOL bUnixExtensions;
297         BOOL bDisableNetbios;
298         BOOL bKernelChangeNotify;
299         BOOL bFamChangeNotify;
300         BOOL bUseKerberosKeytab;
301         BOOL bDeferSharingViolations;
302         BOOL bEnablePrivileges;
303         BOOL bASUSupport;
304         BOOL bUsershareOwnerOnly;
305         BOOL bUsershareAllowGuests;
306         int restrict_anonymous;
307         int name_cache_timeout;
308         int client_signing;
309         int server_signing;
310         int iUsershareMaxShares;
311
312         BOOL bResetOnZeroVC;
313         param_opt_struct *param_opt;
314 } global;
315
316 static global Globals;
317
318 /* 
319  * This structure describes a single service. 
320  */
321 typedef struct {
322         BOOL valid;
323         BOOL autoloaded;
324         int usershare;
325         time_t usershare_last_mod;
326         char *szService;
327         char *szPath;
328         char *szUsername;
329         char **szInvalidUsers;
330         char **szValidUsers;
331         char **szAdminUsers;
332         char *szCopy;
333         char *szInclude;
334         char *szPreExec;
335         char *szPostExec;
336         char *szRootPreExec;
337         char *szRootPostExec;
338         char *szCupsOptions;
339         char *szPrintcommand;
340         char *szLpqcommand;
341         char *szLprmcommand;
342         char *szLppausecommand;
343         char *szLpresumecommand;
344         char *szQueuepausecommand;
345         char *szQueueresumecommand;
346         char *szPrintername;
347         char *szDontdescend;
348         char **szHostsallow;
349         char **szHostsdeny;
350         char *szMagicScript;
351         char *szMagicOutput;
352         char *szMangledMap;
353         char *szVetoFiles;
354         char *szHideFiles;
355         char *szVetoOplockFiles;
356         char *comment;
357         char *force_user;
358         char *force_group;
359         char **readlist;
360         char **writelist;
361         char **printer_admin;
362         char *volume;
363         char *fstype;
364         char **szVfsObjects;
365         char *szMSDfsProxy;
366         char *szAioWriteBehind;
367         char *szDfree;
368         int iMinPrintSpace;
369         int iMaxPrintJobs;
370         int iMaxReportedPrintJobs;
371         int iWriteCacheSize;
372         int iCreate_mask;
373         int iCreate_force_mode;
374         int iSecurity_mask;
375         int iSecurity_force_mode;
376         int iDir_mask;
377         int iDir_force_mode;
378         int iDir_Security_mask;
379         int iDir_Security_force_mode;
380         int iMaxConnections;
381         int iDefaultCase;
382         int iPrinting;
383         int iOplockContentionLimit;
384         int iCSCPolicy;
385         int iBlock_size;
386         int iDfreeCacheTime;
387         BOOL bPreexecClose;
388         BOOL bRootpreexecClose;
389         int  iCaseSensitive;
390         BOOL bCasePreserve;
391         BOOL bShortCasePreserve;
392         BOOL bHideDotFiles;
393         BOOL bHideSpecialFiles;
394         BOOL bHideUnReadable;
395         BOOL bHideUnWriteableFiles;
396         BOOL bBrowseable;
397         BOOL bAvailable;
398         BOOL bRead_only;
399         BOOL bNo_set_dir;
400         BOOL bGuest_only;
401         BOOL bGuest_ok;
402         BOOL bPrint_ok;
403         BOOL bMap_system;
404         BOOL bMap_hidden;
405         BOOL bMap_archive;
406         BOOL bStoreDosAttributes;
407         BOOL bDmapiSupport;
408         BOOL bLocking;
409         int iStrictLocking;
410         BOOL bPosixLocking;
411         BOOL bShareModes;
412         BOOL bOpLocks;
413         BOOL bLevel2OpLocks;
414         BOOL bOnlyUser;
415         BOOL bMangledNames;
416         BOOL bWidelinks;
417         BOOL bSymlinks;
418         BOOL bSyncAlways;
419         BOOL bStrictAllocate;
420         BOOL bStrictSync;
421         char magic_char;
422         BOOL *copymap;
423         BOOL bDeleteReadonly;
424         BOOL bFakeOplocks;
425         BOOL bDeleteVetoFiles;
426         BOOL bDosFilemode;
427         BOOL bDosFiletimes;
428         BOOL bDosFiletimeResolution;
429         BOOL bFakeDirCreateTimes;
430         BOOL bBlockingLocks;
431         BOOL bInheritPerms;
432         BOOL bInheritACLS;
433         BOOL bInheritOwner;
434         BOOL bMSDfsRoot;
435         BOOL bUseClientDriver;
436         BOOL bDefaultDevmode;
437         BOOL bForcePrintername;
438         BOOL bNTAclSupport;
439         BOOL bForceUnknownAclUser;
440         BOOL bUseSendfile;
441         BOOL bProfileAcls;
442         BOOL bMap_acl_inherit;
443         BOOL bAfs_Share;
444         BOOL bEASupport;
445         BOOL bAclCheckPermissions;
446         BOOL bAclMapFullControl;
447         BOOL bAclGroupControl;
448         int iallocation_roundup_size;
449         int iAioReadSize;
450         int iAioWriteSize;
451         int iMap_readonly;
452         int ichange_notify_timeout;
453         param_opt_struct *param_opt;
454
455         char dummy[3];          /* for alignment */
456 } service;
457
458
459 /* This is a default service used to prime a services structure */
460 static service sDefault = {
461         True,                   /* valid */
462         False,                  /* not autoloaded */
463         0,                      /* not a usershare */
464         (time_t)0,              /* No last mod time */
465         NULL,                   /* szService */
466         NULL,                   /* szPath */
467         NULL,                   /* szUsername */
468         NULL,                   /* szInvalidUsers */
469         NULL,                   /* szValidUsers */
470         NULL,                   /* szAdminUsers */
471         NULL,                   /* szCopy */
472         NULL,                   /* szInclude */
473         NULL,                   /* szPreExec */
474         NULL,                   /* szPostExec */
475         NULL,                   /* szRootPreExec */
476         NULL,                   /* szRootPostExec */
477         NULL,                   /* szCupsOptions */
478         NULL,                   /* szPrintcommand */
479         NULL,                   /* szLpqcommand */
480         NULL,                   /* szLprmcommand */
481         NULL,                   /* szLppausecommand */
482         NULL,                   /* szLpresumecommand */
483         NULL,                   /* szQueuepausecommand */
484         NULL,                   /* szQueueresumecommand */
485         NULL,                   /* szPrintername */
486         NULL,                   /* szDontdescend */
487         NULL,                   /* szHostsallow */
488         NULL,                   /* szHostsdeny */
489         NULL,                   /* szMagicScript */
490         NULL,                   /* szMagicOutput */
491         NULL,                   /* szMangledMap */
492         NULL,                   /* szVetoFiles */
493         NULL,                   /* szHideFiles */
494         NULL,                   /* szVetoOplockFiles */
495         NULL,                   /* comment */
496         NULL,                   /* force user */
497         NULL,                   /* force group */
498         NULL,                   /* readlist */
499         NULL,                   /* writelist */
500         NULL,                   /* printer admin */
501         NULL,                   /* volume */
502         NULL,                   /* fstype */
503         NULL,                   /* vfs objects */
504         NULL,                   /* szMSDfsProxy */
505         NULL,                   /* szAioWriteBehind */
506         NULL,                   /* szDfree */
507         0,                      /* iMinPrintSpace */
508         1000,                   /* iMaxPrintJobs */
509         0,                      /* iMaxReportedPrintJobs */
510         0,                      /* iWriteCacheSize */
511         0744,                   /* iCreate_mask */
512         0000,                   /* iCreate_force_mode */
513         0777,                   /* iSecurity_mask */
514         0,                      /* iSecurity_force_mode */
515         0755,                   /* iDir_mask */
516         0000,                   /* iDir_force_mode */
517         0777,                   /* iDir_Security_mask */
518         0,                      /* iDir_Security_force_mode */
519         0,                      /* iMaxConnections */
520         CASE_LOWER,             /* iDefaultCase */
521         DEFAULT_PRINTING,       /* iPrinting */
522         2,                      /* iOplockContentionLimit */
523         0,                      /* iCSCPolicy */
524         1024,                   /* iBlock_size */
525         0,                      /* iDfreeCacheTime */
526         False,                  /* bPreexecClose */
527         False,                  /* bRootpreexecClose */
528         Auto,                   /* case sensitive */
529         True,                   /* case preserve */
530         True,                   /* short case preserve */
531         True,                   /* bHideDotFiles */
532         False,                  /* bHideSpecialFiles */
533         False,                  /* bHideUnReadable */
534         False,                  /* bHideUnWriteableFiles */
535         True,                   /* bBrowseable */
536         True,                   /* bAvailable */
537         True,                   /* bRead_only */
538         True,                   /* bNo_set_dir */
539         False,                  /* bGuest_only */
540         False,                  /* bGuest_ok */
541         False,                  /* bPrint_ok */
542         False,                  /* bMap_system */
543         False,                  /* bMap_hidden */
544         True,                   /* bMap_archive */
545         False,                  /* bStoreDosAttributes */
546         False,                  /* bDmapiSupport */
547         True,                   /* bLocking */
548         Auto,                   /* iStrictLocking */
549         True,                   /* bPosixLocking */
550         True,                   /* bShareModes */
551         True,                   /* bOpLocks */
552         True,                   /* bLevel2OpLocks */
553         False,                  /* bOnlyUser */
554         True,                   /* bMangledNames */
555         True,                   /* bWidelinks */
556         True,                   /* bSymlinks */
557         False,                  /* bSyncAlways */
558         False,                  /* bStrictAllocate */
559         False,                  /* bStrictSync */
560         '~',                    /* magic char */
561         NULL,                   /* copymap */
562         False,                  /* bDeleteReadonly */
563         False,                  /* bFakeOplocks */
564         False,                  /* bDeleteVetoFiles */
565         False,                  /* bDosFilemode */
566         True,                   /* bDosFiletimes */
567         False,                  /* bDosFiletimeResolution */
568         False,                  /* bFakeDirCreateTimes */
569         True,                   /* bBlockingLocks */
570         False,                  /* bInheritPerms */
571         False,                  /* bInheritACLS */
572         False,                  /* bInheritOwner */
573         True,                   /* bMSDfsRoot */
574         False,                  /* bUseClientDriver */
575         True,                   /* bDefaultDevmode */
576         False,                  /* bForcePrintername */
577         True,                   /* bNTAclSupport */
578         False,                  /* bForceUnknownAclUser */
579         False,                  /* bUseSendfile */
580         False,                  /* bProfileAcls */
581         False,                  /* bMap_acl_inherit */
582         False,                  /* bAfs_Share */
583         False,                  /* bEASupport */
584         True,                   /* bAclCheckPermissions */
585         True,                   /* bAclMapFullControl */
586         False,                  /* bAclGroupControl */
587         SMB_ROUNDUP_ALLOCATION_SIZE,            /* iallocation_roundup_size */
588         0,                      /* iAioReadSize */
589         0,                      /* iAioWriteSize */
590         MAP_READONLY_YES,       /* iMap_readonly */
591         60,                     /* ichange_notify_timeout = 1 minute default. */
592         
593         NULL,                   /* Parametric options */
594
595         ""                      /* dummy */
596 };
597
598 /* local variables */
599 static service **ServicePtrs = NULL;
600 static int iNumServices = 0;
601 static int iServiceIndex = 0;
602 static TDB_CONTEXT *ServiceHash;
603 static int *invalid_services = NULL;
604 static int num_invalid_services = 0;
605 static BOOL bInGlobalSection = True;
606 static BOOL bGlobalOnly = False;
607 static int server_role;
608 static int default_server_announce;
609
610 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
611
612 /* prototypes for the special type handlers */
613 static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
614 static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
615 static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
616 static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
617 static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
618 static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
619 static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
620 static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
621 static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
622 static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
623 static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
624
625 static void set_server_role(void);
626 static void set_default_server_announce_type(void);
627 static void set_allowed_client_auth(void);
628
629 static const struct enum_list enum_protocol[] = {
630         {PROTOCOL_NT1, "NT1"},
631         {PROTOCOL_LANMAN2, "LANMAN2"},
632         {PROTOCOL_LANMAN1, "LANMAN1"},
633         {PROTOCOL_CORE, "CORE"},
634         {PROTOCOL_COREPLUS, "COREPLUS"},
635         {PROTOCOL_COREPLUS, "CORE+"},
636         {-1, NULL}
637 };
638
639 static const struct enum_list enum_security[] = {
640         {SEC_SHARE, "SHARE"},
641         {SEC_USER, "USER"},
642         {SEC_SERVER, "SERVER"},
643         {SEC_DOMAIN, "DOMAIN"},
644 #ifdef HAVE_ADS
645         {SEC_ADS, "ADS"},
646 #endif
647         {-1, NULL}
648 };
649
650 static const struct enum_list enum_printing[] = {
651         {PRINT_SYSV, "sysv"},
652         {PRINT_AIX, "aix"},
653         {PRINT_HPUX, "hpux"},
654         {PRINT_BSD, "bsd"},
655         {PRINT_QNX, "qnx"},
656         {PRINT_PLP, "plp"},
657         {PRINT_LPRNG, "lprng"},
658         {PRINT_CUPS, "cups"},
659         {PRINT_IPRINT, "iprint"},
660         {PRINT_LPRNT, "nt"},
661         {PRINT_LPROS2, "os2"},
662 #ifdef DEVELOPER
663         {PRINT_TEST, "test"},
664         {PRINT_VLP, "vlp"},
665 #endif /* DEVELOPER */
666         {-1, NULL}
667 };
668
669 static const struct enum_list enum_ldap_ssl[] = {
670         {LDAP_SSL_OFF, "no"},
671         {LDAP_SSL_OFF, "No"},
672         {LDAP_SSL_OFF, "off"},
673         {LDAP_SSL_OFF, "Off"},
674         {LDAP_SSL_START_TLS, "start tls"},
675         {LDAP_SSL_START_TLS, "Start_tls"},
676         {-1, NULL}
677 };
678
679 static const struct enum_list enum_ldap_passwd_sync[] = {
680         {LDAP_PASSWD_SYNC_OFF, "no"},
681         {LDAP_PASSWD_SYNC_OFF, "No"},
682         {LDAP_PASSWD_SYNC_OFF, "off"},
683         {LDAP_PASSWD_SYNC_OFF, "Off"},
684         {LDAP_PASSWD_SYNC_ON, "Yes"},
685         {LDAP_PASSWD_SYNC_ON, "yes"},
686         {LDAP_PASSWD_SYNC_ON, "on"},
687         {LDAP_PASSWD_SYNC_ON, "On"},
688         {LDAP_PASSWD_SYNC_ONLY, "Only"},
689         {LDAP_PASSWD_SYNC_ONLY, "only"},
690         {-1, NULL}
691 };
692
693 /* Types of machine we can announce as. */
694 #define ANNOUNCE_AS_NT_SERVER 1
695 #define ANNOUNCE_AS_WIN95 2
696 #define ANNOUNCE_AS_WFW 3
697 #define ANNOUNCE_AS_NT_WORKSTATION 4
698
699 static const struct enum_list enum_announce_as[] = {
700         {ANNOUNCE_AS_NT_SERVER, "NT"},
701         {ANNOUNCE_AS_NT_SERVER, "NT Server"},
702         {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
703         {ANNOUNCE_AS_WIN95, "win95"},
704         {ANNOUNCE_AS_WFW, "WfW"},
705         {-1, NULL}
706 };
707
708 static const struct enum_list enum_map_readonly[] = {
709         {MAP_READONLY_NO, "no"},
710         {MAP_READONLY_NO, "false"},
711         {MAP_READONLY_NO, "0"},
712         {MAP_READONLY_YES, "yes"},
713         {MAP_READONLY_YES, "true"},
714         {MAP_READONLY_YES, "1"},
715         {MAP_READONLY_PERMISSIONS, "permissions"},
716         {MAP_READONLY_PERMISSIONS, "perms"},
717         {-1, NULL}
718 };
719
720 static const struct enum_list enum_case[] = {
721         {CASE_LOWER, "lower"},
722         {CASE_UPPER, "upper"},
723         {-1, NULL}
724 };
725
726 static const struct enum_list enum_bool_auto[] = {
727         {False, "No"},
728         {False, "False"},
729         {False, "0"},
730         {True, "Yes"},
731         {True, "True"},
732         {True, "1"},
733         {Auto, "Auto"},
734         {-1, NULL}
735 };
736
737 /* Client-side offline caching policy types */
738 #define CSC_POLICY_MANUAL 0
739 #define CSC_POLICY_DOCUMENTS 1
740 #define CSC_POLICY_PROGRAMS 2
741 #define CSC_POLICY_DISABLE 3
742
743 static const struct enum_list enum_csc_policy[] = {
744         {CSC_POLICY_MANUAL, "manual"},
745         {CSC_POLICY_DOCUMENTS, "documents"},
746         {CSC_POLICY_PROGRAMS, "programs"},
747         {CSC_POLICY_DISABLE, "disable"},
748         {-1, NULL}
749 };
750
751 /* SMB signing types. */
752 static const struct enum_list enum_smb_signing_vals[] = {
753         {False, "No"},
754         {False, "False"},
755         {False, "0"},
756         {False, "Off"},
757         {False, "disabled"},
758         {True, "Yes"},
759         {True, "True"},
760         {True, "1"},
761         {True, "On"},
762         {True, "enabled"},
763         {Auto, "auto"},
764         {Required, "required"},
765         {Required, "mandatory"},
766         {Required, "force"},
767         {Required, "forced"},
768         {Required, "enforced"},
769         {-1, NULL}
770 };
771
772 /* ACL compatibility options. */
773 static const struct enum_list enum_acl_compat_vals[] = {
774     { ACL_COMPAT_AUTO, "auto" },
775     { ACL_COMPAT_WINNT, "winnt" },
776     { ACL_COMPAT_WIN2K, "win2k" },
777     { -1, NULL}
778 };
779
780 /* 
781    Do you want session setups at user level security with a invalid
782    password to be rejected or allowed in as guest? WinNT rejects them
783    but it can be a pain as it means "net view" needs to use a password
784
785    You have 3 choices in the setting of map_to_guest:
786
787    "Never" means session setups with an invalid password
788    are rejected. This is the default.
789
790    "Bad User" means session setups with an invalid password
791    are rejected, unless the username does not exist, in which case it
792    is treated as a guest login
793
794    "Bad Password" means session setups with an invalid password
795    are treated as a guest login
796
797    Note that map_to_guest only has an effect in user or server
798    level security.
799 */
800
801 static const struct enum_list enum_map_to_guest[] = {
802         {NEVER_MAP_TO_GUEST, "Never"},
803         {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
804         {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
805         {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
806         {-1, NULL}
807 };
808
809 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
810  *
811  * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
812  * screen in SWAT. This is used to exclude parameters as well as to squash all
813  * parameters that have been duplicated by pseudonyms.
814  *
815  * NOTE: To display a parameter in BASIC view set FLAG_BASIC
816  *       Any parameter that does NOT have FLAG_ADVANCED will not disply at all
817  *       Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
818  *        respective views.
819  *
820  * NOTE2: Handling of duplicated (synonym) paramters:
821  *      Only the first occurance of a parameter should be enabled by FLAG_BASIC
822  *      and/or FLAG_ADVANCED. All duplicates following the first mention should be
823  *      set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
824  *      name first, and all synonyms must follow it with the FLAG_HIDE attribute.
825  */
826
827 static struct parm_struct parm_table[] = {
828         {N_("Base Options"), P_SEP, P_SEPARATOR}, 
829
830         {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED}, 
831         {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED}, 
832         {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED}, 
833         {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
834         {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
835         {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE}, 
836         {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
837 #ifdef WITH_ADS
838         {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
839 #endif
840         {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
841         {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases,  NULL, FLAG_ADVANCED}, 
842         {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope,  NULL, FLAG_ADVANCED}, 
843         {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED }, 
844         {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
845         {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
846
847         {N_("Security Options"), P_SEP, P_SEPARATOR}, 
848
849         {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
850         {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED}, 
851         {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
852         {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED}, 
853         {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
854         {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
855         {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED}, 
856         {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED}, 
857         {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED}, 
858         {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED}, 
859         {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
860         {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED}, 
861         {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED}, 
862         {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
863         {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED}, 
864         {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED}, 
865         {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE}, 
866         {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE}, 
867         {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, 
868         {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED}, 
869
870         {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED}, 
871         {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED}, 
872         {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED}, 
873         {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED}, 
874         {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED}, 
875         {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED}, 
876         {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED}, 
877         {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED}, 
878         {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED}, 
879         {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED}, 
880         {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED}, 
881         {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED}, 
882         {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED}, 
883         {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED}, 
884         {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED}, 
885         {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED}, 
886
887         {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
888         {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, 
889         {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, 
890
891         {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
892         {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
893         {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
894         {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
895         {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
896         {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED }, 
897         {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
898         {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
899         {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED}, 
900
901         {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE}, 
902         {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
903         {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
904         {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
905
906         {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
907         {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
908         {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
909         {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
910         {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE}, 
911         {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
912         {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
913         {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
914         {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
915         {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
916         {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
917         {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
918         {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
919         {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
920         {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
921         {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
922         {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
923         {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
924         {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE}, 
925
926         {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
927         {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE}, 
928
929         {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED}, 
930         {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
931         {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE}, 
932         {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
933         {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE}, 
934         {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
935         {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED}, 
936
937         {N_("Logging Options"), P_SEP, P_SEPARATOR}, 
938
939         {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED}, 
940         {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE}, 
941         {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED}, 
942         {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED}, 
943         {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED}, 
944
945         {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED}, 
946         {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED}, 
947         {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED}, 
948         {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED}, 
949         {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED}, 
950         {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED}, 
951         {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
952
953         {N_("Protocol Options"), P_SEP, P_SEPARATOR}, 
954
955         {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED}, 
956         {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED}, 
957         {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED}, 
958         {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
959         {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED}, 
960         {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED}, 
961         {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, 
962         {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, 
963         {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED}, 
964         {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED}, 
965         {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED}, 
966         {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED}, 
967         {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED}, 
968         {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED}, 
969
970         {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, NULL,  enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
971         {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
972         {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
973         {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
974         {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED}, 
975         {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED}, 
976         {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
977
978         {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED}, 
979         {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as,  FLAG_ADVANCED}, 
980         {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
981         {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
982         {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED}, 
983         {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED}, 
984
985         {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
986         {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED}, 
987         {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED}, 
988         {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED}, 
989         {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED}, 
990         {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED}, 
991         {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED}, 
992         {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, 
993         {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, 
994         {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED}, 
995
996         {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED}, 
997         {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
998
999         {N_("Tuning Options"), P_SEP, P_SEPARATOR}, 
1000
1001         {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1002         {"change notify timeout", P_INTEGER, P_LOCAL, &sDefault.ichange_notify_timeout, NULL, NULL, FLAG_ADVANCED}, 
1003         {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED}, 
1004         {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED}, 
1005         {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED}, 
1006         {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED}, 
1007         {"fam change notify", P_BOOL, P_GLOBAL, &Globals.bFamChangeNotify, NULL, NULL, FLAG_ADVANCED},
1008
1009         {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED}, 
1010         {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED}, 
1011         {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1012         {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED}, 
1013         {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED}, 
1014         {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED}, 
1015         {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1016         {"open files database hash size", P_INTEGER, P_GLOBAL, &Globals.open_files_db_hash_size, NULL, NULL, FLAG_ADVANCED}, 
1017
1018         {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED}, 
1019         {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1020         {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1021         {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1022         {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED}, 
1023         {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1024         {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED}, 
1025         {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED}, 
1026
1027         {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED}, 
1028
1029         {N_("Printing Options"), P_SEP, P_SEPARATOR}, 
1030
1031         {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1032         {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1033         {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1034         {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1035         {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1036         {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE}, 
1037         {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1038         {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE}, 
1039         {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1040         {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1041         {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1042         {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1043         {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1044         {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1045         {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE}, 
1046         {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1047         {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1048         {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1049         {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1050         {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1051         {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
1052
1053         {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED}, 
1054         {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED}, 
1055         {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED}, 
1056         {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED}, 
1057         {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED}, 
1058         {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED}, 
1059
1060         {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1061         {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE}, 
1062         {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1063         {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1064         {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
1065
1066         {N_("Filename Handling"), P_SEP, P_SEPARATOR}, 
1067         {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED}, 
1068         {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED}, 
1069
1070         {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE}, 
1071         {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1072         {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE}, 
1073         {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1074         {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1075         {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1076         {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1077         {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1078         {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1079         {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1080         {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1081         {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
1082         {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
1083         {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
1084         {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1085         {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1086         {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1087         {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1088         {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1089         {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED }, 
1090         {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED}, 
1091         {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED}, 
1092         {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1093         {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1094
1095
1096         {N_("Domain Options"), P_SEP, P_SEPARATOR}, 
1097
1098         {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
1099
1100         {N_("Logon Options"), P_SEP, P_SEPARATOR}, 
1101
1102         {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED}, 
1103         {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1104         {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED}, 
1105         {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED}, 
1106         {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED}, 
1107         {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED}, 
1108         {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED}, 
1109         {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED}, 
1110         {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED}, 
1111         {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED}, 
1112         {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED}, 
1113         {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED}, 
1114
1115         {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED}, 
1116         {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED}, 
1117         {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED}, 
1118         {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED}, 
1119         {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED}, 
1120
1121         {N_("Browse Options"), P_SEP, P_SEPARATOR}, 
1122
1123         {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, 
1124         {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED}, 
1125         {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED}, 
1126         {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
1127         {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE}, 
1128         {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, 
1129         {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
1130         {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED}, 
1131         {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1132         {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE}, 
1133         {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED}, 
1134
1135         {N_("WINS Options"), P_SEP, P_SEPARATOR}, 
1136
1137         {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED}, 
1138         {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED}, 
1139
1140         {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
1141         {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
1142         {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED}, 
1143
1144         {N_("Locking Options"), P_SEP, P_SEPARATOR}, 
1145
1146         {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1147         {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1148         {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1149         {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
1150         {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1151         {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
1152         {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
1153
1154         {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1155         {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1156         {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
1157         {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1158         {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1159         {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1160         {"share modes", P_BOOL, P_LOCAL,  &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1161
1162         {N_("Ldap Options"), P_SEP, P_SEPARATOR}, 
1163
1164         {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED}, 
1165         {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED}, 
1166         {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED}, 
1167         {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED}, 
1168         {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED}, 
1169         {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED}, 
1170         {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE}, 
1171         {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1172         {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED}, 
1173         {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED}, 
1174         {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1175         {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1176         {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED}, 
1177
1178         {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR}, 
1179         {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED}, 
1180         {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED}, 
1181         {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED}, 
1182
1183         {N_("EventLog Options"), P_SEP, P_SEPARATOR}, 
1184         {"eventlog list",  P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
1185         
1186         {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, 
1187         {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED}, 
1188         {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED}, 
1189         {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED}, 
1190         {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE}, 
1191         {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED}, 
1192 #ifdef WITH_UTMP
1193         {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED}, 
1194         {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED}, 
1195         {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED}, 
1196 #endif
1197
1198         {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED}, 
1199         {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED}, 
1200         {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED}, 
1201         {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED}, 
1202         {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED}, 
1203         {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED}, 
1204         {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED}, 
1205         {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED}, 
1206         {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED}, 
1207         {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED}, 
1208         {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED}, 
1209         {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED}, 
1210         {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1211         {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1212         {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED}, 
1213         {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED}, 
1214         {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE}, 
1215
1216         {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE}, 
1217         {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE}, 
1218         {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1219         {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED}, 
1220
1221         {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1222         {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1223         {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1224         {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1225         {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1226         {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
1227         {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
1228         {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1229         {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED}, 
1230         {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1231         {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED}, 
1232         {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED}, 
1233         {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1234         {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE }, 
1235         {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1236         {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1237         {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1238         {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1239         {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1240         {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1241         {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1242         {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1243         {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1244         {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1245         {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1246
1247         {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
1248         {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED}, 
1249
1250         {N_("VFS module options"), P_SEP, P_SEPARATOR}, 
1251
1252         {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1253         {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE}, 
1254
1255
1256         {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1257         {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
1258         {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED}, 
1259
1260         {N_("Winbind options"), P_SEP, P_SEPARATOR}, 
1261
1262         {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1263         {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED}, 
1264         {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED}, 
1265         {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE}, 
1266         {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED}, 
1267         {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE}, 
1268         {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED}, 
1269         {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED}, 
1270         {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED}, 
1271         {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED}, 
1272         {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED}, 
1273         {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED}, 
1274         {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED}, 
1275         {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED}, 
1276         {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED}, 
1277         {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED}, 
1278         {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED}, 
1279         {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1280
1281         {NULL,  P_BOOL,  P_NONE,  NULL,  NULL,  NULL,  0}
1282 };
1283
1284 /***************************************************************************
1285  Initialise the sDefault parameter structure for the printer values.
1286 ***************************************************************************/
1287
1288 static void init_printer_values(service *pService)
1289 {
1290         /* choose defaults depending on the type of printing */
1291         switch (pService->iPrinting) {
1292                 case PRINT_BSD:
1293                 case PRINT_AIX:
1294                 case PRINT_LPRNT:
1295                 case PRINT_LPROS2:
1296                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
1297                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1298                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1299                         break;
1300
1301                 case PRINT_LPRNG:
1302                 case PRINT_PLP:
1303                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
1304                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1305                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1306                         string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1307                         string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1308                         string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1309                         string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1310                         break;
1311
1312                 case PRINT_CUPS:
1313                 case PRINT_IPRINT:
1314 #ifdef HAVE_CUPS
1315                         /* set the lpq command to contain the destination printer
1316                            name only.  This is used by cups_queue_get() */
1317                         string_set(&pService->szLpqcommand, "%p");
1318                         string_set(&pService->szLprmcommand, "");
1319                         string_set(&pService->szPrintcommand, "");
1320                         string_set(&pService->szLppausecommand, "");
1321                         string_set(&pService->szLpresumecommand, "");
1322                         string_set(&pService->szQueuepausecommand, "");
1323                         string_set(&pService->szQueueresumecommand, "");
1324 #else
1325                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
1326                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1327                         string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1328                         string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1329                         string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1330                         string_set(&pService->szQueuepausecommand, "disable '%p'");
1331                         string_set(&pService->szQueueresumecommand, "enable '%p'");
1332 #endif /* HAVE_CUPS */
1333                         break;
1334
1335                 case PRINT_SYSV:
1336                 case PRINT_HPUX:
1337                         string_set(&pService->szLpqcommand, "lpstat -o%p");
1338                         string_set(&pService->szLprmcommand, "cancel %p-%j");
1339                         string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1340                         string_set(&pService->szQueuepausecommand, "disable %p");
1341                         string_set(&pService->szQueueresumecommand, "enable %p");
1342 #ifndef HPUX
1343                         string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1344                         string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1345 #endif /* HPUX */
1346                         break;
1347
1348                 case PRINT_QNX:
1349                         string_set(&pService->szLpqcommand, "lpq -P%p");
1350                         string_set(&pService->szLprmcommand, "lprm -P%p %j");
1351                         string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1352                         break;
1353
1354 #ifdef DEVELOPER
1355         case PRINT_TEST:
1356         case PRINT_VLP:
1357                 string_set(&pService->szPrintcommand, "vlp print %p %s");
1358                 string_set(&pService->szLpqcommand, "vlp lpq %p");
1359                 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1360                 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1361                 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1362                 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1363                 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1364                 break;
1365 #endif /* DEVELOPER */
1366
1367         }
1368 }
1369
1370 /***************************************************************************
1371  Initialise the global parameter structure.
1372 ***************************************************************************/
1373
1374 static void init_globals(BOOL first_time_only)
1375 {
1376         static BOOL done_init = False;
1377         pstring s;
1378
1379         /* If requested to initialize only once and we've already done it... */
1380         if (first_time_only && done_init) {
1381                 /* ... then we have nothing more to do */
1382                 return;
1383         }
1384
1385         if (!done_init) {
1386                 int i;
1387
1388                 /* The logfile can be set before this is invoked. Free it if so. */
1389                 if (Globals.szLogFile != NULL) {
1390                         string_free(&Globals.szLogFile);
1391                         Globals.szLogFile = NULL;
1392                 }
1393
1394                 memset((void *)&Globals, '\0', sizeof(Globals));
1395
1396                 for (i = 0; parm_table[i].label; i++)
1397                         if ((parm_table[i].type == P_STRING ||
1398                              parm_table[i].type == P_USTRING) &&
1399                             parm_table[i].ptr)
1400                                 string_set((char **)parm_table[i].ptr, "");
1401
1402                 string_set(&sDefault.fstype, FSTYPE_STRING);
1403
1404                 init_printer_values(&sDefault);
1405
1406                 done_init = True;
1407         }
1408
1409
1410         DEBUG(3, ("Initialising global parameters\n"));
1411
1412         string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1413         string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1414
1415         /* use the new 'hash2' method by default, with a prefix of 1 */
1416         string_set(&Globals.szManglingMethod, "hash2");
1417         Globals.mangle_prefix = 1;
1418
1419         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1420
1421         /* using UTF8 by default allows us to support all chars */
1422         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1423
1424 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1425         /* If the system supports nl_langinfo(), try to grab the value
1426            from the user's locale */
1427         string_set(&Globals.display_charset, "LOCALE");
1428 #else
1429         string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1430 #endif
1431
1432         /* Use codepage 850 as a default for the dos character set */
1433         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1434
1435         /*
1436          * Allow the default PASSWD_CHAT to be overridden in local.h.
1437          */
1438         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1439         
1440         set_global_myname(myhostname());
1441         string_set(&Globals.szNetbiosName,global_myname());
1442
1443         set_global_myworkgroup(WORKGROUP);
1444         string_set(&Globals.szWorkgroup, lp_workgroup());
1445         
1446         string_set(&Globals.szPasswdProgram, "");
1447         string_set(&Globals.szPidDir, dyn_PIDDIR);
1448         string_set(&Globals.szLockDir, dyn_LOCKDIR);
1449         string_set(&Globals.szSocketAddress, "0.0.0.0");
1450         pstrcpy(s, "Samba ");
1451         pstrcat(s, SAMBA_VERSION_STRING);
1452         string_set(&Globals.szServerString, s);
1453         slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1454                  DEFAULT_MINOR_VERSION);
1455         string_set(&Globals.szAnnounceVersion, s);
1456 #ifdef DEVELOPER
1457         string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1458 #endif
1459
1460         pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1461
1462         string_set(&Globals.szLogonDrive, "");
1463         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1464         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1465         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1466
1467         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1468         string_set(&Globals.szPasswordServer, "*");
1469
1470         Globals.AlgorithmicRidBase = BASE_RID;
1471
1472         Globals.bLoadPrinters = True;
1473         Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
1474
1475         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1476         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1477         Globals.max_xmit = 0x4104;
1478         Globals.max_mux = 50;   /* This is *needed* for profile support. */
1479         Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
1480         Globals.bDisableSpoolss = False;
1481         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1482         Globals.pwordlevel = 0;
1483         Globals.unamelevel = 0;
1484         Globals.deadtime = 0;
1485         Globals.bLargeReadwrite = True;
1486         Globals.max_log_size = 5000;
1487         Globals.max_open_files = MAX_OPEN_FILES;
1488         Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1489         Globals.maxprotocol = PROTOCOL_NT1;
1490         Globals.minprotocol = PROTOCOL_CORE;
1491         Globals.security = SEC_USER;
1492         Globals.paranoid_server_security = True;
1493         Globals.bEncryptPasswords = True;
1494         Globals.bUpdateEncrypt = False;
1495         Globals.clientSchannel = Auto;
1496         Globals.serverSchannel = Auto;
1497         Globals.bReadRaw = True;
1498         Globals.bWriteRaw = True;
1499         Globals.bReadbmpx = False;
1500         Globals.bNullPasswords = False;
1501         Globals.bObeyPamRestrictions = False;
1502         Globals.syslog = 1;
1503         Globals.bSyslogOnly = False;
1504         Globals.bTimestampLogs = True;
1505         string_set(&Globals.szLogLevel, "0");
1506         Globals.bDebugHiresTimestamp = False;
1507         Globals.bDebugPid = False;
1508         Globals.bDebugUid = False;
1509         Globals.bEnableCoreFiles = True;
1510         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
1511         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
1512         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
1513         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
1514         Globals.bKernelChangeNotify = True;     /* On if we have it. */
1515         Globals.bFamChangeNotify = True;        /* On if we have it. */
1516         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
1517         Globals.lm_interval = 60;
1518         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1519 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1520         Globals.bNISHomeMap = False;
1521 #ifdef WITH_NISPLUS_HOME
1522         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1523 #else
1524         string_set(&Globals.szNISHomeMapName, "auto.home");
1525 #endif
1526 #endif
1527         Globals.bTimeServer = False;
1528         Globals.bBindInterfacesOnly = False;
1529         Globals.bUnixPasswdSync = False;
1530         Globals.bPamPasswordChange = False;
1531         Globals.bPasswdChatDebug = False;
1532         Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1533         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
1534         Globals.bNTStatusSupport = True; /* Use NT status by default. */
1535         Globals.bStatCache = True;      /* use stat cache by default */
1536         Globals.iMaxStatCacheSize = 0;  /* unlimited size in kb by default. */
1537         Globals.restrict_anonymous = 0;
1538         Globals.bClientLanManAuth = True;       /* Do use the LanMan hash if it is available */
1539         Globals.bClientPlaintextAuth = True;    /* Do use a plaintext password if is requested by the server */
1540         Globals.bLanmanAuth = True;     /* Do use the LanMan hash if it is available */
1541         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1542         Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1543         /* Note, that we will use NTLM2 session security (which is different), if it is available */
1544
1545         Globals.map_to_guest = 0;       /* By Default, "Never" */
1546         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
1547         Globals.enhanced_browsing = True; 
1548         Globals.iLockSpinCount = 3; /* Try 3 times. */
1549         Globals.iLockSpinTime = 10; /* usec. */
1550 #ifdef MMAP_BLACKLIST
1551         Globals.bUseMmap = False;
1552 #else
1553         Globals.bUseMmap = True;
1554 #endif
1555         Globals.bUnixExtensions = True;
1556         Globals.bResetOnZeroVC = False;
1557
1558         /* hostname lookups can be very expensive and are broken on
1559            a large number of sites (tridge) */
1560         Globals.bHostnameLookups = False;
1561
1562         string_set(&Globals.szPassdbBackend, "smbpasswd");
1563         string_set(&Globals.szLdapSuffix, "");
1564         string_set(&Globals.szLdapMachineSuffix, "");
1565         string_set(&Globals.szLdapUserSuffix, "");
1566         string_set(&Globals.szLdapGroupSuffix, "");
1567         string_set(&Globals.szLdapIdmapSuffix, "");
1568
1569         string_set(&Globals.szLdapAdminDn, "");
1570         Globals.ldap_ssl = LDAP_SSL_ON;
1571         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1572         Globals.ldap_delete_dn = False;
1573         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1574         Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1575         Globals.ldap_page_size = LDAP_PAGE_SIZE;
1576
1577         /* This is what we tell the afs client. in reality we set the token 
1578          * to never expire, though, when this runs out the afs client will 
1579          * forget the token. Set to 0 to get NEVERDATE.*/
1580         Globals.iAfsTokenLifetime = 604800;
1581
1582 /* these parameters are set to defaults that are more appropriate
1583    for the increasing samba install base:
1584
1585    as a member of the workgroup, that will possibly become a
1586    _local_ master browser (lm = True).  this is opposed to a forced
1587    local master browser startup (pm = True).
1588
1589    doesn't provide WINS server service by default (wsupp = False),
1590    and doesn't provide domain master browser services by default, either.
1591
1592 */
1593
1594         Globals.bMsAddPrinterWizard = True;
1595         Globals.bPreferredMaster = Auto;        /* depending on bDomainMaster */
1596         Globals.os_level = 20;
1597         Globals.bLocalMaster = True;
1598         Globals.bDomainMaster = Auto;   /* depending on bDomainLogons */
1599         Globals.bDomainLogons = False;
1600         Globals.bBrowseList = True;
1601         Globals.bWINSsupport = False;
1602         Globals.bWINSproxy = False;
1603
1604         Globals.bDNSproxy = True;
1605
1606         /* this just means to use them if they exist */
1607         Globals.bKernelOplocks = True;
1608
1609         Globals.bAllowTrustedDomains = True;
1610
1611         string_set(&Globals.szTemplateShell, "/bin/false");
1612         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1613         string_set(&Globals.szWinbindSeparator, "\\");
1614         string_set(&Globals.szAclCompat, "");
1615         string_set(&Globals.szCupsServer, "");
1616         string_set(&Globals.szIPrintServer, "");
1617
1618         Globals.winbind_cache_time = 300;       /* 5 minutes */
1619         Globals.bWinbindEnumUsers = False;
1620         Globals.bWinbindEnumGroups = False;
1621         Globals.bWinbindUseDefaultDomain = False;
1622         Globals.bWinbindTrustedDomainsOnly = False;
1623         Globals.bWinbindNestedGroups = True;
1624         Globals.szWinbindNssInfo = str_list_make("template", NULL);
1625         Globals.bWinbindRefreshTickets = False;
1626         Globals.bWinbindOfflineLogon = False;
1627
1628         Globals.bPassdbExpandExplicit = False;
1629
1630         Globals.name_cache_timeout = 660; /* In seconds */
1631
1632         Globals.bUseSpnego = True;
1633         Globals.bClientUseSpnego = True;
1634
1635         Globals.client_signing = Auto;
1636         Globals.server_signing = False;
1637
1638         Globals.bDeferSharingViolations = True;
1639         string_set(&Globals.smb_ports, SMB_PORTS);
1640
1641         Globals.bEnablePrivileges = True;
1642         Globals.bHostMSDfs        = True;
1643         Globals.bASUSupport       = False;
1644         
1645         /* User defined shares. */
1646         pstrcpy(s, dyn_LOCKDIR);
1647         pstrcat(s, "/usershares");
1648         string_set(&Globals.szUsersharePath, s);
1649         string_set(&Globals.szUsershareTemplateShare, "");
1650         Globals.iUsershareMaxShares = 0;
1651         /* By default disallow sharing of directories not owned by the sharer. */
1652         Globals.bUsershareOwnerOnly = True;
1653         /* By default disallow guest access to usershares. */
1654         Globals.bUsershareAllowGuests = False;
1655 }
1656
1657 static TALLOC_CTX *lp_talloc;
1658
1659 /******************************************************************* a
1660  Free up temporary memory - called from the main loop.
1661 ********************************************************************/
1662
1663 void lp_TALLOC_FREE(void)
1664 {
1665         if (!lp_talloc)
1666                 return;
1667         TALLOC_FREE(lp_talloc);
1668         lp_talloc = NULL;
1669 }
1670
1671 TALLOC_CTX *tmp_talloc_ctx(void)
1672 {
1673         if (lp_talloc == NULL) {
1674                 lp_talloc = talloc_init(NULL);
1675         }
1676
1677         if (lp_talloc == NULL) {
1678                 smb_panic("Could not create temporary talloc context\n");
1679         }
1680
1681         return lp_talloc;
1682 }
1683
1684 /*******************************************************************
1685  Convenience routine to grab string parameters into temporary memory
1686  and run standard_sub_basic on them. The buffers can be written to by
1687  callers without affecting the source string.
1688 ********************************************************************/
1689
1690 static char *lp_string(const char *s)
1691 {
1692         char *ret, *tmpstr;
1693
1694         /* The follow debug is useful for tracking down memory problems
1695            especially if you have an inner loop that is calling a lp_*()
1696            function that returns a string.  Perhaps this debug should be
1697            present all the time? */
1698
1699 #if 0
1700         DEBUG(10, ("lp_string(%s)\n", s));
1701 #endif
1702
1703         if (!lp_talloc)
1704                 lp_talloc = talloc_init("lp_talloc");
1705
1706         tmpstr = alloc_sub_basic(get_current_username(), s);
1707         if (trim_char(tmpstr, '\"', '\"')) {
1708                 if (strchr(tmpstr,'\"') != NULL) {
1709                         SAFE_FREE(tmpstr);
1710                         tmpstr = alloc_sub_basic(get_current_username(),s);
1711                 }
1712         }
1713         ret = talloc_strdup(lp_talloc, tmpstr);
1714         SAFE_FREE(tmpstr);
1715                         
1716         return (ret);
1717 }
1718
1719 /*
1720    In this section all the functions that are used to access the 
1721    parameters from the rest of the program are defined 
1722 */
1723
1724 #define FN_GLOBAL_STRING(fn_name,ptr) \
1725  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1726 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1727  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1728 #define FN_GLOBAL_LIST(fn_name,ptr) \
1729  const char **fn_name(void) {return(*(const char ***)(ptr));}
1730 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1731  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1732 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1733  char fn_name(void) {return(*(char *)(ptr));}
1734 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1735  int fn_name(void) {return(*(int *)(ptr));}
1736
1737 #define FN_LOCAL_STRING(fn_name,val) \
1738  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1739 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1740  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1741 #define FN_LOCAL_LIST(fn_name,val) \
1742  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1743 #define FN_LOCAL_BOOL(fn_name,val) \
1744  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1745 #define FN_LOCAL_CHAR(fn_name,val) \
1746  char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1747 #define FN_LOCAL_INTEGER(fn_name,val) \
1748  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1749
1750 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1751 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1752 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1753 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1754 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1755 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1756 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1757 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1758 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1759 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1760 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1761 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1762 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1763 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1764 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1765 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1766 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1767 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1768 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1769 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1770 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1771 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1772 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1773 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1774 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1775 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1776 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1777 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1778 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1779 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1780 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1781 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1782 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1783 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1784 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1785 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1786 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1787 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1788 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1789 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1790 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1791 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1792 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1793 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1794 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1795 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1796 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1797 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1798 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1799 FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1800 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1801 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1802 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1803 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1804 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1805
1806 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1807 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1808 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1809 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1810 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1811 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1812
1813 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1814
1815 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1816 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1817 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1818
1819 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1820
1821 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1822 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1823 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1824 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1825 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.szAclCompat)
1826 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1827 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1828 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1829 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1830 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1831 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1832 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1833
1834 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend)
1835 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1836
1837 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1838 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1839 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1840 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1841 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1842 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1843 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1844 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1845 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1846 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1847 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1848 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1849 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1850 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1851
1852 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1853
1854 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1855 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1856 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1857 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1858 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1859 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1860 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1861 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1862 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1863 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1864 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1865 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1866 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1867 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1868 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1869 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1870 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1871 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1872 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1873 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1874 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1875 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1876 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1877 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1878 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1879 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1880 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1881 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1882 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1883 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1884 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1885 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1886 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1887 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1888 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1889 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1890 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1891 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1892 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1893 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1894 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1895 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1896 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1897 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1898 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1899 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1900 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1901 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1902 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1903 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1904 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1905 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1906 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1907 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1908 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1909 FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
1910 FN_GLOBAL_BOOL(lp_fam_change_notify, &Globals.bFamChangeNotify)
1911 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
1912 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
1913 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
1914 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
1915 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1916 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1917 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1918 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1919 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1920 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1921 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
1922 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1923 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1924 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1925 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1926 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1927 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1928 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1929 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1930 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1931 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1932 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1933 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1934 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
1935 FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
1936 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1937 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1938 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1939 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1940 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1941 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1942 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1943 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1944 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1945 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
1946
1947 FN_LOCAL_STRING(lp_preexec, szPreExec)
1948 FN_LOCAL_STRING(lp_postexec, szPostExec)
1949 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1950 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1951 FN_LOCAL_STRING(lp_servicename, szService)
1952 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1953 FN_LOCAL_STRING(lp_pathname, szPath)
1954 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1955 FN_LOCAL_STRING(lp_username, szUsername)
1956 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1957 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1958 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1959 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
1960 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
1961 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
1962 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
1963 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1964 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1965 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1966 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1967 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1968 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1969 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1970 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1971 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1972 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1973 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
1974 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
1975 FN_LOCAL_STRING(lp_comment, comment)
1976 FN_LOCAL_STRING(lp_force_user, force_user)
1977 FN_LOCAL_STRING(lp_force_group, force_group)
1978 FN_LOCAL_LIST(lp_readlist, readlist)
1979 FN_LOCAL_LIST(lp_writelist, writelist)
1980 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
1981 FN_LOCAL_STRING(lp_fstype, fstype)
1982 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
1983 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1984 static FN_LOCAL_STRING(lp_volume, volume)
1985 FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
1986 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
1987 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
1988 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
1989 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1990 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
1991 FN_LOCAL_STRING(lp_dfree_command, szDfree)
1992 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1993 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
1994 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
1995 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
1996 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
1997 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
1998 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
1999 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2000 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2001 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2002 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2003 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2004 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2005 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2006 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2007 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2008 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2009 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2010 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2011 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2012 FN_LOCAL_BOOL(lp_locking, bLocking)
2013 FN_LOCAL_INTEGER(lp_strict_locking, iStrictLocking)
2014 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
2015 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2016 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2017 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2018 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2019 FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
2020 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2021 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2022 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2023 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2024 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2025 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2026 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2027 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2028 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2029 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2030 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2031 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2032 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2033 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2034 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2035 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2036 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2037 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2038 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2039 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2040 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2041 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2042 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2043 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2044 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2045 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2046 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2047 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2048 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2049 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2050 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2051 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2052 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2053 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2054 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2055 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2056 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2057 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2058 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2059 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2060 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2061 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2062 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2063 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2064 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2065 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2066 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2067 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2068 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2069 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2070 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2071 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2072 FN_LOCAL_INTEGER(lp_change_notify_timeout, ichange_notify_timeout)
2073 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2074 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2075 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2076 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2077 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2078 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2079 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2080
2081 /* local prototypes */
2082
2083 static int map_parameter(const char *pszParmName);
2084 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
2085 static int getservicebyname(const char *pszServiceName,
2086                             service * pserviceDest);
2087 static void copy_service(service * pserviceDest,
2088                          service * pserviceSource, BOOL *pcopymapDest);
2089 static BOOL service_ok(int iService);
2090 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
2091 static BOOL do_section(const char *pszSectionName);
2092 static void init_copymap(service * pservice);
2093 static BOOL hash_a_service(const char *name, int number);
2094 static void free_service_byindex(int iService);
2095 static char * canonicalize_servicename(const char *name);
2096
2097 /* This is a helper function for parametrical options support. */
2098 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2099 /* Actual parametrical functions are quite simple */
2100 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2101 {
2102         BOOL global_section = False;
2103         char* param_key;
2104         param_opt_struct *data;
2105         
2106         if (snum >= iNumServices) return NULL;
2107         
2108         if (snum < 0) { 
2109                 data = Globals.param_opt;
2110                 global_section = True;
2111         } else {
2112                 data = ServicePtrs[snum]->param_opt;
2113         }
2114     
2115         asprintf(&param_key, "%s:%s", type, option);
2116         if (!param_key) {
2117                 DEBUG(0,("asprintf failed!\n"));
2118                 return NULL;
2119         }
2120
2121         while (data) {
2122                 if (strcmp(data->key, param_key) == 0) {
2123                         string_free(&param_key);
2124                         return data;
2125                 }
2126                 data = data->next;
2127         }
2128
2129         if (!global_section) {
2130                 /* Try to fetch the same option but from globals */
2131                 /* but only if we are not already working with Globals */
2132                 data = Globals.param_opt;
2133                 while (data) {
2134                         if (strcmp(data->key, param_key) == 0) {
2135                                 string_free(&param_key);
2136                                 return data;
2137                         }
2138                         data = data->next;
2139                 }
2140         }
2141
2142         string_free(&param_key);
2143         
2144         return NULL;
2145 }
2146
2147
2148 #define MISSING_PARAMETER(name) \
2149     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2150
2151 /*******************************************************************
2152 convenience routine to return int parameters.
2153 ********************************************************************/
2154 static int lp_int(const char *s)
2155 {
2156
2157         if (!s || !*s) {
2158                 MISSING_PARAMETER(lp_int);
2159                 return (-1);
2160         }
2161
2162         return atoi(s); 
2163 }
2164
2165 /*******************************************************************
2166 convenience routine to return unsigned long parameters.
2167 ********************************************************************/
2168 static unsigned long lp_ulong(const char *s)
2169 {
2170
2171         if (!s || !*s) {
2172                 MISSING_PARAMETER(lp_ulong);
2173                 return (0);
2174         }
2175
2176         return strtoul(s, NULL, 10);
2177 }
2178
2179 /*******************************************************************
2180 convenience routine to return boolean parameters.
2181 ********************************************************************/
2182 static BOOL lp_bool(const char *s)
2183 {
2184         BOOL ret = False;
2185
2186         if (!s || !*s) {
2187                 MISSING_PARAMETER(lp_bool);
2188                 return False;
2189         }
2190         
2191         if (!set_boolean(&ret,s)) {
2192                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2193                 return False;
2194         }
2195
2196         return ret;
2197 }
2198
2199 /*******************************************************************
2200 convenience routine to return enum parameters.
2201 ********************************************************************/
2202 static int lp_enum(const char *s,const struct enum_list *_enum)
2203 {
2204         int i;
2205
2206         if (!s || !*s || !_enum) {
2207                 MISSING_PARAMETER(lp_enum);
2208                 return (-1);
2209         }
2210         
2211         for (i=0; _enum[i].name; i++) {
2212                 if (strequal(_enum[i].name,s))
2213                         return _enum[i].value;
2214         }
2215
2216         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2217         return (-1);
2218 }
2219
2220 #undef MISSING_PARAMETER
2221
2222 /* DO NOT USE lp_parm_string ANYMORE!!!!
2223  * use lp_parm_const_string or lp_parm_talloc_string
2224  *
2225  * lp_parm_string is only used to let old modules find this symbol
2226  */
2227 #undef lp_parm_string
2228  char *lp_parm_string(const char *servicename, const char *type, const char *option)
2229 {
2230         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2231 }
2232
2233 /* Return parametric option from a given service. Type is a part of option before ':' */
2234 /* Parametric option has following syntax: 'Type: option = value' */
2235 /* the returned value is talloced in lp_talloc */
2236 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2237 {
2238         param_opt_struct *data = get_parametrics(snum, type, option);
2239         
2240         if (data == NULL||data->value==NULL) {
2241                 if (def) {
2242                         return lp_string(def);
2243                 } else {
2244                         return NULL;
2245                 }
2246         }
2247
2248         return lp_string(data->value);
2249 }
2250
2251 /* Return parametric option from a given service. Type is a part of option before ':' */
2252 /* Parametric option has following syntax: 'Type: option = value' */
2253 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2254 {
2255         param_opt_struct *data = get_parametrics(snum, type, option);
2256         
2257         if (data == NULL||data->value==NULL)
2258                 return def;
2259                 
2260         return data->value;
2261 }
2262
2263 /* Return parametric option from a given service. Type is a part of option before ':' */
2264 /* Parametric option has following syntax: 'Type: option = value' */
2265
2266 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2267 {
2268         param_opt_struct *data = get_parametrics(snum, type, option);
2269
2270         if (data == NULL||data->value==NULL)
2271                 return (const char **)def;
2272                 
2273         if (data->list==NULL) {
2274                 data->list = str_list_make(data->value, NULL);
2275         }
2276
2277         return (const char **)data->list;
2278 }
2279
2280 /* Return parametric option from a given service. Type is a part of option before ':' */
2281 /* Parametric option has following syntax: 'Type: option = value' */
2282
2283 int lp_parm_int(int snum, const char *type, const char *option, int def)
2284 {
2285         param_opt_struct *data = get_parametrics(snum, type, option);
2286         
2287         if (data && data->value && *data->value)
2288                 return lp_int(data->value);
2289
2290         return def;
2291 }
2292
2293 /* Return parametric option from a given service. Type is a part of option before ':' */
2294 /* Parametric option has following syntax: 'Type: option = value' */
2295
2296 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2297 {
2298         param_opt_struct *data = get_parametrics(snum, type, option);
2299         
2300         if (data && data->value && *data->value)
2301                 return lp_ulong(data->value);
2302
2303         return def;
2304 }
2305
2306 /* Return parametric option from a given service. Type is a part of option before ':' */
2307 /* Parametric option has following syntax: 'Type: option = value' */
2308
2309 BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2310 {
2311         param_opt_struct *data = get_parametrics(snum, type, option);
2312         
2313         if (data && data->value && *data->value)
2314                 return lp_bool(data->value);
2315
2316         return def;
2317 }
2318
2319 /* Return parametric option from a given service. Type is a part of option before ':' */
2320 /* Parametric option has following syntax: 'Type: option = value' */
2321
2322 int lp_parm_enum(int snum, const char *type, const char *option,
2323                  const struct enum_list *_enum, int def)
2324 {
2325         param_opt_struct *data = get_parametrics(snum, type, option);
2326         
2327         if (data && data->value && *data->value && _enum)
2328                 return lp_enum(data->value, _enum);
2329
2330         return def;
2331 }
2332
2333
2334 /***************************************************************************
2335  Initialise a service to the defaults.
2336 ***************************************************************************/
2337
2338 static void init_service(service * pservice)
2339 {
2340         memset((char *)pservice, '\0', sizeof(service));
2341         copy_service(pservice, &sDefault, NULL);
2342 }
2343
2344 /***************************************************************************
2345  Free the dynamically allocated parts of a service struct.
2346 ***************************************************************************/
2347
2348 static void free_service(service *pservice)
2349 {
2350         int i;
2351         param_opt_struct *data, *pdata;
2352         if (!pservice)
2353                 return;
2354
2355         if (pservice->szService)
2356                 DEBUG(5, ("free_service: Freeing service %s\n",
2357                        pservice->szService));
2358
2359         string_free(&pservice->szService);
2360         SAFE_FREE(pservice->copymap);
2361
2362         for (i = 0; parm_table[i].label; i++) {
2363                 if ((parm_table[i].type == P_STRING ||
2364                      parm_table[i].type == P_USTRING) &&
2365                     parm_table[i].p_class == P_LOCAL)
2366                         string_free((char **)
2367                                     (((char *)pservice) +
2368                                      PTR_DIFF(parm_table[i].ptr, &sDefault)));
2369                 else if (parm_table[i].type == P_LIST &&
2370                          parm_table[i].p_class == P_LOCAL)
2371                              str_list_free((char ***)
2372                                             (((char *)pservice) +
2373                                              PTR_DIFF(parm_table[i].ptr, &sDefault)));
2374         }
2375
2376         data = pservice->param_opt;
2377         if (data)
2378                 DEBUG(5,("Freeing parametrics:\n"));
2379         while (data) {
2380                 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2381                 string_free(&data->key);
2382                 string_free(&data->value);
2383                 str_list_free(&data->list);
2384                 pdata = data->next;
2385                 SAFE_FREE(data);
2386                 data = pdata;
2387         }
2388
2389         ZERO_STRUCTP(pservice);
2390 }
2391
2392
2393 /***************************************************************************
2394  remove a service indexed in the ServicePtrs array from the ServiceHash
2395  and free the dynamically allocated parts
2396 ***************************************************************************/
2397
2398 static void free_service_byindex(int idx)
2399 {
2400         if ( !LP_SNUM_OK(idx) ) 
2401                 return;
2402
2403         ServicePtrs[idx]->valid = False;
2404         invalid_services[num_invalid_services++] = idx;
2405
2406         /* we have to cleanup the hash record */
2407
2408         if (ServicePtrs[idx]->szService) {
2409                 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2410                 
2411                 tdb_delete_bystring(ServiceHash, canon_name );
2412         }
2413
2414         free_service(ServicePtrs[idx]);
2415 }
2416
2417 /***************************************************************************
2418  Add a new service to the services array initialising it with the given 
2419  service. 
2420 ***************************************************************************/
2421
2422 static int add_a_service(const service *pservice, const char *name)
2423 {
2424         int i;
2425         service tservice;
2426         int num_to_alloc = iNumServices + 1;
2427         param_opt_struct *data, *pdata;
2428
2429         tservice = *pservice;
2430
2431         /* it might already exist */
2432         if (name) {
2433                 i = getservicebyname(name, NULL);
2434                 if (i >= 0) {
2435                         /* Clean all parametric options for service */
2436                         /* They will be added during parsing again */
2437                         data = ServicePtrs[i]->param_opt;
2438                         while (data) {
2439                                 string_free(&data->key);
2440                                 string_free(&data->value);
2441                                 str_list_free(&data->list);
2442                                 pdata = data->next;
2443                                 SAFE_FREE(data);
2444                                 data = pdata;
2445                         }
2446                         ServicePtrs[i]->param_opt = NULL;
2447                         return (i);
2448                 }
2449         }
2450
2451         /* find an invalid one */
2452         i = iNumServices;
2453         if (num_invalid_services > 0) {
2454                 i = invalid_services[--num_invalid_services];
2455         }
2456
2457         /* if not, then create one */
2458         if (i == iNumServices) {
2459                 service **tsp;
2460                 int *tinvalid;
2461                 
2462                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2463                 if (tsp == NULL) {
2464                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2465                         return (-1);
2466                 }
2467                 ServicePtrs = tsp;
2468                 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2469                 if (!ServicePtrs[iNumServices]) {
2470                         DEBUG(0,("add_a_service: out of memory!\n"));
2471                         return (-1);
2472                 }
2473                 iNumServices++;
2474
2475                 /* enlarge invalid_services here for now... */
2476                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2477                                              num_to_alloc);
2478                 if (tinvalid == NULL) {
2479                         DEBUG(0,("add_a_service: failed to enlarge "
2480                                  "invalid_services!\n"));
2481                         return (-1);
2482                 }
2483                 invalid_services = tinvalid;
2484         } else {
2485                 free_service_byindex(i);
2486         }
2487
2488         ServicePtrs[i]->valid = True;
2489
2490         init_service(ServicePtrs[i]);
2491         copy_service(ServicePtrs[i], &tservice, NULL);
2492         if (name)
2493                 string_set(&ServicePtrs[i]->szService, name);
2494                 
2495         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
2496                 i, ServicePtrs[i]->szService));
2497
2498         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2499                 return (-1);
2500         }
2501                 
2502         return (i);
2503 }
2504
2505 /***************************************************************************
2506   Convert a string to uppercase and remove whitespaces.
2507 ***************************************************************************/
2508
2509 static char *canonicalize_servicename(const char *src)
2510 {
2511         static fstring canon; /* is fstring large enough? */
2512
2513         if ( !src ) {
2514                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2515                 return NULL;
2516         }
2517
2518         fstrcpy( canon, src );
2519         strlower_m( canon );
2520
2521         return canon;
2522 }
2523
2524 /***************************************************************************
2525   Add a name/index pair for the services array to the hash table.
2526 ***************************************************************************/
2527
2528 static BOOL hash_a_service(const char *name, int idx)
2529 {
2530         char *canon_name;
2531
2532         if ( !ServiceHash ) {
2533                 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2534                 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL, 
2535                                         (O_RDWR|O_CREAT), 0600);
2536                 if ( !ServiceHash ) {
2537                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2538                         return False;
2539                 }
2540         }
2541
2542         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2543                 idx, name));
2544
2545         if ( !(canon_name = canonicalize_servicename( name )) )
2546                 return False;
2547
2548         tdb_store_int32(ServiceHash, canon_name, idx);
2549
2550         return True;
2551 }
2552
2553 /***************************************************************************
2554  Add a new home service, with the specified home directory, defaults coming 
2555  from service ifrom.
2556 ***************************************************************************/
2557
2558 BOOL lp_add_home(const char *pszHomename, int iDefaultService, 
2559                  const char *user, const char *pszHomedir)
2560 {
2561         int i;
2562         pstring newHomedir;
2563
2564         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2565
2566         if (i < 0)
2567                 return (False);
2568
2569         if (!(*(ServicePtrs[iDefaultService]->szPath))
2570             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2571                 pstrcpy(newHomedir, pszHomedir);
2572                 string_set(&ServicePtrs[i]->szPath, newHomedir);
2573         } 
2574
2575         if (!(*(ServicePtrs[i]->comment))) {
2576                 pstring comment;
2577                 slprintf(comment, sizeof(comment) - 1,
2578                          "Home directory of %s", user);
2579                 string_set(&ServicePtrs[i]->comment, comment);
2580         }
2581
2582         /* set the browseable flag from the global default */
2583
2584         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2585
2586         ServicePtrs[i]->autoloaded = True;
2587
2588         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
2589                user, ServicePtrs[i]->szPath ));
2590         
2591         return (True);
2592 }
2593
2594 /***************************************************************************
2595  Add a new service, based on an old one.
2596 ***************************************************************************/
2597
2598 int lp_add_service(const char *pszService, int iDefaultService)
2599 {
2600         return (add_a_service(ServicePtrs[iDefaultService], pszService));
2601 }
2602
2603 /***************************************************************************
2604  Add the IPC service.
2605 ***************************************************************************/
2606
2607 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2608 {
2609         pstring comment;
2610         int i = add_a_service(&sDefault, ipc_name);
2611
2612         if (i < 0)
2613                 return (False);
2614
2615         slprintf(comment, sizeof(comment) - 1,
2616                  "IPC Service (%s)", Globals.szServerString);
2617
2618         string_set(&ServicePtrs[i]->szPath, tmpdir());
2619         string_set(&ServicePtrs[i]->szUsername, "");
2620         string_set(&ServicePtrs[i]->comment, comment);
2621         string_set(&ServicePtrs[i]->fstype, "IPC");
2622         ServicePtrs[i]->iMaxConnections = 0;
2623         ServicePtrs[i]->bAvailable = True;
2624         ServicePtrs[i]->bRead_only = True;
2625         ServicePtrs[i]->bGuest_only = False;
2626         ServicePtrs[i]->bGuest_ok = guest_ok;
2627         ServicePtrs[i]->bPrint_ok = False;
2628         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2629
2630         DEBUG(3, ("adding IPC service\n"));
2631
2632         return (True);
2633 }
2634
2635 /***************************************************************************
2636  Add a new printer service, with defaults coming from service iFrom.
2637 ***************************************************************************/
2638
2639 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2640 {
2641         const char *comment = "From Printcap";
2642         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2643
2644         if (i < 0)
2645                 return (False);
2646
2647         /* note that we do NOT default the availability flag to True - */
2648         /* we take it from the default service passed. This allows all */
2649         /* dynamic printers to be disabled by disabling the [printers] */
2650         /* entry (if/when the 'available' keyword is implemented!).    */
2651
2652         /* the printer name is set to the service name. */
2653         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2654         string_set(&ServicePtrs[i]->comment, comment);
2655
2656         /* set the browseable flag from the gloabl default */
2657         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2658
2659         /* Printers cannot be read_only. */
2660         ServicePtrs[i]->bRead_only = False;
2661         /* No share modes on printer services. */
2662         ServicePtrs[i]->bShareModes = False;
2663         /* No oplocks on printer services. */
2664         ServicePtrs[i]->bOpLocks = False;
2665         /* Printer services must be printable. */
2666         ServicePtrs[i]->bPrint_ok = True;
2667         
2668         DEBUG(3, ("adding printer service %s\n", pszPrintername));
2669
2670         return (True);
2671 }
2672
2673 /***************************************************************************
2674  Map a parameter's string representation to something we can use. 
2675  Returns False if the parameter string is not recognised, else TRUE.
2676 ***************************************************************************/
2677
2678 static int map_parameter(const char *pszParmName)
2679 {
2680         int iIndex;
2681
2682         if (*pszParmName == '-')
2683                 return (-1);
2684
2685         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2686                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2687                         return (iIndex);
2688
2689         /* Warn only if it isn't parametric option */
2690         if (strchr(pszParmName, ':') == NULL)
2691                 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2692         /* We do return 'fail' for parametric options as well because they are
2693            stored in different storage
2694          */
2695         return (-1);
2696 }
2697
2698 /***************************************************************************
2699  Show all parameter's name, type, [values,] and flags.
2700 ***************************************************************************/
2701
2702 void show_parameter_list(void)
2703 {
2704         int classIndex, parmIndex, enumIndex, flagIndex;
2705         BOOL hadFlag;
2706         const char *section_names[] = { "local", "global", NULL};
2707         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2708                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2709                 "P_UGSTRING", "P_ENUM", "P_SEP"};
2710         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2711                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2712                 FLAG_HIDE, FLAG_DOS_STRING};
2713         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2714                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2715                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2716
2717         for ( classIndex=0; section_names[classIndex]; classIndex++) {
2718                 printf("[%s]\n", section_names[classIndex]);
2719                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2720                         if (parm_table[parmIndex].p_class == classIndex) {
2721                                 printf("%s=%s", 
2722                                         parm_table[parmIndex].label,
2723                                         type[parm_table[parmIndex].type]);
2724                                 switch (parm_table[parmIndex].type) {
2725                                 case P_ENUM:
2726                                         printf(",");
2727                                         for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2728                                                 printf("%s%s",
2729                                                         enumIndex ? "|" : "",
2730                                                         parm_table[parmIndex].enum_list[enumIndex].name);
2731                                         break;
2732                                 default:
2733                                         break;
2734                                 }
2735                                 printf(",");
2736                                 hadFlag = False;
2737                                 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2738                                         if (parm_table[parmIndex].flags & flags[flagIndex]) {
2739                                                 printf("%s%s",
2740                                                         hadFlag ? "|" : "",
2741                                                         flag_names[flagIndex]);
2742                                                 hadFlag = True;
2743                                         }
2744                                 }
2745                                 printf("\n");
2746                         }
2747                 }
2748         }
2749 }
2750
2751 /***************************************************************************
2752  Set a boolean variable from the text value stored in the passed string.
2753  Returns True in success, False if the passed string does not correctly 
2754  represent a boolean.
2755 ***************************************************************************/
2756
2757 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2758 {
2759         BOOL bRetval;
2760
2761         bRetval = True;
2762         if (strwicmp(pszParmValue, "yes") == 0 ||
2763             strwicmp(pszParmValue, "true") == 0 ||
2764             strwicmp(pszParmValue, "1") == 0)
2765                 *pb = True;
2766         else if (strwicmp(pszParmValue, "no") == 0 ||
2767                     strwicmp(pszParmValue, "False") == 0 ||
2768                     strwicmp(pszParmValue, "0") == 0)
2769                 *pb = False;
2770         else {
2771                 DEBUG(0,
2772                       ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2773                        pszParmValue));
2774                 bRetval = False;
2775         }
2776         return (bRetval);
2777 }
2778
2779 /***************************************************************************
2780 Find a service by name. Otherwise works like get_service.
2781 ***************************************************************************/
2782
2783 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2784 {
2785         int iService = -1;
2786         char *canon_name;
2787
2788         if (ServiceHash != NULL) {
2789                 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2790                         return -1;
2791
2792                 iService = tdb_fetch_int32(ServiceHash, canon_name );
2793
2794                 if (LP_SNUM_OK(iService)) {
2795                         if (pserviceDest != NULL) {
2796                                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2797                         }
2798                 } else {
2799                         iService = -1;
2800                 }
2801         }
2802
2803         return (iService);
2804 }
2805
2806 /***************************************************************************
2807  Copy a service structure to another.
2808  If pcopymapDest is NULL then copy all fields
2809 ***************************************************************************/
2810
2811 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2812 {
2813         int i;
2814         BOOL bcopyall = (pcopymapDest == NULL);
2815         param_opt_struct *data, *pdata, *paramo;
2816         BOOL not_added;
2817
2818         for (i = 0; parm_table[i].label; i++)
2819                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2820                     (bcopyall || pcopymapDest[i])) {
2821                         void *def_ptr = parm_table[i].ptr;
2822                         void *src_ptr =
2823                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2824                                                                     &sDefault);
2825                         void *dest_ptr =
2826                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2827                                                                   &sDefault);
2828
2829                         switch (parm_table[i].type) {
2830                                 case P_BOOL:
2831                                 case P_BOOLREV:
2832                                         *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2833                                         break;
2834
2835                                 case P_INTEGER:
2836                                 case P_ENUM:
2837                                 case P_OCTAL:
2838                                         *(int *)dest_ptr = *(int *)src_ptr;
2839                                         break;
2840
2841                                 case P_CHAR:
2842                                         *(char *)dest_ptr = *(char *)src_ptr;
2843                                         break;
2844
2845                                 case P_STRING:
2846                                         string_set((char **)dest_ptr,
2847                                                    *(char **)src_ptr);
2848                                         break;
2849
2850                                 case P_USTRING:
2851                                         string_set((char **)dest_ptr,
2852                                                    *(char **)src_ptr);
2853                                         strupper_m(*(char **)dest_ptr);
2854                                         break;
2855                                 case P_LIST:
2856                                         str_list_free((char ***)dest_ptr);
2857                                         str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2858                                         break;
2859                                 default:
2860                                         break;
2861                         }
2862                 }
2863
2864         if (bcopyall) {
2865                 init_copymap(pserviceDest);
2866                 if (pserviceSource->copymap)
2867                         memcpy((void *)pserviceDest->copymap,
2868                                (void *)pserviceSource->copymap,
2869                                sizeof(BOOL) * NUMPARAMETERS);
2870         }
2871         
2872         data = pserviceSource->param_opt;
2873         while (data) {
2874                 not_added = True;
2875                 pdata = pserviceDest->param_opt;
2876                 /* Traverse destination */
2877                 while (pdata) {
2878                         /* If we already have same option, override it */
2879                         if (strcmp(pdata->key, data->key) == 0) {
2880                                 string_free(&pdata->value);
2881                                 str_list_free(&data->list);
2882                                 pdata->value = SMB_STRDUP(data->value);
2883                                 not_added = False;
2884                                 break;
2885                         }
2886                         pdata = pdata->next;
2887                 }
2888                 if (not_added) {
2889                     paramo = SMB_XMALLOC_P(param_opt_struct);
2890                     paramo->key = SMB_STRDUP(data->key);
2891                     paramo->value = SMB_STRDUP(data->value);
2892                     paramo->list = NULL;
2893                     DLIST_ADD(pserviceDest->param_opt, paramo);
2894                 }
2895                 data = data->next;
2896         }
2897 }
2898
2899 /***************************************************************************
2900 Check a service for consistency. Return False if the service is in any way
2901 incomplete or faulty, else True.
2902 ***************************************************************************/
2903
2904 static BOOL service_ok(int iService)
2905 {
2906         BOOL bRetval;
2907
2908         bRetval = True;
2909         if (ServicePtrs[iService]->szService[0] == '\0') {
2910                 DEBUG(0, ("The following message indicates an internal error:\n"));
2911                 DEBUG(0, ("No service name in service entry.\n"));
2912                 bRetval = False;
2913         }
2914
2915         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2916         /* I can't see why you'd want a non-printable printer service...        */
2917         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2918                 if (!ServicePtrs[iService]->bPrint_ok) {
2919                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2920                                ServicePtrs[iService]->szService));
2921                         ServicePtrs[iService]->bPrint_ok = True;
2922                 }
2923                 /* [printers] service must also be non-browsable. */
2924                 if (ServicePtrs[iService]->bBrowseable)
2925                         ServicePtrs[iService]->bBrowseable = False;
2926         }
2927
2928         if (ServicePtrs[iService]->szPath[0] == '\0' &&
2929             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2930             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
2931             ) {
2932                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2933                         ServicePtrs[iService]->szService));
2934                 ServicePtrs[iService]->bAvailable = False;
2935         }
2936
2937         /* If a service is flagged unavailable, log the fact at level 0. */
2938         if (!ServicePtrs[iService]->bAvailable)
2939                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2940                           ServicePtrs[iService]->szService));
2941
2942         return (bRetval);
2943 }
2944
2945 static struct file_lists {
2946         struct file_lists *next;
2947         char *name;
2948         char *subfname;
2949         time_t modtime;
2950 } *file_lists = NULL;
2951
2952 /*******************************************************************
2953  Keep a linked list of all config files so we know when one has changed 
2954  it's date and needs to be reloaded.
2955 ********************************************************************/
2956
2957 static void add_to_file_list(const char *fname, const char *subfname)
2958 {
2959         struct file_lists *f = file_lists;
2960
2961         while (f) {
2962                 if (f->name && !strcmp(f->name, fname))
2963                         break;
2964                 f = f->next;
2965         }
2966
2967         if (!f) {
2968                 f = SMB_MALLOC_P(struct file_lists);
2969                 if (!f)
2970                         return;
2971                 f->next = file_lists;
2972                 f->name = SMB_STRDUP(fname);
2973                 if (!f->name) {
2974                         SAFE_FREE(f);
2975                         return;
2976                 }
2977                 f->subfname = SMB_STRDUP(subfname);
2978                 if (!f->subfname) {
2979                         SAFE_FREE(f);
2980                         return;
2981                 }
2982                 file_lists = f;
2983                 f->modtime = file_modtime(subfname);
2984         } else {
2985                 time_t t = file_modtime(subfname);
2986                 if (t)
2987                         f->modtime = t;
2988         }
2989 }
2990
2991 /*******************************************************************
2992  Check if a config file has changed date.
2993 ********************************************************************/
2994
2995 BOOL lp_file_list_changed(void)
2996 {
2997         struct file_lists *f = file_lists;
2998
2999         DEBUG(6, ("lp_file_list_changed()\n"));
3000
3001         while (f) {
3002                 pstring n2;
3003                 time_t mod_time;
3004
3005                 pstrcpy(n2, f->name);
3006                 standard_sub_basic( get_current_username(), n2, sizeof(n2) );
3007
3008                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
3009                              f->name, n2, ctime(&f->modtime)));
3010
3011                 mod_time = file_modtime(n2);
3012
3013                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3014                         DEBUGADD(6,
3015                                  ("file %s modified: %s\n", n2,
3016                                   ctime(&mod_time)));
3017                         f->modtime = mod_time;
3018                         SAFE_FREE(f->subfname);
3019                         f->subfname = SMB_STRDUP(n2);
3020                         return (True);
3021                 }
3022                 f = f->next;
3023         }
3024         return (False);
3025 }
3026
3027 /***************************************************************************
3028  Run standard_sub_basic on netbios name... needed because global_myname
3029  is not accessed through any lp_ macro.
3030  Note: We must *NOT* use string_set() here as ptr points to global_myname.
3031 ***************************************************************************/
3032
3033 static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3034 {
3035         BOOL ret;
3036         pstring netbios_name;
3037
3038         pstrcpy(netbios_name, pszParmValue);
3039
3040         standard_sub_basic(get_current_username(), netbios_name,sizeof(netbios_name));
3041
3042         ret = set_global_myname(netbios_name);
3043         string_set(&Globals.szNetbiosName,global_myname());
3044         
3045         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3046                global_myname()));
3047
3048         return ret;
3049 }
3050
3051 static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3052 {
3053         if (strcmp(*ptr, pszParmValue) != 0) {
3054                 string_set(ptr, pszParmValue);
3055                 init_iconv();
3056         }
3057         return True;
3058 }
3059
3060
3061
3062 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3063 {
3064         BOOL ret;
3065         
3066         ret = set_global_myworkgroup(pszParmValue);
3067         string_set(&Globals.szWorkgroup,lp_workgroup());
3068         
3069         return ret;
3070 }
3071
3072 static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3073 {
3074         BOOL ret;
3075         
3076         ret = set_global_scope(pszParmValue);
3077         string_set(&Globals.szNetbiosScope,global_scope());
3078
3079         return ret;
3080 }
3081
3082 static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3083 {
3084         str_list_free(&Globals.szNetbiosAliases);
3085         Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3086         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3087 }
3088
3089 /***************************************************************************
3090  Handle the include operation.
3091 ***************************************************************************/
3092
3093 static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3094 {
3095         pstring fname;
3096         pstrcpy(fname, pszParmValue);
3097
3098         standard_sub_basic(get_current_username(), fname,sizeof(fname));
3099
3100         add_to_file_list(pszParmValue, fname);
3101
3102         string_set(ptr, fname);
3103
3104         if (file_exist(fname, NULL))
3105                 return (pm_process(fname, do_section, do_parameter));
3106
3107         DEBUG(2, ("Can't find include file %s\n", fname));
3108
3109         return (False);
3110 }
3111
3112 /***************************************************************************
3113  Handle the interpretation of the copy parameter.
3114 ***************************************************************************/
3115
3116 static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3117 {
3118         BOOL bRetval;
3119         int iTemp;
3120         service serviceTemp;
3121
3122         string_set(ptr, pszParmValue);
3123
3124         init_service(&serviceTemp);
3125
3126         bRetval = False;
3127
3128         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3129
3130         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3131                 if (iTemp == iServiceIndex) {
3132                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3133                 } else {
3134                         copy_service(ServicePtrs[iServiceIndex],
3135                                      &serviceTemp,
3136                                      ServicePtrs[iServiceIndex]->copymap);
3137                         bRetval = True;
3138                 }
3139         } else {
3140                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3141                 bRetval = False;
3142         }
3143
3144         free_service(&serviceTemp);
3145         return (bRetval);
3146 }
3147
3148 /***************************************************************************
3149  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
3150  parameters is:
3151
3152  [global]
3153
3154         idmap uid = 1000-1999
3155         idmap gid = 700-899
3156
3157  We only do simple parsing checks here.  The strings are parsed into useful
3158  structures in the idmap daemon code.
3159
3160 ***************************************************************************/
3161
3162 /* Some lp_ routines to return idmap [ug]id information */
3163
3164 static uid_t idmap_uid_low, idmap_uid_high;
3165 static gid_t idmap_gid_low, idmap_gid_high;
3166
3167 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3168 {
3169         if (idmap_uid_low == 0 || idmap_uid_high == 0)
3170                 return False;
3171
3172         if (low)
3173                 *low = idmap_uid_low;
3174
3175         if (high)
3176                 *high = idmap_uid_high;
3177
3178         return True;
3179 }
3180
3181 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3182 {
3183         if (idmap_gid_low == 0 || idmap_gid_high == 0)
3184                 return False;
3185
3186         if (low)
3187                 *low = idmap_gid_low;
3188
3189         if (high)
3190                 *high = idmap_gid_high;
3191
3192         return True;
3193 }
3194
3195 /* Do some simple checks on "idmap [ug]id" parameter values */
3196
3197 static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3198 {
3199         uint32 low, high;
3200
3201         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3202                 return False;
3203
3204         /* Parse OK */
3205
3206         string_set(ptr, pszParmValue);
3207
3208         idmap_uid_low = low;
3209         idmap_uid_high = high;
3210
3211         return True;
3212 }
3213
3214 static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3215 {
3216         uint32 low, high;
3217
3218         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3219                 return False;
3220
3221         /* Parse OK */
3222
3223         string_set(ptr, pszParmValue);
3224
3225         idmap_gid_low = low;
3226         idmap_gid_high = high;
3227
3228         return True;
3229 }
3230
3231 /***************************************************************************
3232  Handle the DEBUG level list.
3233 ***************************************************************************/
3234
3235 static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3236 {
3237         pstring pszParmValue;
3238
3239         pstrcpy(pszParmValue, pszParmValueIn);
3240         string_set(ptr, pszParmValueIn);
3241         return debug_parse_levels( pszParmValue );
3242 }
3243
3244 /***************************************************************************
3245  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3246 ***************************************************************************/
3247
3248 static char* append_ldap_suffix( const char *str )
3249 {
3250         char *suffix_string;
3251
3252
3253         if (!lp_talloc)
3254                 lp_talloc = talloc_init("lp_talloc");
3255
3256         suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3257         if ( !suffix_string ) {
3258                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3259                 return NULL;
3260         }
3261
3262         return suffix_string;
3263 }
3264
3265 char *lp_ldap_machine_suffix(void)
3266 {
3267         if (Globals.szLdapMachineSuffix[0])
3268                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3269
3270         return lp_string(Globals.szLdapSuffix);
3271 }
3272
3273 char *lp_ldap_user_suffix(void)
3274 {
3275         if (Globals.szLdapUserSuffix[0])
3276                 return append_ldap_suffix(Globals.szLdapUserSuffix);
3277
3278         return lp_string(Globals.szLdapSuffix);
3279 }
3280
3281 char *lp_ldap_group_suffix(void)
3282 {
3283         if (Globals.szLdapGroupSuffix[0])
3284                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3285
3286         return lp_string(Globals.szLdapSuffix);
3287 }
3288
3289 char *lp_ldap_idmap_suffix(void)
3290 {
3291         if (Globals.szLdapIdmapSuffix[0])
3292                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3293
3294         return lp_string(Globals.szLdapSuffix);
3295 }
3296
3297 /****************************************************************************
3298  set the value for a P_ENUM
3299  ***************************************************************************/
3300
3301 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3302                               int *ptr )
3303 {
3304         int i;
3305
3306         for (i = 0; parm->enum_list[i].name; i++) {
3307                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3308                         *ptr = parm->enum_list[i].value;
3309                         break;
3310                 }
3311         }
3312 }
3313
3314 /***************************************************************************
3315 ***************************************************************************/
3316
3317 static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3318 {
3319         static int parm_num = -1;
3320         service *s;
3321
3322         if ( parm_num == -1 )
3323                 parm_num = map_parameter( "printing" );
3324
3325         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3326
3327         if ( snum < 0 )
3328                 s = &sDefault;
3329         else
3330                 s = ServicePtrs[snum];
3331
3332         init_printer_values( s );
3333
3334         return True;
3335 }
3336
3337
3338 /***************************************************************************
3339  Initialise a copymap.
3340 ***************************************************************************/
3341
3342 static void init_copymap(service * pservice)
3343 {
3344         int i;
3345         SAFE_FREE(pservice->copymap);
3346         pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3347         if (!pservice->copymap)
3348                 DEBUG(0,
3349                       ("Couldn't allocate copymap!! (size %d)\n",
3350                        (int)NUMPARAMETERS));
3351         else
3352                 for (i = 0; i < NUMPARAMETERS; i++)
3353                         pservice->copymap[i] = True;
3354 }
3355
3356 /***************************************************************************
3357  Return the local pointer to a parameter given the service number and the 
3358  pointer into the default structure.
3359 ***************************************************************************/
3360
3361 void *lp_local_ptr(int snum, void *ptr)
3362 {
3363         return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3364 }
3365
3366 /***************************************************************************
3367  Process a parameter for a particular service number. If snum < 0
3368  then assume we are in the globals.
3369 ***************************************************************************/
3370
3371 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3372 {
3373         int parmnum, i, slen;
3374         void *parm_ptr = NULL;  /* where we are going to store the result */
3375         void *def_ptr = NULL;
3376         pstring param_key;
3377         char *sep;
3378         param_opt_struct *paramo, *data;
3379         BOOL not_added;
3380
3381         parmnum = map_parameter(pszParmName);
3382
3383         if (parmnum < 0) {
3384                 if ((sep=strchr(pszParmName, ':')) != NULL) {
3385                         *sep = '\0';
3386                         ZERO_STRUCT(param_key);
3387                         pstr_sprintf(param_key, "%s:", pszParmName);
3388                         slen = strlen(param_key);
3389                         pstrcat(param_key, sep+1);
3390                         trim_char(param_key+slen, ' ', ' ');
3391                         not_added = True;
3392                         data = (snum < 0) ? Globals.param_opt : 
3393                                 ServicePtrs[snum]->param_opt;
3394                         /* Traverse destination */
3395                         while (data) {
3396                                 /* If we already have same option, override it */
3397                                 if (strcmp(data->key, param_key) == 0) {
3398                                         string_free(&data->value);
3399                                         str_list_free(&data->list);
3400                                         data->value = SMB_STRDUP(pszParmValue);
3401                                         not_added = False;
3402                                         break;
3403                                 }
3404                                 data = data->next;
3405                         }
3406                         if (not_added) {
3407                                 paramo = SMB_XMALLOC_P(param_opt_struct);
3408                                 paramo->key = SMB_STRDUP(param_key);
3409                                 paramo->value = SMB_STRDUP(pszParmValue);
3410                                 paramo->list = NULL;
3411                                 if (snum < 0) {
3412                                         DLIST_ADD(Globals.param_opt, paramo);
3413                                 } else {
3414                                         DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3415                                 }
3416                         }
3417
3418                         *sep = ':';
3419                         return (True);
3420                 }
3421                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3422                 return (True);
3423         }
3424
3425         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3426                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3427                           pszParmName));
3428         }
3429
3430         def_ptr = parm_table[parmnum].ptr;
3431
3432         /* we might point at a service, the default service or a global */
3433         if (snum < 0) {
3434                 parm_ptr = def_ptr;
3435         } else {
3436                 if (parm_table[parmnum].p_class == P_GLOBAL) {
3437                         DEBUG(0,
3438                               ("Global parameter %s found in service section!\n",
3439                                pszParmName));
3440                         return (True);
3441                 }
3442                 parm_ptr =
3443                         ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3444                                                             &sDefault);
3445         }
3446
3447         if (snum >= 0) {
3448                 if (!ServicePtrs[snum]->copymap)
3449                         init_copymap(ServicePtrs[snum]);
3450
3451                 /* this handles the aliases - set the copymap for other entries with
3452                    the same data pointer */
3453                 for (i = 0; parm_table[i].label; i++)
3454                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
3455                                 ServicePtrs[snum]->copymap[i] = False;
3456         }
3457
3458         /* if it is a special case then go ahead */
3459         if (parm_table[parmnum].special) {
3460                 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3461                 return (True);
3462         }
3463
3464         /* now switch on the type of variable it is */
3465         switch (parm_table[parmnum].type)
3466         {
3467                 case P_BOOL:
3468                         *(BOOL *)parm_ptr = lp_bool(pszParmValue);
3469                         break;
3470
3471                 case P_BOOLREV:
3472                         *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
3473                         break;
3474
3475                 case P_INTEGER:
3476                         *(int *)parm_ptr = lp_int(pszParmValue);
3477                         break;
3478
3479                 case P_CHAR:
3480                         *(char *)parm_ptr = *pszParmValue;
3481                         break;
3482
3483                 case P_OCTAL:
3484                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3485                         if ( i != 1 ) {
3486                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3487                         }
3488                         break;
3489
3490                 case P_LIST:
3491                         str_list_free((char ***)parm_ptr);
3492                         *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3493                         break;
3494
3495                 case P_STRING:
3496                         string_set((char **)parm_ptr, pszParmValue);
3497                         break;
3498
3499                 case P_USTRING:
3500                         string_set((char **)parm_ptr, pszParmValue);
3501                         strupper_m(*(char **)parm_ptr);
3502                         break;
3503
3504                 case P_GSTRING:
3505                         pstrcpy((char *)parm_ptr, pszParmValue);
3506                         break;
3507
3508                 case P_UGSTRING:
3509                         pstrcpy((char *)parm_ptr, pszParmValue);
3510                         strupper_m((char *)parm_ptr);
3511                         break;
3512
3513                 case P_ENUM:
3514                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3515                         break;
3516                 case P_SEP:
3517                         break;
3518         }
3519
3520         return (True);
3521 }
3522
3523 /***************************************************************************
3524  Process a parameter.
3525 ***************************************************************************/
3526
3527 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3528 {
3529         if (!bInGlobalSection && bGlobalOnly)
3530                 return (True);
3531
3532         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3533
3534         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3535                                 pszParmName, pszParmValue));
3536 }
3537
3538 /***************************************************************************
3539  Print a parameter of the specified type.
3540 ***************************************************************************/
3541
3542 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3543 {
3544         int i;
3545         switch (p->type)
3546         {
3547                 case P_ENUM:
3548                         for (i = 0; p->enum_list[i].name; i++) {
3549                                 if (*(int *)ptr == p->enum_list[i].value) {
3550                                         fprintf(f, "%s",
3551                                                 p->enum_list[i].name);
3552                                         break;
3553                                 }
3554                         }
3555                         break;
3556
3557                 case P_BOOL:
3558                         fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3559                         break;
3560
3561                 case P_BOOLREV:
3562                         fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3563                         break;
3564
3565                 case P_INTEGER:
3566                         fprintf(f, "%d", *(int *)ptr);
3567                         break;
3568
3569                 case P_CHAR:
3570                         fprintf(f, "%c", *(char *)ptr);
3571                         break;
3572
3573                 case P_OCTAL:
3574                         fprintf(f, "%s", octal_string(*(int *)ptr));
3575                         break;
3576
3577                 case P_LIST:
3578                         if ((char ***)ptr && *(char ***)ptr) {
3579                                 char **list = *(char ***)ptr;
3580                                 
3581                                 for (; *list; list++) {
3582                                         /* surround strings with whitespace in double quotes */
3583                                         if ( strchr_m( *list, ' ' ) )
3584                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3585                                         else
3586                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3587                                 }
3588                         }
3589                         break;
3590
3591                 case P_GSTRING:
3592                 case P_UGSTRING:
3593                         if ((char *)ptr) {
3594                                 fprintf(f, "%s", (char *)ptr);
3595                         }
3596                         break;
3597
3598                 case P_STRING:
3599                 case P_USTRING:
3600                         if (*(char **)ptr) {
3601                                 fprintf(f, "%s", *(char **)ptr);
3602                         }
3603                         break;
3604                 case P_SEP:
3605                         break;
3606         }
3607 }
3608
3609 /***************************************************************************
3610  Check if two parameters are equal.
3611 ***************************************************************************/
3612
3613 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3614 {
3615         switch (type) {
3616                 case P_BOOL:
3617                 case P_BOOLREV:
3618                         return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3619
3620                 case P_INTEGER:
3621                 case P_ENUM:
3622                 case P_OCTAL:
3623                         return (*((int *)ptr1) == *((int *)ptr2));
3624
3625                 case P_CHAR:
3626                         return (*((char *)ptr1) == *((char *)ptr2));
3627                 
3628                 case P_LIST:
3629                         return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3630
3631                 case P_GSTRING:
3632                 case P_UGSTRING:
3633                 {
3634                         char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3635                         if (p1 && !*p1)
3636                                 p1 = NULL;
3637                         if (p2 && !*p2)
3638                                 p2 = NULL;
3639                         return (p1 == p2 || strequal(p1, p2));
3640                 }
3641                 case P_STRING:
3642                 case P_USTRING:
3643                 {
3644                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3645                         if (p1 && !*p1)
3646                                 p1 = NULL;
3647                         if (p2 && !*p2)
3648                                 p2 = NULL;
3649                         return (p1 == p2 || strequal(p1, p2));
3650                 }
3651                 case P_SEP:
3652                         break;
3653         }
3654         return (False);
3655 }
3656
3657 /***************************************************************************
3658  Initialize any local varients in the sDefault table.
3659 ***************************************************************************/
3660
3661 void init_locals(void)
3662 {
3663         /* None as yet. */
3664 }
3665
3666 /***************************************************************************
3667  Process a new section (service). At this stage all sections are services.
3668  Later we'll have special sections that permit server parameters to be set.
3669  Returns True on success, False on failure. 
3670 ***************************************************************************/
3671
3672 static BOOL do_section(const char *pszSectionName)
3673 {
3674         BOOL bRetval;
3675         BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3676                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3677         bRetval = False;
3678
3679         /* if we were in a global section then do the local inits */
3680         if (bInGlobalSection && !isglobal)
3681                 init_locals();
3682
3683         /* if we've just struck a global section, note the fact. */
3684         bInGlobalSection = isglobal;
3685
3686         /* check for multiple global sections */
3687         if (bInGlobalSection) {
3688                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3689                 return (True);
3690         }
3691
3692         if (!bInGlobalSection && bGlobalOnly)
3693                 return (True);
3694
3695         /* if we have a current service, tidy it up before moving on */
3696         bRetval = True;
3697
3698         if (iServiceIndex >= 0)
3699                 bRetval = service_ok(iServiceIndex);
3700
3701         /* if all is still well, move to the next record in the services array */
3702         if (bRetval) {
3703                 /* We put this here to avoid an odd message order if messages are */
3704                 /* issued by the post-processing of a previous section. */
3705                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3706
3707                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3708                     < 0) {
3709                         DEBUG(0, ("Failed to add a new service\n"));
3710                         return (False);
3711                 }
3712         }
3713
3714         return (bRetval);
3715 }
3716
3717
3718 /***************************************************************************
3719  Determine if a partcular base parameter is currentl set to the default value.
3720 ***************************************************************************/
3721
3722 static BOOL is_default(int i)
3723 {
3724         if (!defaults_saved)
3725                 return False;
3726         switch (parm_table[i].type) {
3727                 case P_LIST:
3728                         return str_list_compare (parm_table[i].def.lvalue, 
3729                                                 *(char ***)parm_table[i].ptr);
3730                 case P_STRING:
3731                 case P_USTRING:
3732                         return strequal(parm_table[i].def.svalue,
3733                                         *(char **)parm_table[i].ptr);
3734                 case P_GSTRING:
3735                 case P_UGSTRING:
3736                         return strequal(parm_table[i].def.svalue,
3737                                         (char *)parm_table[i].ptr);
3738                 case P_BOOL:
3739                 case P_BOOLREV:
3740                         return parm_table[i].def.bvalue ==
3741                                 *(BOOL *)parm_table[i].ptr;
3742                 case P_CHAR:
3743                         return parm_table[i].def.cvalue ==
3744                                 *(char *)parm_table[i].ptr;
3745                 case P_INTEGER:
3746                 case P_OCTAL:
3747                 case P_ENUM:
3748                         return parm_table[i].def.ivalue ==
3749                                 *(int *)parm_table[i].ptr;
3750                 case P_SEP:
3751                         break;
3752         }
3753         return False;
3754 }
3755
3756 /***************************************************************************
3757 Display the contents of the global structure.
3758 ***************************************************************************/
3759
3760 static void dump_globals(FILE *f)
3761 {
3762         int i;
3763         param_opt_struct *data;
3764         
3765         fprintf(f, "[global]\n");
3766
3767         for (i = 0; parm_table[i].label; i++)
3768                 if (parm_table[i].p_class == P_GLOBAL &&
3769                     parm_table[i].ptr &&
3770                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3771                         if (defaults_saved && is_default(i))
3772                                 continue;
3773                         fprintf(f, "\t%s = ", parm_table[i].label);
3774                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
3775                         fprintf(f, "\n");
3776         }
3777         if (Globals.param_opt != NULL) {
3778                 data = Globals.param_opt;
3779                 while(data) {
3780                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3781                         data = data->next;
3782                 }
3783         }
3784
3785 }
3786
3787 /***************************************************************************
3788  Return True if a local parameter is currently set to the global default.
3789 ***************************************************************************/
3790
3791 BOOL lp_is_default(int snum, struct parm_struct *parm)
3792 {
3793         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3794
3795         return equal_parameter(parm->type,
3796                                ((char *)ServicePtrs[snum]) + pdiff,
3797                                ((char *)&sDefault) + pdiff);
3798 }
3799
3800 /***************************************************************************
3801  Display the contents of a single services record.
3802 ***************************************************************************/
3803
3804 static void dump_a_service(service * pService, FILE * f)
3805 {
3806         int i;
3807         param_opt_struct *data;
3808         
3809         if (pService != &sDefault)
3810                 fprintf(f, "[%s]\n", pService->szService);
3811
3812         for (i = 0; parm_table[i].label; i++) {
3813
3814                 if (parm_table[i].p_class == P_LOCAL &&
3815                     parm_table[i].ptr &&
3816                     (*parm_table[i].label != '-') &&
3817                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
3818                 {
3819                 
3820                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3821
3822                         if (pService == &sDefault) {
3823                                 if (defaults_saved && is_default(i))
3824                                         continue;
3825                         } else {
3826                                 if (equal_parameter(parm_table[i].type,
3827                                                     ((char *)pService) +
3828                                                     pdiff,
3829                                                     ((char *)&sDefault) +
3830                                                     pdiff))
3831                                         continue;
3832                         }
3833
3834                         fprintf(f, "\t%s = ", parm_table[i].label);
3835                         print_parameter(&parm_table[i],
3836                                         ((char *)pService) + pdiff, f);
3837                         fprintf(f, "\n");
3838                 }
3839         }
3840
3841                 if (pService->param_opt != NULL) {
3842                         data = pService->param_opt;
3843                         while(data) {
3844                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
3845                                 data = data->next;
3846                         }
3847                 }
3848 }
3849
3850 /***************************************************************************
3851  Display the contents of a parameter of a single services record.
3852 ***************************************************************************/
3853
3854 BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
3855 {
3856         service * pService = ServicePtrs[snum];
3857         int i;
3858         BOOL result = False;
3859         parm_class p_class;
3860         unsigned flag = 0;
3861         fstring local_parm_name;
3862         char *parm_opt;
3863         const char *parm_opt_value;
3864
3865         /* check for parametrical option */
3866         fstrcpy( local_parm_name, parm_name);
3867         parm_opt = strchr( local_parm_name, ':');
3868
3869         if (parm_opt) {
3870                 *parm_opt = '\0';
3871                 parm_opt++;
3872                 if (strlen(parm_opt)) {
3873                         parm_opt_value = lp_parm_const_string( snum,
3874                                 local_parm_name, parm_opt, NULL);
3875                         if (parm_opt_value) {
3876                                 printf( "%s\n", parm_opt_value);
3877                                 result = True;
3878                         }
3879                 }
3880                 return result;
3881         }
3882
3883         /* check for a key and print the value */
3884         if (isGlobal) {
3885                 p_class = P_GLOBAL;
3886                 flag = FLAG_GLOBAL;
3887         } else
3888                 p_class = P_LOCAL;
3889
3890         for (i = 0; parm_table[i].label; i++) {
3891                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3892                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3893                     parm_table[i].ptr &&
3894                     (*parm_table[i].label != '-') &&
3895                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
3896                 {
3897                         void *ptr;
3898
3899                         if (isGlobal)
3900                                 ptr = parm_table[i].ptr;
3901                         else
3902                                 ptr = ((char *)pService) +
3903                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
3904
3905                         print_parameter(&parm_table[i],
3906                                         ptr, f);
3907                         fprintf(f, "\n");
3908                         result = True;
3909                         break;
3910                 }
3911         }
3912
3913         return result;
3914 }
3915
3916 /***************************************************************************
3917  Return info about the next service  in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
3918  Return NULL when out of parameters.
3919 ***************************************************************************/
3920
3921 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3922 {
3923         if (snum < 0) {
3924                 /* do the globals */
3925                 for (; parm_table[*i].label; (*i)++) {
3926                         if (parm_table[*i].p_class == P_SEPARATOR)
3927                                 return &parm_table[(*i)++];
3928
3929                         if (!parm_table[*i].ptr
3930                             || (*parm_table[*i].label == '-'))
3931                                 continue;
3932
3933                         if ((*i) > 0
3934                             && (parm_table[*i].ptr ==
3935                                 parm_table[(*i) - 1].ptr))
3936                                 continue;
3937
3938                         return &parm_table[(*i)++];
3939                 }
3940         } else {
3941                 service *pService = ServicePtrs[snum];
3942
3943                 for (; parm_table[*i].label; (*i)++) {
3944                         if (parm_table[*i].p_class == P_SEPARATOR)
3945                                 return &parm_table[(*i)++];
3946
3947                         if (parm_table[*i].p_class == P_LOCAL &&
3948                             parm_table[*i].ptr &&
3949                             (*parm_table[*i].label != '-') &&
3950                             ((*i) == 0 ||
3951                              (parm_table[*i].ptr !=
3952                               parm_table[(*i) - 1].ptr)))
3953                         {
3954                                 int pdiff =
3955                                         PTR_DIFF(parm_table[*i].ptr,
3956                                                  &sDefault);
3957
3958                                 if (allparameters ||
3959                                     !equal_parameter(parm_table[*i].type,
3960                                                      ((char *)pService) +
3961                                                      pdiff,
3962                                                      ((char *)&sDefault) +
3963                                                      pdiff))
3964                                 {
3965                                         return &parm_table[(*i)++];
3966                                 }
3967                         }
3968                 }
3969         }
3970
3971         return NULL;
3972 }
3973
3974
3975 #if 0
3976 /***************************************************************************
3977  Display the contents of a single copy structure.
3978 ***************************************************************************/
3979 static void dump_copy_map(BOOL *pcopymap)
3980 {
3981         int i;
3982         if (!pcopymap)
3983                 return;
3984
3985         printf("\n\tNon-Copied parameters:\n");
3986
3987         for (i = 0; parm_table[i].label; i++)
3988                 if (parm_table[i].p_class == P_LOCAL &&
3989                     parm_table[i].ptr && !pcopymap[i] &&
3990                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3991                 {
3992                         printf("\t\t%s\n", parm_table[i].label);
3993                 }
3994 }
3995 #endif
3996
3997 /***************************************************************************
3998  Return TRUE if the passed service number is within range.
3999 ***************************************************************************/
4000
4001 BOOL lp_snum_ok(int iService)
4002 {
4003         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4004 }
4005
4006 /***************************************************************************
4007  Auto-load some home services.
4008 ***************************************************************************/
4009
4010 static void lp_add_auto_services(char *str)
4011 {
4012         char *s;
4013         char *p;
4014         int homes;
4015
4016         if (!str)
4017                 return;
4018
4019         s = SMB_STRDUP(str);
4020         if (!s)
4021                 return;
4022
4023         homes = lp_servicenumber(HOMES_NAME);
4024
4025         for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4026                 char *home = get_user_home_dir(p);
4027
4028                 if (lp_servicenumber(p) >= 0)
4029                         continue;
4030
4031                 if (home && homes >= 0)
4032                         lp_add_home(p, homes, p, home);
4033         }
4034         SAFE_FREE(s);
4035 }
4036
4037 /***************************************************************************
4038  Auto-load one printer.
4039 ***************************************************************************/
4040
4041 void lp_add_one_printer(char *name, char *comment)
4042 {
4043         int printers = lp_servicenumber(PRINTERS_NAME);
4044         int i;
4045
4046         if (lp_servicenumber(name) < 0) {
4047                 lp_add_printer(name, printers);
4048                 if ((i = lp_servicenumber(name)) >= 0) {
4049                         string_set(&ServicePtrs[i]->comment, comment);
4050                         ServicePtrs[i]->autoloaded = True;
4051                 }
4052         }
4053 }
4054
4055 /***************************************************************************
4056  Have we loaded a services file yet?
4057 ***************************************************************************/
4058
4059 BOOL lp_loaded(void)
4060 {
4061         return (bLoaded);
4062 }
4063
4064 /***************************************************************************
4065  Unload unused services.
4066 ***************************************************************************/
4067
4068 void lp_killunused(BOOL (*snumused) (int))
4069 {
4070         int i;
4071         for (i = 0; i < iNumServices; i++) {
4072                 if (!VALID(i))
4073                         continue;
4074
4075                 /* don't kill autoloaded or usershare services */
4076                 if ( ServicePtrs[i]->autoloaded ||
4077                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4078                         continue;
4079                 }
4080
4081                 if (!snumused || !snumused(i)) {
4082                         free_service_byindex(i);
4083                 }
4084         }
4085 }
4086
4087 /***************************************************************************
4088  Unload a service.
4089 ***************************************************************************/
4090
4091 void lp_killservice(int iServiceIn)
4092 {
4093         if (VALID(iServiceIn)) {
4094                 free_service_byindex(iServiceIn);
4095         }
4096 }
4097
4098 /***************************************************************************
4099  Save the curent values of all global and sDefault parameters into the 
4100  defaults union. This allows swat and testparm to show only the
4101  changed (ie. non-default) parameters.
4102 ***************************************************************************/
4103
4104 static void lp_save_defaults(void)
4105 {
4106         int i;
4107         for (i = 0; parm_table[i].label; i++) {
4108                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4109                         continue;
4110                 switch (parm_table[i].type) {
4111                         case P_LIST:
4112                                 str_list_copy(&(parm_table[i].def.lvalue),
4113                                             *(const char ***)parm_table[i].ptr);
4114                                 break;
4115                         case P_STRING:
4116                         case P_USTRING:
4117                                 if (parm_table[i].ptr) {
4118                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4119                                 } else {
4120                                         parm_table[i].def.svalue = NULL;
4121                                 }
4122                                 break;
4123                         case P_GSTRING:
4124                         case P_UGSTRING:
4125                                 if (parm_table[i].ptr) {
4126                                         parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4127                                 } else {
4128                                         parm_table[i].def.svalue = NULL;
4129                                 }
4130                                 break;
4131                         case P_BOOL:
4132                         case P_BOOLREV:
4133                                 parm_table[i].def.bvalue =
4134                                         *(BOOL *)parm_table[i].ptr;
4135                                 break;
4136                         case P_CHAR:
4137                                 parm_table[i].def.cvalue =
4138                                         *(char *)parm_table[i].ptr;
4139                                 break;
4140                         case P_INTEGER:
4141                         case P_OCTAL:
4142                         case P_ENUM:
4143                                 parm_table[i].def.ivalue =
4144                                         *(int *)parm_table[i].ptr;
4145                                 break;
4146                         case P_SEP:
4147                                 break;
4148                 }
4149         }
4150         defaults_saved = True;
4151 }
4152
4153 /*******************************************************************
4154  Set the server type we will announce as via nmbd.
4155 ********************************************************************/
4156
4157 static const struct srv_role_tab {
4158         uint32 role;
4159         const char *role_str;
4160 } srv_role_tab [] = {
4161         { ROLE_STANDALONE, "ROLE_STANDALONE" },
4162         { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4163         { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4164         { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4165         { 0, NULL }
4166 };
4167
4168 const char* server_role_str(uint32 role)
4169 {
4170         int i = 0;
4171         for (i=0; srv_role_tab[i].role_str; i++) {
4172                 if (role == srv_role_tab[i].role) {
4173                         return srv_role_tab[i].role_str;
4174                 }
4175         }
4176         return NULL;
4177 }
4178
4179 static void set_server_role(void)
4180 {
4181         server_role = ROLE_STANDALONE;
4182
4183         switch (lp_security()) {
4184                 case SEC_SHARE:
4185                         if (lp_domain_logons())
4186                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4187                         break;
4188                 case SEC_SERVER:
4189                         if (lp_domain_logons())
4190                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4191                         server_role = ROLE_DOMAIN_MEMBER;
4192                         break;
4193                 case SEC_DOMAIN:
4194                         if (lp_domain_logons()) {
4195                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4196                                 server_role = ROLE_DOMAIN_BDC;
4197                                 break;
4198                         }
4199                         server_role = ROLE_DOMAIN_MEMBER;
4200                         break;
4201                 case SEC_ADS:
4202                         if (lp_domain_logons()) {
4203                                 server_role = ROLE_DOMAIN_PDC;
4204                                 break;
4205                         }
4206                         server_role = ROLE_DOMAIN_MEMBER;
4207                         break;
4208                 case SEC_USER:
4209                         if (lp_domain_logons()) {
4210
4211                                 if (Globals.bDomainMaster) /* auto or yes */ 
4212                                         server_role = ROLE_DOMAIN_PDC;
4213                                 else
4214                                         server_role = ROLE_DOMAIN_BDC;
4215                         }
4216                         break;
4217                 default:
4218                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4219                         break;
4220         }
4221
4222         DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4223 }
4224
4225 /***********************************************************
4226  If we should send plaintext/LANMAN passwords in the clinet
4227 ************************************************************/
4228
4229 static void set_allowed_client_auth(void)
4230 {
4231         if (Globals.bClientNTLMv2Auth) {
4232                 Globals.bClientLanManAuth = False;
4233         }
4234         if (!Globals.bClientLanManAuth) {
4235                 Globals.bClientPlaintextAuth = False;
4236         }
4237 }
4238
4239 /***************************************************************************
4240  JRA.
4241  The following code allows smbd to read a user defined share file.
4242  Yes, this is my intent. Yes, I'm comfortable with that...
4243
4244  THE FOLLOWING IS SECURITY CRITICAL CODE.
4245
4246  It washes your clothes, it cleans your house, it guards you while you sleep...
4247  Do not f%^k with it....
4248 ***************************************************************************/
4249
4250 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4251
4252 /***************************************************************************
4253  Check allowed stat state of a usershare file.
4254  Ensure we print out who is dicking with us so the admin can
4255  get their sorry ass fired.
4256 ***************************************************************************/
4257
4258 static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4259 {
4260         if (!S_ISREG(psbuf->st_mode)) {
4261                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4262                         "not a regular file\n",
4263                         fname, (unsigned int)psbuf->st_uid ));
4264                 return False;
4265         }
4266
4267         /* Ensure this doesn't have the other write bit set. */
4268         if (psbuf->st_mode & S_IWOTH) {
4269                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4270                         "public write. Refusing to allow as a usershare file.\n",
4271                         fname, (unsigned int)psbuf->st_uid ));
4272                 return False;
4273         }
4274
4275         /* Should be 10k or less. */
4276         if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4277                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4278                         "too large (%u) to be a user share file.\n",
4279                         fname, (unsigned int)psbuf->st_uid,
4280                         (unsigned int)psbuf->st_size ));
4281                 return False;
4282         }
4283
4284         return True;
4285 }
4286
4287 /***************************************************************************
4288  Parse the contents of a usershare file.
4289 ***************************************************************************/
4290
4291 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, 
4292                         SMB_STRUCT_STAT *psbuf,
4293                         const char *servicename,
4294                         int snum,
4295                         char **lines,
4296                         int numlines,
4297                         pstring sharepath,
4298                         pstring comment,
4299                         SEC_DESC **ppsd,
4300                         BOOL *pallow_guest)
4301 {
4302         const char **prefixallowlist = lp_usershare_prefix_allow_list();
4303         const char **prefixdenylist = lp_usershare_prefix_deny_list();
4304         int us_vers;
4305         SMB_STRUCT_DIR *dp;
4306         SMB_STRUCT_STAT sbuf;
4307
4308         *pallow_guest = False;
4309
4310         if (numlines < 4) {
4311                 return USERSHARE_MALFORMED_FILE;
4312         }
4313
4314         if (strcmp(lines[0], "#VERSION 1") == 0) {
4315                 us_vers = 1;
4316         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4317                 us_vers = 2;
4318                 if (numlines < 5) {
4319                         return USERSHARE_MALFORMED_FILE;
4320                 }
4321         } else {
4322                 return USERSHARE_BAD_VERSION;
4323         }
4324
4325         if (strncmp(lines[1], "path=", 5) != 0) {
4326                 return USERSHARE_MALFORMED_PATH;
4327         }
4328
4329         pstrcpy(sharepath, &lines[1][5]);
4330         trim_string(sharepath, " ", " ");
4331
4332         if (strncmp(lines[2], "comment=", 8) != 0) {
4333                 return USERSHARE_MALFORMED_COMMENT_DEF;
4334         }
4335
4336         pstrcpy(comment, &lines[2][8]);
4337         trim_string(comment, " ", " ");
4338         trim_char(comment, '"', '"');
4339
4340         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4341                 return USERSHARE_MALFORMED_ACL_DEF;
4342         }
4343
4344         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4345                 return USERSHARE_ACL_ERR;
4346         }
4347
4348         if (us_vers == 2) {
4349                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4350                         return USERSHARE_MALFORMED_ACL_DEF;
4351                 }
4352                 if (lines[4][9] == 'y') {
4353                         *pallow_guest = True;
4354                 }
4355         }
4356
4357         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4358                 /* Path didn't change, no checks needed. */
4359                 return USERSHARE_OK;
4360         }
4361
4362         /* The path *must* be absolute. */
4363         if (sharepath[0] != '/') {
4364                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4365                         servicename, sharepath));
4366                 return USERSHARE_PATH_NOT_ABSOLUTE;
4367         }
4368
4369         /* If there is a usershare prefix deny list ensure one of these paths
4370            doesn't match the start of the user given path. */
4371         if (prefixdenylist) {
4372                 int i;
4373                 for ( i=0; prefixdenylist[i]; i++ ) {
4374                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4375                                 servicename, i, prefixdenylist[i], sharepath ));
4376                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4377                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4378                                         "usershare prefix deny list entries.\n",
4379                                         servicename, sharepath));
4380                                 return USERSHARE_PATH_IS_DENIED;
4381                         }
4382                 }
4383         }
4384
4385         /* If there is a usershare prefix allow list ensure one of these paths
4386            does match the start of the user given path. */
4387
4388         if (prefixallowlist) {
4389                 int i;
4390                 for ( i=0; prefixallowlist[i]; i++ ) {
4391                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4392                                 servicename, i, prefixallowlist[i], sharepath ));
4393                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4394                                 break;
4395                         }
4396                 }
4397                 if (prefixallowlist[i] == NULL) {
4398                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4399                                 "usershare prefix allow list entries.\n",
4400                                 servicename, sharepath));
4401                         return USERSHARE_PATH_NOT_ALLOWED;
4402                 }
4403         }
4404
4405         /* Ensure this is pointing to a directory. */
4406         dp = sys_opendir(sharepath);
4407
4408         if (!dp) {
4409                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4410                         servicename, sharepath));
4411                 return USERSHARE_PATH_NOT_DIRECTORY;
4412         }
4413
4414         /* Ensure the owner of the usershare file has permission to share
4415            this directory. */
4416
4417         if (sys_stat(sharepath, &sbuf) == -1) {
4418                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4419                         servicename, sharepath, strerror(errno) ));
4420                 sys_closedir(dp);
4421                 return USERSHARE_POSIX_ERR;
4422         }
4423
4424         sys_closedir(dp);
4425
4426         if (!S_ISDIR(sbuf.st_mode)) {
4427                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4428                         servicename, sharepath ));
4429                 return USERSHARE_PATH_NOT_DIRECTORY;
4430         }
4431
4432         /* Check if sharing is restricted to owner-only. */
4433         /* psbuf is the stat of the usershare definition file,
4434            sbuf is the stat of the target directory to be shared. */
4435
4436         if (lp_usershare_owner_only()) {
4437                 /* root can share anything. */
4438                 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4439                         return USERSHARE_PATH_NOT_ALLOWED;
4440                 }
4441         }
4442
4443         return USERSHARE_OK;
4444 }
4445
4446 /***************************************************************************
4447  Deal with a usershare file.
4448  Returns:
4449         >= 0 - snum
4450         -1 - Bad name, invalid contents.
4451            - service name already existed and not a usershare, problem
4452             with permissions to share directory etc.
4453 ***************************************************************************/
4454
4455 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4456 {
4457         SMB_STRUCT_STAT sbuf;
4458         SMB_STRUCT_STAT lsbuf;
4459         pstring fname;
4460         pstring sharepath;
4461         pstring comment;
4462         fstring service_name;
4463         char **lines = NULL;
4464         int numlines = 0;
4465         int fd = -1;
4466         int iService = -1;
4467         TALLOC_CTX *ctx = NULL;
4468         SEC_DESC *psd = NULL;
4469         BOOL guest_ok = False;
4470
4471         /* Ensure share name doesn't contain invalid characters. */
4472         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4473                 DEBUG(0,("process_usershare_file: share name %s contains "
4474                         "invalid characters (any of %s)\n",
4475                         file_name, INVALID_SHARENAME_CHARS ));
4476                 return -1;
4477         }
4478
4479         fstrcpy(service_name, file_name);
4480
4481         pstrcpy(fname, dir_name);
4482         pstrcat(fname, "/");
4483         pstrcat(fname, file_name);
4484
4485         /* Minimize the race condition by doing an lstat before we
4486            open and fstat. Ensure this isn't a symlink link. */
4487
4488         if (sys_lstat(fname, &lsbuf) != 0) {
4489                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4490                         fname, strerror(errno) ));
4491                 return -1;
4492         }
4493
4494         /* This must be a regular file, not a symlink, directory or
4495            other strange filetype. */
4496         if (!check_usershare_stat(fname, &lsbuf)) {
4497                 return -1;
4498         }
4499
4500         /* See if there is already a servicenum for this name. */
4501         /* tdb_fetch_int32 returns -1 if not found. */
4502         iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4503
4504         if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4505                 /* Nothing changed - Mark valid and return. */
4506                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4507                         service_name ));
4508                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4509                 return iService;
4510         }
4511
4512         /* Try and open the file read only - no symlinks allowed. */
4513 #ifdef O_NOFOLLOW
4514         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4515 #else
4516         fd = sys_open(fname, O_RDONLY, 0);
4517 #endif
4518
4519         if (fd == -1) {
4520                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4521                         fname, strerror(errno) ));
4522                 return -1;
4523         }
4524
4525         /* Now fstat to be *SURE* it's a regular file. */
4526         if (sys_fstat(fd, &sbuf) != 0) {
4527                 close(fd);
4528                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4529                         fname, strerror(errno) ));
4530                 return -1;
4531         }
4532
4533         /* Is it the same dev/inode as was lstated ? */
4534         if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4535                 close(fd);
4536                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4537                         "Symlink spoofing going on ?\n", fname ));
4538                 return -1;
4539         }
4540
4541         /* This must be a regular file, not a symlink, directory or
4542            other strange filetype. */
4543         if (!check_usershare_stat(fname, &sbuf)) {
4544                 return -1;
4545         }
4546
4547         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4548
4549         close(fd);
4550         if (lines == NULL) {
4551                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4552                         fname, (unsigned int)sbuf.st_uid ));
4553                 return -1;
4554         }
4555
4556         /* Should we allow printers to be shared... ? */
4557         ctx = talloc_init("usershare_sd_xctx");
4558         if (!ctx) {
4559                 SAFE_FREE(lines);
4560                 return 1;
4561         }
4562
4563         if (parse_usershare_file(ctx, &sbuf, service_name,
4564                         iService, lines, numlines, sharepath,
4565                         comment, &psd, &guest_ok) != USERSHARE_OK) {
4566                 talloc_destroy(ctx);
4567                 SAFE_FREE(lines);
4568                 return -1;
4569         }
4570
4571         SAFE_FREE(lines);
4572
4573         /* Everything ok - add the service possibly using a template. */
4574         if (iService < 0) {
4575                 const service *sp = &sDefault;
4576                 if (snum_template != -1) {
4577                         sp = ServicePtrs[snum_template];
4578                 }
4579
4580                 if ((iService = add_a_service(sp, service_name)) < 0) {
4581                         DEBUG(0, ("process_usershare_file: Failed to add "
4582                                 "new service %s\n", service_name));
4583                         talloc_destroy(ctx);
4584                         return -1;
4585                 }
4586
4587                 /* Read only is controlled by usershare ACL below. */
4588                 ServicePtrs[iService]->bRead_only = False;
4589         }
4590
4591         /* Write the ACL of the new/modified share. */
4592         if (!set_share_security(ctx, service_name, psd)) {
4593                  DEBUG(0, ("process_usershare_file: Failed to set share "
4594                         "security for user share %s\n",
4595                         service_name ));
4596                 lp_remove_service(iService);
4597                 talloc_destroy(ctx);
4598                 return -1;
4599         }
4600
4601         talloc_destroy(ctx);
4602
4603         /* If from a template it may be marked invalid. */
4604         ServicePtrs[iService]->valid = True;
4605
4606         /* Set the service as a valid usershare. */
4607         ServicePtrs[iService]->usershare = USERSHARE_VALID;
4608
4609         /* Set guest access. */
4610         if (lp_usershare_allow_guests()) {
4611                 ServicePtrs[iService]->bGuest_ok = guest_ok;
4612         }
4613
4614         /* And note when it was loaded. */
4615         ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4616         string_set(&ServicePtrs[iService]->szPath, sharepath);
4617         string_set(&ServicePtrs[iService]->comment, comment);
4618
4619         return iService;
4620 }
4621
4622 /***************************************************************************
4623  Checks if a usershare entry has been modified since last load.
4624 ***************************************************************************/
4625
4626 static BOOL usershare_exists(int iService, time_t *last_mod)
4627 {
4628         SMB_STRUCT_STAT lsbuf;
4629         const char *usersharepath = Globals.szUsersharePath;
4630         pstring fname;
4631
4632         pstrcpy(fname, usersharepath);
4633         pstrcat(fname, "/");
4634         pstrcat(fname, ServicePtrs[iService]->szService);
4635
4636         if (sys_lstat(fname, &lsbuf) != 0) {
4637                 return False;
4638         }
4639
4640         if (!S_ISREG(lsbuf.st_mode)) {
4641                 return False;
4642         }
4643
4644         *last_mod = lsbuf.st_mtime;
4645         return True;
4646 }
4647
4648 /***************************************************************************
4649  Load a usershare service by name. Returns a valid servicenumber or -1.
4650 ***************************************************************************/
4651
4652 int load_usershare_service(const char *servicename)
4653 {
4654         SMB_STRUCT_STAT sbuf;
4655         const char *usersharepath = Globals.szUsersharePath;
4656         int max_user_shares = Globals.iUsershareMaxShares;
4657         int snum_template = -1;
4658
4659         if (*usersharepath == 0 ||  max_user_shares == 0) {
4660                 return -1;
4661         }
4662
4663         if (sys_stat(usersharepath, &sbuf) != 0) {
4664                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4665                         usersharepath, strerror(errno) ));
4666                 return -1;
4667         }
4668
4669         if (!S_ISDIR(sbuf.st_mode)) {
4670                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4671                         usersharepath ));
4672                 return -1;
4673         }
4674
4675         /*
4676          * This directory must be owned by root, and have the 't' bit set.
4677          * It also must not be writable by "other".
4678          */
4679
4680 #ifdef S_ISVTX
4681         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4682 #else
4683         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4684 #endif
4685                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4686                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
4687                         usersharepath ));
4688                 return -1;
4689         }
4690
4691         /* Ensure the template share exists if it's set. */
4692         if (Globals.szUsershareTemplateShare[0]) {
4693                 /* We can't use lp_servicenumber here as we are recommending that
4694                    template shares have -valid=False set. */
4695                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4696                         if (ServicePtrs[snum_template]->szService &&
4697                                         strequal(ServicePtrs[snum_template]->szService,
4698                                                 Globals.szUsershareTemplateShare)) {
4699                                 break;
4700                         }
4701                 }
4702
4703                 if (snum_template == -1) {
4704                         DEBUG(0,("load_usershare_service: usershare template share %s "
4705                                 "does not exist.\n",
4706                                 Globals.szUsershareTemplateShare ));
4707                         return -1;
4708                 }
4709         }
4710
4711         return process_usershare_file(usersharepath, servicename, snum_template);
4712 }
4713
4714 /***************************************************************************
4715  Load all user defined shares from the user share directory.
4716  We only do this if we're enumerating the share list.
4717  This is the function that can delete usershares that have
4718  been removed.
4719 ***************************************************************************/
4720
4721 int load_usershare_shares(void)
4722 {
4723         SMB_STRUCT_DIR *dp;
4724         SMB_STRUCT_STAT sbuf;
4725         SMB_STRUCT_DIRENT *de;
4726         int num_usershares = 0;
4727         int max_user_shares = Globals.iUsershareMaxShares;
4728         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4729         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4730         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4731         int iService;
4732         int snum_template = -1;
4733         const char *usersharepath = Globals.szUsersharePath;
4734         int ret = lp_numservices();
4735
4736         if (max_user_shares == 0 || *usersharepath == '\0') {
4737                 return lp_numservices();
4738         }
4739
4740         if (sys_stat(usersharepath, &sbuf) != 0) {
4741                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4742                         usersharepath, strerror(errno) ));
4743                 return ret;
4744         }
4745
4746         /*
4747          * This directory must be owned by root, and have the 't' bit set.
4748          * It also must not be writable by "other".
4749          */
4750
4751 #ifdef S_ISVTX
4752         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4753 #else
4754         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4755 #endif
4756                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4757                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
4758                         usersharepath ));
4759                 return ret;
4760         }
4761
4762         /* Ensure the template share exists if it's set. */
4763         if (Globals.szUsershareTemplateShare[0]) {
4764                 /* We can't use lp_servicenumber here as we are recommending that
4765                    template shares have -valid=False set. */
4766                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4767                         if (ServicePtrs[snum_template]->szService &&
4768                                         strequal(ServicePtrs[snum_template]->szService,
4769                                                 Globals.szUsershareTemplateShare)) {
4770                                 break;
4771                         }
4772                 }
4773
4774                 if (snum_template == -1) {
4775                         DEBUG(0,("load_usershare_shares: usershare template share %s "
4776                                 "does not exist.\n",
4777                                 Globals.szUsershareTemplateShare ));
4778                         return ret;
4779                 }
4780         }
4781
4782         /* Mark all existing usershares as pending delete. */
4783         for (iService = iNumServices - 1; iService >= 0; iService--) {
4784                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4785                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4786                 }
4787         }
4788
4789         dp = sys_opendir(usersharepath);
4790         if (!dp) {
4791                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4792                         usersharepath, strerror(errno) ));
4793                 return ret;
4794         }
4795
4796         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4797                         (de = sys_readdir(dp));
4798                         num_dir_entries++ ) {
4799                 int r;
4800                 const char *n = de->d_name;
4801
4802                 /* Ignore . and .. */
4803                 if (*n == '.') {
4804                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4805                                 continue;
4806                         }
4807                 }
4808
4809                 if (n[0] == ':') {
4810                         /* Temporary file used when creating a share. */
4811                         num_tmp_dir_entries++;
4812                 }
4813
4814                 /* Allow 20% tmp entries. */
4815                 if (num_tmp_dir_entries > allowed_tmp_entries) {
4816                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4817                                 "in directory %s\n",
4818                                 num_tmp_dir_entries, usersharepath));
4819                         break;
4820                 }
4821
4822                 r = process_usershare_file(usersharepath, n, snum_template);
4823                 if (r == 0) {
4824                         /* Update the services count. */
4825                         num_usershares++;
4826                         if (num_usershares >= max_user_shares) {
4827                                 DEBUG(0,("load_usershare_shares: max user shares reached "
4828                                         "on file %s in directory %s\n",
4829                                         n, usersharepath ));
4830                                 break;
4831                         }
4832                 } else if (r == -1) {
4833                         num_bad_dir_entries++;
4834                 }
4835
4836                 /* Allow 20% bad entries. */
4837                 if (num_bad_dir_entries > allowed_bad_entries) {
4838                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4839                                 "in directory %s\n",
4840                                 num_bad_dir_entries, usersharepath));
4841                         break;
4842                 }
4843
4844                 /* Allow 20% bad entries. */
4845                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4846                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4847                         "in directory %s\n",
4848                         num_dir_entries, usersharepath));
4849                         break;
4850                 }
4851         }
4852
4853         sys_closedir(dp);
4854
4855         /* Sweep through and delete any non-refreshed usershares that are
4856            not currently in use. */
4857         for (iService = iNumServices - 1; iService >= 0; iService--) {
4858                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4859                         if (conn_snum_used(iService)) {
4860                                 continue;
4861                         }
4862                         /* Remove from the share ACL db. */
4863                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4864                                 lp_servicename(iService) ));
4865                         delete_share_security(iService);
4866                         free_service_byindex(iService);
4867                 }
4868         }
4869
4870         return lp_numservices();
4871 }
4872
4873 /********************************************************
4874  Destroy global resources allocated in this file
4875 ********************************************************/
4876
4877 void gfree_loadparm(void)
4878 {
4879         struct file_lists *f;
4880         struct file_lists *next;
4881         int i;
4882
4883         lp_TALLOC_FREE();
4884
4885         /* Free the file lists */
4886
4887         f = file_lists;
4888         while( f ) {
4889                 next = f->next;
4890                 SAFE_FREE( f->name );
4891                 SAFE_FREE( f->subfname );
4892                 SAFE_FREE( f );
4893                 f = next;
4894         }
4895
4896         /* Free resources allocated to services */
4897
4898         for ( i = 0; i < iNumServices; i++ ) {
4899                 if ( VALID(i) ) {
4900                         free_service_byindex(i);
4901                 }
4902         }
4903
4904         SAFE_FREE( ServicePtrs );
4905         iNumServices = 0;
4906
4907         /* Now release all resources allocated to global
4908            parameters and the default service */
4909
4910         for (i = 0; parm_table[i].label; i++) 
4911         {
4912                 if ( parm_table[i].type == P_STRING 
4913                         || parm_table[i].type == P_USTRING ) 
4914                 {
4915                         string_free( (char**)parm_table[i].ptr );
4916                 }
4917                 else if (parm_table[i].type == P_LIST) {
4918                         str_list_free( (char***)parm_table[i].ptr );
4919                 }
4920         }
4921 }
4922
4923 /***************************************************************************
4924  Load the services array from the services file. Return True on success, 
4925  False on failure.
4926 ***************************************************************************/
4927
4928 BOOL lp_load(const char *pszFname,
4929              BOOL global_only,
4930              BOOL save_defaults,
4931              BOOL add_ipc,
4932              BOOL initialize_globals)
4933 {
4934         pstring n2;
4935         BOOL bRetval;
4936         param_opt_struct *data, *pdata;
4937
4938         pstrcpy(n2, pszFname);
4939         
4940         standard_sub_basic( get_current_username(), n2,sizeof(n2) );
4941
4942         add_to_file_list(pszFname, n2);
4943
4944         bRetval = False;
4945
4946         DEBUG(3, ("lp_load: refreshing parameters\n"));
4947         
4948         bInGlobalSection = True;
4949         bGlobalOnly = global_only;
4950
4951         init_globals(! initialize_globals);
4952         debug_init();
4953
4954         if (save_defaults) {
4955                 init_locals();
4956                 lp_save_defaults();
4957         }
4958
4959         if (Globals.param_opt != NULL) {
4960                 data = Globals.param_opt;
4961                 while (data) {
4962                         string_free(&data->key);
4963                         string_free(&data->value);
4964                         str_list_free(&data->list);
4965                         pdata = data->next;
4966                         SAFE_FREE(data);
4967                         data = pdata;
4968                 }
4969                 Globals.param_opt = NULL;
4970         }
4971         
4972         /* We get sections first, so have to start 'behind' to make up */
4973         iServiceIndex = -1;
4974         bRetval = pm_process(n2, do_section, do_parameter);
4975
4976         /* finish up the last section */
4977         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4978         if (bRetval)
4979                 if (iServiceIndex >= 0)
4980                         bRetval = service_ok(iServiceIndex);
4981
4982         lp_add_auto_services(lp_auto_services());
4983
4984         if (add_ipc) {
4985                 /* When 'restrict anonymous = 2' guest connections to ipc$
4986                    are denied */
4987                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4988                 if ( lp_enable_asu_support() )
4989                         lp_add_ipc("ADMIN$", False);
4990         }
4991
4992         set_server_role();
4993         set_default_server_announce_type();
4994         set_allowed_client_auth();
4995
4996         bLoaded = True;
4997
4998         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
4999         /* if bWINSsupport is true and we are in the client            */
5000         if (in_client && Globals.bWINSsupport) {
5001                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5002         }
5003
5004         init_iconv();
5005
5006         return (bRetval);
5007 }
5008
5009 /***************************************************************************
5010  Reset the max number of services.
5011 ***************************************************************************/
5012
5013 void lp_resetnumservices(void)
5014 {
5015         iNumServices = 0;
5016 }
5017
5018 /***************************************************************************
5019  Return the max number of services.
5020 ***************************************************************************/
5021
5022 int lp_numservices(void)
5023 {
5024         return (iNumServices);
5025 }
5026
5027 /***************************************************************************
5028 Display the contents of the services array in human-readable form.
5029 ***************************************************************************/
5030
5031 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
5032 {
5033         int iService;
5034
5035         if (show_defaults)
5036                 defaults_saved = False;
5037
5038         dump_globals(f);
5039
5040         dump_a_service(&sDefault, f);
5041
5042         for (iService = 0; iService < maxtoprint; iService++) {
5043                 fprintf(f,"\n");
5044                 lp_dump_one(f, show_defaults, iService);
5045         }
5046 }
5047
5048 /***************************************************************************
5049 Display the contents of one service in human-readable form.
5050 ***************************************************************************/
5051
5052 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
5053 {
5054         if (VALID(snum)) {
5055                 if (ServicePtrs[snum]->szService[0] == '\0')
5056                         return;
5057                 dump_a_service(ServicePtrs[snum], f);
5058         }
5059 }
5060
5061 /***************************************************************************
5062 Return the number of the service with the given name, or -1 if it doesn't
5063 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5064 getservicebyname()! This works ONLY if all services have been loaded, and
5065 does not copy the found service.
5066 ***************************************************************************/
5067
5068 int lp_servicenumber(const char *pszServiceName)
5069 {
5070         int iService;
5071         fstring serviceName;
5072         
5073         if (!pszServiceName) {
5074                 return GLOBAL_SECTION_SNUM;
5075         }
5076         
5077         for (iService = iNumServices - 1; iService >= 0; iService--) {
5078                 if (VALID(iService) && ServicePtrs[iService]->szService) {
5079                         /*
5080                          * The substitution here is used to support %U is
5081                          * service names
5082                          */
5083                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
5084                         standard_sub_basic(get_current_username(), serviceName,sizeof(serviceName));
5085                         if (strequal(serviceName, pszServiceName)) {
5086                                 break;
5087                         }
5088                 }
5089         }
5090
5091         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5092                 time_t last_mod;
5093
5094                 if (!usershare_exists(iService, &last_mod)) {
5095                         /* Remove the share security tdb entry for it. */
5096                         delete_share_security(iService);
5097                         /* Remove it from the array. */
5098                         free_service_byindex(iService);
5099                         /* Doesn't exist anymore. */
5100                         return GLOBAL_SECTION_SNUM;
5101                 }
5102
5103                 /* Has it been modified ? If so delete and reload. */
5104                 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5105                         /* Remove it from the array. */
5106                         free_service_byindex(iService);
5107                         /* and now reload it. */
5108                         iService = load_usershare_service(pszServiceName);
5109                 }
5110         }
5111
5112         if (iService < 0) {
5113                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5114                 return GLOBAL_SECTION_SNUM;
5115         }
5116
5117         return (iService);
5118 }
5119
5120 /*******************************************************************
5121  A useful volume label function. 
5122 ********************************************************************/
5123
5124 char *volume_label(int snum)
5125 {
5126         char *ret = lp_volume(snum);
5127         if (!*ret)
5128                 return lp_servicename(snum);
5129         return (ret);
5130 }
5131
5132
5133 /*******************************************************************
5134  Set the server type we will announce as via nmbd.
5135 ********************************************************************/
5136
5137 static void set_default_server_announce_type(void)
5138 {
5139         default_server_announce = 0;
5140         default_server_announce |= SV_TYPE_WORKSTATION;
5141         default_server_announce |= SV_TYPE_SERVER;
5142         default_server_announce |= SV_TYPE_SERVER_UNIX;
5143
5144         /* note that the flag should be set only if we have a 
5145            printer service but nmbd doesn't actually load the 
5146            services so we can't tell   --jerry */
5147
5148         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5149
5150         switch (lp_announce_as()) {
5151                 case ANNOUNCE_AS_NT_SERVER:
5152                         default_server_announce |= SV_TYPE_SERVER_NT;
5153                         /* fall through... */
5154                 case ANNOUNCE_AS_NT_WORKSTATION:
5155                         default_server_announce |= SV_TYPE_NT;
5156                         break;
5157                 case ANNOUNCE_AS_WIN95:
5158                         default_server_announce |= SV_TYPE_WIN95_PLUS;
5159                         break;
5160                 case ANNOUNCE_AS_WFW:
5161                         default_server_announce |= SV_TYPE_WFW;
5162                         break;
5163                 default:
5164                         break;
5165         }
5166
5167         switch (lp_server_role()) {
5168                 case ROLE_DOMAIN_MEMBER:
5169                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5170                         break;
5171                 case ROLE_DOMAIN_PDC:
5172                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5173                         break;
5174                 case ROLE_DOMAIN_BDC:
5175                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5176                         break;
5177                 case ROLE_STANDALONE:
5178                 default:
5179                         break;
5180         }
5181         if (lp_time_server())
5182                 default_server_announce |= SV_TYPE_TIME_SOURCE;
5183
5184         if (lp_host_msdfs())
5185                 default_server_announce |= SV_TYPE_DFS_SERVER;
5186 }
5187
5188 /***********************************************************
5189  returns role of Samba server
5190 ************************************************************/
5191
5192 int lp_server_role(void)
5193 {
5194         return server_role;
5195 }
5196
5197 /***********************************************************
5198  If we are PDC then prefer us as DMB
5199 ************************************************************/
5200
5201 BOOL lp_domain_master(void)
5202 {
5203         if (Globals.bDomainMaster == Auto)
5204                 return (lp_server_role() == ROLE_DOMAIN_PDC);
5205
5206         return Globals.bDomainMaster;
5207 }
5208
5209 /***********************************************************
5210  If we are DMB then prefer us as LMB
5211 ************************************************************/
5212
5213 BOOL lp_preferred_master(void)
5214 {
5215         if (Globals.bPreferredMaster == Auto)
5216                 return (lp_local_master() && lp_domain_master());
5217
5218         return Globals.bPreferredMaster;
5219 }
5220
5221 /*******************************************************************
5222  Remove a service.
5223 ********************************************************************/
5224
5225 void lp_remove_service(int snum)
5226 {
5227         ServicePtrs[snum]->valid = False;
5228         invalid_services[num_invalid_services++] = snum;
5229 }
5230
5231 /*******************************************************************
5232  Copy a service.
5233 ********************************************************************/
5234
5235 void lp_copy_service(int snum, const char *new_name)
5236 {
5237         do_section(new_name);
5238         if (snum >= 0) {
5239                 snum = lp_servicenumber(new_name);
5240                 if (snum >= 0)
5241                         lp_do_parameter(snum, "copy", lp_servicename(snum));
5242         }
5243 }
5244
5245
5246 /*******************************************************************
5247  Get the default server type we will announce as via nmbd.
5248 ********************************************************************/
5249
5250 int lp_default_server_announce(void)
5251 {
5252         return default_server_announce;
5253 }
5254
5255 /*******************************************************************
5256  Split the announce version into major and minor numbers.
5257 ********************************************************************/
5258
5259 int lp_major_announce_version(void)
5260 {
5261         static BOOL got_major = False;
5262         static int major_version = DEFAULT_MAJOR_VERSION;
5263         char *vers;
5264         char *p;
5265
5266         if (got_major)
5267                 return major_version;
5268
5269         got_major = True;
5270         if ((vers = lp_announce_version()) == NULL)
5271                 return major_version;
5272
5273         if ((p = strchr_m(vers, '.')) == 0)
5274                 return major_version;
5275
5276         *p = '\0';
5277         major_version = atoi(vers);
5278         return major_version;
5279 }
5280
5281 int lp_minor_announce_version(void)
5282 {
5283         static BOOL got_minor = False;
5284         static int minor_version = DEFAULT_MINOR_VERSION;
5285         char *vers;
5286         char *p;
5287
5288         if (got_minor)
5289                 return minor_version;
5290
5291         got_minor = True;
5292         if ((vers = lp_announce_version()) == NULL)
5293                 return minor_version;
5294
5295         if ((p = strchr_m(vers, '.')) == 0)
5296                 return minor_version;
5297
5298         p++;
5299         minor_version = atoi(p);
5300         return minor_version;
5301 }
5302
5303 /***********************************************************
5304  Set the global name resolution order (used in smbclient).
5305 ************************************************************/
5306
5307 void lp_set_name_resolve_order(const char *new_order)
5308 {
5309         string_set(&Globals.szNameResolveOrder, new_order);
5310 }
5311
5312 const char *lp_printername(int snum)
5313 {
5314         const char *ret = _lp_printername(snum);
5315         if (ret == NULL || (ret != NULL && *ret == '\0'))
5316                 ret = lp_const_servicename(snum);
5317
5318         return ret;
5319 }
5320
5321
5322 /***********************************************************
5323  Allow daemons such as winbindd to fix their logfile name.
5324 ************************************************************/
5325
5326 void lp_set_logfile(const char *name)
5327 {
5328         string_set(&Globals.szLogFile, name);
5329         pstrcpy(debugf, name);
5330 }
5331
5332 /*******************************************************************
5333  Return the max print jobs per queue.
5334 ********************************************************************/
5335
5336 int lp_maxprintjobs(int snum)
5337 {
5338         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5339         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5340                 maxjobs = PRINT_MAX_JOBID - 1;
5341
5342         return maxjobs;
5343 }
5344
5345 const char *lp_printcapname(void)
5346 {
5347         if ((Globals.szPrintcapname != NULL) &&
5348             (Globals.szPrintcapname[0] != '\0'))
5349                 return Globals.szPrintcapname;
5350
5351         if (sDefault.iPrinting == PRINT_CUPS) {
5352 #ifdef HAVE_CUPS
5353                 return "cups";
5354 #else
5355                 return "lpstat";
5356 #endif
5357         }
5358
5359         if (sDefault.iPrinting == PRINT_BSD)
5360                 return "/etc/printcap";
5361
5362         return PRINTCAP_NAME;
5363 }
5364
5365 /*******************************************************************
5366  Ensure we don't use sendfile if server smb signing is active.
5367 ********************************************************************/
5368
5369 static uint32 spoolss_state;
5370
5371 BOOL lp_disable_spoolss( void )
5372 {
5373         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5374                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5375
5376         return spoolss_state == SVCCTL_STOPPED ? True : False;
5377 }
5378
5379 void lp_set_spoolss_state( uint32 state )
5380 {
5381         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5382
5383         spoolss_state = state;
5384 }
5385
5386 uint32 lp_get_spoolss_state( void )
5387 {
5388         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5389 }
5390
5391 /*******************************************************************
5392  Ensure we don't use sendfile if server smb signing is active.
5393 ********************************************************************/
5394
5395 BOOL lp_use_sendfile(int snum)
5396 {
5397         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5398         if (Protocol < PROTOCOL_NT1) {
5399                 return False;
5400         }
5401         return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5402 }
5403
5404 /*******************************************************************
5405  Turn off sendfile if we find the underlying OS doesn't support it.
5406 ********************************************************************/
5407
5408 void set_use_sendfile(int snum, BOOL val)
5409 {
5410         if (LP_SNUM_OK(snum))
5411                 ServicePtrs[snum]->bUseSendfile = val;
5412         else
5413                 sDefault.bUseSendfile = val;
5414 }
5415
5416 /*******************************************************************
5417  Turn off storing DOS attributes if this share doesn't support it.
5418 ********************************************************************/
5419
5420 void set_store_dos_attributes(int snum, BOOL val)
5421 {
5422         if (!LP_SNUM_OK(snum))
5423                 return;
5424         ServicePtrs[(snum)]->bStoreDosAttributes = val;
5425 }
5426
5427 void lp_set_mangling_method(const char *new_method)
5428 {
5429         string_set(&Globals.szManglingMethod, new_method);
5430 }
5431
5432 /*******************************************************************
5433  Global state for POSIX pathname processing.
5434 ********************************************************************/
5435
5436 static BOOL posix_pathnames;
5437
5438 BOOL lp_posix_pathnames(void)
5439 {
5440         return posix_pathnames;
5441 }
5442
5443 /*******************************************************************
5444  Change everything needed to ensure POSIX pathname processing (currently
5445  not much).
5446 ********************************************************************/
5447
5448 void lp_set_posix_pathnames(void)
5449 {
5450         posix_pathnames = True;
5451 }
5452
5453 /*******************************************************************
5454  Global state for POSIX lock processing - CIFS unix extensions.
5455 ********************************************************************/
5456
5457 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5458
5459 enum brl_flavour lp_posix_cifsu_locktype(void)
5460 {
5461         return posix_cifsx_locktype;
5462 }
5463
5464 /*******************************************************************
5465 ********************************************************************/
5466
5467 void lp_set_posix_cifsx_locktype(enum brl_flavour val)
5468 {
5469         posix_cifsx_locktype = val;
5470 }