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