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