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