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