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