Merge from Subversion r50.
[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) Anthony Liguori 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 userdom_struct current_user_info;
60 extern pstring user_socket_options;
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[(i)]->valid)
76 #define VALID(i) ServicePtrs[i]->valid
77
78 int keepalive = DEFAULT_KEEPALIVE;
79 BOOL use_getwd_cache = True;
80
81 extern int extra_time_offset;
82
83 static BOOL defaults_saved = False;
84
85 typedef struct _param_opt_struct param_opt_struct;
86 struct _param_opt_struct {
87         param_opt_struct *prev, *next;
88         char *key;
89         char *value;
90 };
91
92 /* 
93  * This structure describes global (ie., server-wide) parameters.
94  */
95 typedef struct
96 {
97         char *smb_ports;
98         char *dos_charset;
99         char *unix_charset;
100         char *display_charset;
101         char *szPrintcapname;
102         char *szEnumPortsCommand;
103         char *szAddPrinterCommand;
104         char *szDeletePrinterCommand;
105         char *szOs2DriverMap;
106         char *szLockDir;
107         char *szPidDir;
108         char *szRootdir;
109         char *szDefaultService;
110         char *szDfree;
111         char *szMsgCommand;
112         char *szHostsEquiv;
113         char *szServerString;
114         char *szAutoServices;
115         char *szPasswdProgram;
116         char *szPasswdChat;
117         char *szLogFile;
118         char *szConfigFile;
119         char *szSMBPasswdFile;
120         char *szPrivateDir;
121         char **szPassdbBackend;
122         char **szSamBackend;
123         char **szPreloadModules;
124         char *szPasswordServer;
125         char *szSocketOptions;
126         char *szRealm;
127         char *szADSserver;
128         char *szUsernameMap;
129         char *szLogonScript;
130         char *szLogonPath;
131         char *szLogonDrive;
132         char *szLogonHome;
133         char **szWINSservers;
134         char **szInterfaces;
135         char *szRemoteAnnounce;
136         char *szRemoteBrowseSync;
137         char *szSocketAddress;
138         char *szNISHomeMapName;
139         char *szAnnounceVersion;        /* This is initialised in init_globals */
140         char *szWorkgroup;
141         char *szNetbiosName;
142         char **szNetbiosAliases;
143         char *szNetbiosScope;
144         char *szDomainOtherSIDs;
145         char *szNameResolveOrder;
146         char *szPanicAction;
147         char *szAddUserScript;
148         char *szDelUserScript;
149         char *szAddGroupScript;
150         char *szDelGroupScript;
151         char *szAddUserToGroupScript;
152         char *szDelUserFromGroupScript;
153         char *szSetPrimaryGroupScript;
154         char *szAddMachineScript;
155         char *szShutdownScript;
156         char *szAbortShutdownScript;
157         char *szWINSHook;
158         char *szWINSPartners;
159 #ifdef WITH_UTMP
160         char *szUtmpDir;
161         char *szWtmpDir;
162         BOOL bUtmp;
163 #endif
164         char *szSourceEnv;
165         char *szIdmapUID;
166         char *szIdmapGID;
167         char *szNonUnixAccountRange;
168         int AlgorithmicRidBase;
169         char *szTemplateHomedir;
170         char *szTemplateShell;
171         char *szWinbindSeparator;
172         BOOL bWinbindEnumUsers;
173         BOOL bWinbindEnumGroups;
174         BOOL bWinbindUseDefaultDomain;
175         char *szWinbindBackend;
176         char *szIdmapBackend;
177         char *szAddShareCommand;
178         char *szChangeShareCommand;
179         char *szDeleteShareCommand;
180         char *szGuestaccount;
181         char *szManglingMethod;
182         int mangle_prefix;
183         int max_log_size;
184         char *szLogLevel;
185         int mangled_stack;
186         int max_xmit;
187         int max_mux;
188         int max_open_files;
189         int pwordlevel;
190         int unamelevel;
191         int deadtime;
192         int maxprotocol;
193         int minprotocol;
194         int security;
195         char **AuthMethods;
196         BOOL paranoid_server_security;
197         int maxdisksize;
198         int lpqcachetime;
199         int iMaxSmbdProcesses;
200         BOOL bDisableSpoolss;
201         int iTotalPrintJobs;
202         int syslog;
203         int os_level;
204         int enhanced_browsing;
205         int max_ttl;
206         int max_wins_ttl;
207         int min_wins_ttl;
208         int ReadSize;
209         int lm_announce;
210         int lm_interval;
211         int announce_as;        /* This is initialised in init_globals */
212         int machine_password_timeout;
213         int change_notify_timeout;
214         int stat_cache_size;
215         int map_to_guest;
216         int min_passwd_length;
217         int oplock_break_wait_time;
218         int winbind_cache_time;
219         int iLockSpinCount;
220         int iLockSpinTime;
221         char *szLdapMachineSuffix;
222         char *szLdapUserSuffix;
223 #ifdef WITH_LDAP_SAMCONFIG
224         int ldap_port;
225         char *szLdapServer;
226 #endif
227         int ldap_ssl;
228         char *szLdapSuffix;
229         char *szLdapFilter;
230         char *szLdapAdminDn;
231         BOOL ldap_trust_ids;
232         char *szAclCompat;
233         int ldap_passwd_sync; 
234         BOOL ldap_delete_dn;
235         BOOL bMsAddPrinterWizard;
236         BOOL bDNSproxy;
237         BOOL bWINSsupport;
238         BOOL bWINSproxy;
239         BOOL bLocalMaster;
240         BOOL bPreferredMaster;
241         BOOL bDomainMaster;
242         BOOL bDomainLogons;
243         BOOL bEncryptPasswords;
244         BOOL bUpdateEncrypt;
245         BOOL bStripDot;
246         BOOL bNullPasswords;
247         BOOL bObeyPamRestrictions;
248         BOOL bLoadPrinters;
249         BOOL bLargeReadwrite;
250         BOOL bReadRaw;
251         BOOL bWriteRaw;
252         BOOL bReadPrediction;
253         BOOL bReadbmpx;
254         BOOL bSyslogOnly;
255         BOOL bBrowseList;
256         BOOL bNISHomeMap;
257         BOOL bTimeServer;
258         BOOL bBindInterfacesOnly;
259         BOOL bPamPasswordChange;
260         BOOL bUnixPasswdSync;
261         BOOL bPasswdChatDebug;
262         BOOL bTimestampLogs;
263         BOOL bNTSmbSupport;
264         BOOL bNTPipeSupport;
265         BOOL bNTStatusSupport;
266         BOOL bStatCache;
267         BOOL bKernelOplocks;
268         BOOL bAllowTrustedDomains;
269         BOOL bLanmanAuth;
270         BOOL bNTLMAuth;
271         BOOL bUseSpnego;
272         BOOL bClientLanManAuth;
273         BOOL bClientNTLMv2Auth;
274         BOOL bClientUseSpnego;
275         BOOL bDebugHiresTimestamp;
276         BOOL bDebugPid;
277         BOOL bDebugUid;
278         BOOL bHostMSDfs;
279         BOOL bHideLocalUsers;
280         BOOL bUnicode;
281         BOOL bUseMmap;
282         BOOL bHostnameLookups;
283         BOOL bUnixExtensions;
284         BOOL bDisableNetbios;
285         BOOL bKernelChangeNotify;
286         int restrict_anonymous;
287         int name_cache_timeout;
288         BOOL client_signing;
289         param_opt_struct *param_opt;
290 }
291 global;
292
293 static global Globals;
294
295 /* 
296  * This structure describes a single service. 
297  */
298 typedef struct
299 {
300         BOOL valid;
301         BOOL autoloaded;
302         char *szService;
303         char *szPath;
304         char *szUsername;
305         char **szInvalidUsers;
306         char **szValidUsers;
307         char **szAdminUsers;
308         char *szCopy;
309         char *szInclude;
310         char *szPreExec;
311         char *szPostExec;
312         char *szRootPreExec;
313         char *szRootPostExec;
314         char *szPrintcommand;
315         char *szLpqcommand;
316         char *szLprmcommand;
317         char *szLppausecommand;
318         char *szLpresumecommand;
319         char *szQueuepausecommand;
320         char *szQueueresumecommand;
321         char *szPrintername;
322         char *szDontdescend;
323         char **szHostsallow;
324         char **szHostsdeny;
325         char *szMagicScript;
326         char *szMagicOutput;
327         char *szMangledMap;
328         char *szVetoFiles;
329         char *szHideFiles;
330         char *szVetoOplockFiles;
331         char *comment;
332         char *force_user;
333         char *force_group;
334         char **readlist;
335         char **writelist;
336         char **printer_admin;
337         char *volume;
338         char *fstype;
339         char *szVfsObjectFile;
340         char *szVfsOptions;
341         char *szVfsPath;
342         char *szMSDfsProxy;
343         int iMinPrintSpace;
344         int iMaxPrintJobs;
345         int iMaxReportedPrintJobs;
346         int iWriteCacheSize;
347         int iCreate_mask;
348         int iCreate_force_mode;
349         int iSecurity_mask;
350         int iSecurity_force_mode;
351         int iDir_mask;
352         int iDir_force_mode;
353         int iDir_Security_mask;
354         int iDir_Security_force_mode;
355         int iMaxConnections;
356         int iDefaultCase;
357         int iPrinting;
358         int iOplockContentionLimit;
359         int iCSCPolicy;
360         int iBlock_size;
361         BOOL bPreexecClose;
362         BOOL bRootpreexecClose;
363         BOOL bCaseSensitive;
364         BOOL bCasePreserve;
365         BOOL bShortCasePreserve;
366         BOOL bCaseMangle;
367         BOOL bHideDotFiles;
368         BOOL bHideSpecialFiles;
369         BOOL bHideUnReadable;
370         BOOL bHideUnWriteableFiles;
371         BOOL bBrowseable;
372         BOOL bAvailable;
373         BOOL bRead_only;
374         BOOL bNo_set_dir;
375         BOOL bGuest_only;
376         BOOL bGuest_ok;
377         BOOL bPrint_ok;
378         BOOL bMap_system;
379         BOOL bMap_hidden;
380         BOOL bMap_archive;
381         BOOL bLocking;
382         BOOL bStrictLocking;
383         BOOL bPosixLocking;
384         BOOL bShareModes;
385         BOOL bOpLocks;
386         BOOL bLevel2OpLocks;
387         BOOL bOnlyUser;
388         BOOL bMangledNames;
389         BOOL bWidelinks;
390         BOOL bSymlinks;
391         BOOL bSyncAlways;
392         BOOL bStrictAllocate;
393         BOOL bStrictSync;
394         char magic_char;
395         BOOL *copymap;
396         BOOL bDeleteReadonly;
397         BOOL bFakeOplocks;
398         BOOL bDeleteVetoFiles;
399         BOOL bDosFilemode;
400         BOOL bDosFiletimes;
401         BOOL bDosFiletimeResolution;
402         BOOL bFakeDirCreateTimes;
403         BOOL bBlockingLocks;
404         BOOL bInheritPerms;
405         BOOL bInheritACLS;
406         BOOL bMSDfsRoot;
407         BOOL bUseClientDriver;
408         BOOL bDefaultDevmode;
409         BOOL bNTAclSupport;
410         BOOL bUseSendfile;
411         BOOL bProfileAcls;
412         param_opt_struct *param_opt;
413
414         char dummy[3];          /* for alignment */
415 }
416 service;
417
418
419 /* This is a default service used to prime a services structure */
420 static service sDefault = {
421         True,                   /* valid */
422         False,                  /* not autoloaded */
423         NULL,                   /* szService */
424         NULL,                   /* szPath */
425         NULL,                   /* szUsername */
426         NULL,                   /* szInvalidUsers */
427         NULL,                   /* szValidUsers */
428         NULL,                   /* szAdminUsers */
429         NULL,                   /* szCopy */
430         NULL,                   /* szInclude */
431         NULL,                   /* szPreExec */
432         NULL,                   /* szPostExec */
433         NULL,                   /* szRootPreExec */
434         NULL,                   /* szRootPostExec */
435         NULL,                   /* szPrintcommand */
436         NULL,                   /* szLpqcommand */
437         NULL,                   /* szLprmcommand */
438         NULL,                   /* szLppausecommand */
439         NULL,                   /* szLpresumecommand */
440         NULL,                   /* szQueuepausecommand */
441         NULL,                   /* szQueueresumecommand */
442         NULL,                   /* szPrintername */
443         NULL,                   /* szDontdescend */
444         NULL,                   /* szHostsallow */
445         NULL,                   /* szHostsdeny */
446         NULL,                   /* szMagicScript */
447         NULL,                   /* szMagicOutput */
448         NULL,                   /* szMangledMap */
449         NULL,                   /* szVetoFiles */
450         NULL,                   /* szHideFiles */
451         NULL,                   /* szVetoOplockFiles */
452         NULL,                   /* comment */
453         NULL,                   /* force user */
454         NULL,                   /* force group */
455         NULL,                   /* readlist */
456         NULL,                   /* writelist */
457         NULL,                   /* printer admin */
458         NULL,                   /* volume */
459         NULL,                   /* fstype */
460         NULL,                   /* vfs object */
461         NULL,                   /* vfs options */
462         NULL,                   /* vfs path */
463         NULL,                   /* szMSDfsProxy */
464         0,                      /* iMinPrintSpace */
465         1000,                   /* iMaxPrintJobs */
466         0,                      /* iMaxReportedPrintJobs */
467         0,                      /* iWriteCacheSize */
468         0744,                   /* iCreate_mask */
469         0000,                   /* iCreate_force_mode */
470         0777,                   /* iSecurity_mask */
471         0,                      /* iSecurity_force_mode */
472         0755,                   /* iDir_mask */
473         0000,                   /* iDir_force_mode */
474         0777,                   /* iDir_Security_mask */
475         0,                      /* iDir_Security_force_mode */
476         0,                      /* iMaxConnections */
477         CASE_LOWER,             /* iDefaultCase */
478         DEFAULT_PRINTING,       /* iPrinting */
479         2,                      /* iOplockContentionLimit */
480         0,                      /* iCSCPolicy */
481         1024,           /* iBlock_size */
482         False,                  /* bPreexecClose */
483         False,                  /* bRootpreexecClose */
484         False,                  /* case sensitive */
485         True,                   /* case preserve */
486         True,                   /* short case preserve */
487         False,                  /* case mangle */
488         True,                   /* bHideDotFiles */
489         False,                  /* bHideSpecialFiles */
490         False,                  /* bHideUnReadable */
491         False,                  /* bHideUnWriteableFiles */
492         True,                   /* bBrowseable */
493         True,                   /* bAvailable */
494         True,                   /* bRead_only */
495         True,                   /* bNo_set_dir */
496         False,                  /* bGuest_only */
497         False,                  /* bGuest_ok */
498         False,                  /* bPrint_ok */
499         False,                  /* bMap_system */
500         False,                  /* bMap_hidden */
501         True,                   /* bMap_archive */
502         True,                   /* bLocking */
503         True,                   /* bStrictLocking */
504         True,                   /* bPosixLocking */
505         True,                   /* bShareModes */
506         True,                   /* bOpLocks */
507         True,                   /* bLevel2OpLocks */
508         False,                  /* bOnlyUser */
509         True,                   /* bMangledNames */
510         True,                   /* bWidelinks */
511         True,                   /* bSymlinks */
512         False,                  /* bSyncAlways */
513         False,                  /* bStrictAllocate */
514         False,                  /* bStrictSync */
515         '~',                    /* magic char */
516         NULL,                   /* copymap */
517         False,                  /* bDeleteReadonly */
518         False,                  /* bFakeOplocks */
519         False,                  /* bDeleteVetoFiles */
520         False,                  /* bDosFilemode */
521         False,                  /* bDosFiletimes */
522         False,                  /* bDosFiletimeResolution */
523         False,                  /* bFakeDirCreateTimes */
524         True,                   /* bBlockingLocks */
525         False,                  /* bInheritPerms */
526         False,                  /* bInheritACLS */
527         False,                  /* bMSDfsRoot */
528         False,                  /* bUseClientDriver */
529         False,                  /* bDefaultDevmode */
530         True,                   /* bNTAclSupport */
531         False,                  /* bUseSendfile */
532         False,                  /* bProfileAcls */
533         
534         NULL,                   /* Parametric options */
535
536         ""                      /* dummy */
537 };
538
539 /* local variables */
540 static service **ServicePtrs = NULL;
541 static int iNumServices = 0;
542 static int iServiceIndex = 0;
543 static BOOL bInGlobalSection = True;
544 static BOOL bGlobalOnly = False;
545 static int server_role;
546 static int default_server_announce;
547
548 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
549
550 /* prototypes for the special type handlers */
551 static BOOL handle_include(const char *pszParmValue, char **ptr);
552 static BOOL handle_copy(const char *pszParmValue, char **ptr);
553 static BOOL handle_source_env(const char *pszParmValue, char **ptr);
554 static BOOL handle_netbios_name(const char *pszParmValue, char **ptr);
555 static BOOL handle_idmap_uid(const char *pszParmValue, char **ptr);
556 static BOOL handle_idmap_gid(const char *pszParmValue, char **ptr);
557 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
558 static BOOL handle_debug_list( const char *pszParmValue, char **ptr );
559 static BOOL handle_workgroup( const char *pszParmValue, char **ptr );
560 static BOOL handle_netbios_aliases( const char *pszParmValue, char **ptr );
561 static BOOL handle_netbios_scope( const char *pszParmValue, char **ptr );
562
563 static BOOL handle_ldap_machine_suffix ( const char *pszParmValue, char **ptr );
564 static BOOL handle_ldap_user_suffix ( const char *pszParmValue, char **ptr );
565 static BOOL handle_ldap_suffix ( const char *pszParmValue, char **ptr );
566
567 static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr);
568
569 static void set_server_role(void);
570 static void set_default_server_announce_type(void);
571
572 static const struct enum_list enum_protocol[] = {
573         {PROTOCOL_NT1, "NT1"},
574         {PROTOCOL_LANMAN2, "LANMAN2"},
575         {PROTOCOL_LANMAN1, "LANMAN1"},
576         {PROTOCOL_CORE, "CORE"},
577         {PROTOCOL_COREPLUS, "COREPLUS"},
578         {PROTOCOL_COREPLUS, "CORE+"},
579         {-1, NULL}
580 };
581
582 static const struct enum_list enum_security[] = {
583         {SEC_SHARE, "SHARE"},
584         {SEC_USER, "USER"},
585         {SEC_SERVER, "SERVER"},
586         {SEC_DOMAIN, "DOMAIN"},
587 #ifdef HAVE_ADS
588         {SEC_ADS, "ADS"},
589 #endif
590         {-1, NULL}
591 };
592
593 static const struct enum_list enum_printing[] = {
594         {PRINT_SYSV, "sysv"},
595         {PRINT_AIX, "aix"},
596         {PRINT_HPUX, "hpux"},
597         {PRINT_BSD, "bsd"},
598         {PRINT_QNX, "qnx"},
599         {PRINT_PLP, "plp"},
600         {PRINT_LPRNG, "lprng"},
601         {PRINT_SOFTQ, "softq"},
602         {PRINT_CUPS, "cups"},
603         {PRINT_LPRNT, "nt"},
604         {PRINT_LPROS2, "os2"},
605 #ifdef DEVELOPER
606         {PRINT_TEST, "test"},
607         {PRINT_VLP, "vlp"},
608 #endif /* DEVELOPER */
609         {-1, NULL}
610 };
611
612 static const struct enum_list enum_ldap_ssl[] = {
613 #ifdef WITH_LDAP_SAMCONFIG
614         {LDAP_SSL_ON, "Yes"},
615         {LDAP_SSL_ON, "yes"},
616         {LDAP_SSL_ON, "on"},
617         {LDAP_SSL_ON, "On"},
618 #endif
619         {LDAP_SSL_OFF, "no"},
620         {LDAP_SSL_OFF, "No"},
621         {LDAP_SSL_OFF, "off"},
622         {LDAP_SSL_OFF, "Off"},
623         {LDAP_SSL_START_TLS, "start tls"},
624         {LDAP_SSL_START_TLS, "Start_tls"},
625         {-1, NULL}
626 };
627
628 static const struct enum_list enum_ldap_passwd_sync[] = {
629         {LDAP_PASSWD_SYNC_ON, "Yes"},
630         {LDAP_PASSWD_SYNC_ON, "yes"},
631         {LDAP_PASSWD_SYNC_ON, "on"},
632         {LDAP_PASSWD_SYNC_ON, "On"},
633         {LDAP_PASSWD_SYNC_OFF, "no"},
634         {LDAP_PASSWD_SYNC_OFF, "No"},
635         {LDAP_PASSWD_SYNC_OFF, "off"},
636         {LDAP_PASSWD_SYNC_OFF, "Off"},
637 #ifdef LDAP_EXOP_X_MODIFY_PASSWD        
638         {LDAP_PASSWD_SYNC_ONLY, "Only"},
639         {LDAP_PASSWD_SYNC_ONLY, "only"},
640 #endif /* LDAP_EXOP_X_MODIFY_PASSWD */  
641         {-1, NULL}
642 };
643
644 /* Types of machine we can announce as. */
645 #define ANNOUNCE_AS_NT_SERVER 1
646 #define ANNOUNCE_AS_WIN95 2
647 #define ANNOUNCE_AS_WFW 3
648 #define ANNOUNCE_AS_NT_WORKSTATION 4
649
650 static const struct enum_list enum_announce_as[] = {
651         {ANNOUNCE_AS_NT_SERVER, "NT"},
652         {ANNOUNCE_AS_NT_SERVER, "NT Server"},
653         {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
654         {ANNOUNCE_AS_WIN95, "win95"},
655         {ANNOUNCE_AS_WFW, "WfW"},
656         {-1, NULL}
657 };
658
659 static const struct enum_list enum_case[] = {
660         {CASE_LOWER, "lower"},
661         {CASE_UPPER, "upper"},
662         {-1, NULL}
663 };
664
665 static const struct enum_list enum_bool_auto[] = {
666         {False, "No"},
667         {False, "False"},
668         {False, "0"},
669         {True, "Yes"},
670         {True, "True"},
671         {True, "1"},
672         {Auto, "Auto"},
673         {-1, NULL}
674 };
675
676 /* Client-side offline caching policy types */
677 #define CSC_POLICY_MANUAL 0
678 #define CSC_POLICY_DOCUMENTS 1
679 #define CSC_POLICY_PROGRAMS 2
680 #define CSC_POLICY_DISABLE 3
681
682 static const struct enum_list enum_csc_policy[] = {
683         {CSC_POLICY_MANUAL, "manual"},
684         {CSC_POLICY_DOCUMENTS, "documents"},
685         {CSC_POLICY_PROGRAMS, "programs"},
686         {CSC_POLICY_DISABLE, "disable"},
687         {-1, NULL}
688 };
689
690 /* 
691    Do you want session setups at user level security with a invalid
692    password to be rejected or allowed in as guest? WinNT rejects them
693    but it can be a pain as it means "net view" needs to use a password
694
695    You have 3 choices in the setting of map_to_guest:
696
697    "Never" means session setups with an invalid password
698    are rejected. This is the default.
699
700    "Bad User" means session setups with an invalid password
701    are rejected, unless the username does not exist, in which case it
702    is treated as a guest login
703
704    "Bad Password" means session setups with an invalid password
705    are treated as a guest login
706
707    Note that map_to_guest only has an effect in user or server
708    level security.
709 */
710
711 static const struct enum_list enum_map_to_guest[] = {
712         {NEVER_MAP_TO_GUEST, "Never"},
713         {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
714         {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
715         {-1, NULL}
716 };
717
718 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
719  *
720  * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
721  * is implied in current control logic. This may change at some later time. A
722  * flag value of 0 means - show as development option only.
723  *
724  * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
725  * screen in SWAT. This is used to exclude parameters as well as to squash all
726  * parameters that have been duplicated by pseudonyms.
727  */
728 static struct parm_struct parm_table[] = {
729         {"Base Options", P_SEP, P_SEPARATOR},
730
731         {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
732         {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
733         {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
734         {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
735         {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
736         {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
737         {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
738         {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
739         {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
740         {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
741         {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
742         {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743         {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED  | FLAG_DEVELOPER},
744         {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
745         {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
746
747         {"Security Options", P_SEP, P_SEPARATOR},
748         
749         {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
750         {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
751         {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
752         {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
753         {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
754         {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
755         {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
756         {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
757         {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758         {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED | FLAG_DEVELOPER},
759         {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
760         {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
761         {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
762         {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
763         {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
764         {"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765         {"sam backend", P_LIST, P_GLOBAL, &Globals.szSamBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766         {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767         {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768         {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769         {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770         {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
771         {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
772         
773         {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
774         {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
775         {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
776         {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
777         {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_DEVELOPER},
778         {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
779         {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
780         {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
781         {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
782         {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
783         {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
784         {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
785         {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
786         
787         {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
788         {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
789         {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
790         
791         {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
792         {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
793         {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
794         {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
795         {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
796         {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_GLOBAL | FLAG_PRINT},
797         {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE},
798         {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE},
799         {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
800         
801         {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
802         {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
803         {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
804         {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
805         
806         {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
807         {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
808         {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
809         {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
810         {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
811         {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
812         {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
813         {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
814         {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
815         {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
816         {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
817         {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_SHARE},
818         {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
819         {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
820
821         {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
822         {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
823         
824         {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
825         {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
826         {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
827         {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
828         {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
829         {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
830
831         {"Logging Options", P_SEP, P_SEPARATOR},
832
833         {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
834         {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
835         {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
836         {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
837         {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
838         
839         {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
840         {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
841         {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_DEVELOPER},
842         {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_DEVELOPER},
843         {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_DEVELOPER},
844         {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_DEVELOPER},
845         
846         {"Protocol Options", P_SEP, P_SEPARATOR},
847         
848         {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
849         {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED | FLAG_DEVELOPER},
850         {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
851         {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
852         {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
853         {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
854         {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_DEVELOPER},
855         {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
856         {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
857         {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
858         
859         {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, handle_acl_compatibility, NULL, FLAG_SHARE | FLAG_GLOBAL | FLAG_ADVANCED},
860         {"nt acl support", P_BOOL,  P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_ADVANCED | FLAG_WIZARD},
861         {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
862         {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
863         {"profile acls", P_BOOL,  P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE  | FLAG_ADVANCED | FLAG_WIZARD},
864         
865         {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
866         {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
867         {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
868         {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
869         
870         {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
871         {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, 
872         {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
873         {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
874         {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
875         {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
876         {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
877         {"client signing", P_BOOL, P_GLOBAL, &Globals.client_signing, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
878         {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_DEVELOPER},
879
880         {"Tuning Options", P_SEP, P_SEPARATOR},
881         
882         {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
883         {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, FLAG_DEVELOPER},
884         {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_DEVELOPER},
885         {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_DEVELOPER},
886         {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
887         {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_DEVELOPER},
888         
889         {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
890         {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_DEVELOPER},
891         {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
892         {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
893         {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_DEVELOPER},
894         {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
895         {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
896         {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, FLAG_DEVELOPER},
897         
898         {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_DEVELOPER},
899         {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, FLAG_DEVELOPER},
900         {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_SHARE},
901         {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE},
902         {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE},
903         {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
904         {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_SHARE},
905         {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
906         {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
907
908         {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
909
910         {"Printing Options", P_SEP, P_SEPARATOR},
911         
912         {"total print jobs", P_INTEGER, P_GLOBAL, &Globals.iTotalPrintJobs, NULL, NULL, FLAG_PRINT},
913         {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_PRINT},
914         {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
915         {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
916         {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
917         {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
918         {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
919         {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
920         {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
921         {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
922         {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
923         {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
924         {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
925         {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
926         {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
927         {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
928         {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
929
930         {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
931         {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
932         {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
933         {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
934         {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
935         
936         {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
937         {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
938         {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_PRINT},
939         {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_PRINT},
940
941         {"Filename Handling", P_SEP, P_SEPARATOR},
942         {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
943         {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
944         {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
945         
946         {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
947         {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE},
948         {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
949         {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_HIDE},
950         {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
951         {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
952         {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
953         {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
954         {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
955         {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
956         {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
957         {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
958         {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
959         {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
960         {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
961         {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL },
962         {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
963         {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
964         {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
965         {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
966         {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
967         {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_DEVELOPER},
968
969         {"Domain Options", P_SEP, P_SEPARATOR},
970         
971         {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
972
973         {"Logon Options", P_SEP, P_SEPARATOR},
974
975         {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
976         {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
977         {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
978         {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
979         {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
980         {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
981         {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
982         {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
983         {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
984         {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
985
986         {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
987         {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
988         {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
989         {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
990         {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
991
992         {"Browse Options", P_SEP, P_SEPARATOR},
993         
994         {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
995         {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
996         {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
997         {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
998         {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
999         {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
1000         {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
1001         {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1002         {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
1003         {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1004         {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
1005
1006         {"WINS Options", P_SEP, P_SEPARATOR},
1007         {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1008         {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1009         
1010         {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1011         {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1012         {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1013         {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
1014
1015         {"Locking Options", P_SEP, P_SEPARATOR},
1016         
1017         {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1018         {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
1019         {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
1020         {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
1021         {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1022         {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
1023         {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
1024         
1025         {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1026         {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1027         {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_GLOBAL},
1028         {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1029         {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1030         {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1031         {"share modes", P_BOOL, P_LOCAL,  &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
1032
1033         {"Ldap Options", P_SEP, P_SEPARATOR},
1034         
1035 #ifdef WITH_LDAP_SAMCONFIG
1036         {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
1037         {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0}, 
1038 #endif
1039         {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, handle_ldap_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1040         {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, handle_ldap_machine_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1041         {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, handle_ldap_user_suffix, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1042         {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1043         {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1044         {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED | FLAG_DEVELOPER},
1045         {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED | FLAG_DEVELOPER},
1046         {"ldap trust ids", P_BOOL, P_GLOBAL, &Globals.ldap_trust_ids, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1047         {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1048
1049         {"Miscellaneous Options", P_SEP, P_SEPARATOR},
1050         {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1051         {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1052         {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1053         
1054         {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1055         {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1056         {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1057         {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE}, 
1058         {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1059         {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER}, 
1060 #ifdef WITH_UTMP
1061         {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1062         {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1063         {"utmp",          P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1064 #endif
1065         
1066         {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1067         {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL,  FLAG_DEVELOPER},
1068         {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1069         {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1070         {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1071         {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1072         {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
1073         {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1074         {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1075         {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1076         {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1077         
1078         {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1079         {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1080         {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1081         {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1082         
1083         {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE},
1084         {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1085         {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1086         {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_SHARE},
1087         {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT},
1088         {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1089         {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
1090         {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
1091         {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE},
1092         {"source environment", P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1093         {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1094         {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1095         {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE},
1096         {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE},
1097         {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE},
1098         {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1099         {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1100         {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1101         {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1102
1103         {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
1104         {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1105         {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1106
1107         {"VFS module options", P_SEP, P_SEPARATOR},
1108         
1109         {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjectFile, NULL, NULL, FLAG_SHARE},
1110         {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, FLAG_SHARE},
1111         {"vfs path", P_STRING, P_LOCAL, &sDefault.szVfsPath, NULL, NULL, FLAG_SHARE},
1112
1113         
1114         {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
1115         {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
1116         {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1117
1118         {"Winbind options", P_SEP, P_SEPARATOR},
1119
1120         {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1121         {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_HIDE},
1122         {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1123         {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER | FLAG_HIDE},
1124         {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1125         {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1126         {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1127         {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1128         {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1129         {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1130         {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1131         {"winbind backend", P_STRING, P_GLOBAL, &Globals.szWinbindBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
1132
1133         {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1134 };
1135
1136 /***************************************************************************
1137  Initialise the sDefault parameter structure for the printer values.
1138 ***************************************************************************/
1139
1140 static void init_printer_values(void)
1141 {
1142         /* choose defaults depending on the type of printing */
1143         switch (sDefault.iPrinting) {
1144                 case PRINT_BSD:
1145                 case PRINT_AIX:
1146                 case PRINT_LPRNT:
1147                 case PRINT_LPROS2:
1148                         string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
1149                         string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
1150                         string_set(&sDefault.szPrintcommand,
1151                                    "lpr -r -P'%p' %s");
1152                         break;
1153
1154                 case PRINT_LPRNG:
1155                 case PRINT_PLP:
1156                         string_set(&sDefault.szLpqcommand, "lpq -P'%p'");
1157                         string_set(&sDefault.szLprmcommand, "lprm -P'%p' %j");
1158                         string_set(&sDefault.szPrintcommand,
1159                                    "lpr -r -P'%p' %s");
1160                         string_set(&sDefault.szQueuepausecommand,
1161                                    "lpc stop '%p'");
1162                         string_set(&sDefault.szQueueresumecommand,
1163                                    "lpc start '%p'");
1164                         string_set(&sDefault.szLppausecommand,
1165                                    "lpc hold '%p' %j");
1166                         string_set(&sDefault.szLpresumecommand,
1167                                    "lpc release '%p' %j");
1168                         break;
1169
1170                 case PRINT_CUPS:
1171 #ifdef HAVE_CUPS
1172                         string_set(&sDefault.szLpqcommand, "");
1173                         string_set(&sDefault.szLprmcommand, "");
1174                         string_set(&sDefault.szPrintcommand, "");
1175                         string_set(&sDefault.szLppausecommand, "");
1176                         string_set(&sDefault.szLpresumecommand, "");
1177                         string_set(&sDefault.szQueuepausecommand, "");
1178                         string_set(&sDefault.szQueueresumecommand, "");
1179
1180                         string_set(&Globals.szPrintcapname, "cups");
1181 #else
1182                         string_set(&sDefault.szLpqcommand,
1183                                    "/usr/bin/lpstat -o '%p'");
1184                         string_set(&sDefault.szLprmcommand,
1185                                    "/usr/bin/cancel '%p-%j'");
1186                         string_set(&sDefault.szPrintcommand,
1187                                    "/usr/bin/lp -d '%p' %s; rm %s");
1188                         string_set(&sDefault.szLppausecommand,
1189                                    "lp -i '%p-%j' -H hold");
1190                         string_set(&sDefault.szLpresumecommand,
1191                                    "lp -i '%p-%j' -H resume");
1192                         string_set(&sDefault.szQueuepausecommand,
1193                                    "/usr/bin/disable '%p'");
1194                         string_set(&sDefault.szQueueresumecommand,
1195                                    "/usr/bin/enable '%p'");
1196                         string_set(&Globals.szPrintcapname, "lpstat");
1197 #endif /* HAVE_CUPS */
1198                         break;
1199
1200                 case PRINT_SYSV:
1201                 case PRINT_HPUX:
1202                         string_set(&sDefault.szLpqcommand, "lpstat -o%p");
1203                         string_set(&sDefault.szLprmcommand, "cancel %p-%j");
1204                         string_set(&sDefault.szPrintcommand,
1205                                    "lp -c -d%p %s; rm %s");
1206                         string_set(&sDefault.szQueuepausecommand,
1207                                    "disable %p");
1208                         string_set(&sDefault.szQueueresumecommand,
1209                                    "enable %p");
1210 #ifndef HPUX
1211                         string_set(&sDefault.szLppausecommand,
1212                                    "lp -i %p-%j -H hold");
1213                         string_set(&sDefault.szLpresumecommand,
1214                                    "lp -i %p-%j -H resume");
1215 #endif /* HPUX */
1216                         break;
1217
1218                 case PRINT_QNX:
1219                         string_set(&sDefault.szLpqcommand, "lpq -P%p");
1220                         string_set(&sDefault.szLprmcommand, "lprm -P%p %j");
1221                         string_set(&sDefault.szPrintcommand, "lp -r -P%p %s");
1222                         break;
1223
1224                 case PRINT_SOFTQ:
1225                         string_set(&sDefault.szLpqcommand, "qstat -l -d%p");
1226                         string_set(&sDefault.szLprmcommand,
1227                                    "qstat -s -j%j -c");
1228                         string_set(&sDefault.szPrintcommand,
1229                                    "lp -d%p -s %s; rm %s");
1230                         string_set(&sDefault.szLppausecommand,
1231                                    "qstat -s -j%j -h");
1232                         string_set(&sDefault.szLpresumecommand,
1233                                    "qstat -s -j%j -r");
1234                         break;
1235 #ifdef DEVELOPER
1236         case PRINT_TEST:
1237         case PRINT_VLP:
1238                 string_set(&sDefault.szPrintcommand, "vlp print %p %s");
1239                 string_set(&sDefault.szLpqcommand, "vlp lpq %p");
1240                 string_set(&sDefault.szLprmcommand, "vlp lprm %p %j");
1241                 string_set(&sDefault.szLppausecommand, "vlp lppause %p %j");
1242                 string_set(&sDefault.szLpresumecommand, "vlp lpresum %p %j");
1243                 string_set(&sDefault.szQueuepausecommand, "vlp queuepause %p");
1244                 string_set(&sDefault.szQueueresumecommand, "vlp queueresume %p");
1245                 break;
1246 #endif /* DEVELOPER */
1247
1248         }
1249 }
1250
1251 /***************************************************************************
1252  Initialise the global parameter structure.
1253 ***************************************************************************/
1254
1255 static void init_globals(void)
1256 {
1257         static BOOL done_init = False;
1258         pstring s;
1259
1260         if (!done_init) {
1261                 int i;
1262                 memset((void *)&Globals, '\0', sizeof(Globals));
1263
1264                 for (i = 0; parm_table[i].label; i++)
1265                         if ((parm_table[i].type == P_STRING ||
1266                              parm_table[i].type == P_USTRING) &&
1267                             parm_table[i].ptr)
1268                                 string_set(parm_table[i].ptr, "");
1269
1270                 string_set(&sDefault.fstype, FSTYPE_STRING);
1271
1272                 init_printer_values();
1273
1274                 done_init = True;
1275         }
1276
1277
1278         DEBUG(3, ("Initialising global parameters\n"));
1279
1280         string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1281         string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1282
1283         /* use the new 'hash2' method by default, with a prefix of 1 */
1284         string_set(&Globals.szManglingMethod, "hash2");
1285         Globals.mangle_prefix = 1;
1286
1287         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1288
1289         /* using UTF8 by default allows us to support all chars */
1290         string_set(&Globals.unix_charset, "UTF8");
1291
1292         /* using UTF8 by default allows us to support all chars */
1293         string_set(&Globals.display_charset, "ASCII");
1294
1295         /* Use codepage 850 as a default for the dos character set */
1296         string_set(&Globals.dos_charset, "CP850");
1297
1298         /*
1299          * Allow the default PASSWD_CHAT to be overridden in local.h.
1300          */
1301         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1302         
1303         set_global_myname(myhostname());
1304         string_set(&Globals.szNetbiosName,global_myname());
1305
1306         set_global_myworkgroup(WORKGROUP);
1307         string_set(&Globals.szWorkgroup, lp_workgroup());
1308         
1309         string_set(&Globals.szPasswdProgram, "");
1310         string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
1311         string_set(&Globals.szPidDir, dyn_PIDDIR);
1312         string_set(&Globals.szLockDir, dyn_LOCKDIR);
1313         string_set(&Globals.szSocketAddress, "0.0.0.0");
1314         pstrcpy(s, "Samba ");
1315         pstrcat(s, VERSION);
1316         string_set(&Globals.szServerString, s);
1317         slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1318                  DEFAULT_MINOR_VERSION);
1319         string_set(&Globals.szAnnounceVersion, s);
1320
1321         pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1322
1323         string_set(&Globals.szLogonDrive, "");
1324         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1325         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1326         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1327
1328         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1329         string_set(&Globals.szPasswordServer, "*");
1330
1331         Globals.AlgorithmicRidBase = BASE_RID;
1332
1333         Globals.bLoadPrinters = True;
1334         Globals.mangled_stack = 50;
1335         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1336         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1337         Globals.max_xmit = 0x4104;
1338         Globals.max_mux = 50;   /* This is *needed* for profile support. */
1339         Globals.lpqcachetime = 10;
1340         Globals.bDisableSpoolss = False;
1341         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1342         Globals.iTotalPrintJobs = 0;  /* no limit specified */
1343         Globals.pwordlevel = 0;
1344         Globals.unamelevel = 0;
1345         Globals.deadtime = 0;
1346         Globals.bLargeReadwrite = True;
1347         Globals.max_log_size = 5000;
1348         Globals.max_open_files = MAX_OPEN_FILES;
1349         Globals.maxprotocol = PROTOCOL_NT1;
1350         Globals.minprotocol = PROTOCOL_CORE;
1351         Globals.security = SEC_USER;
1352         Globals.paranoid_server_security = True;
1353         Globals.bEncryptPasswords = True;
1354         Globals.bUpdateEncrypt = False;
1355         Globals.bReadRaw = True;
1356         Globals.bWriteRaw = True;
1357         Globals.bReadPrediction = False;
1358         Globals.bReadbmpx = False;
1359         Globals.bNullPasswords = False;
1360         Globals.bObeyPamRestrictions = False;
1361         Globals.bStripDot = False;
1362         Globals.syslog = 1;
1363         Globals.bSyslogOnly = False;
1364         Globals.bTimestampLogs = True;
1365         string_set(&Globals.szLogLevel, "0");
1366         Globals.bDebugHiresTimestamp = False;
1367         Globals.bDebugPid = False;
1368         Globals.bDebugUid = False;
1369         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
1370         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
1371         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
1372         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
1373         Globals.change_notify_timeout = 60;     /* 1 minute default. */
1374         Globals.bKernelChangeNotify = True;     /* On if we have it. */
1375         Globals.ReadSize = 16 * 1024;
1376         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
1377         Globals.lm_interval = 60;
1378         Globals.stat_cache_size = 50;   /* Number of stat translations we'll keep */
1379         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1380 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1381         Globals.bNISHomeMap = False;
1382 #ifdef WITH_NISPLUS_HOME
1383         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1384 #else
1385         string_set(&Globals.szNISHomeMapName, "auto.home");
1386 #endif
1387 #endif
1388         Globals.bTimeServer = False;
1389         Globals.bBindInterfacesOnly = False;
1390         Globals.bUnixPasswdSync = False;
1391         Globals.bPamPasswordChange = False;
1392         Globals.bPasswdChatDebug = False;
1393         Globals.bUnicode = True;        /* Do unicode on the wire by default */
1394         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
1395         Globals.bNTStatusSupport = True; /* Use NT status by default. */
1396         Globals.bStatCache = True;      /* use stat cache by default */
1397         Globals.restrict_anonymous = 0;
1398         Globals.bClientLanManAuth = True;       /* Do use the LanMan hash if it is available */
1399         Globals.bLanmanAuth = True;     /* Do use the LanMan hash if it is available */
1400         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1401         
1402         Globals.map_to_guest = 0;       /* By Default, "Never" */
1403         Globals.min_passwd_length = MINPASSWDLENGTH;    /* By Default, 5. */
1404         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
1405         Globals.enhanced_browsing = True; 
1406         Globals.iLockSpinCount = 3; /* Try 2 times. */
1407         Globals.iLockSpinTime = 10; /* usec. */
1408 #ifdef MMAP_BLACKLIST
1409         Globals.bUseMmap = False;
1410 #else
1411         Globals.bUseMmap = True;
1412 #endif
1413         Globals.bUnixExtensions = False;
1414
1415         /* hostname lookups can be very expensive and are broken on
1416            a large number of sites (tridge) */
1417         Globals.bHostnameLookups = False;
1418
1419 #ifdef WITH_LDAP_SAMCONFIG
1420         string_set(&Globals.szLdapServer, "localhost");
1421         Globals.ldap_port = 636;
1422         Globals.szPassdbBackend = str_list_make("ldapsam guest", NULL);
1423 #else
1424         Globals.szPassdbBackend = str_list_make("smbpasswd guest", NULL);
1425 #endif /* WITH_LDAP_SAMCONFIG */
1426
1427         string_set(&Globals.szLdapSuffix, "");
1428         string_set(&Globals.szLdapMachineSuffix, "");
1429         string_set(&Globals.szLdapUserSuffix, "");
1430
1431         string_set(&Globals.szLdapFilter, "(&(uid=%u)(objectclass=sambaAccount))");
1432         string_set(&Globals.szLdapAdminDn, "");
1433         Globals.ldap_ssl = LDAP_SSL_ON;
1434         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1435         Globals.ldap_delete_dn = False;
1436
1437 /* these parameters are set to defaults that are more appropriate
1438    for the increasing samba install base:
1439
1440    as a member of the workgroup, that will possibly become a
1441    _local_ master browser (lm = True).  this is opposed to a forced
1442    local master browser startup (pm = True).
1443
1444    doesn't provide WINS server service by default (wsupp = False),
1445    and doesn't provide domain master browser services by default, either.
1446
1447 */
1448
1449         Globals.bMsAddPrinterWizard = True;
1450         Globals.bPreferredMaster = Auto;        /* depending on bDomainMaster */
1451         Globals.os_level = 20;
1452         Globals.bLocalMaster = True;
1453         Globals.bDomainMaster = Auto;   /* depending on bDomainLogons */
1454         Globals.bDomainLogons = False;
1455         Globals.bBrowseList = True;
1456         Globals.bWINSsupport = False;
1457         Globals.bWINSproxy = False;
1458
1459         Globals.bDNSproxy = True;
1460
1461         /* this just means to use them if they exist */
1462         Globals.bKernelOplocks = True;
1463
1464         Globals.bAllowTrustedDomains = True;
1465
1466         string_set(&Globals.szTemplateShell, "/bin/false");
1467         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1468         string_set(&Globals.szWinbindSeparator, "\\");
1469         string_set(&Globals.szAclCompat, "");
1470
1471         Globals.winbind_cache_time = 15;
1472         Globals.bWinbindEnumUsers = True;
1473         Globals.bWinbindEnumGroups = True;
1474         Globals.bWinbindUseDefaultDomain = False;
1475
1476         string_set(&Globals.szWinbindBackend, "tdb");
1477
1478         Globals.name_cache_timeout = 660; /* In seconds */
1479
1480         Globals.bUseSpnego = True;
1481         Globals.bClientUseSpnego = True;
1482
1483         string_set(&Globals.smb_ports, SMB_PORTS);
1484 }
1485
1486 static TALLOC_CTX *lp_talloc;
1487
1488 /******************************************************************* a
1489  Free up temporary memory - called from the main loop.
1490 ********************************************************************/
1491
1492 void lp_talloc_free(void)
1493 {
1494         if (!lp_talloc)
1495                 return;
1496         talloc_destroy(lp_talloc);
1497         lp_talloc = NULL;
1498 }
1499
1500 /*******************************************************************
1501  Convenience routine to grab string parameters into temporary memory
1502  and run standard_sub_basic on them. The buffers can be written to by
1503  callers without affecting the source string.
1504 ********************************************************************/
1505
1506 static char *lp_string(const char *s)
1507 {
1508         size_t len = s ? strlen(s) : 0;
1509         char *ret;
1510
1511         /* The follow debug is useful for tracking down memory problems
1512            especially if you have an inner loop that is calling a lp_*()
1513            function that returns a string.  Perhaps this debug should be
1514            present all the time? */
1515
1516 #if 0
1517         DEBUG(10, ("lp_string(%s)\n", s));
1518 #endif
1519
1520         if (!lp_talloc)
1521                 lp_talloc = talloc_init("lp_talloc");
1522
1523         ret = (char *)talloc(lp_talloc, len + 100);     /* leave room for substitution */
1524
1525         if (!ret)
1526                 return NULL;
1527
1528         /* Note: StrnCpy touches len+1 bytes, but we allocate 100
1529          * extra bytes so we're OK. */
1530
1531         if (!s)
1532                 *ret = 0;
1533         else
1534                 StrnCpy(ret, s, len);
1535
1536         if (trim_string(ret, "\"", "\"")) {
1537                 if (strchr(ret,'"') != NULL)
1538                         StrnCpy(ret, s, len);
1539         }
1540
1541         standard_sub_basic(current_user_info.smb_name,ret,len+100);
1542         return (ret);
1543 }
1544
1545 /*
1546    In this section all the functions that are used to access the 
1547    parameters from the rest of the program are defined 
1548 */
1549
1550 #define FN_GLOBAL_STRING(fn_name,ptr) \
1551  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1552 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1553  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1554 #define FN_GLOBAL_LIST(fn_name,ptr) \
1555  const char **fn_name(void) {return(*(const char ***)(ptr));}
1556 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1557  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1558 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1559  char fn_name(void) {return(*(char *)(ptr));}
1560 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1561  int fn_name(void) {return(*(int *)(ptr));}
1562
1563 #define FN_LOCAL_STRING(fn_name,val) \
1564  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1565 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1566  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1567 #define FN_LOCAL_LIST(fn_name,val) \
1568  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1569 #define FN_LOCAL_BOOL(fn_name,val) \
1570  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1571 #define FN_LOCAL_CHAR(fn_name,val) \
1572  char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1573 #define FN_LOCAL_INTEGER(fn_name,val) \
1574  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1575
1576 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1577 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1578 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1579 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1580 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1581 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1582 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1583 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1584 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1585 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1586 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1587 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1588 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1589 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1590 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1591 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1592 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1593 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1594 #ifdef WITH_UTMP
1595 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1596 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1597 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1598 #endif
1599 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1600 FN_GLOBAL_STRING(lp_source_environment, &Globals.szSourceEnv)
1601 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1602 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1603 FN_GLOBAL_STRING(lp_dfree_command, &Globals.szDfree)
1604 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1605 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1606 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1607 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1608 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1609 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1610 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1611 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1612 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1613 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1614 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1615 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1616 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1617 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1618 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1619 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1620 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1621 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1622 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1623 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1624 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1625 FN_GLOBAL_LIST(lp_passdb_backend, &Globals.szPassdbBackend)
1626 FN_GLOBAL_LIST(lp_sam_backend, &Globals.szSamBackend)
1627 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1628 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1629 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1630 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1631
1632 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1633 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1634 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1635 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1636 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1637 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1638
1639 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1640
1641 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1642 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1643
1644 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1645 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1646 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1647 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1648 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1649 FN_GLOBAL_STRING(lp_acl_compatibility, &Globals.szAclCompat)
1650 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1651 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1652 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1653 FN_GLOBAL_STRING(lp_winbind_backend, &Globals.szWinbindBackend)
1654
1655 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
1656
1657 #ifdef WITH_LDAP_SAMCONFIG
1658 FN_GLOBAL_STRING(lp_ldap_server, &Globals.szLdapServer)
1659 FN_GLOBAL_INTEGER(lp_ldap_port, &Globals.ldap_port)
1660 #endif
1661 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1662 FN_GLOBAL_STRING(lp_ldap_machine_suffix, &Globals.szLdapMachineSuffix)
1663 FN_GLOBAL_STRING(lp_ldap_user_suffix, &Globals.szLdapUserSuffix)
1664 FN_GLOBAL_STRING(lp_ldap_filter, &Globals.szLdapFilter)
1665 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1666 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1667 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1668 FN_GLOBAL_BOOL(lp_ldap_trust_ids, &Globals.ldap_trust_ids)
1669 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1670 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1671 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1672 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1673
1674 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1675 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1676 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1677 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1678 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1679 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1680 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1681 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1682 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1683 FN_GLOBAL_BOOL(lp_readprediction, &Globals.bReadPrediction)
1684 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1685 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1686 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1687 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1688 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1689 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1690 FN_GLOBAL_BOOL(lp_strip_dot, &Globals.bStripDot)
1691 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1692 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1693 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1694 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1695 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1696 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1697 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1698 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1699 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1700 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1701 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1702 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1703 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1704 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1705 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1706 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1707 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1708 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1709 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1710 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1711 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1712 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1713 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1714 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1715 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1716 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1717 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1718 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1719 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1720 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1721 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1722 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1723 FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
1724 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1725 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1726 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1727 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1728 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1729 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1730 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1731 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1732 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1733 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1734 FN_GLOBAL_INTEGER(lp_readsize, &Globals.ReadSize)
1735 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1736 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1737 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1738 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1739 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1740 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1741 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1742 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1743 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
1744 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1745 FN_GLOBAL_INTEGER(lp_totalprintjobs, &Globals.iTotalPrintJobs)
1746 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1747 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1748 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1749 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1750 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1751 FN_GLOBAL_INTEGER(lp_change_notify_timeout, &Globals.change_notify_timeout)
1752 FN_GLOBAL_INTEGER(lp_stat_cache_size, &Globals.stat_cache_size)
1753 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1754 FN_GLOBAL_INTEGER(lp_min_passwd_length, &Globals.min_passwd_length)
1755 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1756 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1757 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1758 FN_LOCAL_STRING(lp_preexec, szPreExec)
1759 FN_LOCAL_STRING(lp_postexec, szPostExec)
1760 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1761 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1762 FN_LOCAL_STRING(lp_servicename, szService)
1763 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1764 FN_LOCAL_STRING(lp_pathname, szPath)
1765 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1766 FN_LOCAL_STRING(lp_username, szUsername)
1767 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1768 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1769 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1770 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1771 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1772 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1773 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1774 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1775 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1776 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1777 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1778 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1779 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1780 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
1781 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
1782 FN_LOCAL_STRING(lp_comment, comment)
1783 FN_LOCAL_STRING(lp_force_user, force_user)
1784 FN_LOCAL_STRING(lp_force_group, force_group)
1785 FN_LOCAL_LIST(lp_readlist, readlist)
1786 FN_LOCAL_LIST(lp_writelist, writelist)
1787 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
1788 FN_LOCAL_STRING(lp_fstype, fstype)
1789 FN_LOCAL_LIST(lp_vfsobj, szVfsObjectFile)
1790 FN_LOCAL_STRING(lp_vfs_options, szVfsOptions)
1791 FN_LOCAL_STRING(lp_vfs_path, szVfsPath)
1792 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1793 static FN_LOCAL_STRING(lp_volume, volume)
1794 FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
1795 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
1796 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
1797 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
1798 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1799 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1800 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
1801 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
1802 FN_LOCAL_BOOL(lp_casesensitive, bCaseSensitive)
1803 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
1804 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
1805 FN_LOCAL_BOOL(lp_casemangle, bCaseMangle)
1806 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
1807 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
1808 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
1809 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
1810 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1811 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1812 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
1813 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1814 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1815 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1816 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1817 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1818 FN_LOCAL_BOOL(lp_locking, bLocking)
1819 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1820 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1821 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1822 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1823 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1824 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1825 FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
1826 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
1827 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
1828 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
1829 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
1830 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1831 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1832 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
1833 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
1834 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
1835 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
1836 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
1837 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
1838 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
1839 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
1840 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
1841 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
1842 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
1843 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
1844 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
1845 FN_LOCAL_BOOL(lp_use_sendfile, bUseSendfile)
1846 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
1847 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
1848 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
1849 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
1850 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
1851 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
1852 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
1853 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
1854 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
1855 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1856 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
1857 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1858 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1859 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
1860 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
1861 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1862 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
1863 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
1864 FN_LOCAL_CHAR(lp_magicchar, magic_char)
1865 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1866 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1867 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
1868 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1869 FN_GLOBAL_BOOL(lp_client_signing, &Globals.client_signing)
1870
1871 /* local prototypes */
1872
1873 static int map_parameter(const char *pszParmName);
1874 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1875 static int getservicebyname(const char *pszServiceName,
1876                             service * pserviceDest);
1877 static void copy_service(service * pserviceDest,
1878                          service * pserviceSource, BOOL *pcopymapDest);
1879 static BOOL service_ok(int iService);
1880 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
1881 static BOOL do_section(const char *pszSectionName);
1882 static void init_copymap(service * pservice);
1883
1884 /* This is a helper function for parametrical options support. */
1885 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1886 /* Actual parametrical functions are quite simple */
1887 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1888 {
1889         char* vfskey;
1890         param_opt_struct *data;
1891         
1892         if (lookup_service >= iNumServices) return NULL;
1893         
1894         data = (lookup_service < 0) ? 
1895                 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1896     
1897         asprintf(&vfskey, "%s:%s", type, option);
1898         while (data) {
1899                 if (strcmp(data->key, vfskey) == 0) {
1900                         string_free(&vfskey);
1901                         return data->value;
1902                 }
1903                 data = data->next;
1904         }
1905
1906         if (lookup_service >= 0) {
1907                 /* Try to fetch the same option but from globals */
1908                 /* but only if we are not already working with Globals */
1909                 data = Globals.param_opt;
1910                 while (data) {
1911                         if (strcmp(data->key, vfskey) == 0) {
1912                                 string_free(&vfskey);
1913                                 return data->value;
1914                         }
1915                         data = data->next;
1916                 }
1917         }
1918
1919         string_free(&vfskey);
1920         
1921         return NULL;
1922 }
1923
1924
1925 /*******************************************************************
1926 convenience routine to return int parameters.
1927 ********************************************************************/
1928 static int lp_int(const char *s)
1929 {
1930
1931         if (!s) {
1932                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1933                 return (-1);
1934         }
1935
1936         return atoi(s); 
1937 }
1938
1939 /*******************************************************************
1940 convenience routine to return unsigned long parameters.
1941 ********************************************************************/
1942 static int lp_ulong(const char *s)
1943 {
1944
1945         if (!s) {
1946                 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1947                 return (-1);
1948         }
1949
1950         return strtoul(s, NULL, 10);
1951 }
1952
1953 /*******************************************************************
1954 convenience routine to return boolean parameters.
1955 ********************************************************************/
1956 static BOOL lp_bool(const char *s)
1957 {
1958         BOOL ret = False;
1959
1960         if (!s) {
1961                 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1962                 return False;
1963         }
1964         
1965         if (!set_boolean(&ret,s)) {
1966                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1967                 return False;
1968         }
1969
1970         return ret;
1971 }
1972
1973 /*******************************************************************
1974 convenience routine to return enum parameters.
1975 ********************************************************************/
1976 static int lp_enum(const char *s,const struct enum_list *_enum)
1977 {
1978         int i;
1979
1980         if (!s || !_enum) {
1981                 DEBUG(0,("lp_enum(%s,enum): is called with NULL!\n",s));
1982                 return False;
1983         }
1984         
1985         for (i=0; _enum[i].name; i++) {
1986                 if (strcasecmp(_enum[i].name,s)==0)
1987                         return _enum[i].value;
1988         }
1989
1990         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
1991         return (-1);
1992 }
1993
1994 /* Return parametric option from a given service. Type is a part of option before ':' */
1995 /* Parametric option has following syntax: 'Type: option = value' */
1996 /* Returned value is allocated in 'lp_talloc' context */
1997
1998 char *lp_parm_string(int lookup_service, const char *type, const char *option)
1999 {
2000         const char *value = get_parametrics(lookup_service, type, option);
2001         
2002         if (value)
2003                 return lp_string(value);
2004
2005         return NULL;
2006 }
2007
2008 /* Return parametric option from a given service. Type is a part of option before ':' */
2009 /* Parametric option has following syntax: 'Type: option = value' */
2010 /* Returned value is allocated in 'lp_talloc' context */
2011
2012 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
2013                            const char *separator)
2014 {
2015         const char *value = get_parametrics(lookup_service, type, option);
2016         
2017         if (value)
2018                 return str_list_make(value, separator);
2019
2020         return NULL;
2021 }
2022
2023 /* Return parametric option from a given service. Type is a part of option before ':' */
2024 /* Parametric option has following syntax: 'Type: option = value' */
2025
2026 int lp_parm_int(int lookup_service, const char *type, const char *option)
2027 {
2028         const char *value = get_parametrics(lookup_service, type, option);
2029         
2030         if (value)
2031                 return lp_int(value);
2032
2033         return (-1);
2034 }
2035
2036 /* Return parametric option from a given service. Type is a part of option before ':' */
2037 /* Parametric option has following syntax: 'Type: option = value' */
2038
2039 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
2040 {
2041         const char *value = get_parametrics(lookup_service, type, option);
2042         
2043         if (value)
2044                 return lp_ulong(value);
2045
2046         return (0);
2047 }
2048
2049 /* Return parametric option from a given service. Type is a part of option before ':' */
2050 /* Parametric option has following syntax: 'Type: option = value' */
2051
2052 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option)
2053 {
2054         const char *value = get_parametrics(lookup_service, type, option);
2055         
2056         if (value)
2057                 return lp_bool(value);
2058
2059         return False;
2060 }
2061
2062 /* Return parametric option from a given service. Type is a part of option before ':' */
2063 /* Parametric option has following syntax: 'Type: option = value' */
2064
2065 int lp_parm_enum(int lookup_service, const char *type, const char *option,
2066                  const struct enum_list *_enum)
2067 {
2068         const char *value = get_parametrics(lookup_service, type, option);
2069         
2070         if (value)
2071                 return lp_enum(value, _enum);
2072
2073         return (-1);
2074 }
2075
2076
2077 /***************************************************************************
2078  Initialise a service to the defaults.
2079 ***************************************************************************/
2080
2081 static void init_service(service * pservice)
2082 {
2083         memset((char *)pservice, '\0', sizeof(service));
2084         copy_service(pservice, &sDefault, NULL);
2085 }
2086
2087 /***************************************************************************
2088  Free the dynamically allocated parts of a service struct.
2089 ***************************************************************************/
2090
2091 static void free_service(service *pservice)
2092 {
2093         int i;
2094         param_opt_struct *data, *pdata;
2095         if (!pservice)
2096                 return;
2097
2098         if (pservice->szService)
2099                 DEBUG(5, ("free_service: Freeing service %s\n",
2100                        pservice->szService));
2101
2102         string_free(&pservice->szService);
2103         SAFE_FREE(pservice->copymap);
2104
2105         for (i = 0; parm_table[i].label; i++) {
2106                 if ((parm_table[i].type == P_STRING ||
2107                      parm_table[i].type == P_USTRING) &&
2108                     parm_table[i].class == P_LOCAL)
2109                         string_free((char **)
2110                                     (((char *)pservice) +
2111                                      PTR_DIFF(parm_table[i].ptr, &sDefault)));
2112                 else if (parm_table[i].type == P_LIST &&
2113                          parm_table[i].class == P_LOCAL)
2114                              str_list_free((char ***)
2115                                             (((char *)pservice) +
2116                                              PTR_DIFF(parm_table[i].ptr, &sDefault)));
2117         }
2118                                 
2119         DEBUG(5,("Freeing parametrics:\n"));
2120         data = pservice->param_opt;
2121         while (data) {
2122                 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2123                 string_free(&data->key);
2124                 string_free(&data->value);
2125                 pdata = data->next;
2126                 SAFE_FREE(data);
2127                 data = pdata;
2128         }
2129
2130         ZERO_STRUCTP(pservice);
2131 }
2132
2133 /***************************************************************************
2134  Add a new service to the services array initialising it with the given 
2135  service. 
2136 ***************************************************************************/
2137
2138 static int add_a_service(const service *pservice, const char *name)
2139 {
2140         int i;
2141         service tservice;
2142         int num_to_alloc = iNumServices + 1;
2143         param_opt_struct *data, *pdata;
2144
2145         tservice = *pservice;
2146
2147         /* it might already exist */
2148         if (name) {
2149                 i = getservicebyname(name, NULL);
2150                 if (i >= 0) {
2151                         /* Clean all parametric options for service */
2152                         /* They will be added during parsing again */
2153                         data = ServicePtrs[i]->param_opt;
2154                         while (data) {
2155                                 string_free(&data->key);
2156                                 string_free(&data->value);
2157                                 pdata = data->next;
2158                                 SAFE_FREE(data);
2159                                 data = pdata;
2160                         }
2161                         ServicePtrs[i]->param_opt = NULL;
2162                         return (i);
2163                 }
2164         }
2165
2166         /* find an invalid one */
2167         for (i = 0; i < iNumServices; i++)
2168                 if (!ServicePtrs[i]->valid)
2169                         break;
2170
2171         /* if not, then create one */
2172         if (i == iNumServices) {
2173                 service **tsp;
2174                 
2175                 tsp = (service **) Realloc(ServicePtrs,
2176                                            sizeof(service *) *
2177                                            num_to_alloc);
2178                                            
2179                 if (!tsp) {
2180                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2181                         return (-1);
2182                 }
2183                 else {
2184                         ServicePtrs = tsp;
2185                         ServicePtrs[iNumServices] =
2186                                 (service *) malloc(sizeof(service));
2187                 }
2188                 if (!ServicePtrs[iNumServices]) {
2189                         DEBUG(0,("add_a_service: out of memory!\n"));
2190                         return (-1);
2191                 }
2192
2193                 iNumServices++;
2194         } else
2195                 free_service(ServicePtrs[i]);
2196
2197         ServicePtrs[i]->valid = True;
2198
2199         init_service(ServicePtrs[i]);
2200         copy_service(ServicePtrs[i], &tservice, NULL);
2201         if (name)
2202                 string_set(&ServicePtrs[i]->szService, name);
2203         return (i);
2204 }
2205
2206 /***************************************************************************
2207  Add a new home service, with the specified home directory, defaults coming 
2208  from service ifrom.
2209 ***************************************************************************/
2210
2211 BOOL lp_add_home(const char *pszHomename, int iDefaultService, 
2212                  const char *user, const char *pszHomedir)
2213 {
2214         int i;
2215         pstring newHomedir;
2216
2217         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2218
2219         if (i < 0)
2220                 return (False);
2221
2222         if (!(*(ServicePtrs[iDefaultService]->szPath))
2223             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
2224                 pstrcpy(newHomedir, pszHomedir);
2225         } else {
2226                 pstrcpy(newHomedir, lp_pathname(iDefaultService));
2227                 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir)); 
2228         }
2229
2230         string_set(&ServicePtrs[i]->szPath, newHomedir);
2231
2232         if (!(*(ServicePtrs[i]->comment))) {
2233                 pstring comment;
2234                 slprintf(comment, sizeof(comment) - 1,
2235                          "Home directory of %s", user);
2236                 string_set(&ServicePtrs[i]->comment, comment);
2237         }
2238         ServicePtrs[i]->bAvailable = sDefault.bAvailable;
2239         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2240
2241         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
2242                user, newHomedir));
2243         
2244         return (True);
2245 }
2246
2247 /***************************************************************************
2248  Add a new service, based on an old one.
2249 ***************************************************************************/
2250
2251 int lp_add_service(const char *pszService, int iDefaultService)
2252 {
2253         return (add_a_service(ServicePtrs[iDefaultService], pszService));
2254 }
2255
2256 /***************************************************************************
2257  Add the IPC service.
2258 ***************************************************************************/
2259
2260 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2261 {
2262         pstring comment;
2263         int i = add_a_service(&sDefault, ipc_name);
2264
2265         if (i < 0)
2266                 return (False);
2267
2268         slprintf(comment, sizeof(comment) - 1,
2269                  "IPC Service (%s)", Globals.szServerString);
2270
2271         string_set(&ServicePtrs[i]->szPath, tmpdir());
2272         string_set(&ServicePtrs[i]->szUsername, "");
2273         string_set(&ServicePtrs[i]->comment, comment);
2274         string_set(&ServicePtrs[i]->fstype, "IPC");
2275         ServicePtrs[i]->iMaxConnections = 0;
2276         ServicePtrs[i]->bAvailable = True;
2277         ServicePtrs[i]->bRead_only = True;
2278         ServicePtrs[i]->bGuest_only = False;
2279         ServicePtrs[i]->bGuest_ok = guest_ok;
2280         ServicePtrs[i]->bPrint_ok = False;
2281         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2282
2283         DEBUG(3, ("adding IPC service\n"));
2284
2285         return (True);
2286 }
2287
2288 /***************************************************************************
2289  Add a new printer service, with defaults coming from service iFrom.
2290 ***************************************************************************/
2291
2292 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2293 {
2294         const char *comment = "From Printcap";
2295         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2296
2297         if (i < 0)
2298                 return (False);
2299
2300         /* note that we do NOT default the availability flag to True - */
2301         /* we take it from the default service passed. This allows all */
2302         /* dynamic printers to be disabled by disabling the [printers] */
2303         /* entry (if/when the 'available' keyword is implemented!).    */
2304
2305         /* the printer name is set to the service name. */
2306         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2307         string_set(&ServicePtrs[i]->comment, comment);
2308         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2309         /* Printers cannot be read_only. */
2310         ServicePtrs[i]->bRead_only = False;
2311         /* No share modes on printer services. */
2312         ServicePtrs[i]->bShareModes = False;
2313         /* No oplocks on printer services. */
2314         ServicePtrs[i]->bOpLocks = False;
2315         /* Printer services must be printable. */
2316         ServicePtrs[i]->bPrint_ok = True;
2317
2318         DEBUG(3, ("adding printer service %s\n", pszPrintername));
2319
2320         update_server_announce_as_printserver();
2321
2322         return (True);
2323 }
2324
2325 /***************************************************************************
2326  Map a parameter's string representation to something we can use. 
2327  Returns False if the parameter string is not recognised, else TRUE.
2328 ***************************************************************************/
2329
2330 static int map_parameter(const char *pszParmName)
2331 {
2332         int iIndex;
2333
2334         if (*pszParmName == '-')
2335                 return (-1);
2336
2337         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2338                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2339                         return (iIndex);
2340
2341         /* Warn only if it isn't parametric option */
2342         if (strchr(pszParmName, ':') == NULL)
2343                 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2344         /* We do return 'fail' for parametric options as well because they are
2345            stored in different storage
2346          */
2347         return (-1);
2348 }
2349
2350 /***************************************************************************
2351  Set a boolean variable from the text value stored in the passed string.
2352  Returns True in success, False if the passed string does not correctly 
2353  represent a boolean.
2354 ***************************************************************************/
2355
2356 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2357 {
2358         BOOL bRetval;
2359
2360         bRetval = True;
2361         if (strwicmp(pszParmValue, "yes") == 0 ||
2362             strwicmp(pszParmValue, "true") == 0 ||
2363             strwicmp(pszParmValue, "1") == 0)
2364                 *pb = True;
2365         else if (strwicmp(pszParmValue, "no") == 0 ||
2366                     strwicmp(pszParmValue, "False") == 0 ||
2367                     strwicmp(pszParmValue, "0") == 0)
2368                 *pb = False;
2369         else {
2370                 DEBUG(0,
2371                       ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2372                        pszParmValue));
2373                 bRetval = False;
2374         }
2375         return (bRetval);
2376 }
2377
2378 /***************************************************************************
2379 Find a service by name. Otherwise works like get_service.
2380 ***************************************************************************/
2381
2382 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2383 {
2384         int iService;
2385
2386         for (iService = iNumServices - 1; iService >= 0; iService--)
2387                 if (VALID(iService) &&
2388                     strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
2389                         if (pserviceDest != NULL)
2390                                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2391                         break;
2392                 }
2393
2394         return (iService);
2395 }
2396
2397 /***************************************************************************
2398  Copy a service structure to another.
2399  If pcopymapDest is NULL then copy all fields
2400 ***************************************************************************/
2401
2402 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2403 {
2404         int i;
2405         BOOL bcopyall = (pcopymapDest == NULL);
2406         param_opt_struct *data, *pdata, *paramo;
2407         BOOL not_added;
2408
2409         for (i = 0; parm_table[i].label; i++)
2410                 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
2411                     (bcopyall || pcopymapDest[i])) {
2412                         void *def_ptr = parm_table[i].ptr;
2413                         void *src_ptr =
2414                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2415                                                                     &sDefault);
2416                         void *dest_ptr =
2417                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2418                                                                   &sDefault);
2419
2420                         switch (parm_table[i].type) {
2421                                 case P_BOOL:
2422                                 case P_BOOLREV:
2423                                         *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2424                                         break;
2425
2426                                 case P_INTEGER:
2427                                 case P_ENUM:
2428                                 case P_OCTAL:
2429                                         *(int *)dest_ptr = *(int *)src_ptr;
2430                                         break;
2431
2432                                 case P_CHAR:
2433                                         *(char *)dest_ptr = *(char *)src_ptr;
2434                                         break;
2435
2436                                 case P_STRING:
2437                                         string_set(dest_ptr,
2438                                                    *(char **)src_ptr);
2439                                         break;
2440
2441                                 case P_USTRING:
2442                                         string_set(dest_ptr,
2443                                                    *(char **)src_ptr);
2444                                         strupper(*(char **)dest_ptr);
2445                                         break;
2446                                 case P_LIST:
2447                                         str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2448                                         break;
2449                                 default:
2450                                         break;
2451                         }
2452                 }
2453
2454         if (bcopyall) {
2455                 init_copymap(pserviceDest);
2456                 if (pserviceSource->copymap)
2457                         memcpy((void *)pserviceDest->copymap,
2458                                (void *)pserviceSource->copymap,
2459                                sizeof(BOOL) * NUMPARAMETERS);
2460         }
2461         
2462         data = pserviceSource->param_opt;
2463         while (data) {
2464                 not_added = True;
2465                 pdata = pserviceDest->param_opt;
2466                 /* Traverse destination */
2467                 while (pdata) {
2468                         /* If we already have same option, override it */
2469                         if (strcmp(pdata->key, data->key) == 0) {
2470                                 string_free(&pdata->value);
2471                                 pdata->value = strdup(data->value);
2472                                 not_added = False;
2473                                 break;
2474                         }
2475                         pdata = pdata->next;
2476                 }
2477                 if (not_added) {
2478                     paramo = smb_xmalloc(sizeof(param_opt_struct));
2479                     paramo->key = strdup(data->key);
2480                     paramo->value = strdup(data->value);
2481                     DLIST_ADD(pserviceDest->param_opt, paramo);
2482                 }
2483                 data = data->next;
2484         }
2485 }
2486
2487 /***************************************************************************
2488 Check a service for consistency. Return False if the service is in any way
2489 incomplete or faulty, else True.
2490 ***************************************************************************/
2491
2492 static BOOL service_ok(int iService)
2493 {
2494         BOOL bRetval;
2495
2496         bRetval = True;
2497         if (ServicePtrs[iService]->szService[0] == '\0') {
2498                 DEBUG(0, ("The following message indicates an internal error:\n"));
2499                 DEBUG(0, ("No service name in service entry.\n"));
2500                 bRetval = False;
2501         }
2502
2503         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2504         /* I can't see why you'd want a non-printable printer service...        */
2505         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2506                 if (!ServicePtrs[iService]->bPrint_ok) {
2507                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2508                                ServicePtrs[iService]->szService));
2509                         ServicePtrs[iService]->bPrint_ok = True;
2510                 }
2511                 /* [printers] service must also be non-browsable. */
2512                 if (ServicePtrs[iService]->bBrowseable)
2513                         ServicePtrs[iService]->bBrowseable = False;
2514         }
2515
2516         if (ServicePtrs[iService]->szPath[0] == '\0' &&
2517             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0) {
2518                 DEBUG(0, ("No path in service %s - using %s\n",
2519                        ServicePtrs[iService]->szService, tmpdir()));
2520                 string_set(&ServicePtrs[iService]->szPath, tmpdir());
2521         }
2522
2523         /* If a service is flagged unavailable, log the fact at level 0. */
2524         if (!ServicePtrs[iService]->bAvailable)
2525                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2526                           ServicePtrs[iService]->szService));
2527
2528         return (bRetval);
2529 }
2530
2531 static struct file_lists {
2532         struct file_lists *next;
2533         char *name;
2534         char *subfname;
2535         time_t modtime;
2536 } *file_lists = NULL;
2537
2538 /*******************************************************************
2539  Keep a linked list of all config files so we know when one has changed 
2540  it's date and needs to be reloaded.
2541 ********************************************************************/
2542
2543 static void add_to_file_list(const char *fname, const char *subfname)
2544 {
2545         struct file_lists *f = file_lists;
2546
2547         while (f) {
2548                 if (f->name && !strcmp(f->name, fname))
2549                         break;
2550                 f = f->next;
2551         }
2552
2553         if (!f) {
2554                 f = (struct file_lists *)malloc(sizeof(file_lists[0]));
2555                 if (!f)
2556                         return;
2557                 f->next = file_lists;
2558                 f->name = strdup(fname);
2559                 if (!f->name) {
2560                         SAFE_FREE(f);
2561                         return;
2562                 }
2563                 f->subfname = strdup(subfname);
2564                 if (!f->subfname) {
2565                         SAFE_FREE(f);
2566                         return;
2567                 }
2568                 file_lists = f;
2569                 f->modtime = file_modtime(subfname);
2570         } else {
2571                 time_t t = file_modtime(subfname);
2572                 if (t)
2573                         f->modtime = t;
2574         }
2575 }
2576
2577 /*******************************************************************
2578  Check if a config file has changed date.
2579 ********************************************************************/
2580
2581 BOOL lp_file_list_changed(void)
2582 {
2583         struct file_lists *f = file_lists;
2584         DEBUG(6, ("lp_file_list_changed()\n"));
2585
2586         while (f) {
2587                 pstring n2;
2588                 time_t mod_time;
2589
2590                 pstrcpy(n2, f->name);
2591                 standard_sub_basic(current_user_info.smb_name, n2,sizeof(n2));
2592
2593                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
2594                              f->name, n2, ctime(&f->modtime)));
2595
2596                 mod_time = file_modtime(n2);
2597
2598                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2599                         DEBUGADD(6,
2600                                  ("file %s modified: %s\n", n2,
2601                                   ctime(&mod_time)));
2602                         f->modtime = mod_time;
2603                         SAFE_FREE(f->subfname);
2604                         f->subfname = strdup(n2);
2605                         return (True);
2606                 }
2607                 f = f->next;
2608         }
2609         return (False);
2610 }
2611
2612 /***************************************************************************
2613  Run standard_sub_basic on netbios name... needed because global_myname
2614  is not accessed through any lp_ macro.
2615  Note: We must *NOT* use string_set() here as ptr points to global_myname.
2616 ***************************************************************************/
2617
2618 static BOOL handle_netbios_name(const char *pszParmValue, char **ptr)
2619 {
2620         BOOL ret;
2621         pstring netbios_name;
2622
2623         pstrcpy(netbios_name, pszParmValue);
2624
2625         standard_sub_basic(current_user_info.smb_name, netbios_name,sizeof(netbios_name));
2626
2627
2628         ret = set_global_myname(netbios_name);
2629         string_set(&Globals.szNetbiosName,global_myname());
2630         
2631         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
2632                global_myname()));
2633
2634         return ret;
2635 }
2636
2637 static BOOL handle_workgroup(const char *pszParmValue, char **ptr)
2638 {
2639         BOOL ret;
2640         
2641         ret = set_global_myworkgroup(pszParmValue);
2642         string_set(&Globals.szWorkgroup,lp_workgroup());
2643         
2644         return ret;
2645 }
2646
2647 static BOOL handle_netbios_scope(const char *pszParmValue, char **ptr)
2648 {
2649         BOOL ret;
2650         
2651         ret = set_global_scope(pszParmValue);
2652         string_set(&Globals.szNetbiosScope,global_scope());
2653
2654         return ret;
2655 }
2656
2657 static BOOL handle_netbios_aliases(const char *pszParmValue, char **ptr)
2658 {
2659         Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
2660         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
2661 }
2662
2663 /***************************************************************************
2664  Do the work of sourcing in environment variable/value pairs.
2665 ***************************************************************************/
2666
2667 static BOOL source_env(char **lines)
2668 {
2669         char *varval;
2670         size_t len;
2671         int i;
2672         char *p;
2673
2674         for (i = 0; lines[i]; i++) {
2675                 char *line = lines[i];
2676
2677                 if ((len = strlen(line)) == 0)
2678                         continue;
2679
2680                 if (line[len - 1] == '\n')
2681                         line[--len] = '\0';
2682
2683                 if ((varval = malloc(len + 1)) == NULL) {
2684                         DEBUG(0, ("source_env: Not enough memory!\n"));
2685                         return (False);
2686                 }
2687
2688                 DEBUG(4, ("source_env: Adding to environment: %s\n", line));
2689                 strncpy(varval, line, len);
2690                 varval[len] = '\0';
2691
2692                 p = strchr_m(line, (int)'=');
2693                 if (p == NULL) {
2694                         DEBUG(4, ("source_env: missing '=': %s\n", line));
2695                         continue;
2696                 }
2697
2698                 if (putenv(varval)) {
2699                         DEBUG(0, ("source_env: Failed to put environment variable %s\n",
2700                                varval));
2701                         continue;
2702                 }
2703
2704                 *p = '\0';
2705                 p++;
2706                 DEBUG(4, ("source_env: getting var %s = %s\n", line, getenv(line)));
2707         }
2708
2709         DEBUG(4, ("source_env: returning successfully\n"));
2710         return (True);
2711 }
2712
2713 /***************************************************************************
2714  Handle the source environment operation.
2715 ***************************************************************************/
2716
2717 static BOOL handle_source_env(const char *pszParmValue, char **ptr)
2718 {
2719         pstring fname;
2720         char *p = fname;
2721         BOOL result;
2722         char **lines;
2723
2724         pstrcpy(fname, pszParmValue);
2725
2726         standard_sub_basic(current_user_info.smb_name, fname,sizeof(fname));
2727
2728         string_set(ptr, pszParmValue);
2729
2730         DEBUG(4, ("handle_source_env: checking env type\n"));
2731
2732         /*
2733          * Filename starting with '|' means popen and read from stdin.
2734          */
2735
2736         if (*p == '|')
2737                 lines = file_lines_pload(p + 1, NULL);
2738         else
2739                 lines = file_lines_load(fname, NULL);
2740
2741         if (!lines) {
2742                 DEBUG(0, ("handle_source_env: Failed to open file %s, Error was %s\n",
2743                        fname, strerror(errno)));
2744                 return (False);
2745         }
2746
2747         result = source_env(lines);
2748         file_lines_free(lines);
2749
2750         return (result);
2751 }
2752
2753 /***************************************************************************
2754  Handle the include operation.
2755 ***************************************************************************/
2756
2757 static BOOL handle_include(const char *pszParmValue, char **ptr)
2758 {
2759         pstring fname;
2760         pstrcpy(fname, pszParmValue);
2761
2762         standard_sub_basic(current_user_info.smb_name, fname,sizeof(fname));
2763
2764         add_to_file_list(pszParmValue, fname);
2765
2766         string_set(ptr, fname);
2767
2768         if (file_exist(fname, NULL))
2769                 return (pm_process(fname, do_section, do_parameter));
2770
2771         DEBUG(2, ("Can't find include file %s\n", fname));
2772
2773         return (False);
2774 }
2775
2776 /***************************************************************************
2777  Handle the interpretation of the copy parameter.
2778 ***************************************************************************/
2779
2780 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2781 {
2782         BOOL bRetval;
2783         int iTemp;
2784         service serviceTemp;
2785
2786         string_set(ptr, pszParmValue);
2787
2788         init_service(&serviceTemp);
2789
2790         bRetval = False;
2791
2792         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2793
2794         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2795                 if (iTemp == iServiceIndex) {
2796                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2797                 } else {
2798                         copy_service(ServicePtrs[iServiceIndex],
2799                                      &serviceTemp,
2800                                      ServicePtrs[iServiceIndex]->copymap);
2801                         bRetval = True;
2802                 }
2803         } else {
2804                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2805                 bRetval = False;
2806         }
2807
2808         free_service(&serviceTemp);
2809         return (bRetval);
2810 }
2811
2812 /***************************************************************************
2813  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
2814  parameters is:
2815
2816  [global]
2817
2818         idmap uid = 1000-1999
2819         idmap gid = 700-899
2820
2821  We only do simple parsing checks here.  The strings are parsed into useful
2822  structures in the idmap daemon code.
2823
2824 ***************************************************************************/
2825
2826 /* Some lp_ routines to return idmap [ug]id information */
2827
2828 static uid_t idmap_uid_low, idmap_uid_high;
2829 static gid_t idmap_gid_low, idmap_gid_high;
2830 static uint32 non_unix_account_low, non_unix_account_high;
2831
2832 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
2833 {
2834         if (idmap_uid_low == 0 || idmap_uid_high == 0)
2835                 return False;
2836
2837         if (low)
2838                 *low = idmap_uid_low;
2839
2840         if (high)
2841                 *high = idmap_uid_high;
2842
2843         return True;
2844 }
2845
2846 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
2847 {
2848         if (idmap_gid_low == 0 || idmap_gid_high == 0)
2849                 return False;
2850
2851         if (low)
2852                 *low = idmap_gid_low;
2853
2854         if (high)
2855                 *high = idmap_gid_high;
2856
2857         return True;
2858 }
2859
2860 BOOL lp_non_unix_account_range(uint32 *low, uint32 *high)
2861 {
2862         if (non_unix_account_low == 0 || non_unix_account_high == 0)
2863                 return False;
2864
2865         if (low)
2866                 *low = non_unix_account_low;
2867
2868         if (high)
2869                 *high = non_unix_account_high;
2870
2871         return True;
2872 }
2873
2874 /* Do some simple checks on "idmap [ug]id" parameter values */
2875
2876 static BOOL handle_idmap_uid(const char *pszParmValue, char **ptr)
2877 {
2878         uint32 low, high;
2879
2880         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2881                 return False;
2882
2883         /* Parse OK */
2884
2885         string_set(ptr, pszParmValue);
2886
2887         idmap_uid_low = low;
2888         idmap_uid_high = high;
2889
2890         return True;
2891 }
2892
2893 static BOOL handle_idmap_gid(const char *pszParmValue, char **ptr)
2894 {
2895         uint32 low, high;
2896
2897         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2898                 return False;
2899
2900         /* Parse OK */
2901
2902         string_set(ptr, pszParmValue);
2903
2904         idmap_gid_low = low;
2905         idmap_gid_high = high;
2906
2907         return True;
2908 }
2909
2910 /***************************************************************************
2911  Do some simple checks on "non unix account range" parameter values.
2912 ***************************************************************************/
2913
2914 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2915 {
2916         uint32 low, high;
2917
2918         if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2919                 return False;
2920
2921         /* Parse OK */
2922
2923         string_set(ptr, pszParmValue);
2924
2925         non_unix_account_low = low;
2926         non_unix_account_high = high;
2927
2928         return True;
2929 }
2930
2931 /***************************************************************************
2932  Handle the DEBUG level list.
2933 ***************************************************************************/
2934
2935 static BOOL handle_debug_list( const char *pszParmValueIn, char **ptr )
2936 {
2937         pstring pszParmValue;
2938
2939         pstrcpy(pszParmValue, pszParmValueIn);
2940         string_set(ptr, pszParmValueIn);
2941         return debug_parse_levels( pszParmValue );
2942 }
2943
2944 /***************************************************************************
2945  Handle the ldap machine suffix option.
2946 ***************************************************************************/
2947
2948 static BOOL handle_ldap_machine_suffix( const char *pszParmValue, char **ptr)
2949 {
2950        pstring suffix;
2951        
2952        pstrcpy(suffix, pszParmValue);
2953
2954        if (! *Globals.szLdapSuffix ) {
2955                string_set( ptr, suffix );
2956                return True;
2957        }
2958
2959        if (! strstr(suffix, Globals.szLdapSuffix) ) {
2960                if ( *pszParmValue )
2961                        pstrcat(suffix, ",");
2962                pstrcat(suffix, Globals.szLdapSuffix);
2963        }
2964        string_set( ptr, suffix );
2965        return True;
2966 }
2967
2968 /***************************************************************************
2969  Handle the ldap user suffix option.
2970 ***************************************************************************/
2971
2972 static BOOL handle_ldap_user_suffix( const char *pszParmValue, char **ptr)
2973 {
2974        pstring suffix;
2975        
2976        pstrcpy(suffix, pszParmValue);
2977
2978        if (! *Globals.szLdapSuffix ) {
2979                string_set( ptr, suffix );
2980                return True;
2981        }
2982        
2983        if (! strstr(suffix, Globals.szLdapSuffix) ) {
2984                if ( *pszParmValue )
2985                        pstrcat(suffix, ",");
2986                pstrcat(suffix, Globals.szLdapSuffix);
2987        }
2988        string_set( ptr, suffix );
2989        return True;
2990 }
2991
2992 /***************************************************************************
2993  Handle setting ldap suffix and determines whether ldap machine suffix needs
2994  to be set as well.
2995 ***************************************************************************/
2996
2997 static BOOL handle_ldap_suffix( const char *pszParmValue, char **ptr)
2998 {
2999        pstring suffix;
3000        pstring user_suffix;
3001        pstring machine_suffix;
3002                
3003        pstrcpy(suffix, pszParmValue);
3004
3005        if (! *Globals.szLdapMachineSuffix )
3006                string_set(&Globals.szLdapMachineSuffix, suffix);
3007        if (! *Globals.szLdapUserSuffix ) 
3008                string_set(&Globals.szLdapUserSuffix, suffix);
3009        
3010        if (! strstr(Globals.szLdapMachineSuffix, suffix)) {
3011                pstrcpy(machine_suffix, Globals.szLdapMachineSuffix);
3012                if ( *Globals.szLdapMachineSuffix )
3013                        pstrcat(machine_suffix, ",");
3014                pstrcat(machine_suffix, suffix);
3015                string_set(&Globals.szLdapMachineSuffix, machine_suffix);       
3016        }
3017
3018        if (! strstr(Globals.szLdapUserSuffix, suffix)) {
3019                pstrcpy(user_suffix, Globals.szLdapUserSuffix);
3020                if ( *Globals.szLdapUserSuffix )
3021                        pstrcat(user_suffix, ",");
3022                pstrcat(user_suffix, suffix);   
3023                string_set(&Globals.szLdapUserSuffix, user_suffix);
3024        } 
3025
3026        string_set(ptr, suffix); 
3027        return True;
3028 }
3029
3030 static BOOL handle_acl_compatibility(const char *pszParmValue, char **ptr)
3031 {
3032         if (strequal(pszParmValue, "auto"))
3033                 string_set(ptr, "");
3034         else if (strequal(pszParmValue, "winnt"))
3035                 string_set(ptr, "winnt");
3036         else if (strequal(pszParmValue, "win2k"))
3037                 string_set(ptr, "win2k");
3038         else
3039                 return False;
3040
3041         return True;
3042 }
3043 /***************************************************************************
3044  Initialise a copymap.
3045 ***************************************************************************/
3046
3047 static void init_copymap(service * pservice)
3048 {
3049         int i;
3050         SAFE_FREE(pservice->copymap);
3051         pservice->copymap = (BOOL *)malloc(sizeof(BOOL) * NUMPARAMETERS);
3052         if (!pservice->copymap)
3053                 DEBUG(0,
3054                       ("Couldn't allocate copymap!! (size %d)\n",
3055                        (int)NUMPARAMETERS));
3056         else
3057                 for (i = 0; i < NUMPARAMETERS; i++)
3058                         pservice->copymap[i] = True;
3059 }
3060
3061 /***************************************************************************
3062  Return the local pointer to a parameter given the service number and the 
3063  pointer into the default structure.
3064 ***************************************************************************/
3065
3066 void *lp_local_ptr(int snum, void *ptr)
3067 {
3068         return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3069 }
3070
3071 /***************************************************************************
3072  Process a parameter for a particular service number. If snum < 0
3073  then assume we are in the globals.
3074 ***************************************************************************/
3075
3076 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3077 {
3078         int parmnum, i, slen;
3079         void *parm_ptr = NULL;  /* where we are going to store the result */
3080         void *def_ptr = NULL;
3081         pstring vfskey;
3082         char *sep;
3083         param_opt_struct *paramo, *data;
3084         BOOL not_added;
3085
3086         parmnum = map_parameter(pszParmName);
3087
3088         if (parmnum < 0) {
3089                 if ((sep=strchr(pszParmName, ':')) != NULL) {
3090                         *sep = 0;
3091                         ZERO_STRUCT(vfskey);
3092                         pstr_sprintf(vfskey, "%s:", pszParmName);
3093                         slen = strlen(vfskey);
3094                         pstrcat(vfskey, sep+1);
3095                         trim_string(vfskey+slen, " ", " ");
3096                         not_added = True;
3097                         data = (snum < 0) ? Globals.param_opt : 
3098                                 ServicePtrs[snum]->param_opt;
3099                         /* Traverse destination */
3100                         while (data) {
3101                                 /* If we already have same option, override it */
3102                                 if (strcmp(data->key, vfskey) == 0) {
3103                                         string_free(&data->value);
3104                                         data->value = strdup(pszParmValue);
3105                                         not_added = False;
3106                                         break;
3107                                 }
3108                                 data = data->next;
3109                         }
3110                         if (not_added) {
3111                                 paramo = smb_xmalloc(sizeof(param_opt_struct));
3112                                 paramo->key = strdup(vfskey);
3113                                 paramo->value = strdup(pszParmValue);
3114                                 if (snum < 0) {
3115                                         DLIST_ADD(Globals.param_opt, paramo);
3116                                 } else {
3117                                         DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3118                                 }
3119                         }
3120
3121                         *sep = ':';
3122                         return (True);
3123                 }
3124                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3125                 return (True);
3126         }
3127
3128         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3129                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3130                           pszParmName));
3131         }
3132
3133         def_ptr = parm_table[parmnum].ptr;
3134
3135         /* we might point at a service, the default service or a global */
3136         if (snum < 0) {
3137                 parm_ptr = def_ptr;
3138         } else {
3139                 if (parm_table[parmnum].class == P_GLOBAL) {
3140                         DEBUG(0,
3141                               ("Global parameter %s found in service section!\n",
3142                                pszParmName));
3143                         return (True);
3144                 }
3145                 parm_ptr =
3146                         ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3147                                                             &sDefault);
3148         }
3149
3150         if (snum >= 0) {
3151                 if (!ServicePtrs[snum]->copymap)
3152                         init_copymap(ServicePtrs[snum]);
3153
3154                 /* this handles the aliases - set the copymap for other entries with
3155                    the same data pointer */
3156                 for (i = 0; parm_table[i].label; i++)
3157                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
3158                                 ServicePtrs[snum]->copymap[i] = False;
3159         }
3160
3161         /* if it is a special case then go ahead */
3162         if (parm_table[parmnum].special) {
3163                 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
3164                 return (True);
3165         }
3166
3167         /* now switch on the type of variable it is */
3168         switch (parm_table[parmnum].type)
3169         {
3170                 case P_BOOL:
3171                         set_boolean(parm_ptr, pszParmValue);
3172                         break;
3173
3174                 case P_BOOLREV:
3175                         set_boolean(parm_ptr, pszParmValue);
3176                         *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
3177                         break;
3178
3179                 case P_INTEGER:
3180                         *(int *)parm_ptr = atoi(pszParmValue);
3181                         break;
3182
3183                 case P_CHAR:
3184                         *(char *)parm_ptr = *pszParmValue;
3185                         break;
3186
3187                 case P_OCTAL:
3188                         sscanf(pszParmValue, "%o", (int *)parm_ptr);
3189                         break;
3190
3191                 case P_LIST:
3192                         str_list_free(parm_ptr);
3193                         *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3194                         break;
3195
3196                 case P_STRING:
3197                         string_set(parm_ptr, pszParmValue);
3198                         break;
3199
3200                 case P_USTRING:
3201                         string_set(parm_ptr, pszParmValue);
3202                         strupper(*(char **)parm_ptr);
3203                         break;
3204
3205                 case P_GSTRING:
3206                         pstrcpy((char *)parm_ptr, pszParmValue);
3207                         break;
3208
3209                 case P_UGSTRING:
3210                         pstrcpy((char *)parm_ptr, pszParmValue);
3211                         strupper((char *)parm_ptr);
3212                         break;
3213
3214                 case P_ENUM:
3215                         for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
3216                                 if (strequal
3217                                     (pszParmValue,
3218                                      parm_table[parmnum].enum_list[i].name)) {
3219                                         *(int *)parm_ptr =
3220                                                 parm_table[parmnum].
3221                                                 enum_list[i].value;
3222                                         break;
3223                                 }
3224                         }
3225                         break;
3226                 case P_SEP:
3227                         break;
3228         }
3229
3230         return (True);
3231 }
3232
3233 /***************************************************************************
3234  Process a parameter.
3235 ***************************************************************************/
3236
3237 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3238 {
3239         if (!bInGlobalSection && bGlobalOnly)
3240                 return (True);
3241
3242         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3243
3244         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3245                                 pszParmName, pszParmValue));
3246 }
3247
3248 /***************************************************************************
3249  Print a parameter of the specified type.
3250 ***************************************************************************/
3251
3252 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3253 {
3254         int i;
3255         switch (p->type)
3256         {
3257                 case P_ENUM:
3258                         for (i = 0; p->enum_list[i].name; i++) {
3259                                 if (*(int *)ptr == p->enum_list[i].value) {
3260                                         fprintf(f, "%s",
3261                                                 p->enum_list[i].name);
3262                                         break;
3263                                 }
3264                         }
3265                         break;
3266
3267                 case P_BOOL:
3268                         fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3269                         break;
3270
3271                 case P_BOOLREV:
3272                         fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3273                         break;
3274
3275                 case P_INTEGER:
3276                         fprintf(f, "%d", *(int *)ptr);
3277                         break;
3278
3279                 case P_CHAR:
3280                         fprintf(f, "%c", *(char *)ptr);
3281                         break;
3282
3283                 case P_OCTAL:
3284                         fprintf(f, "%s", octal_string(*(int *)ptr));
3285                         break;
3286
3287                 case P_LIST:
3288                         if ((char ***)ptr && *(char ***)ptr) {
3289                                 char **list = *(char ***)ptr;
3290                                 
3291                                 for (; *list; list++)
3292                                         fprintf(f, "%s%s", *list,
3293                                                 ((*(list+1))?", ":""));
3294                         }
3295                         break;
3296
3297                 case P_GSTRING:
3298                 case P_UGSTRING:
3299                         if ((char *)ptr) {
3300                                 fprintf(f, "%s", (char *)ptr);
3301                         }
3302                         break;
3303
3304                 case P_STRING:
3305                 case P_USTRING:
3306                         if (*(char **)ptr) {
3307                                 fprintf(f, "%s", *(char **)ptr);
3308                         }
3309                         break;
3310                 case P_SEP:
3311                         break;
3312         }
3313 }
3314
3315 /***************************************************************************
3316  Check if two parameters are equal.
3317 ***************************************************************************/
3318
3319 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3320 {
3321         switch (type) {
3322                 case P_BOOL:
3323                 case P_BOOLREV:
3324                         return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3325
3326                 case P_INTEGER:
3327                 case P_ENUM:
3328                 case P_OCTAL:
3329                         return (*((int *)ptr1) == *((int *)ptr2));
3330
3331                 case P_CHAR:
3332                         return (*((char *)ptr1) == *((char *)ptr2));
3333                 
3334                 case P_LIST:
3335                         return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3336
3337                 case P_GSTRING:
3338                 case P_UGSTRING:
3339                 {
3340                         char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3341                         if (p1 && !*p1)
3342                                 p1 = NULL;
3343                         if (p2 && !*p2)
3344                                 p2 = NULL;
3345                         return (p1 == p2 || strequal(p1, p2));
3346                 }
3347                 case P_STRING:
3348                 case P_USTRING:
3349                 {
3350                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3351                         if (p1 && !*p1)
3352                                 p1 = NULL;
3353                         if (p2 && !*p2)
3354                                 p2 = NULL;
3355                         return (p1 == p2 || strequal(p1, p2));
3356                 }
3357                 case P_SEP:
3358                         break;
3359         }
3360         return (False);
3361 }
3362
3363 /***************************************************************************
3364  Initialize any local varients in the sDefault table.
3365 ***************************************************************************/
3366
3367 void init_locals(void)
3368 {
3369         /* None as yet. */
3370 }
3371
3372 /***************************************************************************
3373  Process a new section (service). At this stage all sections are services.
3374  Later we'll have special sections that permit server parameters to be set.
3375  Returns True on success, False on failure. 
3376 ***************************************************************************/
3377
3378 static BOOL do_section(const char *pszSectionName)
3379 {
3380         BOOL bRetval;
3381         BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3382                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3383         bRetval = False;
3384
3385         /* if we were in a global section then do the local inits */
3386         if (bInGlobalSection && !isglobal)
3387                 init_locals();
3388
3389         /* if we've just struck a global section, note the fact. */
3390         bInGlobalSection = isglobal;
3391
3392         /* check for multiple global sections */
3393         if (bInGlobalSection) {
3394                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3395                 return (True);
3396         }
3397
3398         if (!bInGlobalSection && bGlobalOnly)
3399                 return (True);
3400
3401         /* if we have a current service, tidy it up before moving on */
3402         bRetval = True;
3403
3404         if (iServiceIndex >= 0)
3405                 bRetval = service_ok(iServiceIndex);
3406
3407         /* if all is still well, move to the next record in the services array */
3408         if (bRetval) {
3409                 /* We put this here to avoid an odd message order if messages are */
3410                 /* issued by the post-processing of a previous section. */
3411                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3412
3413                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3414                     < 0) {
3415                         DEBUG(0, ("Failed to add a new service\n"));
3416                         return (False);
3417                 }
3418         }
3419
3420         return (bRetval);
3421 }
3422
3423
3424 /***************************************************************************
3425  Determine if a partcular base parameter is currentl set to the default value.
3426 ***************************************************************************/
3427
3428 static BOOL is_default(int i)
3429 {
3430         if (!defaults_saved)
3431                 return False;
3432         switch (parm_table[i].type) {
3433                 case P_LIST:
3434                         return str_list_compare (parm_table[i].def.lvalue, 
3435                                                 *(char ***)parm_table[i].ptr);
3436                 case P_STRING:
3437                 case P_USTRING:
3438                         return strequal(parm_table[i].def.svalue,
3439                                         *(char **)parm_table[i].ptr);
3440                 case P_GSTRING:
3441                 case P_UGSTRING:
3442                         return strequal(parm_table[i].def.svalue,
3443                                         (char *)parm_table[i].ptr);
3444                 case P_BOOL:
3445                 case P_BOOLREV:
3446                         return parm_table[i].def.bvalue ==
3447                                 *(BOOL *)parm_table[i].ptr;
3448                 case P_CHAR:
3449                         return parm_table[i].def.cvalue ==
3450                                 *(char *)parm_table[i].ptr;
3451                 case P_INTEGER:
3452                 case P_OCTAL:
3453                 case P_ENUM:
3454                         return parm_table[i].def.ivalue ==
3455                                 *(int *)parm_table[i].ptr;
3456                 case P_SEP:
3457                         break;
3458         }
3459         return False;
3460 }
3461
3462 /***************************************************************************
3463 Display the contents of the global structure.
3464 ***************************************************************************/
3465
3466 static void dump_globals(FILE *f)
3467 {
3468         int i;
3469         param_opt_struct *data;
3470         
3471         fprintf(f, "# Global parameters\n[global]\n");
3472
3473         for (i = 0; parm_table[i].label; i++)
3474                 if (parm_table[i].class == P_GLOBAL &&
3475                     parm_table[i].ptr &&
3476                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3477                         if (defaults_saved && is_default(i))
3478                                 continue;
3479                         fprintf(f, "\t%s = ", parm_table[i].label);
3480                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
3481                         fprintf(f, "\n");
3482         }
3483         if (Globals.param_opt != NULL) {
3484                 data = Globals.param_opt;
3485                 while(data) {
3486                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3487                         data = data->next;
3488                 }
3489         }
3490
3491 }
3492
3493 /***************************************************************************
3494  Return True if a local parameter is currently set to the global default.
3495 ***************************************************************************/
3496
3497 BOOL lp_is_default(int snum, struct parm_struct *parm)
3498 {
3499         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3500
3501         return equal_parameter(parm->type,
3502                                ((char *)ServicePtrs[snum]) + pdiff,
3503                                ((char *)&sDefault) + pdiff);
3504 }
3505
3506 /***************************************************************************
3507  Display the contents of a single services record.
3508 ***************************************************************************/
3509
3510 static void dump_a_service(service * pService, FILE * f)
3511 {
3512         int i;
3513         param_opt_struct *data;
3514         
3515         if (pService != &sDefault)
3516                 fprintf(f, "\n[%s]\n", pService->szService);
3517
3518         for (i = 0; parm_table[i].label; i++)
3519                 if (parm_table[i].class == P_LOCAL &&
3520                     parm_table[i].ptr &&
3521                     (*parm_table[i].label != '-') &&
3522                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3523                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3524
3525                         if (pService == &sDefault) {
3526                                 if (defaults_saved && is_default(i))
3527                                         continue;
3528                         } else {
3529                                 if (equal_parameter(parm_table[i].type,
3530                                                     ((char *)pService) +
3531                                                     pdiff,
3532                                                     ((char *)&sDefault) +
3533                                                     pdiff))
3534                                         continue;
3535                         }
3536
3537                         fprintf(f, "\t%s = ", parm_table[i].label);
3538                         print_parameter(&parm_table[i],
3539                                         ((char *)pService) + pdiff, f);
3540                         fprintf(f, "\n");
3541         }
3542         if (pService->param_opt != NULL) {
3543                 data = pService->param_opt;
3544                 while(data) {
3545                         fprintf(f, "\t%s = %s\n", data->key, data->value);
3546                         data = data->next;
3547                 }
3548         }
3549 }
3550
3551
3552 /***************************************************************************
3553  Return info about the next service  in a service. snum==-1 gives the globals.
3554  Return NULL when out of parameters.
3555 ***************************************************************************/
3556
3557 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3558 {
3559         if (snum == -1) {
3560                 /* do the globals */
3561                 for (; parm_table[*i].label; (*i)++) {
3562                         if (parm_table[*i].class == P_SEPARATOR)
3563                                 return &parm_table[(*i)++];
3564
3565                         if (!parm_table[*i].ptr
3566                             || (*parm_table[*i].label == '-'))
3567                                 continue;
3568
3569                         if ((*i) > 0
3570                             && (parm_table[*i].ptr ==
3571                                 parm_table[(*i) - 1].ptr))
3572                                 continue;
3573
3574                         return &parm_table[(*i)++];
3575                 }
3576         } else {
3577                 service *pService = ServicePtrs[snum];
3578
3579                 for (; parm_table[*i].label; (*i)++) {
3580                         if (parm_table[*i].class == P_SEPARATOR)
3581                                 return &parm_table[(*i)++];
3582
3583                         if (parm_table[*i].class == P_LOCAL &&
3584                             parm_table[*i].ptr &&
3585                             (*parm_table[*i].label != '-') &&
3586                             ((*i) == 0 ||
3587                              (parm_table[*i].ptr !=
3588                               parm_table[(*i) - 1].ptr)))
3589                         {
3590                                 int pdiff =
3591                                         PTR_DIFF(parm_table[*i].ptr,
3592                                                  &sDefault);
3593
3594                                 if (allparameters ||
3595                                     !equal_parameter(parm_table[*i].type,
3596                                                      ((char *)pService) +
3597                                                      pdiff,
3598                                                      ((char *)&sDefault) +
3599                                                      pdiff))
3600                                 {
3601                                         return &parm_table[(*i)++];
3602                                 }
3603                         }
3604                 }
3605         }
3606
3607         return NULL;
3608 }
3609
3610
3611 #if 0
3612 /***************************************************************************
3613  Display the contents of a single copy structure.
3614 ***************************************************************************/
3615 static void dump_copy_map(BOOL *pcopymap)
3616 {
3617         int i;
3618         if (!pcopymap)
3619                 return;
3620
3621         printf("\n\tNon-Copied parameters:\n");
3622
3623         for (i = 0; parm_table[i].label; i++)
3624                 if (parm_table[i].class == P_LOCAL &&
3625                     parm_table[i].ptr && !pcopymap[i] &&
3626                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3627                 {
3628                         printf("\t\t%s\n", parm_table[i].label);
3629                 }
3630 }
3631 #endif
3632
3633 /***************************************************************************
3634  Return TRUE if the passed service number is within range.
3635 ***************************************************************************/
3636
3637 BOOL lp_snum_ok(int iService)
3638 {
3639         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
3640 }
3641
3642 /***************************************************************************
3643  Auto-load some home services.
3644 ***************************************************************************/
3645
3646 static void lp_add_auto_services(char *str)
3647 {
3648         char *s;
3649         char *p;
3650         int homes;
3651
3652         if (!str)
3653                 return;
3654
3655         s = strdup(str);
3656         if (!s)
3657                 return;
3658
3659         homes = lp_servicenumber(HOMES_NAME);
3660
3661         for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
3662                 char *home = get_user_home_dir(p);
3663
3664                 if (lp_servicenumber(p) >= 0)
3665                         continue;
3666
3667                 if (home && homes >= 0)
3668                         lp_add_home(p, homes, p, home);
3669         }
3670         SAFE_FREE(s);
3671 }
3672
3673 /***************************************************************************
3674  Auto-load one printer.
3675 ***************************************************************************/
3676
3677 void lp_add_one_printer(char *name, char *comment)
3678 {
3679         int printers = lp_servicenumber(PRINTERS_NAME);
3680         int i;
3681
3682         if (lp_servicenumber(name) < 0) {
3683                 lp_add_printer(name, printers);
3684                 if ((i = lp_servicenumber(name)) >= 0) {
3685                         string_set(&ServicePtrs[i]->comment, comment);
3686                         ServicePtrs[i]->autoloaded = True;
3687                 }
3688         }
3689 }
3690
3691 /***************************************************************************
3692  Announce ourselves as a print server.
3693 ***************************************************************************/
3694
3695 void update_server_announce_as_printserver(void)
3696 {
3697         default_server_announce |= SV_TYPE_PRINTQ_SERVER;       
3698 }
3699
3700 /***************************************************************************
3701  Have we loaded a services file yet?
3702 ***************************************************************************/
3703
3704 BOOL lp_loaded(void)
3705 {
3706         return (bLoaded);
3707 }
3708
3709 /***************************************************************************
3710  Unload unused services.
3711 ***************************************************************************/
3712
3713 void lp_killunused(BOOL (*snumused) (int))
3714 {
3715         int i;
3716         for (i = 0; i < iNumServices; i++) {
3717                 if (!VALID(i))
3718                         continue;
3719
3720                 if (!snumused || !snumused(i)) {
3721                         ServicePtrs[i]->valid = False;
3722                         free_service(ServicePtrs[i]);
3723                 }
3724         }
3725 }
3726
3727 /***************************************************************************
3728  Unload a service.
3729 ***************************************************************************/
3730
3731 void lp_killservice(int iServiceIn)
3732 {
3733         if (VALID(iServiceIn)) {
3734                 ServicePtrs[iServiceIn]->valid = False;
3735                 free_service(ServicePtrs[iServiceIn]);
3736         }
3737 }
3738
3739 /***************************************************************************
3740  Save the curent values of all global and sDefault parameters into the 
3741  defaults union. This allows swat and testparm to show only the
3742  changed (ie. non-default) parameters.
3743 ***************************************************************************/
3744
3745 static void lp_save_defaults(void)
3746 {
3747         int i;
3748         for (i = 0; parm_table[i].label; i++) {
3749                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
3750                         continue;
3751                 switch (parm_table[i].type) {
3752                         case P_LIST:
3753                                 str_list_copy(&(parm_table[i].def.lvalue),
3754                                             *(const char ***)parm_table[i].ptr);
3755                                 break;
3756                         case P_STRING:
3757                         case P_USTRING:
3758                                 if (parm_table[i].ptr) {
3759                                         parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
3760                                 } else {
3761                                         parm_table[i].def.svalue = NULL;
3762                                 }
3763                                 break;
3764                         case P_GSTRING:
3765                         case P_UGSTRING:
3766                                 if (parm_table[i].ptr) {
3767                                         parm_table[i].def.svalue = strdup((char *)parm_table[i].ptr);
3768                                 } else {
3769                                         parm_table[i].def.svalue = NULL;
3770                                 }
3771                                 break;
3772                         case P_BOOL:
3773                         case P_BOOLREV:
3774                                 parm_table[i].def.bvalue =
3775                                         *(BOOL *)parm_table[i].ptr;
3776                                 break;
3777                         case P_CHAR:
3778                                 parm_table[i].def.cvalue =
3779                                         *(char *)parm_table[i].ptr;
3780                                 break;
3781                         case P_INTEGER:
3782                         case P_OCTAL:
3783                         case P_ENUM:
3784                                 parm_table[i].def.ivalue =
3785                                         *(int *)parm_table[i].ptr;
3786                                 break;
3787                         case P_SEP:
3788                                 break;
3789                 }
3790         }
3791         defaults_saved = True;
3792 }
3793
3794 /*******************************************************************
3795  Set the server type we will announce as via nmbd.
3796 ********************************************************************/
3797
3798 static void set_server_role(void)
3799 {
3800         server_role = ROLE_STANDALONE;
3801
3802         switch (lp_security()) {
3803                 case SEC_SHARE:
3804                         if (lp_domain_logons())
3805                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
3806                         break;
3807                 case SEC_SERVER:
3808                         if (lp_domain_logons())
3809                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
3810                         server_role = ROLE_DOMAIN_MEMBER;
3811                         break;
3812                 case SEC_DOMAIN:
3813                         if (lp_domain_logons()) {
3814                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
3815                                 server_role = ROLE_DOMAIN_BDC;
3816                                 break;
3817                         }
3818                         server_role = ROLE_DOMAIN_MEMBER;
3819                         break;
3820                 case SEC_ADS:
3821                         if (lp_domain_logons()) {
3822                                 server_role = ROLE_DOMAIN_PDC;
3823                                 break;
3824                         }
3825                         server_role = ROLE_DOMAIN_MEMBER;
3826                         break;
3827                 case SEC_USER:
3828                         if (lp_domain_logons()) {
3829
3830                                 if (Globals.bDomainMaster) /* auto or yes */ 
3831                                         server_role = ROLE_DOMAIN_PDC;
3832                                 else
3833                                         server_role = ROLE_DOMAIN_BDC;
3834                         }
3835                         break;
3836                 default:
3837                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
3838                         break;
3839         }
3840
3841         DEBUG(10, ("set_server_role: role = "));
3842
3843         switch(server_role) {
3844         case ROLE_STANDALONE:
3845                 DEBUGADD(10, ("ROLE_STANDALONE\n"));
3846                 break;
3847         case ROLE_DOMAIN_MEMBER:
3848                 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
3849                 break;
3850         case ROLE_DOMAIN_BDC:
3851                 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
3852                 break;
3853         case ROLE_DOMAIN_PDC:
3854                 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
3855                 break;
3856         }
3857 }
3858
3859 /***************************************************************************
3860  Load the services array from the services file. Return True on success, 
3861  False on failure.
3862 ***************************************************************************/
3863
3864 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3865              BOOL add_ipc)
3866 {
3867         pstring n2;
3868         BOOL bRetval;
3869         param_opt_struct *data, *pdata;
3870
3871         pstrcpy(n2, pszFname);
3872         standard_sub_basic(current_user_info.smb_name, n2,sizeof(n2));
3873
3874         add_to_file_list(pszFname, n2);
3875
3876         bRetval = False;
3877
3878         DEBUG(3, ("lp_load: refreshing parameters\n"));
3879         
3880         bInGlobalSection = True;
3881         bGlobalOnly = global_only;
3882
3883         init_globals();
3884         debug_init();
3885
3886         if (save_defaults)
3887         {
3888                 init_locals();
3889                 lp_save_defaults();
3890         }
3891
3892         if (Globals.param_opt != NULL) {
3893                 data = Globals.param_opt;
3894                 while (data) {
3895                         string_free(&data->key);
3896                         string_free(&data->value);
3897                         pdata = data->next;
3898                         SAFE_FREE(data);
3899                         data = pdata;
3900                 }
3901                 Globals.param_opt = NULL;
3902         }
3903         
3904         /* We get sections first, so have to start 'behind' to make up */
3905         iServiceIndex = -1;
3906         bRetval = pm_process(n2, do_section, do_parameter);
3907
3908         /* finish up the last section */
3909         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3910         if (bRetval)
3911                 if (iServiceIndex >= 0)
3912                         bRetval = service_ok(iServiceIndex);
3913
3914         lp_add_auto_services(lp_auto_services());
3915
3916         if (add_ipc) {
3917                 /* When 'restrict anonymous = 2' guest connections to ipc$
3918                    are denied */
3919                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3920                 lp_add_ipc("ADMIN$", False);
3921         }
3922
3923         set_server_role();
3924         set_default_server_announce_type();
3925
3926         bLoaded = True;
3927
3928         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3929         /* if bWINSsupport is true and we are in the client            */
3930         if (in_client && Globals.bWINSsupport) {
3931                 lp_do_parameter(-1, "wins server", "127.0.0.1");
3932         }
3933
3934         init_iconv();
3935
3936         return (bRetval);
3937 }
3938
3939 /***************************************************************************
3940  Reset the max number of services.
3941 ***************************************************************************/
3942
3943 void lp_resetnumservices(void)
3944 {
3945         iNumServices = 0;
3946 }
3947
3948 /***************************************************************************
3949  Return the max number of services.
3950 ***************************************************************************/
3951
3952 int lp_numservices(void)
3953 {
3954         return (iNumServices);
3955 }
3956
3957 /***************************************************************************
3958 Display the contents of the services array in human-readable form.
3959 ***************************************************************************/
3960
3961 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3962 {
3963         int iService;
3964
3965         if (show_defaults)
3966                 defaults_saved = False;
3967
3968         dump_globals(f);
3969
3970         dump_a_service(&sDefault, f);
3971
3972         for (iService = 0; iService < maxtoprint; iService++)
3973                 lp_dump_one(f, show_defaults, iService);
3974 }
3975
3976 /***************************************************************************
3977 Display the contents of one service in human-readable form.
3978 ***************************************************************************/
3979
3980 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3981 {
3982         if (VALID(snum)) {
3983                 if (ServicePtrs[snum]->szService[0] == '\0')
3984                         return;
3985                 dump_a_service(ServicePtrs[snum], f);
3986         }
3987 }
3988
3989 /***************************************************************************
3990 Return the number of the service with the given name, or -1 if it doesn't
3991 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3992 getservicebyname()! This works ONLY if all services have been loaded, and
3993 does not copy the found service.
3994 ***************************************************************************/
3995
3996 int lp_servicenumber(const char *pszServiceName)
3997 {
3998         int iService;
3999         fstring serviceName;
4000  
4001  
4002         for (iService = iNumServices - 1; iService >= 0; iService--) {
4003                 if (VALID(iService) && ServicePtrs[iService]->szService) {
4004                         /*
4005                          * The substitution here is used to support %U is
4006                          * service names
4007                          */
4008                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
4009                         standard_sub_basic(current_user_info.smb_name, serviceName,sizeof(serviceName));
4010                         if (strequal(serviceName, pszServiceName))
4011                                 break;
4012                 }
4013         }
4014
4015         if (iService < 0)
4016                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
4017
4018         return (iService);
4019 }
4020
4021 /*******************************************************************
4022  A useful volume label function. 
4023 ********************************************************************/
4024
4025 char *volume_label(int snum)
4026 {
4027         char *ret = lp_volume(snum);
4028         if (!*ret)
4029                 return lp_servicename(snum);
4030         return (ret);
4031 }
4032
4033
4034 /*******************************************************************
4035  Set the server type we will announce as via nmbd.
4036 ********************************************************************/
4037
4038 static void set_default_server_announce_type(void)
4039 {
4040         default_server_announce = 0;
4041         default_server_announce |= SV_TYPE_WORKSTATION;
4042         default_server_announce |= SV_TYPE_SERVER;
4043         default_server_announce |= SV_TYPE_SERVER_UNIX;
4044
4045         switch (lp_announce_as()) {
4046                 case ANNOUNCE_AS_NT_SERVER:
4047                         default_server_announce |= SV_TYPE_SERVER_NT;
4048                         /* fall through... */
4049                 case ANNOUNCE_AS_NT_WORKSTATION:
4050                         default_server_announce |= SV_TYPE_NT;
4051                         break;
4052                 case ANNOUNCE_AS_WIN95:
4053                         default_server_announce |= SV_TYPE_WIN95_PLUS;
4054                         break;
4055                 case ANNOUNCE_AS_WFW:
4056                         default_server_announce |= SV_TYPE_WFW;
4057                         break;
4058                 default:
4059                         break;
4060         }
4061
4062         switch (lp_server_role()) {
4063                 case ROLE_DOMAIN_MEMBER:
4064                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
4065                         break;
4066                 case ROLE_DOMAIN_PDC:
4067                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
4068                         break;
4069                 case ROLE_DOMAIN_BDC:
4070                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
4071                         break;
4072                 case ROLE_STANDALONE:
4073                 default:
4074                         break;
4075         }
4076         if (lp_time_server())
4077                 default_server_announce |= SV_TYPE_TIME_SOURCE;
4078
4079         if (lp_host_msdfs())
4080                 default_server_announce |= SV_TYPE_DFS_SERVER;
4081 }
4082
4083 /***********************************************************
4084  returns role of Samba server
4085 ************************************************************/
4086
4087 int lp_server_role(void)
4088 {
4089         return server_role;
4090 }
4091
4092 /***********************************************************
4093  If we are PDC then prefer us as DMB
4094 ************************************************************/
4095
4096 BOOL lp_domain_master(void)
4097 {
4098         if (Globals.bDomainMaster == Auto)
4099                 return (lp_server_role() == ROLE_DOMAIN_PDC);
4100
4101         return Globals.bDomainMaster;
4102 }
4103
4104 /***********************************************************
4105  If we are DMB then prefer us as LMB
4106 ************************************************************/
4107
4108 BOOL lp_preferred_master(void)
4109 {
4110         if (Globals.bPreferredMaster == Auto)
4111                 return (lp_local_master() && lp_domain_master());
4112
4113         return Globals.bPreferredMaster;
4114 }
4115
4116 /*******************************************************************
4117  Remove a service.
4118 ********************************************************************/
4119
4120 void lp_remove_service(int snum)
4121 {
4122         ServicePtrs[snum]->valid = False;
4123 }
4124
4125 /*******************************************************************
4126  Copy a service.
4127 ********************************************************************/
4128
4129 void lp_copy_service(int snum, const char *new_name)
4130 {
4131         char *oldname = lp_servicename(snum);
4132         do_section(new_name);
4133         if (snum >= 0) {
4134                 snum = lp_servicenumber(new_name);
4135                 if (snum >= 0)
4136                         lp_do_parameter(snum, "copy", oldname);
4137         }
4138 }
4139
4140
4141 /*******************************************************************
4142  Get the default server type we will announce as via nmbd.
4143 ********************************************************************/
4144
4145 int lp_default_server_announce(void)
4146 {
4147         return default_server_announce;
4148 }
4149
4150 /*******************************************************************
4151  Split the announce version into major and minor numbers.
4152 ********************************************************************/
4153
4154 int lp_major_announce_version(void)
4155 {
4156         static BOOL got_major = False;
4157         static int major_version = DEFAULT_MAJOR_VERSION;
4158         char *vers;
4159         char *p;
4160
4161         if (got_major)
4162                 return major_version;
4163
4164         got_major = True;
4165         if ((vers = lp_announce_version()) == NULL)
4166                 return major_version;
4167
4168         if ((p = strchr_m(vers, '.')) == 0)
4169                 return major_version;
4170
4171         *p = '\0';
4172         major_version = atoi(vers);
4173         return major_version;
4174 }
4175
4176 int lp_minor_announce_version(void)
4177 {
4178         static BOOL got_minor = False;
4179         static int minor_version = DEFAULT_MINOR_VERSION;
4180         char *vers;
4181         char *p;
4182
4183         if (got_minor)
4184                 return minor_version;
4185
4186         got_minor = True;
4187         if ((vers = lp_announce_version()) == NULL)
4188                 return minor_version;
4189
4190         if ((p = strchr_m(vers, '.')) == 0)
4191                 return minor_version;
4192
4193         p++;
4194         minor_version = atoi(p);
4195         return minor_version;
4196 }
4197
4198 /***********************************************************
4199  Set the global name resolution order (used in smbclient).
4200 ************************************************************/
4201
4202 void lp_set_name_resolve_order(char *new_order)
4203 {
4204         Globals.szNameResolveOrder = new_order;
4205 }
4206
4207 const char *lp_printername(int snum)
4208 {
4209         const char *ret = _lp_printername(snum);
4210         if (ret == NULL || (ret != NULL && *ret == '\0'))
4211                 ret = lp_const_servicename(snum);
4212
4213         return ret;
4214 }
4215
4216
4217 /****************************************************************
4218  Compatibility fn. for 2.2.2 code.....
4219 *****************************************************************/
4220
4221 void get_private_directory(pstring privdir)
4222 {
4223         pstrcpy (privdir, lp_private_dir());
4224 }
4225
4226 /***********************************************************
4227  Allow daemons such as winbindd to fix their logfile name.
4228 ************************************************************/
4229
4230 void lp_set_logfile(const char *name)
4231 {
4232         extern pstring debugf;
4233         string_set(&Globals.szLogFile, name);
4234         pstrcpy(debugf, name);
4235 }
4236
4237 /*******************************************************************
4238  Return the NetBIOS called name.
4239 ********************************************************************/
4240
4241 const char *get_called_name(void)
4242 {
4243         extern fstring local_machine;
4244         static fstring called_name;
4245
4246         if (! *local_machine)
4247                 return global_myname();
4248
4249         /*
4250          * Windows NT/2k uses "*SMBSERVER" and XP uses "*SMBSERV"
4251          * arrggg!!! but we've already rewritten the client's
4252          * netbios name at this point...
4253          */
4254
4255         if (*local_machine) {
4256                 if (!StrCaseCmp(local_machine, "_SMBSERVER") || !StrCaseCmp(local_machine, "_SMBSERV")) {
4257                         fstrcpy(called_name, get_my_primary_ip());
4258                         DEBUG(8,("get_called_name: assuming that client used IP address [%s] as called name.\n",
4259                                 called_name));
4260                         return called_name;
4261                 }
4262         }
4263
4264         return local_machine;
4265 }
4266
4267 /*******************************************************************
4268  Return the max print jobs per queue.
4269 ********************************************************************/
4270
4271 int lp_maxprintjobs(int snum)
4272 {
4273         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
4274         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
4275                 maxjobs = PRINT_MAX_JOBID - 1;
4276
4277         return maxjobs;
4278 }