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