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