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