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