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