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