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