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