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