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