1 /*
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Parameter loading functions
5 
6    Copyright (C) Karl Auer 1993-1998
7 
8    Copyright (C) 2011-2021
9    Free Software Foundation, Inc.
10 
11    Largely re-written by Andrew Tridgell, September 1994
12 
13    This file is part of the Midnight Commander.
14 
15    The Midnight Commander is free software: you can redistribute it
16    and/or modify it under the terms of the GNU General Public License as
17    published by the Free Software Foundation, either version 3 of the License,
18    or (at your option) any later version.
19 
20    The Midnight Commander is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23    GNU General Public License for more details.
24 
25    You should have received a copy of the GNU General Public License
26    along with this program.  If not, see <http://www.gnu.org/licenses/>.
27  */
28 
29 /*
30  *  Load parameters.
31  *
32  *  This module provides suitable callback functions for the params
33  *  module. It builds the internal table of service details which is
34  *  then used by the rest of the server.
35  *
36  * To add a parameter:
37  *
38  * 1) add it to the global or service structure definition
39  * 2) add it to the parm_table
40  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
41  * 4) If it's a global then initialise it in init_globals. If a local
42  *    (ie. service) parameter then initialise it in the sDefault structure
43  *
44  *
45  * Notes:
46  *   The configuration file is processed sequentially for speed. It is NOT
47  *   accessed randomly as happens in 'real' Windows. For this reason, there
48  *   is a fair bit of sequence-dependent code here - ie., code which assumes
49  *   that certain things happen before others. In particular, the code which
50  *   happens at the boundary between sections is delicately poised, so be
51  *   careful!
52  *
53  */
54 
55 #include "includes.h"
56 
57 /* Set default coding system for KANJI if none specified in Makefile. */
58 /*
59  * We treat KANJI specially due to historical precedent (it was the
60  * first non-english codepage added to Samba). With the new dynamic
61  * codepage support this is not needed anymore.
62  *
63  * The define 'KANJI' is being overloaded to mean 'use kanji codepage
64  * by default' and also 'this is the filename-to-disk conversion
65  * method to use'. This really should be removed and all control
66  * over this left in the smb.conf parameters 'client codepage'
67  * and 'coding system'.
68  */
69 #ifndef KANJI
70 #define KANJI "sbcs"
71 #endif /* KANJI */
72 
73 BOOL in_client = False;         /* Not in the client by default */
74 BOOL bLoaded = False;
75 
76 extern int DEBUGLEVEL;
77 extern pstring user_socket_options;
78 extern pstring global_myname;
79 pstring global_scope = "";
80 
81 #ifndef GLOBAL_NAME
82 #define GLOBAL_NAME "global"
83 #endif
84 
85 #ifndef PRINTERS_NAME
86 #define PRINTERS_NAME "printers"
87 #endif
88 
89 #ifndef HOMES_NAME
90 #define HOMES_NAME "homes"
91 #endif
92 
93 /* some helpful bits */
94 #define pSERVICE(i) ServicePtrs[i]
95 #define iSERVICE(i) (*pSERVICE(i))
96 #define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
97 #define VALID(i) iSERVICE(i).valid
98 
99 int keepalive = DEFAULT_KEEPALIVE;
100 static BOOL use_getwd_cache;
101 
102 extern int extra_time_offset;
103 
104 /*
105  * This structure describes global (ie., server-wide) parameters.
106  */
107 typedef struct
108 {
109     char *szPrintcapname;
110     char *szLockDir;
111     char *szRootdir;
112     char *szDefaultService;
113     char *szDfree;
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 *szPasswordServer;
124     char *szSocketOptions;
125     char *szValidChars;
126     char *szWorkGroup;
127     char *szDomainAdminGroup;
128     char *szDomainGuestGroup;
129     char *szDomainAdminUsers;
130     char *szDomainGuestUsers;
131     char *szDomainHostsallow;
132     char *szDomainHostsdeny;
133     char *szUsernameMap;
134 #ifdef USING_GROUPNAME_MAP
135     char *szGroupnameMap;
136 #endif                          /* USING_GROUPNAME_MAP */
137     char *szCharacterSet;
138     char *szLogonScript;
139     char *szLogonPath;
140     char *szLogonDrive;
141     char *szLogonHome;
142     char *szSmbrun;
143     char *szWINSserver;
144     char *szCodingSystem;
145     char *szInterfaces;
146     char *szRemoteAnnounce;
147     char *szRemoteBrowseSync;
148     char *szSocketAddress;
149     char *szNISHomeMapName;
150     char *szAnnounceVersion;    /* This is initialised in init_globals */
151     char *szNetbiosAliases;
152     char *szDomainOtherSIDs;
153     char *szDomainGroups;
154     char *szDriverFile;
155     char *szNameResolveOrder;
156     char *szLdapServer;
157     char *szLdapSuffix;
158     char *szLdapFilter;
159     char *szLdapRoot;
160     char *szLdapRootPassword;
161     char *szPanicAction;
162     char *szAddUserScript;
163     char *szDelUserScript;
164     int max_log_size;
165     int mangled_stack;
166     int max_xmit;
167     int max_mux;
168     int max_open_files;
169     int max_packet;
170     int pwordlevel;
171     int unamelevel;
172     int deadtime;
173     int maxprotocol;
174     int security;
175     int maxdisksize;
176     int lpqcachetime;
177     int syslog;
178     int os_level;
179     int max_ttl;
180     int max_wins_ttl;
181     int min_wins_ttl;
182     int ReadSize;
183     int lm_announce;
184     int lm_interval;
185     int shmem_size;
186     int client_code_page;
187     int announce_as;            /* This is initialised in init_globals */
188     int machine_password_timeout;
189     int change_notify_timeout;
190     int stat_cache_size;
191     int map_to_guest;
192     int min_passwd_length;
193     int oplock_break_wait_time;
194 #ifdef WITH_LDAP
195     int ldap_port;
196 #endif                          /* WITH_LDAP */
197 #ifdef WITH_SSL
198     int sslVersion;
199     char *sslHostsRequire;
200     char *sslHostsResign;
201     char *sslCaCertDir;
202     char *sslCaCertFile;
203     char *sslCert;
204     char *sslPrivKey;
205     char *sslClientCert;
206     char *sslClientPrivKey;
207     char *sslCiphers;
208     BOOL sslEnabled;
209     BOOL sslReqClientCert;
210     BOOL sslReqServerCert;
211     BOOL sslCompatibility;
212 #endif                          /* WITH_SSL */
213     BOOL bDNSproxy;
214     BOOL bWINSsupport;
215     BOOL bWINSproxy;
216     BOOL bLocalMaster;
217     BOOL bPreferredMaster;
218     BOOL bDomainMaster;
219     BOOL bDomainLogons;
220     BOOL bEncryptPasswords;
221     BOOL bUpdateEncrypt;
222     BOOL bStripDot;
223     BOOL bNullPasswords;
224     BOOL bLoadPrinters;
225     BOOL bUseRhosts;
226     BOOL bReadRaw;
227     BOOL bWriteRaw;
228     BOOL bReadPrediction;
229     BOOL bReadbmpx;
230     BOOL bSyslogOnly;
231     BOOL bBrowseList;
232     BOOL bUnixRealname;
233     BOOL bNISHomeMap;
234     BOOL bTimeServer;
235     BOOL bBindInterfacesOnly;
236     BOOL bUnixPasswdSync;
237     BOOL bPasswdChatDebug;
238     BOOL bOleLockingCompat;
239     BOOL bTimestampLogs;
240     BOOL bNTSmbSupport;
241     BOOL bNTPipeSupport;
242     BOOL bNTAclSupport;
243     BOOL bStatCache;
244     BOOL bKernelOplocks;
245     BOOL bAllowTrustedDomains;
246     BOOL bRestrictAnonymous;
247 } global;
248 
249 static global Globals;
250 
251 
252 
253 /*
254  * This structure describes a single service.
255  */
256 typedef struct
257 {
258     BOOL valid;
259     char *szService;
260     char *szPath;
261     char *szUsername;
262     char *szGuestaccount;
263     char *szInvalidUsers;
264     char *szValidUsers;
265     char *szAdminUsers;
266     char *szCopy;
267     char *szInclude;
268     char *szPreExec;
269     char *szPostExec;
270     char *szRootPreExec;
271     char *szRootPostExec;
272     char *szPrintcommand;
273     char *szLpqcommand;
274     char *szLprmcommand;
275     char *szLppausecommand;
276     char *szLpresumecommand;
277     char *szQueuepausecommand;
278     char *szQueueresumecommand;
279     char *szPrintername;
280     char *szPrinterDriver;
281     char *szPrinterDriverLocation;
282     char *szDontdescend;
283     char *szHostsallow;
284     char *szHostsdeny;
285     char *szMagicScript;
286     char *szMagicOutput;
287     char *szMangledMap;
288     char *szVetoFiles;
289     char *szHideFiles;
290     char *szVetoOplockFiles;
291     char *comment;
292     char *force_user;
293     char *force_group;
294     char *readlist;
295     char *writelist;
296     char *volume;
297     char *fstype;
298     int iMinPrintSpace;
299     int iCreate_mask;
300     int iCreate_force_mode;
301     int iDir_mask;
302     int iDir_force_mode;
303     int iMaxConnections;
304     int iDefaultCase;
305     int iPrinting;
306     int iOplockContentionLimit;
307     BOOL bAlternatePerm;
308     BOOL bRevalidate;
309     BOOL bCaseSensitive;
310     BOOL bCasePreserve;
311     BOOL bShortCasePreserve;
312     BOOL bCaseMangle;
313     BOOL status;
314     BOOL bHideDotFiles;
315     BOOL bBrowseable;
316     BOOL bAvailable;
317     BOOL bRead_only;
318     BOOL bNo_set_dir;
319     BOOL bGuest_only;
320     BOOL bGuest_ok;
321     BOOL bPrint_ok;
322     BOOL bPostscript;
323     BOOL bMap_system;
324     BOOL bMap_hidden;
325     BOOL bMap_archive;
326     BOOL bLocking;
327     BOOL bStrictLocking;
328     BOOL bShareModes;
329     BOOL bOpLocks;
330     BOOL bOnlyUser;
331     BOOL bMangledNames;
332     BOOL bWidelinks;
333     BOOL bSymlinks;
334     BOOL bSyncAlways;
335     BOOL bStrictSync;
336     char magic_char;
337     BOOL *copymap;
338     BOOL bDeleteReadonly;
339     BOOL bFakeOplocks;
340     BOOL bDeleteVetoFiles;
341     BOOL bDosFiletimes;
342     BOOL bDosFiletimeResolution;
343     BOOL bFakeDirCreateTimes;
344     BOOL bBlockingLocks;
345     BOOL bMangleLocks;
346     char dummy[3];              /* for alignment */
347 } service;
348 
349 
350 /* This is a default service used to prime a services structure */
351 static service sDefault = {
352     True,                       /* valid */
353     NULL,                       /* szService */
354     NULL,                       /* szPath */
355     NULL,                       /* szUsername */
356     NULL,                       /* szGuestAccount  - this is set in init_globals() */
357     NULL,                       /* szInvalidUsers */
358     NULL,                       /* szValidUsers */
359     NULL,                       /* szAdminUsers */
360     NULL,                       /* szCopy */
361     NULL,                       /* szInclude */
362     NULL,                       /* szPreExec */
363     NULL,                       /* szPostExec */
364     NULL,                       /* szRootPreExec */
365     NULL,                       /* szRootPostExec */
366     NULL,                       /* szPrintcommand */
367     NULL,                       /* szLpqcommand */
368     NULL,                       /* szLprmcommand */
369     NULL,                       /* szLppausecommand */
370     NULL,                       /* szLpresumecommand */
371     NULL,                       /* szQueuepausecommand */
372     NULL,                       /* szQueueresumecommand */
373     NULL,                       /* szPrintername */
374     NULL,                       /* szPrinterDriver - this is set in init_globals() */
375     NULL,                       /* szPrinterDriverLocation */
376     NULL,                       /* szDontdescend */
377     NULL,                       /* szHostsallow */
378     NULL,                       /* szHostsdeny */
379     NULL,                       /* szMagicScript */
380     NULL,                       /* szMagicOutput */
381     NULL,                       /* szMangledMap */
382     NULL,                       /* szVetoFiles */
383     NULL,                       /* szHideFiles */
384     NULL,                       /* szVetoOplockFiles */
385     NULL,                       /* comment */
386     NULL,                       /* force user */
387     NULL,                       /* force group */
388     NULL,                       /* readlist */
389     NULL,                       /* writelist */
390     NULL,                       /* volume */
391     NULL,                       /* fstype */
392     0,                          /* iMinPrintSpace */
393     0744,                       /* iCreate_mask */
394     0000,                       /* iCreate_force_mode */
395     0755,                       /* iDir_mask */
396     0000,                       /* iDir_force_mode */
397     0,                          /* iMaxConnections */
398     CASE_LOWER,                 /* iDefaultCase */
399     DEFAULT_PRINTING,           /* iPrinting */
400     2,                          /* iOplockContentionLimit */
401     False,                      /* bAlternatePerm */
402     False,                      /* revalidate */
403     False,                      /* case sensitive */
404     True,                       /* case preserve */
405     True,                       /* short case preserve */
406     False,                      /* case mangle */
407     True,                       /* status */
408     True,                       /* bHideDotFiles */
409     True,                       /* bBrowseable */
410     True,                       /* bAvailable */
411     True,                       /* bRead_only */
412     True,                       /* bNo_set_dir */
413     False,                      /* bGuest_only */
414     False,                      /* bGuest_ok */
415     False,                      /* bPrint_ok */
416     False,                      /* bPostscript */
417     False,                      /* bMap_system */
418     False,                      /* bMap_hidden */
419     True,                       /* bMap_archive */
420     True,                       /* bLocking */
421     False,                      /* bStrictLocking */
422     True,                       /* bShareModes */
423     True,                       /* bOpLocks */
424     False,                      /* bOnlyUser */
425     True,                       /* bMangledNames */
426     True,                       /* bWidelinks */
427     True,                       /* bSymlinks */
428     False,                      /* bSyncAlways */
429     False,                      /* bStrictSync */
430     '~',                        /* magic char */
431     NULL,                       /* copymap */
432     False,                      /* bDeleteReadonly */
433     False,                      /* bFakeOplocks */
434     False,                      /* bDeleteVetoFiles */
435     False,                      /* bDosFiletimes */
436     False,                      /* bDosFiletimeResolution */
437     False,                      /* bFakeDirCreateTimes */
438     True,                       /* bBlockingLocks */
439     True,                       /* bMangleLocks */
440     ""                          /* dummy */
441 };
442 
443 
444 
445 /* local variables */
446 static service **ServicePtrs = NULL;
447 static int iNumServices = 0;
448 static int iServiceIndex = 0;
449 static BOOL bInGlobalSection = True;
450 static BOOL bGlobalOnly = False;
451 
452 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
453 
454 /* prototypes for the special type handlers */
455 static BOOL handle_valid_chars (const char *pszParmValue, char **ptr);
456 static BOOL handle_include (const char *pszParmValue, char **ptr);
457 static BOOL handle_copy (const char *pszParmValue, char **ptr);
458 static BOOL handle_character_set (const char *pszParmValue, char **ptr);
459 static BOOL handle_coding_system (const char *pszParmValue, char **ptr);
460 #if 0
461 static void set_default_server_announce_type (void);
462 #endif /* 0 */
463 static struct enum_list const enum_protocol[] =
464     { {PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
465 {PROTOCOL_LANMAN1, "LANMAN1"}, {PROTOCOL_CORE, "CORE"},
466 {PROTOCOL_COREPLUS, "COREPLUS"},
467 {PROTOCOL_COREPLUS, "CORE+"}, {-1, NULL}
468 };
469 
470 static struct enum_list const enum_security[] = { {SEC_SHARE, "SHARE"}, {SEC_USER, "USER"},
471 {SEC_SERVER, "SERVER"}, {SEC_DOMAIN, "DOMAIN"},
472 {-1, NULL}
473 };
474 
475 static struct enum_list const enum_printing[] = { {PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"},
476 {PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
477 {PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
478 {PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"},
479 {-1, NULL}
480 };
481 
482 /* Types of machine we can announce as. */
483 #define ANNOUNCE_AS_NT_SERVER 1
484 #define ANNOUNCE_AS_WIN95 2
485 #define ANNOUNCE_AS_WFW 3
486 #define ANNOUNCE_AS_NT_WORKSTATION 4
487 
488 /* *INDENT-OFF* */
489 static struct enum_list const enum_announce_as[] =
490 {
491     {ANNOUNCE_AS_NT_SERVER, "NT"},
492     {ANNOUNCE_AS_NT_SERVER, "NT Server"},
493     {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
494     {ANNOUNCE_AS_WIN95, "win95"},
495     {ANNOUNCE_AS_WFW, "WfW"},
496     {-1, NULL}
497 };
498 /* *INDENT-ON* */
499 
500 static struct enum_list const enum_case[] =
501     { {CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL} };
502 
503 static struct enum_list const enum_lm_announce[] =
504     { {0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL} };
505 
506 /*
507    Do you want session setups at user level security with a invalid
508    password to be rejected or allowed in as guest? WinNT rejects them
509    but it can be a pain as it means "net view" needs to use a password
510 
511    You have 3 choices in the setting of map_to_guest:
512 
513    "Never" means session setups with an invalid password
514    are rejected. This is the default.
515 
516    "Bad User" means session setups with an invalid password
517    are rejected, unless the username does not exist, in which case it
518    is treated as a guest login
519 
520    "Bad Password" means session setups with an invalid password
521    are treated as a guest login
522 
523    Note that map_to_guest only has an effect in user or server
524    level security.
525  */
526 
527 /* *INDENT-OFF* */
528 static struct enum_list const enum_map_to_guest[] =
529 {
530     {NEVER_MAP_TO_GUEST, "Never"},
531     {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
532     {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
533     {-1, NULL}
534 };
535 /* *INDENT-ON* */
536 
537 #ifdef WITH_SSL
538 static struct enum_list const enum_ssl_version[] = { {SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3, "ssl3"},
539 {SMB_SSL_V23, "ssl2or3"}, {SMB_SSL_TLS1, "tls1"}, {-1, NULL}
540 };
541 #endif
542 
543 #define PARM_SEPARATOR(label) {label, P_SEP, P_SEPARATOR, NULL, NULL, NULL, 0, {0}}
544 /* note that we do not initialise the defaults union - it is not allowed in ANSI C */
545 static struct parm_struct const parm_table[] = {
546     PARM_SEPARATOR ("Base Options"),
547     {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL,
548      FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}},
549     {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_SHARE | FLAG_PRINT,
550      {0}},
551     {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0, {0}},
552     {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC, {0}},
553     {"netbios name", P_UGSTRING, P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC, {0}},
554     {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0, {0}},
555     {"netbios scope", P_UGSTRING, P_GLOBAL, global_scope, NULL, NULL, 0, {0}},
556     {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC, {0}},
557     {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC, {0}},
558     {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, 0, {0}},
559 
560     PARM_SEPARATOR ("Security Options"),
561     {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC, {0}},
562     {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC,
563      {0}},
564     {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC, {0}},
565     {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, 0, {0}},
566     {"alternate permissions", P_BOOL, P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL,
567      FLAG_GLOBAL | FLAG_DEPRECATED, {0}},
568     {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0, {0}},
569     {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0, {0}},
570     {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0, {0}},
571     {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, 0, {0}},
572     {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0, {0}},
573     {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0, {0}},
574     {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0, {0}},
575     {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0, {0}},
576     {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0, {0}},
577     {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0, {0}},
578     {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, 0, {0}},
579     {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, 0, {0}},
580     {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, 0, {0}},
581     {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, 0, {0}},
582     {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0, {0}},
583     {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0, {0}},
584     {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0, {0}},
585     {"restrict anonymous", P_BOOL, P_GLOBAL, &Globals.bRestrictAnonymous, NULL, NULL, 0, {0}},
586     {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE,
587      {0}},
588     {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0, {0}},
589     {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE,
590      {0}},
591     {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0, {0}},
592     {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0, {0}},
593     {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL,
594      FLAG_BASIC | FLAG_SHARE | FLAG_PRINT | FLAG_GLOBAL, {0}},
595     {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL,
596      FLAG_GLOBAL | FLAG_SHARE, {0}},
597     {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE,
598      {0}},
599     {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE,
600      {0}},
601     {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE, {0}},
602     {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE,
603      {0}},
604     {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE, {0}},
605     {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE, {0}},
606     {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0, {0}},
607     {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_SHARE, {0}},
608     {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0, {0}},
609     {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0, {0}},
610     {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0, {0}},
611     {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE,
612      {0}},
613     {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL, {0}},
614     {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL,
615      FLAG_GLOBAL | FLAG_SHARE, {0}},
616     {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE,
617      {0}},
618     {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL, {0}},
619     {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL,
620      FLAG_GLOBAL | FLAG_SHARE, {0}},
621     {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE, {0}},
622     {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0, {0}},
623     {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL,
624      FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}},
625     {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0, {0}},
626     {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE, {0}},
627     {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL,
628      FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}},
629     {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0, {0}},
630     {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL,
631      FLAG_GLOBAL | FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}},
632     {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0, {0}},
633 
634 #ifdef WITH_SSL
635     PARM_SEPARATOR ("Secure Socket Layer Options"),
636     {"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0, {0}},
637     {"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0, {0}},
638     {"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0},
639     {"ssl CA certDir", P_STRING, P_GLOBAL, &Globals.sslCaCertDir, NULL, NULL, 0, {0}},
640     {"ssl CA certFile", P_STRING, P_GLOBAL, &Globals.sslCaCertFile, NULL, NULL, 0, {0}},
641     {"ssl server cert", P_STRING, P_GLOBAL, &Globals.sslCert, NULL, NULL, 0, {0}},
642     {"ssl server key", P_STRING, P_GLOBAL, &Globals.sslPrivKey, NULL, NULL, 0, {0}},
643     {"ssl client cert", P_STRING, P_GLOBAL, &Globals.sslClientCert, NULL, NULL, 0, {0}},
644     {"ssl client key", P_STRING, P_GLOBAL, &Globals.sslClientPrivKey, NULL, NULL, 0, {0}},
645     {"ssl require clientcert", P_BOOL, P_GLOBAL, &Globals.sslReqClientCert, NULL, NULL, 0, {0}},
646     {"ssl require servercert", P_BOOL, P_GLOBAL, &Globals.sslReqServerCert, NULL, NULL, 0, {0}},
647     {"ssl ciphers", P_STRING, P_GLOBAL, &Globals.sslCiphers, NULL, NULL, 0, {0}},
648     {"ssl version", P_ENUM, P_GLOBAL, &Globals.sslVersion, NULL, enum_ssl_version, 0, {0}},
649     {"ssl compatibility", P_BOOL, P_GLOBAL, &Globals.sslCompatibility, NULL, NULL, 0, {0}},
650 #endif /* WITH_SSL */
651 
652     PARM_SEPARATOR ("Logging Options"),
653     {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC, {0}},
654     {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0, {0}},
655     {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0, {0}},
656     {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0, {0}},
657     {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0, {0}},
658     {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0, {0}},
659     {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0, {0}},
660     {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0, {0}},
661     {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE | FLAG_PRINT,
662      {0}},
663 
664     PARM_SEPARATOR ("Protocol Options"),
665     {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0, {0}},
666     {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0, {0}},
667     {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0, {0}},
668     {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0, {0}},
669     {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0, {0}},
670     {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0, {0}},
671     {"nt acl support", P_BOOL, P_GLOBAL, &Globals.bNTAclSupport, NULL, NULL, 0, {0}},
672     {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0, {0}},
673     {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0, {0}},
674     {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0, {0}},
675     {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0, {0}},
676     {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0, {0}},
677     {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0, {0}},
678     {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0, {0}},
679     {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0, {0}},
680     {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0, {0}},
681     {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0, {0}},
682     {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0, {0}},
683 
684     PARM_SEPARATOR ("Tuning Options"),
685     {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0,
686      {0}},
687     {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0, {0}},
688     {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0, {0}},
689     {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0, {0}},
690     {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0, {0}},
691     {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE, {0}},
692     {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0, {0}},
693     {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0, {0}},
694     {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT, {0}},
695     {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0, {0}},
696     {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0, {0}},
697     {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0, {0}},
698     {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0, {0}},
699     {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0, {0}},
700     {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE, {0}},
701     {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE, {0}},
702 
703     PARM_SEPARATOR ("Printing Options"),
704     {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT, {0}},
705     {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT, {0}},
706     {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0, {0}},
707     {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, FLAG_PRINT, {0}},
708     {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT, {0}},
709     {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0, {0}},
710     {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT, {0}},
711     {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing,
712      FLAG_PRINT | FLAG_GLOBAL, {0}},
713     {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL,
714      FLAG_PRINT | FLAG_GLOBAL, {0}},
715     {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL,
716      {0}},
717     {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL,
718      FLAG_PRINT | FLAG_GLOBAL, {0}},
719     {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL,
720      FLAG_PRINT | FLAG_GLOBAL, {0}},
721     {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL,
722      FLAG_PRINT | FLAG_GLOBAL, {0}},
723     {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL,
724      FLAG_PRINT | FLAG_GLOBAL, {0}},
725     {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL,
726      FLAG_PRINT | FLAG_GLOBAL, {0}},
727 
728     {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT, {0}},
729     {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0, {0}},
730     {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT, {0}},
731     {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL,
732      FLAG_PRINT | FLAG_GLOBAL, {0}},
733 
734 
735     PARM_SEPARATOR ("Filename Handling"),
736     {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0, {0}},
737     {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0,
738      {0}},
739     {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0, {0}},
740     {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0,
741      {0}},
742     {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0, {0}},
743     {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE, {0}},
744     {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL,
745      FLAG_SHARE | FLAG_GLOBAL, {0}},
746     {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0, {0}},
747     {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL,
748      FLAG_SHARE | FLAG_GLOBAL, {0}},
749     {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL,
750      FLAG_SHARE | FLAG_GLOBAL, {0}},
751     {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
752      {0}},
753     {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
754      {0}},
755     {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL,
756      FLAG_SHARE | FLAG_GLOBAL, {0}},
757     {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL,
758      FLAG_SHARE | FLAG_GLOBAL, {0}},
759     {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
760      {0}},
761     {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
762      {0}},
763     {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL,
764      FLAG_SHARE | FLAG_GLOBAL, {0}},
765     {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
766      {0}},
767     {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
768      {0}},
769     {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
770      {0}},
771     {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL,
772      FLAG_SHARE | FLAG_GLOBAL, {0}},
773     {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
774      {0}},
775     {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0, {0}},
776 
777     PARM_SEPARATOR ("Domain Options"),
778     {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0, {0}},
779     {"domain admin group", P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0, {0}},
780     {"domain guest group", P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0, {0}},
781     {"domain admin users", P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0, {0}},
782     {"domain guest users", P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0, {0}},
783 #ifdef USING_GROUPNAME_MAP
784     {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0, {0}},
785 #endif /* USING_GROUPNAME_MAP */
786     {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL,
787      0, {0}},
788 
789     PARM_SEPARATOR ("Logon Options"),
790     {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, 0, {0}},
791     {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, 0, {0}},
792     {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0, {0}},
793     {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0, {0}},
794     {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0, {0}},
795     {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0, {0}},
796     {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0, {0}},
797 
798     PARM_SEPARATOR ("Browse Options"),
799     {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC, {0}},
800     {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0, {0}},
801     {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0, {0}},
802     {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, FLAG_BASIC, {0}},
803     {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0, {0}},
804     {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC, {0}},
805     {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, FLAG_BASIC, {0}},
806     {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0, {0}},
807     {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL,
808      FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}},
809     {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0, {0}},
810 
811     PARM_SEPARATOR ("WINS Options"),
812     {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0, {0}},
813     {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0, {0}},
814     {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC, {0}},
815     {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC, {0}},
816 
817     PARM_SEPARATOR ("Locking Options"),
818     {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL,
819      FLAG_SHARE | FLAG_GLOBAL, {0}},
820     {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE, {0}},
821     {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL, {0}},
822     {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, {0}},
823     {"mangle locks", P_BOOL, P_LOCAL, &sDefault.bMangleLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
824      {0}},
825     {"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL,
826      FLAG_GLOBAL, {0}},
827     {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL, {0}},
828     {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL,
829      FLAG_GLOBAL, {0}},
830     {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL,
831      FLAG_SHARE | FLAG_GLOBAL, {0}},
832     {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL,
833      FLAG_SHARE | FLAG_GLOBAL, {0}},
834     {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
835      {0}},
836 
837 #ifdef WITH_LDAP
838     PARM_SEPARATOR ("Ldap Options"),
839     {"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0, {0}},
840     {"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0, {0}},
841     {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0, {0}},
842     {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0, {0}},
843     {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0, {0}},
844     {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword, NULL, NULL, 0, {0}},
845 #endif /* WITH_LDAP */
846 
847 
848     PARM_SEPARATOR ("Miscellaneous Options"),
849     {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0, {0}},
850     {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE, {0}},
851     {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0, {0}},
852     {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0, {0}},
853     {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0, {0}},
854     {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0, {0}},
855     {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0, {0}},
856     {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0, {0}},
857     {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0, {0}},
858     {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL, NULL, 0, {0}},
859     {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars, NULL, 0, {0}},
860     {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, 0, {0}},
861     {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, 0, {0}},
862     {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, 0, {0}},
863     {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, 0, {0}},
864     {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, 0, {0}},
865     {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL, NULL, 0, {0}},
866     {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, 0, {0}},
867     {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE, {0}},
868     {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE, {0}},
869     {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE, {0}},
870     {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT, {0}},
871     {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0, {0}},
872     {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE | FLAG_PRINT, {0}},
873     {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL,
874      FLAG_SHARE | FLAG_PRINT, {0}},
875     {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL,
876      FLAG_SHARE | FLAG_PRINT, {0}},
877     {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL,
878      FLAG_BASIC | FLAG_SHARE | FLAG_PRINT, {0}},
879     {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE, {0}},
880     {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE, {0}},
881     {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE, {0}},
882     {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
883      {0}},
884     {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL,
885      {0}},
886     {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE, {0}},
887     {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE, {0}},
888     {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE, {0}},
889     {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL,
890      FLAG_SHARE | FLAG_GLOBAL, {0}},
891     {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL,
892      FLAG_SHARE | FLAG_GLOBAL, {0}},
893     {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL,
894      FLAG_SHARE | FLAG_GLOBAL, {0}},
895 
896     {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL,
897      FLAG_SHARE | FLAG_GLOBAL, {0}},
898     {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0, {0}},
899 
900     {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0, {0}}
901 };
902 
903 
904 
905 /***************************************************************************
906 Initialise the global parameter structure.
907 ***************************************************************************/
908 static void
init_globals(void)909 init_globals (void)
910 {
911     static BOOL done_init = False;
912     fstring s;
913 
914     if (!done_init)
915     {
916         int i;
917         memset ((void *) &Globals, '\0', sizeof (Globals));
918 
919         for (i = 0; parm_table[i].label; i++)
920             if ((parm_table[i].type == P_STRING ||
921                  parm_table[i].type == P_USTRING) && parm_table[i].ptr)
922                 string_init (parm_table[i].ptr, "");
923 
924         string_set (&sDefault.szGuestaccount, GUEST_ACCOUNT);
925         string_set (&sDefault.szPrinterDriver, "NULL");
926         string_set (&sDefault.fstype, FSTYPE_STRING);
927 
928         done_init = True;
929     }
930 
931 
932     DEBUG (3, ("Initialising global parameters\n"));
933 
934     string_set (&Globals.szWorkGroup, WORKGROUP);
935     string_set (&Globals.szPrintcapname, PRINTCAP_NAME);
936     string_set (&Globals.szDriverFile, DRIVERFILE);
937     string_set (&Globals.szRootdir, "/");
938     string_set (&Globals.szSocketAddress, "0.0.0.0");
939     string_set (&Globals.szServerString, "Samba " VERSION);
940     slprintf (s, sizeof (s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
941     string_set (&Globals.szAnnounceVersion, s);
942 
943     pstrcpy (user_socket_options, DEFAULT_SOCKET_OPTIONS);
944 
945     string_set (&Globals.szLogonDrive, "");
946     /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
947     string_set (&Globals.szLogonHome, "\\\\%N\\%U");
948     string_set (&Globals.szLogonPath, "\\\\%N\\%U\\profile");
949 
950     string_set (&Globals.szNameResolveOrder, "lmhosts host wins bcast");
951 
952     Globals.bLoadPrinters = True;
953     Globals.bUseRhosts = False;
954     Globals.max_packet = 65535;
955     Globals.mangled_stack = 50;
956     Globals.max_xmit = 65535;
957     Globals.max_mux = 50;       /* This is *needed* for profile support. */
958     Globals.lpqcachetime = 10;
959     Globals.pwordlevel = 0;
960     Globals.unamelevel = 0;
961     Globals.deadtime = 0;
962     Globals.max_log_size = 5000;
963     Globals.max_open_files = MAX_OPEN_FILES;
964     Globals.maxprotocol = PROTOCOL_NT1;
965     Globals.security = SEC_USER;
966     Globals.bEncryptPasswords = False;
967     Globals.bUpdateEncrypt = False;
968     Globals.bReadRaw = True;
969     Globals.bWriteRaw = True;
970     Globals.bReadPrediction = False;
971     Globals.bReadbmpx = False;
972     Globals.bNullPasswords = False;
973     Globals.bStripDot = False;
974     Globals.syslog = 1;
975     Globals.bSyslogOnly = False;
976     Globals.bTimestampLogs = True;
977     Globals.os_level = 0;
978     Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
979     Globals.max_wins_ttl = 60 * 60 * 24 * 6;    /* 6 days default. */
980     Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
981     Globals.machine_password_timeout = 60 * 60 * 24 * 7;        /* 7 days default. */
982     Globals.change_notify_timeout = 60; /* 1 minute default. */
983     Globals.ReadSize = 16 * 1024;
984     Globals.lm_announce = 2;    /* = Auto: send only if LM clients found */
985     Globals.lm_interval = 60;
986     Globals.shmem_size = SHMEM_SIZE;
987     Globals.stat_cache_size = 50;       /* Number of stat translations we'll keep */
988     Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
989     Globals.bUnixRealname = False;
990 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
991     Globals.bNISHomeMap = False;
992 #ifdef WITH_NISPLUS_HOME
993     string_set (&Globals.szNISHomeMapName, "auto_home.org_dir");
994 #else
995     string_set (&Globals.szNISHomeMapName, "auto.home");
996 #endif
997 #endif
998     Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
999     Globals.bTimeServer = False;
1000     Globals.bBindInterfacesOnly = False;
1001     Globals.bUnixPasswdSync = False;
1002     Globals.bPasswdChatDebug = False;
1003     Globals.bOleLockingCompat = True;
1004     Globals.bNTSmbSupport = True;       /* Do NT SMB's by default. */
1005     Globals.bNTPipeSupport = True;      /* Do NT pipes by default. */
1006     Globals.bNTAclSupport = True;       /* Use NT ACLs by default. */
1007     Globals.bStatCache = True;  /* use stat cache by default */
1008     Globals.bRestrictAnonymous = False;
1009     Globals.map_to_guest = 0;   /* By Default, "Never" */
1010     Globals.min_passwd_length = MINPASSWDLENGTH;        /* By Default, 5. */
1011     Globals.oplock_break_wait_time = 10;        /* By Default, 10 msecs. */
1012 
1013 #ifdef WITH_LDAP
1014     /* default values for ldap */
1015     string_set (&Globals.szLdapServer, "localhost");
1016     Globals.ldap_port = 389;
1017 #endif /* WITH_LDAP */
1018 
1019 #ifdef WITH_SSL
1020     Globals.sslVersion = SMB_SSL_V23;
1021     string_set (&Globals.sslHostsRequire, "");
1022     string_set (&Globals.sslHostsResign, "");
1023     string_set (&Globals.sslCaCertDir, "");
1024     string_set (&Globals.sslCaCertFile, "");
1025     string_set (&Globals.sslCert, "");
1026     string_set (&Globals.sslPrivKey, "");
1027     string_set (&Globals.sslClientCert, "");
1028     string_set (&Globals.sslClientPrivKey, "");
1029     string_set (&Globals.sslCiphers, "");
1030     Globals.sslEnabled = False;
1031     Globals.sslReqClientCert = False;
1032     Globals.sslReqServerCert = False;
1033     Globals.sslCompatibility = False;
1034 #endif /* WITH_SSL */
1035 
1036     /* these parameters are set to defaults that are more appropriate
1037        for the increasing samba install base:
1038 
1039        as a member of the workgroup, that will possibly become a
1040        _local_ master browser (lm = True).  this is opposed to a forced
1041        local master browser startup (pm = True).
1042 
1043        doesn't provide WINS server service by default (wsupp = False),
1044        and doesn't provide domain master browser services by default, either.
1045 
1046      */
1047 
1048     Globals.bPreferredMaster = False;
1049     Globals.bLocalMaster = True;
1050     Globals.bDomainMaster = False;
1051     Globals.bDomainLogons = False;
1052     Globals.bBrowseList = True;
1053     Globals.bWINSsupport = False;
1054     Globals.bWINSproxy = False;
1055 
1056     Globals.bDNSproxy = True;
1057 
1058     /*
1059      * smbd will check at runtime to see if this value
1060      * will really be used or not.
1061      */
1062     Globals.bKernelOplocks = True;
1063 
1064     Globals.bAllowTrustedDomains = True;
1065 
1066     /*
1067      * This must be done last as it checks the value in
1068      * client_code_page.
1069      */
1070 
1071     interpret_coding_system (KANJI);
1072 }
1073 
1074 #if 0
1075 /***************************************************************************
1076 check if a string is initialised and if not then initialise it
1077 ***************************************************************************/
1078 static void
1079 string_initial (char **s, char *v)
1080 {
1081     if (!*s || !**s)
1082         string_init (s, v);
1083 }
1084 
1085 #else
1086 #define init_locals()
1087 #endif /* 0 */
1088 
1089 static size_t
size_max(size_t a,size_t b)1090 size_max (size_t a, size_t b)
1091 {
1092     return (a > b) ? a : b;
1093 }
1094 
1095 /******************************************************************* a
1096 convenience routine to grab string parameters into a rotating buffer,
1097 and run standard_sub_basic on them. The buffers can be written to by
1098 callers without affecting the source string.
1099 ********************************************************************/
1100 static char *
lp_string(const char * s)1101 lp_string (const char *s)
1102 {
1103     static char *bufs[10];
1104     static int buflen[10];
1105     static int next = -1;
1106     char *ret;
1107     int i;
1108     int len = s ? strlen (s) : 0;
1109 
1110     if (next == -1)
1111     {
1112         /* initialisation */
1113         for (i = 0; i < 10; i++)
1114         {
1115             bufs[i] = NULL;
1116             buflen[i] = 0;
1117         }
1118         next = 0;
1119     }
1120 
1121     len = size_max (len + 100, sizeof (pstring));       /* the +100 is for some
1122                                                            substitution room */
1123 
1124     if (buflen[next] != len)
1125     {
1126         buflen[next] = len;
1127         if (bufs[next])
1128             free (bufs[next]);
1129         bufs[next] = (char *) malloc (len);
1130         if (!bufs[next])
1131         {
1132             DEBUG (0, ("out of memory in lp_string()"));
1133             exit (1);
1134         }
1135     }
1136 
1137     ret = &bufs[next][0];
1138     next = (next + 1) % 10;
1139 
1140     if (!s)
1141         *ret = 0;
1142     else
1143         StrCpy (ret, s);
1144 
1145     trim_string (ret, "\"", "\"");
1146 
1147     standard_sub_basic (ret);
1148     return (ret);
1149 }
1150 
1151 
1152 /*
1153    In this section all the functions that are used to access the
1154    parameters from the rest of the program are defined
1155  */
1156 
1157 #define FN_GLOBAL_STRING(fn_name,ptr) \
1158  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1159 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1160  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1161 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1162  char fn_name(void) {return(*(char *)(ptr));}
1163 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1164  int fn_name(void) {return(*(int *)(ptr));}
1165 
1166 #define FN_LOCAL_STRING(fn_name,val) \
1167  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
1168 #define FN_LOCAL_BOOL(fn_name,val) \
1169  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1170 #define FN_LOCAL_CHAR(fn_name,val) \
1171  char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1172 #define FN_LOCAL_INTEGER(fn_name,val) \
1173  int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
1174 
1175 FN_GLOBAL_STRING (lp_logfile, &Globals.szLogFile)
1176 FN_GLOBAL_STRING (lp_configfile, &Globals.szConfigFile)
1177 FN_GLOBAL_STRING (lp_serverstring, &Globals.szServerString)
1178 FN_GLOBAL_STRING (lp_printcapname, &Globals.szPrintcapname)
1179 FN_GLOBAL_STRING (lp_lockdir, &Globals.szLockDir)
1180 FN_GLOBAL_STRING (lp_rootdir, &Globals.szRootdir)
1181 FN_GLOBAL_STRING (lp_defaultservice, &Globals.szDefaultService)
1182 FN_GLOBAL_STRING (lp_msg_command, &Globals.szMsgCommand)
1183 FN_GLOBAL_STRING (lp_hosts_equiv, &Globals.szHostsEquiv)
1184 FN_GLOBAL_STRING (lp_auto_services, &Globals.szAutoServices)
1185 FN_GLOBAL_STRING (lp_passwordserver, &Globals.szPasswordServer)
1186 FN_GLOBAL_STRING (lp_name_resolve_order, &Globals.szNameResolveOrder)
1187 FN_GLOBAL_STRING (lp_workgroup, &Globals.szWorkGroup)
1188 FN_GLOBAL_STRING (lp_username_map, &Globals.szUsernameMap)
1189 #ifdef USING_GROUPNAME_MAP
1190     FN_GLOBAL_STRING (lp_groupname_map, &Globals.szGroupnameMap)
1191 #endif /* USING_GROUPNAME_MAP */
1192     FN_GLOBAL_STRING (lp_remote_announce, &Globals.szRemoteAnnounce)
1193 FN_GLOBAL_STRING (lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1194 FN_GLOBAL_STRING (lp_wins_server, &Globals.szWINSserver)
1195 FN_GLOBAL_STRING (lp_interfaces, &Globals.szInterfaces)
1196 FN_GLOBAL_STRING (lp_socket_address, &Globals.szSocketAddress)
1197 FN_GLOBAL_STRING (lp_nis_home_map_name, &Globals.szNISHomeMapName)
1198 #if 0
1199      static FN_GLOBAL_STRING (lp_announce_version, &Globals.szAnnounceVersion)
1200 #endif                          /* 0 */
1201 FN_GLOBAL_STRING (lp_netbios_aliases, &Globals.szNetbiosAliases)
1202 FN_GLOBAL_STRING (lp_driverfile, &Globals.szDriverFile)
1203 FN_GLOBAL_STRING (lp_panic_action, &Globals.szPanicAction)
1204 FN_GLOBAL_STRING (lp_domain_groups, &Globals.szDomainGroups)
1205 FN_GLOBAL_STRING (lp_domain_admin_group, &Globals.szDomainAdminGroup)
1206 FN_GLOBAL_STRING (lp_domain_guest_group, &Globals.szDomainGuestGroup)
1207 FN_GLOBAL_STRING (lp_domain_admin_users, &Globals.szDomainAdminUsers)
1208 FN_GLOBAL_STRING (lp_domain_guest_users, &Globals.szDomainGuestUsers)
1209 #ifdef WITH_LDAP
1210 FN_GLOBAL_STRING (lp_ldap_server, &Globals.szLdapServer);
1211 FN_GLOBAL_STRING (lp_ldap_suffix, &Globals.szLdapSuffix);
1212 FN_GLOBAL_STRING (lp_ldap_filter, &Globals.szLdapFilter);
1213 FN_GLOBAL_STRING (lp_ldap_root, &Globals.szLdapRoot);
1214 FN_GLOBAL_STRING (lp_ldap_rootpasswd, &Globals.szLdapRootPassword);
1215 #endif /* WITH_LDAP */
1216 
1217 #ifdef WITH_SSL
1218 FN_GLOBAL_INTEGER (lp_ssl_version, &Globals.sslVersion);
1219 FN_GLOBAL_STRING (lp_ssl_hosts, &Globals.sslHostsRequire);
1220 FN_GLOBAL_STRING (lp_ssl_hosts_resign, &Globals.sslHostsResign);
1221 FN_GLOBAL_STRING (lp_ssl_cacertdir, &Globals.sslCaCertDir);
1222 FN_GLOBAL_STRING (lp_ssl_cacertfile, &Globals.sslCaCertFile);
1223 FN_GLOBAL_STRING (lp_ssl_cert, &Globals.sslCert);
1224 FN_GLOBAL_STRING (lp_ssl_privkey, &Globals.sslPrivKey);
1225 FN_GLOBAL_STRING (lp_ssl_client_cert, &Globals.sslClientCert);
1226 FN_GLOBAL_STRING (lp_ssl_client_privkey, &Globals.sslClientPrivKey);
1227 FN_GLOBAL_STRING (lp_ssl_ciphers, &Globals.sslCiphers);
1228 FN_GLOBAL_BOOL (lp_ssl_enabled, &Globals.sslEnabled);
1229 FN_GLOBAL_BOOL (lp_ssl_reqClientCert, &Globals.sslReqClientCert);
1230 FN_GLOBAL_BOOL (lp_ssl_reqServerCert, &Globals.sslReqServerCert);
1231 FN_GLOBAL_BOOL (lp_ssl_compatibility, &Globals.sslCompatibility);
1232 #endif /* WITH_SSL */
1233 
1234 FN_GLOBAL_BOOL (lp_dns_proxy, &Globals.bDNSproxy)
1235 FN_GLOBAL_BOOL (lp_wins_support, &Globals.bWINSsupport)
1236 FN_GLOBAL_BOOL (lp_we_are_a_wins_server, &Globals.bWINSsupport)
1237 FN_GLOBAL_BOOL (lp_wins_proxy, &Globals.bWINSproxy)
1238 FN_GLOBAL_BOOL (lp_local_master, &Globals.bLocalMaster)
1239 FN_GLOBAL_BOOL (lp_domain_master, &Globals.bDomainMaster)
1240 FN_GLOBAL_BOOL (lp_domain_logons, &Globals.bDomainLogons)
1241 FN_GLOBAL_BOOL (lp_preferred_master, &Globals.bPreferredMaster)
1242 FN_GLOBAL_BOOL (lp_use_rhosts, &Globals.bUseRhosts)
1243 FN_GLOBAL_BOOL (lp_readprediction, &Globals.bReadPrediction)
1244 FN_GLOBAL_BOOL (lp_readbmpx, &Globals.bReadbmpx)
1245 FN_GLOBAL_BOOL (lp_readraw, &Globals.bReadRaw)
1246 FN_GLOBAL_BOOL (lp_writeraw, &Globals.bWriteRaw)
1247 FN_GLOBAL_BOOL (lp_null_passwords, &Globals.bNullPasswords)
1248 FN_GLOBAL_BOOL (lp_strip_dot, &Globals.bStripDot)
1249 FN_GLOBAL_BOOL (lp_encrypted_passwords, &Globals.bEncryptPasswords)
1250 FN_GLOBAL_BOOL (lp_update_encrypted, &Globals.bUpdateEncrypt)
1251 FN_GLOBAL_BOOL (lp_syslog_only, &Globals.bSyslogOnly)
1252 FN_GLOBAL_BOOL (lp_timestamp_logs, &Globals.bTimestampLogs)
1253 FN_GLOBAL_BOOL (lp_browse_list, &Globals.bBrowseList)
1254 FN_GLOBAL_BOOL (lp_unix_realname, &Globals.bUnixRealname)
1255 FN_GLOBAL_BOOL (lp_nis_home_map, &Globals.bNISHomeMap)
1256 #if 0
1257      static FN_GLOBAL_BOOL (lp_time_server, &Globals.bTimeServer)
1258 #endif                          /* 0 */
1259 FN_GLOBAL_BOOL (lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1260 FN_GLOBAL_BOOL (lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1261 FN_GLOBAL_BOOL (lp_ole_locking_compat, &Globals.bOleLockingCompat)
1262 FN_GLOBAL_BOOL (lp_nt_smb_support, &Globals.bNTSmbSupport)
1263 FN_GLOBAL_BOOL (lp_nt_pipe_support, &Globals.bNTPipeSupport)
1264 FN_GLOBAL_BOOL (lp_nt_acl_support, &Globals.bNTAclSupport)
1265 FN_GLOBAL_BOOL (lp_stat_cache, &Globals.bStatCache)
1266 FN_GLOBAL_BOOL (lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1267 FN_GLOBAL_BOOL (lp_restrict_anonymous, &Globals.bRestrictAnonymous)
1268 FN_GLOBAL_INTEGER (lp_os_level, &Globals.os_level)
1269 FN_GLOBAL_INTEGER (lp_max_ttl, &Globals.max_ttl)
1270 FN_GLOBAL_INTEGER (lp_max_wins_ttl, &Globals.max_wins_ttl)
1271 FN_GLOBAL_INTEGER (lp_min_wins_ttl, &Globals.min_wins_ttl)
1272 FN_GLOBAL_INTEGER (lp_maxxmit, &Globals.max_xmit)
1273 FN_GLOBAL_INTEGER (lp_maxmux, &Globals.max_mux)
1274 FN_GLOBAL_INTEGER (lp_passwordlevel, &Globals.pwordlevel)
1275 FN_GLOBAL_INTEGER (lp_usernamelevel, &Globals.unamelevel)
1276 FN_GLOBAL_INTEGER (lp_readsize, &Globals.ReadSize)
1277 FN_GLOBAL_INTEGER (lp_deadtime, &Globals.deadtime)
1278 FN_GLOBAL_INTEGER (lp_maxprotocol, &Globals.maxprotocol)
1279 FN_GLOBAL_INTEGER (lp_security, &Globals.security)
1280 FN_GLOBAL_INTEGER (lp_maxdisksize, &Globals.maxdisksize)
1281 FN_GLOBAL_INTEGER (lp_client_code_page, &Globals.client_code_page)
1282 #if 0
1283      static FN_GLOBAL_INTEGER (lp_announce_as, &Globals.announce_as)
1284 #endif
1285 FN_GLOBAL_INTEGER (lp_lm_announce, &Globals.lm_announce)
1286 FN_GLOBAL_INTEGER (lp_lm_interval, &Globals.lm_interval)
1287 FN_GLOBAL_INTEGER (lp_machine_password_timeout, &Globals.machine_password_timeout)
1288 FN_GLOBAL_INTEGER (lp_change_notify_timeout, &Globals.change_notify_timeout)
1289 FN_GLOBAL_INTEGER (lp_stat_cache_size, &Globals.stat_cache_size)
1290 FN_GLOBAL_INTEGER (lp_map_to_guest, &Globals.map_to_guest)
1291 FN_GLOBAL_INTEGER (lp_min_passwd_length, &Globals.min_passwd_length)
1292 FN_GLOBAL_INTEGER (lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1293 #ifdef WITH_LDAP
1294 FN_GLOBAL_INTEGER (lp_ldap_port, &Globals.ldap_port)
1295 #endif                          /* WITH_LDAP */
1296 FN_LOCAL_STRING (lp_preexec, szPreExec)
1297 FN_LOCAL_STRING (lp_postexec, szPostExec)
1298 FN_LOCAL_STRING (lp_rootpreexec, szRootPreExec)
1299 FN_LOCAL_STRING (lp_rootpostexec, szRootPostExec)
1300 FN_LOCAL_STRING (lp_servicename, szService)
1301 FN_LOCAL_STRING (lp_pathname, szPath)
1302 FN_LOCAL_STRING (lp_dontdescend, szDontdescend)
1303 FN_LOCAL_STRING (lp_username, szUsername)
1304 FN_LOCAL_STRING (lp_guestaccount, szGuestaccount)
1305 FN_LOCAL_STRING (lp_invalid_users, szInvalidUsers)
1306 FN_LOCAL_STRING (lp_valid_users, szValidUsers)
1307 FN_LOCAL_STRING (lp_admin_users, szAdminUsers)
1308 #if 0
1309 FN_LOCAL_STRING (lp_printcommand, szPrintcommand)
1310 FN_LOCAL_STRING (lp_lpqcommand, szLpqcommand)
1311 FN_LOCAL_STRING (lp_lprmcommand, szLprmcommand)
1312 FN_LOCAL_STRING (lp_lppausecommand, szLppausecommand)
1313 FN_LOCAL_STRING (lp_lpresumecommand, szLpresumecommand)
1314 FN_LOCAL_STRING (lp_queuepausecommand, szQueuepausecommand)
1315 FN_LOCAL_STRING (lp_queueresumecommand, szQueueresumecommand)
1316 FN_LOCAL_STRING (lp_printername, szPrintername)
1317 FN_LOCAL_STRING (lp_printerdriver, szPrinterDriver)
1318 #endif                          /* 0 */
1319 FN_LOCAL_STRING (lp_hostsallow, szHostsallow)
1320 FN_LOCAL_STRING (lp_hostsdeny, szHostsdeny)
1321 FN_LOCAL_STRING (lp_magicscript, szMagicScript)
1322 FN_LOCAL_STRING (lp_magicoutput, szMagicOutput)
1323 FN_LOCAL_STRING (lp_comment, comment)
1324 FN_LOCAL_STRING (lp_force_user, force_user)
1325 FN_LOCAL_STRING (lp_force_group, force_group)
1326 FN_LOCAL_STRING (lp_readlist, readlist)
1327 FN_LOCAL_STRING (lp_writelist, writelist)
1328 FN_LOCAL_STRING (lp_fstype, fstype)
1329 #if 0
1330      static FN_LOCAL_STRING (lp_volume, volume)
1331 #endif
1332 FN_LOCAL_STRING (lp_mangled_map, szMangledMap)
1333 FN_LOCAL_STRING (lp_veto_files, szVetoFiles)
1334 FN_LOCAL_STRING (lp_hide_files, szHideFiles)
1335 FN_LOCAL_STRING (lp_veto_oplocks, szVetoOplockFiles)
1336 FN_LOCAL_BOOL (lp_revalidate, bRevalidate)
1337 FN_LOCAL_BOOL (lp_casesensitive, bCaseSensitive)
1338 FN_LOCAL_BOOL (lp_preservecase, bCasePreserve)
1339 FN_LOCAL_BOOL (lp_shortpreservecase, bShortCasePreserve)
1340 FN_LOCAL_BOOL (lp_casemangle, bCaseMangle)
1341 FN_LOCAL_BOOL (lp_status, status)
1342 FN_LOCAL_BOOL (lp_hide_dot_files, bHideDotFiles)
1343 FN_LOCAL_BOOL (lp_browseable, bBrowseable)
1344 FN_LOCAL_BOOL (lp_readonly, bRead_only)
1345 FN_LOCAL_BOOL (lp_no_set_dir, bNo_set_dir)
1346 FN_LOCAL_BOOL (lp_guest_ok, bGuest_ok)
1347 FN_LOCAL_BOOL (lp_guest_only, bGuest_only)
1348 FN_LOCAL_BOOL (lp_print_ok, bPrint_ok)
1349 FN_LOCAL_BOOL (lp_postscript, bPostscript)
1350 FN_LOCAL_BOOL (lp_map_hidden, bMap_hidden)
1351 FN_LOCAL_BOOL (lp_map_archive, bMap_archive)
1352 FN_LOCAL_BOOL (lp_locking, bLocking)
1353 FN_LOCAL_BOOL (lp_strict_locking, bStrictLocking)
1354 FN_LOCAL_BOOL (lp_share_modes, bShareModes)
1355 FN_LOCAL_BOOL (lp_oplocks, bOpLocks)
1356 FN_LOCAL_BOOL (lp_onlyuser, bOnlyUser)
1357 FN_LOCAL_BOOL (lp_manglednames, bMangledNames)
1358 FN_LOCAL_BOOL (lp_widelinks, bWidelinks)
1359 FN_LOCAL_BOOL (lp_symlinks, bSymlinks)
1360 FN_LOCAL_BOOL (lp_syncalways, bSyncAlways)
1361 FN_LOCAL_BOOL (lp_strict_sync, bStrictSync)
1362 FN_LOCAL_BOOL (lp_map_system, bMap_system)
1363 FN_LOCAL_BOOL (lp_delete_readonly, bDeleteReadonly)
1364 FN_LOCAL_BOOL (lp_fake_oplocks, bFakeOplocks)
1365 FN_LOCAL_BOOL (lp_recursive_veto_delete, bDeleteVetoFiles)
1366 FN_LOCAL_BOOL (lp_dos_filetimes, bDosFiletimes)
1367 FN_LOCAL_BOOL (lp_dos_filetime_resolution, bDosFiletimeResolution)
1368 FN_LOCAL_BOOL (lp_fake_dir_create_times, bFakeDirCreateTimes)
1369 FN_LOCAL_BOOL (lp_blocking_locks, bBlockingLocks)
1370 FN_LOCAL_BOOL (lp_mangle_locks, bMangleLocks)
1371 FN_LOCAL_INTEGER (lp_create_mode, iCreate_mask)
1372 FN_LOCAL_INTEGER (lp_force_create_mode, iCreate_force_mode)
1373 FN_LOCAL_INTEGER (lp_dir_mode, iDir_mask)
1374 FN_LOCAL_INTEGER (lp_force_dir_mode, iDir_force_mode)
1375 FN_LOCAL_INTEGER (lp_max_connections, iMaxConnections)
1376 FN_LOCAL_INTEGER (lp_defaultcase, iDefaultCase)
1377 FN_LOCAL_INTEGER (lp_minprintspace, iMinPrintSpace)
1378 FN_LOCAL_INTEGER (lp_printing, iPrinting)
1379 FN_LOCAL_INTEGER (lp_oplock_contention_limit, iOplockContentionLimit)
1380 FN_LOCAL_CHAR (lp_magicchar, magic_char)
1381 /* local prototypes */
1382      static int strwicmp (const char *psz1, const char *psz2);
1383      static int map_parameter (const char *pszParmName);
1384      static BOOL set_boolean (BOOL * pb, const char *pszParmValue);
1385      static int getservicebyname (const char *pszServiceName, service * pserviceDest);
1386      static void copy_service (service * pserviceDest,
1387                                service * pserviceSource, BOOL * pcopymapDest);
1388      static BOOL service_ok (int iService);
1389      static BOOL do_parameter (const char *pszParmName, const char *pszParmValue);
1390      static BOOL do_section (const char *pszSectionName);
1391      static void init_copymap (service * pservice);
1392 
1393 
1394 /***************************************************************************
1395 initialise a service to the defaults
1396 ***************************************************************************/
init_service(service * pservice)1397      static void init_service (service * pservice)
1398 {
1399     memset ((char *) pservice, '\0', sizeof (service));
1400     copy_service (pservice, &sDefault, NULL);
1401 }
1402 
1403 
1404 /***************************************************************************
1405 free the dynamically allocated parts of a service struct
1406 ***************************************************************************/
1407 static void
free_service(service * pservice)1408 free_service (service * pservice)
1409 {
1410     int i;
1411     if (!pservice)
1412         return;
1413 
1414     if (pservice->szService)
1415         DEBUG (5, ("free_service: Freeing service %s\n", pservice->szService));
1416 
1417     string_free (&pservice->szService);
1418     if (pservice->copymap)
1419     {
1420         free (pservice->copymap);
1421         pservice->copymap = NULL;
1422     }
1423 
1424     for (i = 0; parm_table[i].label; i++)
1425         if ((parm_table[i].type == P_STRING ||
1426              parm_table[i].type == P_USTRING) && parm_table[i].class == P_LOCAL)
1427             string_free ((char **) (((char *) pservice) + PTR_DIFF (parm_table[i].ptr, &sDefault)));
1428 }
1429 
1430 /***************************************************************************
1431 add a new service to the services array initialising it with the given
1432 service
1433 ***************************************************************************/
1434 static int
add_a_service(service * pservice,const char * name)1435 add_a_service (service * pservice, const char *name)
1436 {
1437     int i;
1438     service tservice;
1439     int num_to_alloc = iNumServices + 1;
1440 
1441     tservice = *pservice;
1442 
1443     /* it might already exist */
1444     if (name)
1445     {
1446         i = getservicebyname (name, NULL);
1447         if (i >= 0)
1448             return (i);
1449     }
1450 
1451     /* find an invalid one */
1452     for (i = 0; i < iNumServices; i++)
1453         if (!pSERVICE (i)->valid)
1454             break;
1455 
1456     /* if not, then create one */
1457     if (i == iNumServices)
1458     {
1459         ServicePtrs = (service **) Realloc (ServicePtrs, sizeof (service *) * num_to_alloc);
1460         if (ServicePtrs)
1461             pSERVICE (iNumServices) = (service *) malloc (sizeof (service));
1462 
1463         if (!ServicePtrs || !pSERVICE (iNumServices))
1464             return (-1);
1465 
1466         iNumServices++;
1467     }
1468     else
1469         free_service (pSERVICE (i));
1470 
1471     pSERVICE (i)->valid = True;
1472 
1473     init_service (pSERVICE (i));
1474     copy_service (pSERVICE (i), &tservice, NULL);
1475     if (name)
1476         string_set (&iSERVICE (i).szService, name);
1477 
1478     return (i);
1479 }
1480 
1481 /***************************************************************************
1482 add a new home service, with the specified home directory, defaults coming
1483 from service ifrom
1484 ***************************************************************************/
1485 BOOL
lp_add_home(const char * pszHomename,int iDefaultService,const char * pszHomedir)1486 lp_add_home (const char *pszHomename, int iDefaultService, const char *pszHomedir)
1487 {
1488     int i = add_a_service (pSERVICE (iDefaultService), pszHomename);
1489 
1490     if (i < 0)
1491         return (False);
1492 
1493     if (!(*(iSERVICE (i).szPath)) || strequal (iSERVICE (i).szPath, lp_pathname (-1)))
1494         string_set (&iSERVICE (i).szPath, pszHomedir);
1495     if (!(*(iSERVICE (i).comment)))
1496     {
1497         pstring comment;
1498         slprintf (comment, sizeof (comment) - 1, "Home directory of %s", pszHomename);
1499         string_set (&iSERVICE (i).comment, comment);
1500     }
1501     iSERVICE (i).bAvailable = sDefault.bAvailable;
1502     iSERVICE (i).bBrowseable = sDefault.bBrowseable;
1503 
1504     DEBUG (3, ("adding home directory %s at %s\n", pszHomename, pszHomedir));
1505 
1506     return (True);
1507 }
1508 
1509 /***************************************************************************
1510 add a new service, based on an old one
1511 ***************************************************************************/
1512 int
lp_add_service(char * pszService,int iDefaultService)1513 lp_add_service (char *pszService, int iDefaultService)
1514 {
1515     return (add_a_service (pSERVICE (iDefaultService), pszService));
1516 }
1517 
1518 #if 0
1519 /***************************************************************************
1520 add the IPC service
1521 ***************************************************************************/
1522 static BOOL
1523 lp_add_ipc (void)
1524 {
1525     pstring comment;
1526     int i = add_a_service (&sDefault, "IPC$");
1527 
1528     if (i < 0)
1529         return (False);
1530 
1531     slprintf (comment, sizeof (comment) - 1, "IPC Service (%s)", Globals.szServerString);
1532 
1533     string_set (&iSERVICE (i).szPath, tmpdir ());
1534     string_set (&iSERVICE (i).szUsername, "");
1535     string_set (&iSERVICE (i).comment, comment);
1536     string_set (&iSERVICE (i).fstype, "IPC");
1537     iSERVICE (i).status = False;
1538     iSERVICE (i).iMaxConnections = 0;
1539     iSERVICE (i).bAvailable = True;
1540     iSERVICE (i).bRead_only = True;
1541     iSERVICE (i).bGuest_only = False;
1542     iSERVICE (i).bGuest_ok = True;
1543     iSERVICE (i).bPrint_ok = False;
1544     iSERVICE (i).bBrowseable = sDefault.bBrowseable;
1545 
1546     DEBUG (3, ("adding IPC service\n"));
1547 
1548     return (True);
1549 }
1550 #endif /* 0 */
1551 
1552 /***************************************************************************
1553 Do a case-insensitive, whitespace-ignoring string compare.
1554 ***************************************************************************/
1555 static int
strwicmp(const char * psz1,const char * psz2)1556 strwicmp (const char *psz1, const char *psz2)
1557 {
1558     /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
1559     /* appropriate value. */
1560     if (psz1 == psz2)
1561         return (0);
1562     else if (psz1 == NULL)
1563         return (-1);
1564     else if (psz2 == NULL)
1565         return (1);
1566 
1567     /* sync the strings on first non-whitespace */
1568     while (1)
1569     {
1570         while (isspace ((unsigned char) *psz1))
1571             psz1++;
1572         while (isspace ((unsigned char) *psz2))
1573             psz2++;
1574         if (toupper ((unsigned char) *psz1) != toupper ((unsigned char) *psz2) || *psz1 == '\0'
1575             || *psz2 == '\0')
1576             break;
1577         psz1++;
1578         psz2++;
1579     }
1580     return (*psz1 - *psz2);
1581 }
1582 
1583 /***************************************************************************
1584 Map a parameter's string representation to something we can use.
1585 Returns False if the parameter string is not recognised, else TRUE.
1586 ***************************************************************************/
1587 static int
map_parameter(const char * pszParmName)1588 map_parameter (const char *pszParmName)
1589 {
1590     int iIndex;
1591 
1592     if (*pszParmName == '-')
1593         return (-1);
1594 
1595     for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1596         if (strwicmp (parm_table[iIndex].label, pszParmName) == 0)
1597             return (iIndex);
1598 
1599     DEBUG (0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1600     return (-1);
1601 }
1602 
1603 
1604 /***************************************************************************
1605 Set a boolean variable from the text value stored in the passed string.
1606 Returns True in success, False if the passed string does not correctly
1607 represent a boolean.
1608 ***************************************************************************/
1609 static BOOL
set_boolean(BOOL * pb,const char * pszParmValue)1610 set_boolean (BOOL * pb, const char *pszParmValue)
1611 {
1612     BOOL bRetval;
1613 
1614     bRetval = True;
1615     if (strwicmp (pszParmValue, "yes") == 0 ||
1616         strwicmp (pszParmValue, "true") == 0 || strwicmp (pszParmValue, "1") == 0)
1617         *pb = True;
1618     else if (strwicmp (pszParmValue, "no") == 0 ||
1619              strwicmp (pszParmValue, "False") == 0 || strwicmp (pszParmValue, "0") == 0)
1620         *pb = False;
1621     else
1622     {
1623         DEBUG (0, ("ERROR: Badly formed boolean in configuration file: \"%s\".\n", pszParmValue));
1624         bRetval = False;
1625     }
1626     return (bRetval);
1627 }
1628 
1629 /***************************************************************************
1630 Find a service by name. Otherwise works like get_service.
1631 ***************************************************************************/
1632 static int
getservicebyname(const char * pszServiceName,service * pserviceDest)1633 getservicebyname (const char *pszServiceName, service * pserviceDest)
1634 {
1635     int iService;
1636 
1637     for (iService = iNumServices - 1; iService >= 0; iService--)
1638         if (VALID (iService) && strwicmp (iSERVICE (iService).szService, pszServiceName) == 0)
1639         {
1640             if (pserviceDest != NULL)
1641                 copy_service (pserviceDest, pSERVICE (iService), NULL);
1642             break;
1643         }
1644 
1645     return (iService);
1646 }
1647 
1648 
1649 
1650 /***************************************************************************
1651 Copy a service structure to another
1652 
1653 If pcopymapDest is NULL then copy all fields
1654 ***************************************************************************/
1655 static void
copy_service(service * pserviceDest,service * pserviceSource,BOOL * pcopymapDest)1656 copy_service (service * pserviceDest, service * pserviceSource, BOOL * pcopymapDest)
1657 {
1658     int i;
1659     BOOL bcopyall = (pcopymapDest == NULL);
1660 
1661     for (i = 0; parm_table[i].label; i++)
1662         if (parm_table[i].ptr && parm_table[i].class == P_LOCAL && (bcopyall || pcopymapDest[i]))
1663         {
1664             void *def_ptr = parm_table[i].ptr;
1665             void *src_ptr = ((char *) pserviceSource) + PTR_DIFF (def_ptr, &sDefault);
1666             void *dest_ptr = ((char *) pserviceDest) + PTR_DIFF (def_ptr, &sDefault);
1667 
1668             switch (parm_table[i].type)
1669             {
1670             case P_BOOL:
1671             case P_BOOLREV:
1672                 *(BOOL *) dest_ptr = *(BOOL *) src_ptr;
1673                 break;
1674 
1675             case P_INTEGER:
1676             case P_ENUM:
1677             case P_OCTAL:
1678                 *(int *) dest_ptr = *(int *) src_ptr;
1679                 break;
1680 
1681             case P_CHAR:
1682                 *(char *) dest_ptr = *(char *) src_ptr;
1683                 break;
1684 
1685             case P_STRING:
1686                 string_set (dest_ptr, *(char **) src_ptr);
1687                 break;
1688 
1689             case P_USTRING:
1690                 string_set (dest_ptr, *(char **) src_ptr);
1691                 strupper (*(char **) dest_ptr);
1692                 break;
1693             default:
1694                 break;
1695             }
1696         }
1697 
1698     if (bcopyall)
1699     {
1700         init_copymap (pserviceDest);
1701         if (pserviceSource->copymap)
1702             memcpy ((void *) pserviceDest->copymap,
1703                     (void *) pserviceSource->copymap, sizeof (BOOL) * NUMPARAMETERS);
1704     }
1705 }
1706 
1707 /***************************************************************************
1708 Check a service for consistency. Return False if the service is in any way
1709 incomplete or faulty, else True.
1710 ***************************************************************************/
1711 static BOOL
service_ok(int iService)1712 service_ok (int iService)
1713 {
1714     BOOL bRetval;
1715 
1716     bRetval = True;
1717     if (iSERVICE (iService).szService[0] == '\0')
1718     {
1719         DEBUG (0, ("The following message indicates an internal error:\n"));
1720         DEBUG (0, ("No service name in service entry.\n"));
1721         bRetval = False;
1722     }
1723 
1724     /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1725     /* I can't see why you'd want a non-printable printer service...        */
1726     if (strwicmp (iSERVICE (iService).szService, PRINTERS_NAME) == 0)
1727         if (!iSERVICE (iService).bPrint_ok)
1728         {
1729             DEBUG (0, ("WARNING: [%s] service MUST be printable!\n",
1730                        iSERVICE (iService).szService));
1731             iSERVICE (iService).bPrint_ok = True;
1732         }
1733 
1734     if (iSERVICE (iService).szPath[0] == '\0' &&
1735         strwicmp (iSERVICE (iService).szService, HOMES_NAME) != 0)
1736     {
1737         DEBUG (0, ("No path in service %s - using %s\n", iSERVICE (iService).szService, tmpdir ()));
1738         string_set (&iSERVICE (iService).szPath, tmpdir ());
1739     }
1740 
1741     /* If a service is flagged unavailable, log the fact at level 0. */
1742     if (!iSERVICE (iService).bAvailable)
1743         DEBUG (1, ("NOTE: Service %s is flagged unavailable.\n", iSERVICE (iService).szService));
1744 
1745     return (bRetval);
1746 }
1747 
1748 #if 0
1749 static struct file_lists
1750 {
1751     struct file_lists *next;
1752     char *name;
1753     time_t modtime;
1754 } *file_lists = NULL;
1755 
1756 /*******************************************************************
1757 keep a linked list of all config files so we know when one has changed
1758 it's date and needs to be reloaded
1759 ********************************************************************/
1760 static void
1761 add_to_file_list (const char *fname)
1762 {
1763     struct file_lists *f = file_lists;
1764 
1765     while (f)
1766     {
1767         if (f->name && !strcmp (f->name, fname))
1768             break;
1769         f = f->next;
1770     }
1771 
1772     if (!f)
1773     {
1774         f = (struct file_lists *) malloc (sizeof (file_lists[0]));
1775         if (!f)
1776             return;
1777         f->next = file_lists;
1778         f->name = strdup (fname);
1779         if (!f->name)
1780         {
1781             free (f);
1782             return;
1783         }
1784         file_lists = f;
1785     }
1786 
1787     {
1788         pstring n2;
1789         pstrcpy (n2, fname);
1790         standard_sub_basic (n2);
1791         f->modtime = file_modtime (n2);
1792     }
1793 
1794 }
1795 
1796 
1797 /*******************************************************************
1798 check if a config file has changed date
1799 ********************************************************************/
1800 BOOL
1801 lp_file_list_changed (void)
1802 {
1803     struct file_lists *f = file_lists;
1804     DEBUG (6, ("lp_file_list_changed()\n"));
1805 
1806     while (f)
1807     {
1808         pstring n2;
1809         time_t mod_time;
1810 
1811         pstrcpy (n2, f->name);
1812         standard_sub_basic (n2);
1813 
1814         DEBUGADD (6, ("file %s -> %s  last mod_time: %s\n", f->name, n2, ctime (&f->modtime)));
1815 
1816         mod_time = file_modtime (n2);
1817 
1818         if (f->modtime != mod_time)
1819         {
1820             DEBUGADD (6, ("file %s modified: %s\n", n2, ctime (&mod_time)));
1821             f->modtime = mod_time;
1822             return (True);
1823         }
1824         f = f->next;
1825     }
1826     return (False);
1827 }
1828 #else
1829 #define add_to_file_list(x)
1830 #endif /* 0 */
1831 
1832 /***************************************************************************
1833   handle the interpretation of the coding system parameter
1834   *************************************************************************/
1835 static BOOL
handle_coding_system(const char * pszParmValue,char ** ptr)1836 handle_coding_system (const char *pszParmValue, char **ptr)
1837 {
1838     string_set (ptr, pszParmValue);
1839     interpret_coding_system (pszParmValue);
1840     return (True);
1841 }
1842 
1843 /***************************************************************************
1844 handle the interpretation of the character set system parameter
1845 ***************************************************************************/
1846 static BOOL
handle_character_set(const char * pszParmValue,char ** ptr)1847 handle_character_set (const char *pszParmValue, char **ptr)
1848 {
1849     string_set (ptr, pszParmValue);
1850     interpret_character_set (pszParmValue);
1851     return (True);
1852 }
1853 
1854 
1855 /***************************************************************************
1856 handle the valid chars lines
1857 ***************************************************************************/
1858 static BOOL
handle_valid_chars(const char * pszParmValue,char ** ptr)1859 handle_valid_chars (const char *pszParmValue, char **ptr)
1860 {
1861     string_set (ptr, pszParmValue);
1862 
1863     /* A dependency here is that the parameter client code page must be
1864        set before this is called - as calling codepage_initialise()
1865        would overwrite the valid char lines.
1866      */
1867     codepage_initialise (lp_client_code_page ());
1868 
1869     add_char_string (pszParmValue);
1870     return (True);
1871 }
1872 
1873 
1874 /***************************************************************************
1875 handle the include operation
1876 ***************************************************************************/
1877 static BOOL
handle_include(const char * pszParmValue,char ** ptr)1878 handle_include (const char *pszParmValue, char **ptr)
1879 {
1880     pstring fname;
1881     pstrcpy (fname, pszParmValue);
1882 
1883     add_to_file_list (fname);
1884 
1885     standard_sub_basic (fname);
1886 
1887     string_set (ptr, fname);
1888 
1889     if (file_exist (fname, NULL))
1890         return (pm_process (fname, do_section, do_parameter));
1891 
1892     DEBUG (2, ("Cannot find include file %s\n", fname));
1893 
1894     return (False);
1895 }
1896 
1897 
1898 /***************************************************************************
1899 handle the interpretation of the copy parameter
1900 ***************************************************************************/
1901 static BOOL
handle_copy(const char * pszParmValue,char ** ptr)1902 handle_copy (const char *pszParmValue, char **ptr)
1903 {
1904     BOOL bRetval;
1905     int iTemp;
1906     service serviceTemp;
1907 
1908     string_set (ptr, pszParmValue);
1909 
1910     init_service (&serviceTemp);
1911 
1912     bRetval = False;
1913 
1914     DEBUG (3, ("Copying service from service %s\n", pszParmValue));
1915 
1916     if ((iTemp = getservicebyname (pszParmValue, &serviceTemp)) >= 0)
1917     {
1918         if (iTemp == iServiceIndex)
1919         {
1920             DEBUG (0, ("Cannot copy service %s - unable to copy self!\n", pszParmValue));
1921         }
1922         else
1923         {
1924             copy_service (pSERVICE (iServiceIndex), &serviceTemp, iSERVICE (iServiceIndex).copymap);
1925             bRetval = True;
1926         }
1927     }
1928     else
1929     {
1930         DEBUG (0, ("Unable to copy service - source not found: %s\n", pszParmValue));
1931         bRetval = False;
1932     }
1933 
1934     free_service (&serviceTemp);
1935     return (bRetval);
1936 }
1937 
1938 
1939 /***************************************************************************
1940 initialise a copymap
1941 ***************************************************************************/
1942 static void
init_copymap(service * pservice)1943 init_copymap (service * pservice)
1944 {
1945     size_t i;
1946     if (pservice->copymap)
1947         free (pservice->copymap);
1948     pservice->copymap = (BOOL *) malloc (sizeof (BOOL) * NUMPARAMETERS);
1949     if (!pservice->copymap)
1950         DEBUG (0, ("Couldn't allocate copymap!! (size %d)\n", (int) NUMPARAMETERS));
1951     else
1952         for (i = 0; i < NUMPARAMETERS; i++)
1953             pservice->copymap[i] = True;
1954 }
1955 
1956 #if 0
1957 /***************************************************************************
1958  return the local pointer to a parameter given the service number and the
1959  pointer into the default structure
1960 ***************************************************************************/
1961 void *
1962 lp_local_ptr (int snum, void *ptr)
1963 {
1964     return (void *) (((char *) pSERVICE (snum)) + PTR_DIFF (ptr, &sDefault));
1965 }
1966 #endif /* 0 */
1967 
1968 /***************************************************************************
1969 Process a parameter for a particular service number. If snum < 0
1970 then assume we are in the globals
1971 ***************************************************************************/
1972 BOOL
lp_do_parameter(int snum,const char * pszParmName,const char * pszParmValue)1973 lp_do_parameter (int snum, const char *pszParmName, const char *pszParmValue)
1974 {
1975     int parmnum, i;
1976     void *parm_ptr = NULL;      /* where we are going to store the result */
1977     void *def_ptr = NULL;
1978 
1979     parmnum = map_parameter (pszParmName);
1980 
1981     if (parmnum < 0)
1982     {
1983         DEBUG (0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
1984         return (True);
1985     }
1986 
1987     if (parm_table[parmnum].flags & FLAG_DEPRECATED)
1988     {
1989         DEBUG (1, ("WARNING: The \"%s\"option is deprecated\n", pszParmName));
1990     }
1991 
1992     def_ptr = parm_table[parmnum].ptr;
1993 
1994     /* we might point at a service, the default service or a global */
1995     if (snum < 0)
1996     {
1997         parm_ptr = def_ptr;
1998     }
1999     else
2000     {
2001         if (parm_table[parmnum].class == P_GLOBAL)
2002         {
2003             DEBUG (0, ("Global parameter %s found in service section!\n", pszParmName));
2004             return (True);
2005         }
2006         parm_ptr = ((char *) pSERVICE (snum)) + PTR_DIFF (def_ptr, &sDefault);
2007     }
2008 
2009     if (snum >= 0)
2010     {
2011         if (!iSERVICE (snum).copymap)
2012             init_copymap (pSERVICE (snum));
2013 
2014         /* this handles the aliases - set the copymap for other entries with
2015            the same data pointer */
2016         for (i = 0; parm_table[i].label; i++)
2017             if (parm_table[i].ptr == parm_table[parmnum].ptr)
2018                 iSERVICE (snum).copymap[i] = False;
2019     }
2020 
2021     /* if it is a special case then go ahead */
2022     if (parm_table[parmnum].special)
2023     {
2024         parm_table[parmnum].special (pszParmValue, (char **) parm_ptr);
2025         return (True);
2026     }
2027 
2028     /* now switch on the type of variable it is */
2029     switch (parm_table[parmnum].type)
2030     {
2031     case P_BOOL:
2032         set_boolean (parm_ptr, pszParmValue);
2033         break;
2034 
2035     case P_BOOLREV:
2036         set_boolean (parm_ptr, pszParmValue);
2037         *(BOOL *) parm_ptr = !*(BOOL *) parm_ptr;
2038         break;
2039 
2040     case P_INTEGER:
2041         *(int *) parm_ptr = atoi (pszParmValue);
2042         break;
2043 
2044     case P_CHAR:
2045         *(char *) parm_ptr = *pszParmValue;
2046         break;
2047 
2048     case P_OCTAL:
2049         sscanf (pszParmValue, "%o", (int *) parm_ptr);
2050         break;
2051 
2052     case P_STRING:
2053         string_set (parm_ptr, pszParmValue);
2054         break;
2055 
2056     case P_USTRING:
2057         string_set (parm_ptr, pszParmValue);
2058         strupper (*(char **) parm_ptr);
2059         break;
2060 
2061     case P_GSTRING:
2062         pstrcpy ((char *) parm_ptr, pszParmValue);
2063         break;
2064 
2065     case P_UGSTRING:
2066         pstrcpy ((char *) parm_ptr, pszParmValue);
2067         strupper ((char *) parm_ptr);
2068         break;
2069 
2070     case P_ENUM:
2071         for (i = 0; parm_table[parmnum].enum_list[i].name; i++)
2072         {
2073             if (strequal (pszParmValue, parm_table[parmnum].enum_list[i].name))
2074             {
2075                 *(int *) parm_ptr = parm_table[parmnum].enum_list[i].value;
2076                 break;
2077             }
2078         }
2079         break;
2080     case P_SEP:
2081         break;
2082     }
2083 
2084     return (True);
2085 }
2086 
2087 /***************************************************************************
2088 Process a parameter.
2089 ***************************************************************************/
2090 static BOOL
do_parameter(const char * pszParmName,const char * pszParmValue)2091 do_parameter (const char *pszParmName, const char *pszParmValue)
2092 {
2093     if (!bInGlobalSection && bGlobalOnly)
2094         return (True);
2095 
2096     DEBUGADD (3, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
2097 
2098     return (lp_do_parameter (bInGlobalSection ? -2 : iServiceIndex, pszParmName, pszParmValue));
2099 }
2100 
2101 #if 0
2102 /***************************************************************************
2103 check if two parameters are equal
2104 ***************************************************************************/
2105 static BOOL
2106 equal_parameter (parm_type type, void *ptr1, void *ptr2)
2107 {
2108     switch (type)
2109     {
2110     case P_BOOL:
2111     case P_BOOLREV:
2112         return (*((BOOL *) ptr1) == *((BOOL *) ptr2));
2113 
2114     case P_INTEGER:
2115     case P_ENUM:
2116     case P_OCTAL:
2117         return (*((int *) ptr1) == *((int *) ptr2));
2118 
2119     case P_CHAR:
2120         return (*((char *) ptr1) == *((char *) ptr2));
2121 
2122     case P_GSTRING:
2123     case P_UGSTRING:
2124         {
2125             char *p1 = (char *) ptr1, *p2 = (char *) ptr2;
2126             if (p1 && !*p1)
2127                 p1 = NULL;
2128             if (p2 && !*p2)
2129                 p2 = NULL;
2130             return (p1 == p2 || strequal (p1, p2));
2131         }
2132     case P_STRING:
2133     case P_USTRING:
2134         {
2135             char *p1 = *(char **) ptr1, *p2 = *(char **) ptr2;
2136             if (p1 && !*p1)
2137                 p1 = NULL;
2138             if (p2 && !*p2)
2139                 p2 = NULL;
2140             return (p1 == p2 || strequal (p1, p2));
2141         }
2142     case P_SEP:
2143         break;
2144     }
2145     return (False);
2146 }
2147 #endif /* 0 */
2148 
2149 /***************************************************************************
2150 Process a new section (service). At this stage all sections are services.
2151 Later we'll have special sections that permit server parameters to be set.
2152 Returns True on success, False on failure.
2153 ***************************************************************************/
2154 static BOOL
do_section(const char * pszSectionName)2155 do_section (const char *pszSectionName)
2156 {
2157     BOOL bRetval;
2158     BOOL isglobal = ((strwicmp (pszSectionName, GLOBAL_NAME) == 0) ||
2159                      (strwicmp (pszSectionName, GLOBAL_NAME2) == 0));
2160     bRetval = False;
2161 
2162     /* if we were in a global section then do the local inits */
2163     if (bInGlobalSection && !isglobal)
2164     {
2165         init_locals ();
2166     }
2167 
2168     /* if we've just struck a global section, note the fact. */
2169     bInGlobalSection = isglobal;
2170 
2171     /* check for multiple global sections */
2172     if (bInGlobalSection)
2173     {
2174         DEBUG (3, ("Processing section \"[%s]\"\n", pszSectionName));
2175         return (True);
2176     }
2177 
2178     if (!bInGlobalSection && bGlobalOnly)
2179         return (True);
2180 
2181     /* if we have a current service, tidy it up before moving on */
2182     bRetval = True;
2183 
2184     if (iServiceIndex >= 0)
2185         bRetval = service_ok (iServiceIndex);
2186 
2187     /* if all is still well, move to the next record in the services array */
2188     if (bRetval)
2189     {
2190         /* We put this here to avoid an odd message order if messages are */
2191         /* issued by the post-processing of a previous section. */
2192         DEBUG (2, ("Processing section \"[%s]\"\n", pszSectionName));
2193 
2194         if ((iServiceIndex = add_a_service (&sDefault, pszSectionName)) < 0)
2195         {
2196             DEBUG (0, ("Failed to add a new service\n"));
2197             return (False);
2198         }
2199     }
2200 
2201     return (bRetval);
2202 }
2203 
2204 #if 0
2205 /***************************************************************************
2206 return True if a local parameter is currently set to the global default
2207 ***************************************************************************/
2208 BOOL
2209 lp_is_default (int snum, struct parm_struct * parm)
2210 {
2211     int pdiff = PTR_DIFF (parm->ptr, &sDefault);
2212 
2213     return equal_parameter (parm->type,
2214                             ((char *) pSERVICE (snum)) + pdiff, ((char *) &sDefault) + pdiff);
2215 }
2216 #endif /* 0 */
2217 #if 0
2218 /***************************************************************************
2219 return info about the next service  in a service. snum==-1 gives the globals
2220 
2221 return NULL when out of parameters
2222 ***************************************************************************/
2223 struct parm_struct *
2224 lp_next_parameter (int snum, int *i, int allparameters)
2225 {
2226     if (snum == -1)
2227     {
2228         /* do the globals */
2229         for (; parm_table[*i].label; (*i)++)
2230         {
2231             if (parm_table[*i].class == P_SEPARATOR)
2232                 return &parm_table[(*i)++];
2233 
2234             if (!parm_table[*i].ptr || (*parm_table[*i].label == '-'))
2235                 continue;
2236 
2237             if ((*i) > 0 && (parm_table[*i].ptr == parm_table[(*i) - 1].ptr))
2238                 continue;
2239 
2240             return &parm_table[(*i)++];
2241         }
2242     }
2243     else
2244     {
2245         service *pService = pSERVICE (snum);
2246 
2247         for (; parm_table[*i].label; (*i)++)
2248         {
2249             if (parm_table[*i].class == P_SEPARATOR)
2250                 return &parm_table[(*i)++];
2251 
2252             if (parm_table[*i].class == P_LOCAL &&
2253                 parm_table[*i].ptr &&
2254                 (*parm_table[*i].label != '-') &&
2255                 ((*i) == 0 || (parm_table[*i].ptr != parm_table[(*i) - 1].ptr)))
2256             {
2257                 int pdiff = PTR_DIFF (parm_table[*i].ptr, &sDefault);
2258 
2259                 if (allparameters ||
2260                     !equal_parameter (parm_table[*i].type,
2261                                       ((char *) pService) + pdiff, ((char *) &sDefault) + pdiff))
2262                 {
2263                     return &parm_table[(*i)++];
2264                 }
2265             }
2266         }
2267     }
2268 
2269     return NULL;
2270 }
2271 #endif /* 0 */
2272 #if 0
2273 /***************************************************************************
2274 Return TRUE if the passed service number is within range.
2275 ***************************************************************************/
2276 BOOL
2277 lp_snum_ok (int iService)
2278 {
2279     return (LP_SNUM_OK (iService) && iSERVICE (iService).bAvailable);
2280 }
2281 #endif /* 0 */
2282 
2283 /***************************************************************************
2284 auto-load some home services
2285 ***************************************************************************/
2286 static void
lp_add_auto_services(char * str)2287 lp_add_auto_services (char *str)
2288 {
2289     char *s;
2290     char *p;
2291     int homes;
2292 
2293     if (!str)
2294         return;
2295 
2296     s = strdup (str);
2297     if (!s)
2298         return;
2299 
2300     homes = lp_servicenumber (HOMES_NAME);
2301 
2302     for (p = strtok (s, LIST_SEP); p; p = strtok (NULL, LIST_SEP))
2303     {
2304         const char *home = get_home_dir (p);
2305 
2306         if (lp_servicenumber (p) >= 0)
2307             continue;
2308 
2309         if (home && homes >= 0)
2310         {
2311             lp_add_home (p, homes, home);
2312         }
2313     }
2314     free (s);
2315 }
2316 
2317 
2318 /***************************************************************************
2319 have we loaded a services file yet?
2320 ***************************************************************************/
2321 BOOL
lp_loaded(void)2322 lp_loaded (void)
2323 {
2324     return (bLoaded);
2325 }
2326 
2327 #if 0
2328 /***************************************************************************
2329 unload unused services
2330 ***************************************************************************/
2331 void
2332 lp_killunused (BOOL (*snumused) (int))
2333 {
2334     int i;
2335     for (i = 0; i < iNumServices; i++)
2336         if (VALID (i) && (!snumused || !snumused (i)))
2337         {
2338             iSERVICE (i).valid = False;
2339             free_service (pSERVICE (i));
2340         }
2341 }
2342 #endif /* 0 */
2343 #if 0
2344 /***************************************************************************
2345 save the current values of all global and sDefault parameters into the
2346 defaults union. This allows swat and testparm to show only the
2347 changed (ie. non-default) parameters.
2348 ***************************************************************************/
2349 static void
2350 lp_save_defaults (void)
2351 {
2352     static BOOL defaults_saved = False;
2353     int i;
2354 
2355     for (i = 0; parm_table[i].label; i++)
2356     {
2357         if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2358             continue;
2359         switch (parm_table[i].type)
2360         {
2361         case P_STRING:
2362         case P_USTRING:
2363             parm_table[i].def.svalue = strdup (*(char **) parm_table[i].ptr);
2364             break;
2365         case P_GSTRING:
2366         case P_UGSTRING:
2367             parm_table[i].def.svalue = strdup ((char *) parm_table[i].ptr);
2368             break;
2369         case P_BOOL:
2370         case P_BOOLREV:
2371             parm_table[i].def.bvalue = *(BOOL *) parm_table[i].ptr;
2372             break;
2373         case P_CHAR:
2374             parm_table[i].def.cvalue = *(char *) parm_table[i].ptr;
2375             break;
2376         case P_INTEGER:
2377         case P_OCTAL:
2378         case P_ENUM:
2379             parm_table[i].def.ivalue = *(int *) parm_table[i].ptr;
2380             break;
2381         case P_SEP:
2382             break;
2383         }
2384     }
2385     defaults_saved = True;
2386 }
2387 #endif /* 0 */
2388 
2389 /***************************************************************************
2390 Load the services array from the services file. Return True on success,
2391 False on failure.
2392 ***************************************************************************/
2393 BOOL
lp_load(const char * pszFname,BOOL global_only,BOOL save_defaults,BOOL add_ipc)2394 lp_load (const char *pszFname, BOOL global_only, BOOL save_defaults, BOOL add_ipc)
2395 {
2396     pstring n2;
2397     BOOL bRetval;
2398 
2399     add_to_file_list (pszFname);
2400 
2401     bRetval = False;
2402 
2403     bInGlobalSection = True;
2404     bGlobalOnly = global_only;
2405 
2406     init_globals ();
2407 #if 0
2408     if (save_defaults)
2409     {
2410         init_locals ();
2411         lp_save_defaults ();
2412     }
2413 #else
2414     (void) &save_defaults;
2415 #endif /* 0 */
2416     pstrcpy (n2, pszFname);
2417     standard_sub_basic (n2);
2418 
2419     /* We get sections first, so have to start 'behind' to make up */
2420     iServiceIndex = -1;
2421     bRetval = pm_process (n2, do_section, do_parameter);
2422 
2423     /* finish up the last section */
2424     DEBUG (3, ("pm_process() returned %s\n", BOOLSTR (bRetval)));
2425     if (bRetval)
2426         if (iServiceIndex >= 0)
2427             bRetval = service_ok (iServiceIndex);
2428 
2429     lp_add_auto_services (lp_auto_services ());
2430 #if 0
2431     if (add_ipc)
2432         lp_add_ipc ();
2433     set_default_server_announce_type ();
2434 #else
2435     (void) &add_ipc;
2436 #endif /* 0 */
2437 
2438     bLoaded = True;
2439 
2440     /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
2441     /* if bWINSsupport is true and we are in the client            */
2442 
2443     if (in_client && Globals.bWINSsupport)
2444     {
2445 
2446         string_set (&Globals.szWINSserver, "127.0.0.1");
2447 
2448     }
2449 
2450     return (bRetval);
2451 }
2452 
2453 #if 0
2454 /***************************************************************************
2455 reset the max number of services
2456 ***************************************************************************/
2457 void
2458 lp_resetnumservices (void)
2459 {
2460     iNumServices = 0;
2461 }
2462 
2463 
2464 /***************************************************************************
2465 return the max number of services
2466 ***************************************************************************/
2467 int
2468 lp_numservices (void)
2469 {
2470     return (iNumServices);
2471 }
2472 #endif /* 0 */
2473 
2474 /***************************************************************************
2475 Return the number of the service with the given name, or -1 if it doesn't
2476 exist. Note that this is a DIFFERENT ANIMAL from the internal function
2477 getservicebyname()! This works ONLY if all services have been loaded, and
2478 does not copy the found service.
2479 ***************************************************************************/
2480 int
lp_servicenumber(const char * pszServiceName)2481 lp_servicenumber (const char *pszServiceName)
2482 {
2483     int iService;
2484 
2485     for (iService = iNumServices - 1; iService >= 0; iService--)
2486         if (VALID (iService) && strequal (lp_servicename (iService), pszServiceName))
2487             break;
2488 
2489     if (iService < 0)
2490         DEBUG (7, ("lp_servicenumber: couldn't find %s\n", pszServiceName));
2491 
2492     return (iService);
2493 }
2494 
2495 #if 0
2496 /*******************************************************************
2497   a useful volume label function
2498   ******************************************************************/
2499 char *
2500 volume_label (int snum)
2501 {
2502     char *ret = lp_volume (snum);
2503     if (!*ret)
2504         return (lp_servicename (snum));
2505     return (ret);
2506 }
2507 
2508 /***********************************************************
2509  Set the global name resolution order (used in smbclient).
2510 ************************************************************/
2511 
2512 void
2513 lp_set_name_resolve_order (char *new_order)
2514 {
2515     Globals.szNameResolveOrder = new_order;
2516 }
2517 #endif /* 0 */
2518