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