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