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