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