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