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