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