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