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