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