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