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