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