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