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