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