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