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