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