r7531: Finally fix lp_load(). I had left hooks in place which restricted us
[Samba/ekacnet.git] / source4 / param / loadparm.c
blobdeb7d2284ff00418eb0647795f3578fd570b09ad
1 /*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough (jmcd@us.ibm.com) 2003.
12 Copyright (C) James Myers 2003 <myersjj@samba.org>
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 2 of the License, or
17 (at your option) any later version.
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 * Load parameters.
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.
36 * To add a parameter:
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
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!
55 #include "includes.h"
56 #include "version.h"
57 #include "dynconfig.h"
58 #include "system/time.h"
59 #include "system/iconv.h"
60 #include "system/network.h"
61 #include "system/printing.h"
62 #include "librpc/gen_ndr/ndr_svcctl.h"
63 #include "librpc/gen_ndr/ndr_samr.h"
64 #include "librpc/gen_ndr/ndr_nbt.h"
65 #include "dlinklist.h"
66 #include "param/loadparm.h"
68 BOOL in_client = False; /* Not in the client by default */
69 static BOOL bLoaded = False;
71 #ifndef GLOBAL_NAME
72 #define GLOBAL_NAME "global"
73 #endif
75 #ifndef PRINTERS_NAME
76 #define PRINTERS_NAME "printers"
77 #endif
79 #ifndef HOMES_NAME
80 #define HOMES_NAME "homes"
81 #endif
83 /* some helpful bits */
84 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
85 #define VALID(i) ServicePtrs[i]->valid
87 static BOOL do_parameter(const char *, const char *);
88 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
90 static BOOL defaults_saved = False;
93 #define FLAG_BASIC 0x0001 /* fundamental options */
94 #define FLAG_SHARE 0x0002 /* file sharing options */
95 #define FLAG_PRINT 0x0004 /* printing options */
96 #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
97 #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
98 #define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
99 #define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
100 #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
101 #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
102 #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
103 #define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
108 struct param_opt {
109 struct param_opt *prev, *next;
110 char *key;
111 char *value;
112 int flags;
116 * This structure describes global (ie., server-wide) parameters.
118 typedef struct
120 char **smb_ports;
121 char *dos_charset;
122 char *unix_charset;
123 char *ncalrpc_dir;
124 char *display_charset;
125 char *szPrintcapname;
126 char *szLockDir;
127 char *szPidDir;
128 char *szRootdir;
129 char *szDefaultService;
130 char *szHostsEquiv;
131 char *szServerString;
132 char *szAutoServices;
133 char *szPasswdProgram;
134 char *szPasswdChat;
135 char *szLogFile;
136 char *szConfigFile;
137 char *szSMBPasswdFile;
138 char *szSAM_URL;
139 char *szSPOOLSS_URL;
140 char *szWINS_URL;
141 char *szPrivateDir;
142 char **szPreloadModules;
143 char **szPasswordServers;
144 char *szSocketOptions;
145 char *szRealm;
146 char *szADSserver;
147 char *szLogonScript;
148 char *szLogonPath;
149 char *szLogonDrive;
150 char *szLogonHome;
151 char **szWINSservers;
152 char **szInterfaces;
153 char *szRemoteAnnounce;
154 char *szRemoteBrowseSync;
155 char *szSocketAddress;
156 char *szAnnounceVersion; /* This is initialised in init_globals */
157 char *szWorkgroup;
158 char *szNetbiosName;
159 char **szNetbiosAliases;
160 char *szNetbiosScope;
161 char *szDomainOtherSIDs;
162 char **szNameResolveOrder;
163 char *szPanicAction;
164 char *szAddUserScript;
165 char *szAddMachineScript;
166 char *szWINSHook;
167 char *szWINSPartners;
168 char **dcerpc_ep_servers;
169 char **server_services;
170 char *szWinbindUID;
171 char *szWinbindGID;
172 char *szNonUnixAccountRange;
173 char *szTemplateHomedir;
174 char *szTemplateShell;
175 char *szWinbindSeparator;
176 BOOL bWinbindEnumUsers;
177 BOOL bWinbindEnumGroups;
178 BOOL bWinbindUseDefaultDomain;
179 char *szIDMapBackend;
180 char *szGuestaccount;
181 char *swat_directory;
182 BOOL web_tls;
183 char *web_keyfile;
184 char *web_certfile;
185 char *web_cafile;
186 char *web_crlfile;
187 int max_mux;
188 int max_xmit;
189 int pwordlevel;
190 int unamelevel;
191 int maxprotocol;
192 int minprotocol;
193 int security;
194 char **AuthMethods;
195 BOOL paranoid_server_security;
196 int lpqcachetime;
197 BOOL bDisableSpoolss;
198 int os_level;
199 int enhanced_browsing;
200 int time_offset;
201 int max_ttl;
202 int max_wins_ttl;
203 int min_wins_ttl;
204 int lm_announce;
205 int lm_interval;
206 int announce_as; /* This is initialised in init_globals */
207 int machine_password_timeout;
208 int winbind_cache_time;
209 int iLockSpinCount;
210 int iLockSpinTime;
211 int nbt_port;
212 int dgram_port;
213 int cldap_port;
214 int krb5_port;
215 int web_port;
216 char *socket_options;
217 BOOL bDNSproxy;
218 BOOL bWINSsupport;
219 BOOL bWINSproxy;
220 BOOL bLocalMaster;
221 BOOL bPreferredMaster;
222 BOOL bDomainMaster;
223 BOOL bDomainLogons;
224 BOOL bEncryptPasswords;
225 BOOL bNullPasswords;
226 BOOL bObeyPamRestrictions;
227 BOOL bLoadPrinters;
228 BOOL bLargeReadwrite;
229 BOOL bReadRaw;
230 BOOL bWriteRaw;
231 BOOL bTimeServer;
232 BOOL bBindInterfacesOnly;
233 BOOL bPamPasswordChange;
234 BOOL bNTSmbSupport;
235 BOOL bNTStatusSupport;
236 BOOL bAllowTrustedDomains;
237 BOOL bLanmanAuth;
238 BOOL bNTLMAuth;
239 BOOL bUseSpnego;
240 int server_signing;
241 int client_signing;
242 BOOL bClientLanManAuth;
243 BOOL bClientNTLMv2Auth;
244 BOOL bHostMSDfs;
245 BOOL bHideLocalUsers;
246 BOOL bUnicode;
247 BOOL bUseMmap;
248 BOOL bHostnameLookups;
249 BOOL bUnixExtensions;
250 BOOL bDisableNetbios;
251 BOOL bRpcBigEndian;
252 int restrict_anonymous;
253 int name_cache_timeout;
254 struct param_opt *param_opt;
256 global;
258 static global Globals;
261 * This structure describes a single service.
263 typedef struct
265 BOOL valid;
266 BOOL autoloaded;
267 char *szService;
268 char *szPath;
269 char *szUsername;
270 char **szInvalidUsers;
271 char **szValidUsers;
272 char **szAdminUsers;
273 char *szCopy;
274 char *szInclude;
275 char *szPrintcommand;
276 char *szLpqcommand;
277 char *szLprmcommand;
278 char *szLppausecommand;
279 char *szLpresumecommand;
280 char *szQueuepausecommand;
281 char *szQueueresumecommand;
282 char *szPrintername;
283 char **szHostsallow;
284 char **szHostsdeny;
285 char *comment;
286 char *volume;
287 char *fstype;
288 char *szMSDfsProxy;
289 char **ntvfs_handler;
290 int iMinPrintSpace;
291 int iMaxPrintJobs;
292 int iMaxConnections;
293 int iPrinting;
294 int iCSCPolicy;
295 BOOL bAvailable;
296 BOOL bBrowseable;
297 BOOL bRead_only;
298 BOOL bPrint_ok;
299 BOOL bMap_system;
300 BOOL bMap_hidden;
301 BOOL bMap_archive;
302 BOOL bLocking;
303 BOOL bStrictLocking;
304 BOOL bPosixLocking;
305 BOOL bOpLocks;
306 BOOL bLevel2OpLocks;
307 BOOL bOnlyUser;
308 BOOL bGuest_only;
309 BOOL bGuest_ok;
310 BOOL *copymap;
311 BOOL bMSDfsRoot;
312 BOOL bShareModes;
313 BOOL bStrictSync;
314 BOOL bCIFileSystem;
315 struct param_opt *param_opt;
317 char dummy[3]; /* for alignment */
319 service;
322 /* This is a default service used to prime a services structure */
323 static service sDefault = {
324 True, /* valid */
325 False, /* not autoloaded */
326 NULL, /* szService */
327 NULL, /* szPath */
328 NULL, /* szUsername */
329 NULL, /* szInvalidUsers */
330 NULL, /* szValidUsers */
331 NULL, /* szAdminUsers */
332 NULL, /* szCopy */
333 NULL, /* szInclude */
334 NULL, /* szPrintcommand */
335 NULL, /* szLpqcommand */
336 NULL, /* szLprmcommand */
337 NULL, /* szLppausecommand */
338 NULL, /* szLpresumecommand */
339 NULL, /* szQueuepausecommand */
340 NULL, /* szQueueresumecommand */
341 NULL, /* szPrintername */
342 NULL, /* szHostsallow */
343 NULL, /* szHostsdeny */
344 NULL, /* comment */
345 NULL, /* volume */
346 NULL, /* fstype */
347 NULL, /* szMSDfsProxy */
348 NULL, /* ntvfs_handler */
349 0, /* iMinPrintSpace */
350 1000, /* iMaxPrintJobs */
351 0, /* iMaxConnections */
352 DEFAULT_PRINTING, /* iPrinting */
353 0, /* iCSCPolicy */
354 True, /* bAvailable */
355 True, /* bBrowseable */
356 True, /* bRead_only */
357 False, /* bPrint_ok */
358 False, /* bMap_system */
359 False, /* bMap_hidden */
360 True, /* bMap_archive */
361 True, /* bLocking */
362 True, /* bStrictLocking */
363 True, /* bPosixLocking */
364 True, /* bOpLocks */
365 True, /* bLevel2OpLocks */
366 False, /* bOnlyUser */
367 False, /* bGuest_only */
368 False, /* bGuest_ok */
369 NULL, /* copymap */
370 False, /* bMSDfsRoot */
371 True, /* bShareModes */
372 False, /* bStrictSync */
373 False, /* bCIFileSystem */
374 NULL, /* Parametric options */
376 "" /* dummy */
379 /* local variables */
380 static service **ServicePtrs = NULL;
381 static int iNumServices = 0;
382 static int iServiceIndex = 0;
383 static BOOL bInGlobalSection = True;
384 static int server_role;
385 static int default_server_announce;
387 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
389 /* prototypes for the special type handlers */
390 static BOOL handle_include(const char *pszParmValue, char **ptr);
391 static BOOL handle_copy(const char *pszParmValue, char **ptr);
392 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
393 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
394 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
396 static void set_server_role(void);
397 static void set_default_server_announce_type(void);
399 static const struct enum_list enum_protocol[] = {
400 {PROTOCOL_NT1, "NT1"},
401 {PROTOCOL_LANMAN2, "LANMAN2"},
402 {PROTOCOL_LANMAN1, "LANMAN1"},
403 {PROTOCOL_CORE, "CORE"},
404 {PROTOCOL_COREPLUS, "COREPLUS"},
405 {PROTOCOL_COREPLUS, "CORE+"},
406 {-1, NULL}
409 static const struct enum_list enum_security[] = {
410 {SEC_SHARE, "SHARE"},
411 {SEC_USER, "USER"},
412 {SEC_SERVER, "SERVER"},
413 {SEC_DOMAIN, "DOMAIN"},
414 #ifdef HAVE_ADS
415 {SEC_ADS, "ADS"},
416 #endif
417 {-1, NULL}
420 static const struct enum_list enum_printing[] = {
421 {PRINT_SYSV, "sysv"},
422 {PRINT_AIX, "aix"},
423 {PRINT_HPUX, "hpux"},
424 {PRINT_BSD, "bsd"},
425 {PRINT_QNX, "qnx"},
426 {PRINT_PLP, "plp"},
427 {PRINT_LPRNG, "lprng"},
428 {PRINT_SOFTQ, "softq"},
429 {PRINT_CUPS, "cups"},
430 {PRINT_LPRNT, "nt"},
431 {PRINT_LPROS2, "os2"},
432 #ifdef DEVELOPER
433 {PRINT_TEST, "test"},
434 {PRINT_VLP, "vlp"},
435 #endif /* DEVELOPER */
436 {-1, NULL}
439 /* Types of machine we can announce as. */
440 #define ANNOUNCE_AS_NT_SERVER 1
441 #define ANNOUNCE_AS_WIN95 2
442 #define ANNOUNCE_AS_WFW 3
443 #define ANNOUNCE_AS_NT_WORKSTATION 4
445 static const struct enum_list enum_announce_as[] = {
446 {ANNOUNCE_AS_NT_SERVER, "NT"},
447 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
448 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
449 {ANNOUNCE_AS_WIN95, "win95"},
450 {ANNOUNCE_AS_WFW, "WfW"},
451 {-1, NULL}
454 static const struct enum_list enum_bool_auto[] = {
455 {False, "No"},
456 {False, "False"},
457 {False, "0"},
458 {True, "Yes"},
459 {True, "True"},
460 {True, "1"},
461 {Auto, "Auto"},
462 {-1, NULL}
465 /* Client-side offline caching policy types */
466 #define CSC_POLICY_MANUAL 0
467 #define CSC_POLICY_DOCUMENTS 1
468 #define CSC_POLICY_PROGRAMS 2
469 #define CSC_POLICY_DISABLE 3
471 static const struct enum_list enum_csc_policy[] = {
472 {CSC_POLICY_MANUAL, "manual"},
473 {CSC_POLICY_DOCUMENTS, "documents"},
474 {CSC_POLICY_PROGRAMS, "programs"},
475 {CSC_POLICY_DISABLE, "disable"},
476 {-1, NULL}
479 /* SMB signing types. */
480 static const struct enum_list enum_smb_signing_vals[] = {
481 {SMB_SIGNING_OFF, "No"},
482 {SMB_SIGNING_OFF, "False"},
483 {SMB_SIGNING_OFF, "0"},
484 {SMB_SIGNING_OFF, "Off"},
485 {SMB_SIGNING_OFF, "disabled"},
486 {SMB_SIGNING_SUPPORTED, "Yes"},
487 {SMB_SIGNING_SUPPORTED, "True"},
488 {SMB_SIGNING_SUPPORTED, "1"},
489 {SMB_SIGNING_SUPPORTED, "On"},
490 {SMB_SIGNING_SUPPORTED, "enabled"},
491 {SMB_SIGNING_REQUIRED, "required"},
492 {SMB_SIGNING_REQUIRED, "mandatory"},
493 {SMB_SIGNING_REQUIRED, "force"},
494 {SMB_SIGNING_REQUIRED, "forced"},
495 {SMB_SIGNING_REQUIRED, "enforced"},
496 {SMB_SIGNING_AUTO, "auto"},
497 {-1, NULL}
501 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
503 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
504 * is implied in current control logic. This may change at some later time. A
505 * flag value of 0 means - show as development option only.
507 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
508 * screen in SWAT. This is used to exclude parameters as well as to squash all
509 * parameters that have been duplicated by pseudonyms.
511 static struct parm_struct parm_table[] = {
512 {"Base Options", P_SEP, P_SEPARATOR},
514 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
515 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
516 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
517 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
518 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
519 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
520 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
521 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
522 {"realm", P_STRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
523 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
524 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
525 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
526 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
527 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
528 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
529 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
530 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
531 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
532 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
534 {"Security Options", P_SEP, P_SEPARATOR},
536 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
537 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
538 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
539 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
540 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
541 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
542 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
543 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
544 {"password server", P_LIST, P_GLOBAL, &Globals.szPasswordServers, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
545 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
548 {"wins database", P_STRING, P_GLOBAL, &Globals.szWINS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
549 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
550 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
551 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
552 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
553 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
554 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
556 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
557 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
558 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
560 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
564 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
568 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
569 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
571 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
572 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
573 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
575 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
577 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
579 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
581 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
582 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
583 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
584 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
586 {"Logging Options", P_SEP, P_SEPARATOR},
588 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
589 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
590 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
592 {"Protocol Options", P_SEP, P_SEPARATOR},
594 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
595 {"nbt port", P_INTEGER, P_GLOBAL, &Globals.nbt_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
596 {"dgram port", P_INTEGER, P_GLOBAL, &Globals.dgram_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
597 {"cldap port", P_INTEGER, P_GLOBAL, &Globals.cldap_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
598 {"krb5 port", P_INTEGER, P_GLOBAL, &Globals.krb5_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
599 {"web port", P_INTEGER, P_GLOBAL, &Globals.web_port, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
600 {"web tls", P_BOOL, P_GLOBAL, &Globals.web_tls, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
601 {"web tls keyfile", P_STRING, P_GLOBAL, &Globals.web_keyfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
602 {"web tls certfile", P_STRING, P_GLOBAL, &Globals.web_certfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
603 {"web tls cafile", P_STRING, P_GLOBAL, &Globals.web_cafile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
604 {"web tls crlfile", P_STRING, P_GLOBAL, &Globals.web_crlfile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
605 {"swat directory", P_STRING, P_GLOBAL, &Globals.swat_directory, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
606 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
607 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
608 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
609 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
610 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
611 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
612 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
614 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
616 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
617 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
618 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
619 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
621 {"name resolve order", P_LIST, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
622 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
623 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
624 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
625 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
626 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
627 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
628 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
629 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
630 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
632 {"Tuning Options", P_SEP, P_SEPARATOR},
634 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
635 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
636 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
637 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
639 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
640 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
641 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
643 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
644 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
645 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
647 {"Printing Options", P_SEP, P_SEPARATOR},
649 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
650 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
651 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
652 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
653 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
654 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
655 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
656 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
657 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
658 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
659 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
660 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
661 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
662 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
663 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
665 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
666 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
668 {"Filename Handling", P_SEP, P_SEPARATOR},
670 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
671 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
672 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
674 {"Domain Options", P_SEP, P_SEPARATOR},
676 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
678 {"Logon Options", P_SEP, P_SEPARATOR},
680 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
681 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
683 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
684 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
685 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
686 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
687 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
689 {"Browse Options", P_SEP, P_SEPARATOR},
691 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
692 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
695 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
696 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
697 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
698 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
699 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
700 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
702 {"WINS Options", P_SEP, P_SEPARATOR},
703 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
704 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
706 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
707 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
708 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
709 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
711 {"Locking Options", P_SEP, P_SEPARATOR},
713 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
714 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
715 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
716 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
718 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
719 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
720 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
721 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
722 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
724 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
726 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
727 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
728 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
729 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
730 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
731 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
733 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
734 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
735 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
736 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
737 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
738 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
739 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
741 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
742 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
744 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
745 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
746 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
748 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
749 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
751 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
752 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
753 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
754 {"Winbind options", P_SEP, P_SEPARATOR},
756 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
757 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
759 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
760 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
761 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
762 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
763 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
764 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
769 /***************************************************************************
770 Initialise the sDefault parameter structure for the printer values.
771 ***************************************************************************/
773 static void init_printer_values(void)
775 /* choose defaults depending on the type of printing */
776 switch (sDefault.iPrinting) {
777 case PRINT_BSD:
778 case PRINT_AIX:
779 case PRINT_LPRNT:
780 case PRINT_LPROS2:
781 do_parameter("Lpqcommand", "lpq -P'%p'");
782 do_parameter("Lprmcommand", "lprm -P'%p' %j");
783 do_parameter("Printcommand",
784 "lpr -r -P'%p' %s");
785 break;
787 case PRINT_LPRNG:
788 case PRINT_PLP:
789 do_parameter("Lpqcommand", "lpq -P'%p'");
790 do_parameter("Lprmcommand", "lprm -P'%p' %j");
791 do_parameter("Printcommand",
792 "lpr -r -P'%p' %s");
793 do_parameter("Queuepausecommand",
794 "lpc stop '%p'");
795 do_parameter("Queueresumecommand",
796 "lpc start '%p'");
797 do_parameter("Lppausecommand",
798 "lpc hold '%p' %j");
799 do_parameter("Lpresumecommand",
800 "lpc release '%p' %j");
801 break;
803 case PRINT_CUPS:
804 #ifdef HAVE_CUPS
805 do_parameter("Lpqcommand", "");
806 do_parameter("Lprmcommand", "");
807 do_parameter("Printcommand", "");
808 do_parameter("Lppausecommand", "");
809 do_parameter("Lpresumecommand", "");
810 do_parameter("Queuepausecommand", "");
811 do_parameter("Queueresumecommand", "");
813 do_parameter("Printcapname", "cups");
814 #else
815 do_parameter("Lpqcommand",
816 "/usr/bin/lpstat -o '%p'");
817 do_parameter("Lprmcommand",
818 "/usr/bin/cancel '%p-%j'");
819 do_parameter("Printcommand",
820 "/usr/bin/lp -d '%p' %s; rm %s");
821 do_parameter("Lppausecommand",
822 "lp -i '%p-%j' -H hold");
823 do_parameter("Lpresumecommand",
824 "lp -i '%p-%j' -H resume");
825 do_parameter("Queuepausecommand",
826 "/usr/bin/disable '%p'");
827 do_parameter("Queueresumecommand",
828 "/usr/bin/enable '%p'");
829 do_parameter("Printcapname", "lpstat");
830 #endif /* HAVE_CUPS */
831 break;
833 case PRINT_SYSV:
834 case PRINT_HPUX:
835 do_parameter("Lpqcommand", "lpstat -o%p");
836 do_parameter("Lprmcommand", "cancel %p-%j");
837 do_parameter("Printcommand",
838 "lp -c -d%p %s; rm %s");
839 do_parameter("Queuepausecommand",
840 "disable %p");
841 do_parameter("Queueresumecommand",
842 "enable %p");
843 #ifndef HPUX
844 do_parameter("Lppausecommand",
845 "lp -i %p-%j -H hold");
846 do_parameter("Lpresumecommand",
847 "lp -i %p-%j -H resume");
848 #endif /* HPUX */
849 break;
851 case PRINT_QNX:
852 do_parameter("Lpqcommand", "lpq -P%p");
853 do_parameter("Lprmcommand", "lprm -P%p %j");
854 do_parameter("Printcommand", "lp -r -P%p %s");
855 break;
857 case PRINT_SOFTQ:
858 do_parameter("Lpqcommand", "qstat -l -d%p");
859 do_parameter("Lprmcommand",
860 "qstat -s -j%j -c");
861 do_parameter("Printcommand",
862 "lp -d%p -s %s; rm %s");
863 do_parameter("Lppausecommand",
864 "qstat -s -j%j -h");
865 do_parameter("Lpresumecommand",
866 "qstat -s -j%j -r");
867 break;
868 #ifdef DEVELOPER
869 case PRINT_TEST:
870 case PRINT_VLP:
871 do_parameter("Printcommand", "vlp print %p %s");
872 do_parameter("Lpqcommand", "vlp lpq %p");
873 do_parameter("Lprmcommand", "vlp lprm %p %j");
874 do_parameter("Lppausecommand", "vlp lppause %p %j");
875 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
876 do_parameter("Queuepausecommand", "vlp queuepause %p");
877 do_parameter("Queueresumecommand", "vlp queueresume %p");
878 break;
879 #endif /* DEVELOPER */
885 /***************************************************************************
886 Initialise the global parameter structure.
887 ***************************************************************************/
888 static void init_globals(void)
890 int i;
891 char *myname;
893 DEBUG(3, ("Initialising global parameters\n"));
895 for (i = 0; parm_table[i].label; i++) {
896 if ((parm_table[i].type == P_STRING ||
897 parm_table[i].type == P_USTRING) &&
898 parm_table[i].ptr &&
899 !(parm_table[i].flags & FLAG_CMDLINE)) {
900 string_set(parm_table[i].ptr, "");
904 /* options that can be set on the command line must be initialised via
905 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
906 #ifdef TCP_NODELAY
907 do_parameter("socket options", "TCP_NODELAY");
908 #endif
909 do_parameter("workgroup", DEFAULT_WORKGROUP);
910 myname = get_myname();
911 do_parameter("netbios name", myname);
912 SAFE_FREE(myname);
913 do_parameter("max protocol", "NT1");
914 do_parameter("name resolve order", "lmhosts wins host bcast");
916 init_printer_values();
918 do_parameter("fstype", FSTYPE_STRING);
919 do_parameter("ntvfs handler", "unixuid default");
920 do_parameter("max connections", "-1");
922 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg dssetup");
923 do_parameter("server services", "smb rpc nbt ldap cldap web");
924 do_parameter("auth methods", "anonymous sam_ignoredomain");
925 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
926 do_parameter("private dir", dyn_PRIVATE_DIR);
927 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
928 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
929 do_parameter_var("wins database", "tdb://%s/wins.ldb", dyn_PRIVATE_DIR);
930 do_parameter_var("registry:HKEY_LOCAL_MACHINE", "ldb:/%s/hklm.ldb", dyn_PRIVATE_DIR);
931 do_parameter("guest account", GUEST_ACCOUNT);
933 /* using UTF8 by default allows us to support all chars */
934 do_parameter("unix charset", "UTF8");
936 /* Use codepage 850 as a default for the dos character set */
937 do_parameter("dos charset", "CP850");
940 * Allow the default PASSWD_CHAT to be overridden in local.h.
942 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
944 do_parameter("passwd program", "");
945 do_parameter("printcap name", PRINTCAP_NAME);
947 do_parameter("pid directory", dyn_PIDDIR);
948 do_parameter("lock dir", dyn_LOCKDIR);
949 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
951 do_parameter("socket address", "0.0.0.0");
952 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
954 do_parameter_var("announce version", "%d.%d",
955 DEFAULT_MAJOR_VERSION,
956 DEFAULT_MINOR_VERSION);
958 do_parameter("logon drive", "");
960 do_parameter("logon home", "\\\\%N\\%U");
961 do_parameter("logon path", "\\\\%N\\%U\\profile");
962 do_parameter("password server", "*");
964 do_parameter("load printers", "True");
966 do_parameter("max mux", "50");
967 do_parameter("max xmit", "12288");
968 do_parameter("lpqcachetime", "10");
969 do_parameter("DisableSpoolss", "False");
970 do_parameter("password level", "0");
971 do_parameter("username level", "0");
972 do_parameter("LargeReadwrite", "True");
973 do_parameter("minprotocol", "CORE");
974 do_parameter("security", "USER");
975 do_parameter("paranoid server security", "True");
976 do_parameter("EncryptPasswords", "True");
977 do_parameter("ReadRaw", "True");
978 do_parameter("WriteRaw", "True");
979 do_parameter("NullPasswords", "False");
980 do_parameter("ObeyPamRestrictions", "False");
981 do_parameter("lm announce", "Auto");
982 do_parameter("lm interval", "60");
983 do_parameter("announce as", "NT SERVER");
985 do_parameter("TimeServer", "False");
986 do_parameter("BindInterfacesOnly", "False");
987 do_parameter("PamPasswordChange", "False");
988 do_parameter("Unicode", "True");
989 do_parameter("restrict anonymous", "0");
990 do_parameter("ClientLanManAuth", "True");
991 do_parameter("LanmanAuth", "True");
992 do_parameter("NTLMAuth", "True");
994 do_parameter("enhanced browsing", "True");
995 do_parameter("LockSpinCount", "3");
996 do_parameter("LockSpinTime", "10");
997 #ifdef MMAP_BLACKLIST
998 do_parameter("UseMmap", "False");
999 #else
1000 do_parameter("UseMmap", "True");
1001 #endif
1002 do_parameter("UnixExtensions", "False");
1004 /* hostname lookups can be very expensive and are broken on
1005 a large number of sites (tridge) */
1006 do_parameter("HostnameLookups", "False");
1008 do_parameter("PreferredMaster", "Auto");
1009 do_parameter("os level", "20");
1010 do_parameter("LocalMaster", "True");
1011 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1012 do_parameter("DomainLogons", "False");
1013 do_parameter("WINSsupport", "False");
1014 do_parameter("WINSproxy", "False");
1016 do_parameter("DNSproxy", "True");
1018 do_parameter("AllowTrustedDomains", "True");
1020 do_parameter("TemplateShell", "/bin/false");
1021 do_parameter("TemplateHomedir", "/home/%D/%U");
1022 do_parameter("WinbindSeparator", "\\");
1024 do_parameter("winbind cache time", "15");
1025 do_parameter("WinbindEnumUsers", "True");
1026 do_parameter("WinbindEnumGroups", "True");
1027 do_parameter("WinbindUseDefaultDomain", "False");
1029 do_parameter("IDMapBackend", "tdb");
1031 do_parameter("name cache timeout", "660"); /* In seconds */
1033 do_parameter("client signing", "Yes");
1034 do_parameter("server signing", "auto");
1036 do_parameter("use spnego", "True");
1038 do_parameter("smb ports", SMB_PORTS);
1039 do_parameter("nbt port", "137");
1040 do_parameter("dgram port", "138");
1041 do_parameter("cldap port", "389");
1042 do_parameter("krb5 port", "88");
1043 do_parameter("web port", "901");
1044 do_parameter("swat directory", dyn_SWATDIR);
1046 do_parameter("nt status support", "True");
1048 do_parameter("max wins ttl", "432000");
1049 do_parameter("min wins ttl", "10");
1051 do_parameter("web tls", "True");
1052 do_parameter_var("web tls keyfile", "%s/tls/key.pem", dyn_PRIVATE_DIR);
1053 do_parameter_var("web tls certfile", "%s/tls/cert.pem", dyn_PRIVATE_DIR);
1054 do_parameter_var("web tls cafile", "%s/tls/ca.pem", dyn_PRIVATE_DIR);
1057 static TALLOC_CTX *lp_talloc;
1059 /******************************************************************* a
1060 Free up temporary memory - called from the main loop.
1061 ********************************************************************/
1063 void lp_talloc_free(void)
1065 if (!lp_talloc)
1066 return;
1067 talloc_free(lp_talloc);
1068 lp_talloc = NULL;
1071 /*******************************************************************
1072 Convenience routine to grab string parameters into temporary memory
1073 and run standard_sub_basic on them. The buffers can be written to by
1074 callers without affecting the source string.
1075 ********************************************************************/
1077 static const char *lp_string(const char *s)
1079 #if 0 /* until REWRITE done to make thread-safe */
1080 size_t len = s ? strlen(s) : 0;
1081 char *ret;
1082 #endif
1084 /* The follow debug is useful for tracking down memory problems
1085 especially if you have an inner loop that is calling a lp_*()
1086 function that returns a string. Perhaps this debug should be
1087 present all the time? */
1089 #if 0
1090 DEBUG(10, ("lp_string(%s)\n", s));
1091 #endif
1093 #if 0 /* until REWRITE done to make thread-safe */
1094 if (!lp_talloc)
1095 lp_talloc = talloc_init("lp_talloc");
1097 ret = talloc_array(lp_talloc, char, len + 100); /* leave room for substitution */
1099 if (!ret)
1100 return NULL;
1102 if (!s)
1103 *ret = 0;
1104 else
1105 StrnCpy(ret, s, len);
1107 if (trim_string(ret, "\"", "\"")) {
1108 if (strchr(ret,'"') != NULL)
1109 StrnCpy(ret, s, len);
1112 standard_sub_basic(ret,len+100);
1113 return (ret);
1114 #endif
1115 return s;
1119 In this section all the functions that are used to access the
1120 parameters from the rest of the program are defined
1123 #define FN_GLOBAL_STRING(fn_name,ptr) \
1124 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1125 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1126 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1127 #define FN_GLOBAL_LIST(fn_name,ptr) \
1128 const char **fn_name(void) {return(*(const char ***)(ptr));}
1129 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1130 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1131 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1132 char fn_name(void) {return(*(char *)(ptr));}
1133 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1134 int fn_name(void) {return(*(int *)(ptr));}
1136 #define FN_LOCAL_STRING(fn_name,val) \
1137 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1138 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1139 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1140 #define FN_LOCAL_LIST(fn_name,val) \
1141 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1142 #define FN_LOCAL_BOOL(fn_name,val) \
1143 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1144 #define FN_LOCAL_CHAR(fn_name,val) \
1145 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1146 #define FN_LOCAL_INTEGER(fn_name,val) \
1147 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1149 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1150 FN_GLOBAL_INTEGER(lp_nbt_port, &Globals.nbt_port)
1151 FN_GLOBAL_INTEGER(lp_dgram_port, &Globals.dgram_port)
1152 FN_GLOBAL_INTEGER(lp_cldap_port, &Globals.cldap_port)
1153 FN_GLOBAL_INTEGER(lp_krb5_port, &Globals.krb5_port)
1154 FN_GLOBAL_INTEGER(lp_web_port, &Globals.web_port)
1155 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1156 FN_GLOBAL_STRING(lp_swat_directory, &Globals.swat_directory)
1157 FN_GLOBAL_BOOL(lp_web_tls, &Globals.web_tls)
1158 FN_GLOBAL_STRING(lp_web_keyfile, &Globals.web_keyfile)
1159 FN_GLOBAL_STRING(lp_web_certfile, &Globals.web_certfile)
1160 FN_GLOBAL_STRING(lp_web_cafile, &Globals.web_cafile)
1161 FN_GLOBAL_STRING(lp_web_crlfile, &Globals.web_crlfile)
1162 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1163 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1164 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1165 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1166 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1167 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1168 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1169 FN_GLOBAL_STRING(lp_wins_url, &Globals.szWINS_URL)
1170 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1171 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1172 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1173 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1174 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1175 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1176 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1177 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1178 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1179 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1180 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1181 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1182 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1183 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1184 FN_GLOBAL_LIST(lp_passwordserver, &Globals.szPasswordServers)
1185 FN_GLOBAL_LIST(lp_name_resolve_order, &Globals.szNameResolveOrder)
1186 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1187 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1188 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1189 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1190 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1191 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1192 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1193 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1194 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1195 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1196 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1197 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1198 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1199 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1200 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1201 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1202 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1203 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1204 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1206 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1208 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1210 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1211 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1212 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1213 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1214 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1215 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1216 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1217 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1218 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1220 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1221 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1222 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1223 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1224 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1225 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1226 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1227 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1228 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1229 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1230 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1231 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1232 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1233 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1234 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1235 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1236 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1237 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1238 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1239 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1240 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1241 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1242 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1243 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1244 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1245 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1246 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1247 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1248 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1249 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1250 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1251 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1252 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1253 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1254 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1255 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1256 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1257 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1258 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1259 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1260 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1261 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1262 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1263 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1264 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1265 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1266 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1267 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1268 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1269 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1270 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1271 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1272 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1273 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1274 FN_LOCAL_STRING(lp_servicename, szService)
1275 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1276 FN_LOCAL_STRING(lp_pathname, szPath)
1277 FN_LOCAL_STRING(lp_username, szUsername)
1278 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1279 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1280 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1281 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1282 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1283 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1284 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1285 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1286 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1287 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1288 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1289 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1290 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1291 FN_LOCAL_STRING(lp_comment, comment)
1292 FN_LOCAL_STRING(lp_fstype, fstype)
1293 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1294 static FN_LOCAL_STRING(lp_volume, volume)
1295 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1296 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1297 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1298 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1299 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1300 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1301 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1302 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1303 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1304 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1305 FN_LOCAL_BOOL(lp_locking, bLocking)
1306 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1307 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1308 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1309 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1310 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1311 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1312 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1313 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1314 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1315 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1316 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1317 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1318 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1319 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1320 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1321 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1322 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1323 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1325 /* local prototypes */
1327 static int map_parameter(const char *pszParmName);
1328 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1329 static int getservicebyname(const char *pszServiceName,
1330 service * pserviceDest);
1331 static void copy_service(service * pserviceDest,
1332 service * pserviceSource, BOOL *pcopymapDest);
1333 static BOOL service_ok(int iService);
1334 static BOOL do_section(const char *pszSectionName);
1335 static void init_copymap(service * pservice);
1337 /* This is a helper function for parametrical options support. */
1338 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1339 /* Actual parametrical functions are quite simple */
1340 const char *lp_get_parametric(int lookup_service, const char *type, const char *option)
1342 char *vfskey;
1343 struct param_opt *data;
1345 if (lookup_service >= iNumServices) return NULL;
1347 data = (lookup_service < 0) ?
1348 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1350 asprintf(&vfskey, "%s:%s", type, option);
1351 strlower(vfskey);
1353 while (data) {
1354 if (strcmp(data->key, vfskey) == 0) {
1355 free(vfskey);
1356 return data->value;
1358 data = data->next;
1361 if (lookup_service >= 0) {
1362 /* Try to fetch the same option but from globals */
1363 /* but only if we are not already working with Globals */
1364 data = Globals.param_opt;
1365 while (data) {
1366 if (strcmp(data->key, vfskey) == 0) {
1367 free(vfskey);
1368 return data->value;
1370 data = data->next;
1374 free(vfskey);
1376 return NULL;
1380 /*******************************************************************
1381 convenience routine to return int parameters.
1382 ********************************************************************/
1383 static int lp_int(const char *s)
1386 if (!s) {
1387 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1388 return (-1);
1391 return atoi(s);
1394 /*******************************************************************
1395 convenience routine to return unsigned long parameters.
1396 ********************************************************************/
1397 static int lp_ulong(const char *s)
1400 if (!s) {
1401 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1402 return (-1);
1405 return strtoul(s, NULL, 10);
1408 /*******************************************************************
1409 convenience routine to return boolean parameters.
1410 ********************************************************************/
1411 static BOOL lp_bool(const char *s)
1413 BOOL ret = False;
1415 if (!s) {
1416 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1417 return False;
1420 if (!set_boolean(&ret,s)) {
1421 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1422 return False;
1425 return ret;
1429 /* Return parametric option from a given service. Type is a part of option before ':' */
1430 /* Parametric option has following syntax: 'Type: option = value' */
1431 /* Returned value is allocated in 'lp_talloc' context */
1433 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1435 const char *value = lp_get_parametric(lookup_service, type, option);
1437 if (value)
1438 return lp_string(value);
1440 return NULL;
1443 /* Return parametric option from a given service. Type is a part of option before ':' */
1444 /* Parametric option has following syntax: 'Type: option = value' */
1445 /* Returned value is allocated in 'lp_talloc' context */
1447 const char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1448 const char *separator)
1450 const char *value = lp_get_parametric(lookup_service, type, option);
1452 if (value)
1453 return str_list_make(talloc_autofree_context(), value, separator);
1455 return NULL;
1458 /* Return parametric option from a given service. Type is a part of option before ':' */
1459 /* Parametric option has following syntax: 'Type: option = value' */
1461 int lp_parm_int(int lookup_service, const char *type, const char *option, int default_v)
1463 const char *value = lp_get_parametric(lookup_service, type, option);
1465 if (value)
1466 return lp_int(value);
1468 return default_v;
1471 /* Return parametric option from a given service. Type is a part of option before ':' */
1472 /* Parametric option has following syntax: 'Type: option = value' */
1474 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option, unsigned long default_v)
1476 const char *value = lp_get_parametric(lookup_service, type, option);
1478 if (value)
1479 return lp_ulong(value);
1481 return default_v;
1484 /* Return parametric option from a given service. Type is a part of option before ':' */
1485 /* Parametric option has following syntax: 'Type: option = value' */
1487 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1489 const char *value = lp_get_parametric(lookup_service, type, option);
1491 if (value)
1492 return lp_bool(value);
1494 return default_v;
1498 /***************************************************************************
1499 Initialise a service to the defaults.
1500 ***************************************************************************/
1502 static void init_service(service * pservice)
1504 memset((char *)pservice, '\0', sizeof(service));
1505 copy_service(pservice, &sDefault, NULL);
1508 /***************************************************************************
1509 Free the dynamically allocated parts of a service struct.
1510 ***************************************************************************/
1512 static void free_service(service *pservice)
1514 int i;
1515 struct param_opt *data, *pdata;
1516 if (!pservice)
1517 return;
1519 if (pservice->szService)
1520 DEBUG(5, ("free_service: Freeing service %s\n",
1521 pservice->szService));
1523 string_free(&pservice->szService);
1524 SAFE_FREE(pservice->copymap);
1526 for (i = 0; parm_table[i].label; i++) {
1527 if ((parm_table[i].type == P_STRING ||
1528 parm_table[i].type == P_USTRING) &&
1529 parm_table[i].class == P_LOCAL) {
1530 string_free((char **)
1531 (((char *)pservice) +
1532 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1533 } else if (parm_table[i].type == P_LIST &&
1534 parm_table[i].class == P_LOCAL) {
1535 char ***listp = (char ***)(((char *)pservice) +
1536 PTR_DIFF(parm_table[i].ptr, &sDefault));
1537 talloc_free(*listp);
1538 *listp = NULL;
1542 DEBUG(5,("Freeing parametrics:\n"));
1543 data = pservice->param_opt;
1544 while (data) {
1545 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1546 string_free(&data->key);
1547 string_free(&data->value);
1548 pdata = data->next;
1549 SAFE_FREE(data);
1550 data = pdata;
1553 ZERO_STRUCTP(pservice);
1556 /***************************************************************************
1557 Add a new service to the services array initialising it with the given
1558 service.
1559 ***************************************************************************/
1561 static int add_a_service(const service *pservice, const char *name)
1563 int i;
1564 service tservice;
1565 int num_to_alloc = iNumServices + 1;
1566 struct param_opt *data, *pdata;
1568 tservice = *pservice;
1570 /* it might already exist */
1571 if (name) {
1572 i = getservicebyname(name, NULL);
1573 if (i >= 0) {
1574 /* Clean all parametric options for service */
1575 /* They will be added during parsing again */
1576 data = ServicePtrs[i]->param_opt;
1577 while (data) {
1578 string_free(&data->key);
1579 string_free(&data->value);
1580 pdata = data->next;
1581 SAFE_FREE(data);
1582 data = pdata;
1584 ServicePtrs[i]->param_opt = NULL;
1585 return (i);
1589 /* find an invalid one */
1590 for (i = 0; i < iNumServices; i++)
1591 if (!ServicePtrs[i]->valid)
1592 break;
1594 /* if not, then create one */
1595 if (i == iNumServices) {
1596 service **tsp;
1598 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1600 if (!tsp) {
1601 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1602 return (-1);
1604 else {
1605 ServicePtrs = tsp;
1606 ServicePtrs[iNumServices] = malloc_p(service);
1608 if (!ServicePtrs[iNumServices]) {
1609 DEBUG(0,("add_a_service: out of memory!\n"));
1610 return (-1);
1613 iNumServices++;
1614 } else
1615 free_service(ServicePtrs[i]);
1617 ServicePtrs[i]->valid = True;
1619 init_service(ServicePtrs[i]);
1620 copy_service(ServicePtrs[i], &tservice, NULL);
1621 if (name)
1622 string_set(&ServicePtrs[i]->szService, name);
1623 return (i);
1626 /***************************************************************************
1627 Add a new home service, with the specified home directory, defaults coming
1628 from service ifrom.
1629 ***************************************************************************/
1631 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1632 const char *user, const char *pszHomedir)
1634 int i;
1635 pstring newHomedir;
1637 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1639 if (i < 0)
1640 return (False);
1642 if (!(*(ServicePtrs[iDefaultService]->szPath))
1643 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1644 pstrcpy(newHomedir, pszHomedir);
1645 } else {
1646 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1647 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1650 string_set(&ServicePtrs[i]->szPath, newHomedir);
1652 if (!(*(ServicePtrs[i]->comment))) {
1653 pstring comment;
1654 slprintf(comment, sizeof(comment) - 1,
1655 "Home directory of %s", user);
1656 string_set(&ServicePtrs[i]->comment, comment);
1658 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1659 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1661 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1662 user, newHomedir));
1664 return (True);
1667 /***************************************************************************
1668 Add a new service, based on an old one.
1669 ***************************************************************************/
1671 int lp_add_service(const char *pszService, int iDefaultService)
1673 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1676 /***************************************************************************
1677 Add the IPC service.
1678 ***************************************************************************/
1680 static BOOL lp_add_hidden(const char *name, const char *fstype, BOOL guest_ok)
1682 pstring comment;
1683 int i = add_a_service(&sDefault, name);
1685 if (i < 0)
1686 return (False);
1688 slprintf(comment, sizeof(comment) - 1,
1689 "%s Service (%s)", fstype, Globals.szServerString);
1691 string_set(&ServicePtrs[i]->szPath, tmpdir());
1692 string_set(&ServicePtrs[i]->szUsername, "");
1693 string_set(&ServicePtrs[i]->comment, comment);
1694 string_set(&ServicePtrs[i]->fstype, fstype);
1695 ServicePtrs[i]->iMaxConnections = -1;
1696 ServicePtrs[i]->bAvailable = True;
1697 ServicePtrs[i]->bRead_only = True;
1698 ServicePtrs[i]->bGuest_only = False;
1699 ServicePtrs[i]->bGuest_ok = guest_ok;
1700 ServicePtrs[i]->bPrint_ok = False;
1701 ServicePtrs[i]->bBrowseable = False;
1703 if (strcasecmp(fstype, "IPC") == 0) {
1704 lp_do_parameter(i, "ntvfs handler", "default");
1707 DEBUG(3, ("adding hidden service %s\n", name));
1709 return (True);
1712 /***************************************************************************
1713 Add a new printer service, with defaults coming from service iFrom.
1714 ***************************************************************************/
1716 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1718 const char *comment = "From Printcap";
1719 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1721 if (i < 0)
1722 return (False);
1724 /* note that we do NOT default the availability flag to True - */
1725 /* we take it from the default service passed. This allows all */
1726 /* dynamic printers to be disabled by disabling the [printers] */
1727 /* entry (if/when the 'available' keyword is implemented!). */
1729 /* the printer name is set to the service name. */
1730 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1731 string_set(&ServicePtrs[i]->comment, comment);
1732 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1733 /* Printers cannot be read_only. */
1734 ServicePtrs[i]->bRead_only = False;
1735 /* No share modes on printer services. */
1736 ServicePtrs[i]->bShareModes = False;
1737 /* No oplocks on printer services. */
1738 ServicePtrs[i]->bOpLocks = False;
1739 /* Printer services must be printable. */
1740 ServicePtrs[i]->bPrint_ok = True;
1742 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1744 update_server_announce_as_printserver();
1746 return (True);
1749 /***************************************************************************
1750 Map a parameter's string representation to something we can use.
1751 Returns False if the parameter string is not recognised, else TRUE.
1752 ***************************************************************************/
1754 static int map_parameter(const char *pszParmName)
1756 int iIndex;
1758 if (*pszParmName == '-')
1759 return (-1);
1761 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1762 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1763 return (iIndex);
1765 /* Warn only if it isn't parametric option */
1766 if (strchr(pszParmName, ':') == NULL)
1767 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1768 /* We do return 'fail' for parametric options as well because they are
1769 stored in different storage
1771 return (-1);
1776 return the parameter structure for a parameter
1778 struct parm_struct *lp_parm_struct(const char *name)
1780 int parmnum = map_parameter(name);
1781 if (parmnum == -1) return NULL;
1782 return &parm_table[parmnum];
1786 return the parameter pointer for a parameter
1788 void *lp_parm_ptr(int snum, struct parm_struct *parm)
1790 if (snum == -1) {
1791 return parm->ptr;
1793 return ((char *)ServicePtrs[snum]) + PTR_DIFF(parm->ptr, &sDefault);
1796 /***************************************************************************
1797 Set a boolean variable from the text value stored in the passed string.
1798 Returns True in success, False if the passed string does not correctly
1799 represent a boolean.
1800 ***************************************************************************/
1802 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1804 BOOL bRetval;
1806 bRetval = True;
1807 if (strwicmp(pszParmValue, "yes") == 0 ||
1808 strwicmp(pszParmValue, "true") == 0 ||
1809 strwicmp(pszParmValue, "1") == 0)
1810 *pb = True;
1811 else if (strwicmp(pszParmValue, "no") == 0 ||
1812 strwicmp(pszParmValue, "False") == 0 ||
1813 strwicmp(pszParmValue, "0") == 0)
1814 *pb = False;
1815 else {
1816 DEBUG(0,
1817 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1818 pszParmValue));
1819 bRetval = False;
1821 return (bRetval);
1824 /***************************************************************************
1825 Find a service by name. Otherwise works like get_service.
1826 ***************************************************************************/
1828 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1830 int iService;
1832 for (iService = iNumServices - 1; iService >= 0; iService--)
1833 if (VALID(iService) &&
1834 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1835 if (pserviceDest != NULL)
1836 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1837 break;
1840 return (iService);
1843 /***************************************************************************
1844 Copy a service structure to another.
1845 If pcopymapDest is NULL then copy all fields
1846 ***************************************************************************/
1848 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1850 int i;
1851 BOOL bcopyall = (pcopymapDest == NULL);
1852 struct param_opt *data, *pdata, *paramo;
1853 BOOL not_added;
1855 for (i = 0; parm_table[i].label; i++)
1856 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1857 (bcopyall || pcopymapDest[i])) {
1858 void *def_ptr = parm_table[i].ptr;
1859 void *src_ptr =
1860 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1861 &sDefault);
1862 void *dest_ptr =
1863 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1864 &sDefault);
1866 switch (parm_table[i].type) {
1867 case P_BOOL:
1868 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1869 break;
1871 case P_INTEGER:
1872 case P_ENUM:
1873 *(int *)dest_ptr = *(int *)src_ptr;
1874 break;
1876 case P_STRING:
1877 string_set(dest_ptr,
1878 *(char **)src_ptr);
1879 break;
1881 case P_USTRING:
1882 string_set(dest_ptr,
1883 *(char **)src_ptr);
1884 strupper(*(char **)dest_ptr);
1885 break;
1886 case P_LIST:
1887 *(const char ***)dest_ptr = str_list_copy(talloc_autofree_context(),
1888 *(const char ***)src_ptr);
1889 break;
1890 default:
1891 break;
1895 if (bcopyall) {
1896 init_copymap(pserviceDest);
1897 if (pserviceSource->copymap)
1898 memcpy((void *)pserviceDest->copymap,
1899 (void *)pserviceSource->copymap,
1900 sizeof(BOOL) * NUMPARAMETERS);
1903 data = pserviceSource->param_opt;
1904 while (data) {
1905 not_added = True;
1906 pdata = pserviceDest->param_opt;
1907 /* Traverse destination */
1908 while (pdata) {
1909 /* If we already have same option, override it */
1910 if (strcmp(pdata->key, data->key) == 0) {
1911 string_free(&pdata->value);
1912 pdata->value = strdup(data->value);
1913 not_added = False;
1914 break;
1916 pdata = pdata->next;
1918 if (not_added) {
1919 paramo = smb_xmalloc_p(struct param_opt);
1920 paramo->key = strdup(data->key);
1921 paramo->value = strdup(data->value);
1922 DLIST_ADD(pserviceDest->param_opt, paramo);
1924 data = data->next;
1928 /***************************************************************************
1929 Check a service for consistency. Return False if the service is in any way
1930 incomplete or faulty, else True.
1931 ***************************************************************************/
1933 static BOOL service_ok(int iService)
1935 BOOL bRetval;
1937 bRetval = True;
1938 if (ServicePtrs[iService]->szService[0] == '\0') {
1939 DEBUG(0, ("The following message indicates an internal error:\n"));
1940 DEBUG(0, ("No service name in service entry.\n"));
1941 bRetval = False;
1944 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1945 /* I can't see why you'd want a non-printable printer service... */
1946 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1947 if (!ServicePtrs[iService]->bPrint_ok) {
1948 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1949 ServicePtrs[iService]->szService));
1950 ServicePtrs[iService]->bPrint_ok = True;
1951 update_server_announce_as_printserver();
1953 /* [printers] service must also be non-browsable. */
1954 if (ServicePtrs[iService]->bBrowseable)
1955 ServicePtrs[iService]->bBrowseable = False;
1958 /* If a service is flagged unavailable, log the fact at level 0. */
1959 if (!ServicePtrs[iService]->bAvailable)
1960 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1961 ServicePtrs[iService]->szService));
1963 return (bRetval);
1966 static struct file_lists {
1967 struct file_lists *next;
1968 char *name;
1969 char *subfname;
1970 time_t modtime;
1971 } *file_lists = NULL;
1973 /*******************************************************************
1974 Keep a linked list of all config files so we know when one has changed
1975 it's date and needs to be reloaded.
1976 ********************************************************************/
1978 static void add_to_file_list(const char *fname, const char *subfname)
1980 struct file_lists *f = file_lists;
1982 while (f) {
1983 if (f->name && !strcmp(f->name, fname))
1984 break;
1985 f = f->next;
1988 if (!f) {
1989 f = malloc_p(struct file_lists);
1990 if (!f)
1991 return;
1992 f->next = file_lists;
1993 f->name = strdup(fname);
1994 if (!f->name) {
1995 SAFE_FREE(f);
1996 return;
1998 f->subfname = strdup(subfname);
1999 if (!f->subfname) {
2000 SAFE_FREE(f);
2001 return;
2003 file_lists = f;
2004 f->modtime = file_modtime(subfname);
2005 } else {
2006 time_t t = file_modtime(subfname);
2007 if (t)
2008 f->modtime = t;
2012 /*******************************************************************
2013 Check if a config file has changed date.
2014 ********************************************************************/
2016 BOOL lp_file_list_changed(void)
2018 struct file_lists *f = file_lists;
2019 DEBUG(6, ("lp_file_list_changed()\n"));
2021 while (f) {
2022 pstring n2;
2023 time_t mod_time;
2025 pstrcpy(n2, f->name);
2026 standard_sub_basic(n2,sizeof(n2));
2028 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
2029 f->name, n2, ctime(&f->modtime)));
2031 mod_time = file_modtime(n2);
2033 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
2034 DEBUGADD(6,
2035 ("file %s modified: %s\n", n2,
2036 ctime(&mod_time)));
2037 f->modtime = mod_time;
2038 SAFE_FREE(f->subfname);
2039 f->subfname = strdup(n2);
2040 return (True);
2042 f = f->next;
2044 return (False);
2047 /***************************************************************************
2048 Handle the include operation.
2049 ***************************************************************************/
2051 static BOOL handle_include(const char *pszParmValue, char **ptr)
2053 pstring fname;
2054 pstrcpy(fname, pszParmValue);
2056 standard_sub_basic(fname,sizeof(fname));
2058 add_to_file_list(pszParmValue, fname);
2060 string_set(ptr, fname);
2062 if (file_exist(fname))
2063 return (pm_process(fname, do_section, do_parameter));
2065 DEBUG(2, ("Can't find include file %s\n", fname));
2067 return (False);
2070 /***************************************************************************
2071 Handle the interpretation of the copy parameter.
2072 ***************************************************************************/
2074 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2076 BOOL bRetval;
2077 int iTemp;
2078 service serviceTemp;
2080 string_set(ptr, pszParmValue);
2082 init_service(&serviceTemp);
2084 bRetval = False;
2086 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2088 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2089 if (iTemp == iServiceIndex) {
2090 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2091 } else {
2092 copy_service(ServicePtrs[iServiceIndex],
2093 &serviceTemp,
2094 ServicePtrs[iServiceIndex]->copymap);
2095 bRetval = True;
2097 } else {
2098 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2099 bRetval = False;
2102 free_service(&serviceTemp);
2103 return (bRetval);
2106 /***************************************************************************
2107 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2108 parameters is:
2110 [global]
2112 winbind uid = 1000-1999
2113 winbind gid = 700-899
2115 We only do simple parsing checks here. The strings are parsed into useful
2116 structures in the winbind daemon code.
2118 ***************************************************************************/
2120 /* Some lp_ routines to return winbind [ug]id information */
2122 static uid_t winbind_uid_low, winbind_uid_high;
2123 static gid_t winbind_gid_low, winbind_gid_high;
2124 static uint32_t non_unix_account_low, non_unix_account_high;
2126 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2128 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2129 return False;
2131 if (low)
2132 *low = winbind_uid_low;
2134 if (high)
2135 *high = winbind_uid_high;
2137 return True;
2140 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2142 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2143 return False;
2145 if (low)
2146 *low = winbind_gid_low;
2148 if (high)
2149 *high = winbind_gid_high;
2151 return True;
2154 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2156 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2157 return False;
2159 if (low)
2160 *low = non_unix_account_low;
2162 if (high)
2163 *high = non_unix_account_high;
2165 return True;
2168 /* Do some simple checks on "winbind [ug]id" parameter values */
2170 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2172 uint32_t low, high;
2174 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2175 return False;
2177 /* Parse OK */
2179 string_set(ptr, pszParmValue);
2181 winbind_uid_low = low;
2182 winbind_uid_high = high;
2184 return True;
2187 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2189 uint32_t low, high;
2191 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2192 return False;
2194 /* Parse OK */
2196 string_set(ptr, pszParmValue);
2198 winbind_gid_low = low;
2199 winbind_gid_high = high;
2201 return True;
2204 /***************************************************************************
2205 Do some simple checks on "non unix account range" parameter values.
2206 ***************************************************************************/
2208 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2210 uint32_t low, high;
2212 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2213 return False;
2215 /* Parse OK */
2217 string_set(ptr, pszParmValue);
2219 non_unix_account_low = low;
2220 non_unix_account_high = high;
2222 return True;
2226 /***************************************************************************
2227 Initialise a copymap.
2228 ***************************************************************************/
2230 static void init_copymap(service * pservice)
2232 int i;
2233 SAFE_FREE(pservice->copymap);
2234 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2235 if (!pservice->copymap)
2236 DEBUG(0,
2237 ("Couldn't allocate copymap!! (size %d)\n",
2238 (int)NUMPARAMETERS));
2239 else
2240 for (i = 0; i < NUMPARAMETERS; i++)
2241 pservice->copymap[i] = True;
2244 /***************************************************************************
2245 Return the local pointer to a parameter given the service number and the
2246 pointer into the default structure.
2247 ***************************************************************************/
2249 void *lp_local_ptr(int snum, void *ptr)
2251 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2255 /***************************************************************************
2256 Process a parametric option
2257 ***************************************************************************/
2258 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2260 struct param_opt *paramo, *data;
2261 char *name;
2263 while (isspace(*pszParmName)) {
2264 pszParmName++;
2267 name = strdup(pszParmName);
2268 if (!name) return False;
2270 strlower(name);
2272 if (snum < 0) {
2273 data = Globals.param_opt;
2274 } else {
2275 data = ServicePtrs[snum]->param_opt;
2278 /* Traverse destination */
2279 for (paramo=data; paramo; paramo=paramo->next) {
2280 /* If we already have the option set, override it unless
2281 it was a command line option and the new one isn't */
2282 if (strcmp(paramo->key, name) == 0) {
2283 if ((paramo->flags & FLAG_CMDLINE) &&
2284 !(flags & FLAG_CMDLINE)) {
2285 return True;
2288 free(paramo->value);
2289 paramo->value = strdup(pszParmValue);
2290 paramo->flags = flags;
2291 free(name);
2292 return True;
2296 paramo = smb_xmalloc_p(struct param_opt);
2297 paramo->key = strdup(name);
2298 paramo->value = strdup(pszParmValue);
2299 paramo->flags = flags;
2300 if (snum < 0) {
2301 DLIST_ADD(Globals.param_opt, paramo);
2302 } else {
2303 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2306 free(name);
2308 return True;
2311 /***************************************************************************
2312 Process a parameter for a particular service number. If snum < 0
2313 then assume we are in the globals.
2314 ***************************************************************************/
2315 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2317 int parmnum, i;
2318 void *parm_ptr = NULL; /* where we are going to store the result */
2319 void *def_ptr = NULL;
2321 parmnum = map_parameter(pszParmName);
2323 if (parmnum < 0) {
2324 if (strchr(pszParmName, ':')) {
2325 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2327 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2328 return (True);
2331 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2332 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2333 pszParmName));
2336 /* if the flag has been set on the command line, then don't allow override,
2337 but don't report an error */
2338 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2339 return True;
2342 def_ptr = parm_table[parmnum].ptr;
2344 /* we might point at a service, the default service or a global */
2345 if (snum < 0) {
2346 parm_ptr = def_ptr;
2347 } else {
2348 if (parm_table[parmnum].class == P_GLOBAL) {
2349 DEBUG(0,
2350 ("Global parameter %s found in service section!\n",
2351 pszParmName));
2352 return (True);
2354 parm_ptr =
2355 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2356 &sDefault);
2359 if (snum >= 0) {
2360 if (!ServicePtrs[snum]->copymap)
2361 init_copymap(ServicePtrs[snum]);
2363 /* this handles the aliases - set the copymap for other entries with
2364 the same data pointer */
2365 for (i = 0; parm_table[i].label; i++)
2366 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2367 ServicePtrs[snum]->copymap[i] = False;
2370 /* if it is a special case then go ahead */
2371 if (parm_table[parmnum].special) {
2372 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2373 return (True);
2376 /* now switch on the type of variable it is */
2377 switch (parm_table[parmnum].type)
2379 case P_BOOL:
2380 set_boolean(parm_ptr, pszParmValue);
2381 break;
2383 case P_INTEGER:
2384 *(int *)parm_ptr = atoi(pszParmValue);
2385 break;
2387 case P_LIST:
2388 *(const char ***)parm_ptr = str_list_make(talloc_autofree_context(),
2389 pszParmValue, NULL);
2390 break;
2392 case P_STRING:
2393 string_set(parm_ptr, pszParmValue);
2394 break;
2396 case P_USTRING:
2397 string_set(parm_ptr, pszParmValue);
2398 strupper(*(char **)parm_ptr);
2399 break;
2401 case P_ENUM:
2402 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2403 if (strequal
2404 (pszParmValue,
2405 parm_table[parmnum].enum_list[i].name)) {
2406 *(int *)parm_ptr =
2407 parm_table[parmnum].
2408 enum_list[i].value;
2409 break;
2412 if (!parm_table[parmnum].enum_list[i].name) {
2413 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2414 pszParmValue, pszParmName));
2415 return False;
2417 break;
2418 case P_SEP:
2419 break;
2422 return (True);
2425 /***************************************************************************
2426 Process a parameter.
2427 ***************************************************************************/
2429 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2431 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2432 pszParmName, pszParmValue));
2436 variable argument do parameter
2438 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2440 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2442 char *s;
2443 BOOL ret;
2444 va_list ap;
2446 va_start(ap, fmt);
2447 s = talloc_vasprintf(NULL, fmt, ap);
2448 va_end(ap);
2449 ret = do_parameter(pszParmName, s);
2450 talloc_free(s);
2451 return ret;
2456 set a parameter from the commandline - this is called from command line parameter
2457 parsing code. It sets the parameter then marks the parameter as unable to be modified
2458 by smb.conf processing
2460 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2462 int parmnum = map_parameter(pszParmName);
2463 int i;
2465 while (isspace(*pszParmValue)) pszParmValue++;
2468 if (parmnum < 0 && strchr(pszParmName, ':')) {
2469 /* set a parametric option */
2470 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2473 if (parmnum < 0) {
2474 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2475 return False;
2478 /* reset the CMDLINE flag in case this has been called before */
2479 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2481 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2482 return False;
2485 parm_table[parmnum].flags |= FLAG_CMDLINE;
2487 /* we have to also set FLAG_CMDLINE on aliases */
2488 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2489 parm_table[i].flags |= FLAG_CMDLINE;
2491 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2492 parm_table[i].flags |= FLAG_CMDLINE;
2495 return True;
2499 set a option from the commandline in 'a=b' format. Use to support --option
2501 BOOL lp_set_option(const char *option)
2503 char *p, *s;
2504 BOOL ret;
2506 s = strdup(option);
2507 if (!s) {
2508 return False;
2511 p = strchr(s, '=');
2512 if (!p) {
2513 free(s);
2514 return False;
2517 *p = 0;
2519 ret = lp_set_cmdline(s, p+1);
2520 free(s);
2521 return ret;
2525 #define BOOLSTR(b) ((b) ? "Yes" : "No")
2527 /***************************************************************************
2528 Print a parameter of the specified type.
2529 ***************************************************************************/
2531 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2533 int i;
2534 switch (p->type)
2536 case P_ENUM:
2537 for (i = 0; p->enum_list[i].name; i++) {
2538 if (*(int *)ptr == p->enum_list[i].value) {
2539 fprintf(f, "%s",
2540 p->enum_list[i].name);
2541 break;
2544 break;
2546 case P_BOOL:
2547 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2548 break;
2550 case P_INTEGER:
2551 fprintf(f, "%d", *(int *)ptr);
2552 break;
2554 case P_LIST:
2555 if ((char ***)ptr && *(char ***)ptr) {
2556 char **list = *(char ***)ptr;
2558 for (; *list; list++)
2559 fprintf(f, "%s%s", *list,
2560 ((*(list+1))?", ":""));
2562 break;
2564 case P_STRING:
2565 case P_USTRING:
2566 if (*(char **)ptr) {
2567 fprintf(f, "%s", *(char **)ptr);
2569 break;
2570 case P_SEP:
2571 break;
2575 /***************************************************************************
2576 Check if two parameters are equal.
2577 ***************************************************************************/
2579 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2581 switch (type) {
2582 case P_BOOL:
2583 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2585 case P_INTEGER:
2586 case P_ENUM:
2587 return (*((int *)ptr1) == *((int *)ptr2));
2589 case P_LIST:
2590 return str_list_equal((const char **)(*(char ***)ptr1),
2591 (const char **)(*(char ***)ptr2));
2593 case P_STRING:
2594 case P_USTRING:
2596 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2597 if (p1 && !*p1)
2598 p1 = NULL;
2599 if (p2 && !*p2)
2600 p2 = NULL;
2601 return (p1 == p2 || strequal(p1, p2));
2603 case P_SEP:
2604 break;
2606 return (False);
2609 /***************************************************************************
2610 Process a new section (service). At this stage all sections are services.
2611 Later we'll have special sections that permit server parameters to be set.
2612 Returns True on success, False on failure.
2613 ***************************************************************************/
2615 static BOOL do_section(const char *pszSectionName)
2617 BOOL bRetval;
2618 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2619 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2620 bRetval = False;
2622 /* if we've just struck a global section, note the fact. */
2623 bInGlobalSection = isglobal;
2625 /* check for multiple global sections */
2626 if (bInGlobalSection) {
2627 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2628 return (True);
2631 /* if we have a current service, tidy it up before moving on */
2632 bRetval = True;
2634 if (iServiceIndex >= 0)
2635 bRetval = service_ok(iServiceIndex);
2637 /* if all is still well, move to the next record in the services array */
2638 if (bRetval) {
2639 /* We put this here to avoid an odd message order if messages are */
2640 /* issued by the post-processing of a previous section. */
2641 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2643 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2644 < 0) {
2645 DEBUG(0, ("Failed to add a new service\n"));
2646 return (False);
2650 return (bRetval);
2654 /***************************************************************************
2655 Determine if a partcular base parameter is currentl set to the default value.
2656 ***************************************************************************/
2658 static BOOL is_default(int i)
2660 if (!defaults_saved)
2661 return False;
2662 switch (parm_table[i].type) {
2663 case P_LIST:
2664 return str_list_equal((const char **)parm_table[i].def.lvalue,
2665 (const char **)(*(char ***)parm_table[i].ptr));
2666 case P_STRING:
2667 case P_USTRING:
2668 return strequal(parm_table[i].def.svalue,
2669 *(char **)parm_table[i].ptr);
2670 case P_BOOL:
2671 return parm_table[i].def.bvalue ==
2672 *(BOOL *)parm_table[i].ptr;
2673 case P_INTEGER:
2674 case P_ENUM:
2675 return parm_table[i].def.ivalue ==
2676 *(int *)parm_table[i].ptr;
2677 case P_SEP:
2678 break;
2680 return False;
2683 /***************************************************************************
2684 Display the contents of the global structure.
2685 ***************************************************************************/
2687 static void dump_globals(FILE *f)
2689 int i;
2690 struct param_opt *data;
2692 fprintf(f, "# Global parameters\n[global]\n");
2694 for (i = 0; parm_table[i].label; i++)
2695 if (parm_table[i].class == P_GLOBAL &&
2696 parm_table[i].ptr &&
2697 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2698 if (defaults_saved && is_default(i))
2699 continue;
2700 fprintf(f, "\t%s = ", parm_table[i].label);
2701 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2702 fprintf(f, "\n");
2704 if (Globals.param_opt != NULL) {
2705 data = Globals.param_opt;
2706 while(data) {
2707 fprintf(f, "\t%s = %s\n", data->key, data->value);
2708 data = data->next;
2714 /***************************************************************************
2715 Display the contents of a single services record.
2716 ***************************************************************************/
2718 static void dump_a_service(service * pService, FILE * f)
2720 int i;
2721 struct param_opt *data;
2723 if (pService != &sDefault)
2724 fprintf(f, "\n[%s]\n", pService->szService);
2726 for (i = 0; parm_table[i].label; i++)
2727 if (parm_table[i].class == P_LOCAL &&
2728 parm_table[i].ptr &&
2729 (*parm_table[i].label != '-') &&
2730 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2731 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2733 if (pService == &sDefault) {
2734 if (defaults_saved && is_default(i))
2735 continue;
2736 } else {
2737 if (equal_parameter(parm_table[i].type,
2738 ((char *)pService) +
2739 pdiff,
2740 ((char *)&sDefault) +
2741 pdiff))
2742 continue;
2745 fprintf(f, "\t%s = ", parm_table[i].label);
2746 print_parameter(&parm_table[i],
2747 ((char *)pService) + pdiff, f);
2748 fprintf(f, "\n");
2750 if (pService->param_opt != NULL) {
2751 data = pService->param_opt;
2752 while(data) {
2753 fprintf(f, "\t%s = %s\n", data->key, data->value);
2754 data = data->next;
2760 /***************************************************************************
2761 Return info about the next service in a service. snum==-1 gives the globals.
2762 Return NULL when out of parameters.
2763 ***************************************************************************/
2765 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2767 if (snum == -1) {
2768 /* do the globals */
2769 for (; parm_table[*i].label; (*i)++) {
2770 if (parm_table[*i].class == P_SEPARATOR)
2771 return &parm_table[(*i)++];
2773 if (!parm_table[*i].ptr
2774 || (*parm_table[*i].label == '-'))
2775 continue;
2777 if ((*i) > 0
2778 && (parm_table[*i].ptr ==
2779 parm_table[(*i) - 1].ptr))
2780 continue;
2782 return &parm_table[(*i)++];
2784 } else {
2785 service *pService = ServicePtrs[snum];
2787 for (; parm_table[*i].label; (*i)++) {
2788 if (parm_table[*i].class == P_SEPARATOR)
2789 return &parm_table[(*i)++];
2791 if (parm_table[*i].class == P_LOCAL &&
2792 parm_table[*i].ptr &&
2793 (*parm_table[*i].label != '-') &&
2794 ((*i) == 0 ||
2795 (parm_table[*i].ptr !=
2796 parm_table[(*i) - 1].ptr)))
2798 int pdiff =
2799 PTR_DIFF(parm_table[*i].ptr,
2800 &sDefault);
2802 if (allparameters ||
2803 !equal_parameter(parm_table[*i].type,
2804 ((char *)pService) +
2805 pdiff,
2806 ((char *)&sDefault) +
2807 pdiff))
2809 return &parm_table[(*i)++];
2815 return NULL;
2819 /***************************************************************************
2820 Return TRUE if the passed service number is within range.
2821 ***************************************************************************/
2823 BOOL lp_snum_ok(int iService)
2825 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2828 /***************************************************************************
2829 Auto-load some home services.
2830 ***************************************************************************/
2832 static void lp_add_auto_services(const char *str)
2834 return;
2837 /***************************************************************************
2838 Auto-load one printer.
2839 ***************************************************************************/
2841 void lp_add_one_printer(char *name, char *comment)
2843 int printers = lp_servicenumber(PRINTERS_NAME);
2844 int i;
2846 if (lp_servicenumber(name) < 0) {
2847 lp_add_printer(name, printers);
2848 if ((i = lp_servicenumber(name)) >= 0) {
2849 string_set(&ServicePtrs[i]->comment, comment);
2850 ServicePtrs[i]->autoloaded = True;
2855 /***************************************************************************
2856 Announce ourselves as a print server.
2857 ***************************************************************************/
2859 void update_server_announce_as_printserver(void)
2861 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2864 /***************************************************************************
2865 Have we loaded a services file yet?
2866 ***************************************************************************/
2868 BOOL lp_loaded(void)
2870 return (bLoaded);
2873 /***************************************************************************
2874 Unload unused services.
2875 ***************************************************************************/
2877 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2879 int i;
2880 for (i = 0; i < iNumServices; i++) {
2881 if (!VALID(i))
2882 continue;
2884 if (!snumused || !snumused(smb, i)) {
2885 ServicePtrs[i]->valid = False;
2886 free_service(ServicePtrs[i]);
2891 /***************************************************************************
2892 Unload a service.
2893 ***************************************************************************/
2895 void lp_killservice(int iServiceIn)
2897 if (VALID(iServiceIn)) {
2898 ServicePtrs[iServiceIn]->valid = False;
2899 free_service(ServicePtrs[iServiceIn]);
2903 /*******************************************************************
2904 Set the server type we will announce as via nmbd.
2905 ********************************************************************/
2907 static void set_server_role(void)
2909 server_role = ROLE_STANDALONE;
2911 switch (lp_security()) {
2912 case SEC_SHARE:
2913 if (lp_domain_logons())
2914 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2915 break;
2916 case SEC_SERVER:
2917 case SEC_DOMAIN:
2918 case SEC_ADS:
2919 if (lp_domain_logons()) {
2920 if (Globals.bDomainMaster) /* auto or yes */
2921 server_role = ROLE_DOMAIN_PDC;
2922 else
2923 server_role = ROLE_DOMAIN_BDC;
2924 break;
2926 server_role = ROLE_DOMAIN_MEMBER;
2927 break;
2928 case SEC_USER:
2929 if (lp_domain_logons()) {
2931 if (Globals.bDomainMaster) /* auto or yes */
2932 server_role = ROLE_DOMAIN_PDC;
2933 else
2934 server_role = ROLE_DOMAIN_BDC;
2936 break;
2937 default:
2938 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2939 break;
2942 DEBUG(10, ("set_server_role: role = "));
2944 switch(server_role) {
2945 case ROLE_STANDALONE:
2946 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2947 break;
2948 case ROLE_DOMAIN_MEMBER:
2949 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
2950 break;
2951 case ROLE_DOMAIN_BDC:
2952 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
2953 break;
2954 case ROLE_DOMAIN_PDC:
2955 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
2956 break;
2960 /***************************************************************************
2961 Load the services array from the services file. Return True on success,
2962 False on failure.
2963 ***************************************************************************/
2965 BOOL lp_load(const char *pszFname)
2967 pstring n2;
2968 BOOL bRetval;
2969 struct param_opt *data;
2971 pstrcpy(n2, pszFname);
2972 standard_sub_basic(n2,sizeof(n2));
2974 add_to_file_list(pszFname, n2);
2976 bRetval = False;
2978 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
2980 bInGlobalSection = True;
2982 if (Globals.param_opt != NULL) {
2983 struct param_opt *next;
2984 for (data=Globals.param_opt; data; data=next) {
2985 next = data->next;
2986 if (data->flags & FLAG_CMDLINE) continue;
2987 free(data->key);
2988 free(data->value);
2989 DLIST_REMOVE(Globals.param_opt, data);
2990 free(data);
2994 init_globals();
2996 /* We get sections first, so have to start 'behind' to make up */
2997 iServiceIndex = -1;
2998 bRetval = pm_process(n2, do_section, do_parameter);
3000 /* finish up the last section */
3001 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3002 if (bRetval)
3003 if (iServiceIndex >= 0)
3004 bRetval = service_ok(iServiceIndex);
3006 lp_add_auto_services(lp_auto_services());
3008 /* When 'restrict anonymous = 2' guest connections to ipc$
3009 are denied */
3010 lp_add_hidden("IPC$", "IPC", (lp_restrict_anonymous() < 2));
3011 lp_add_hidden("ADMIN$", "DISK", False);
3013 set_server_role();
3014 set_default_server_announce_type();
3016 bLoaded = True;
3018 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3019 /* if bWINSsupport is true and we are in the client */
3020 if (in_client && Globals.bWINSsupport) {
3021 lp_do_parameter(-1, "wins server", "127.0.0.1");
3024 init_iconv();
3026 return (bRetval);
3029 /***************************************************************************
3030 Reset the max number of services.
3031 ***************************************************************************/
3033 void lp_resetnumservices(void)
3035 iNumServices = 0;
3038 /***************************************************************************
3039 Return the max number of services.
3040 ***************************************************************************/
3042 int lp_numservices(void)
3044 return (iNumServices);
3047 /***************************************************************************
3048 Display the contents of the services array in human-readable form.
3049 ***************************************************************************/
3051 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3053 int iService;
3055 if (show_defaults)
3056 defaults_saved = False;
3058 dump_globals(f);
3060 dump_a_service(&sDefault, f);
3062 for (iService = 0; iService < maxtoprint; iService++)
3063 lp_dump_one(f, show_defaults, iService);
3066 /***************************************************************************
3067 Display the contents of one service in human-readable form.
3068 ***************************************************************************/
3070 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3072 if (VALID(snum)) {
3073 if (ServicePtrs[snum]->szService[0] == '\0')
3074 return;
3075 dump_a_service(ServicePtrs[snum], f);
3079 /***************************************************************************
3080 Return the number of the service with the given name, or -1 if it doesn't
3081 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3082 getservicebyname()! This works ONLY if all services have been loaded, and
3083 does not copy the found service.
3084 ***************************************************************************/
3086 int lp_servicenumber(const char *pszServiceName)
3088 int iService;
3089 fstring serviceName;
3092 for (iService = iNumServices - 1; iService >= 0; iService--) {
3093 if (VALID(iService) && ServicePtrs[iService]->szService) {
3095 * The substitution here is used to support %U is
3096 * service names
3098 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3099 standard_sub_basic(serviceName,sizeof(serviceName));
3100 if (strequal(serviceName, pszServiceName))
3101 break;
3105 if (iService < 0)
3106 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3108 return (iService);
3111 /*******************************************************************
3112 A useful volume label function.
3113 ********************************************************************/
3114 const char *volume_label(int snum)
3116 const char *ret = lp_volume(snum);
3117 if (!*ret)
3118 return lp_servicename(snum);
3119 return (ret);
3123 /*******************************************************************
3124 Set the server type we will announce as via nmbd.
3125 ********************************************************************/
3127 static void set_default_server_announce_type(void)
3129 default_server_announce = 0;
3130 default_server_announce |= SV_TYPE_WORKSTATION;
3131 default_server_announce |= SV_TYPE_SERVER;
3132 default_server_announce |= SV_TYPE_SERVER_UNIX;
3134 switch (lp_announce_as()) {
3135 case ANNOUNCE_AS_NT_SERVER:
3136 default_server_announce |= SV_TYPE_SERVER_NT;
3137 /* fall through... */
3138 case ANNOUNCE_AS_NT_WORKSTATION:
3139 default_server_announce |= SV_TYPE_NT;
3140 break;
3141 case ANNOUNCE_AS_WIN95:
3142 default_server_announce |= SV_TYPE_WIN95_PLUS;
3143 break;
3144 case ANNOUNCE_AS_WFW:
3145 default_server_announce |= SV_TYPE_WFW;
3146 break;
3147 default:
3148 break;
3151 switch (lp_server_role()) {
3152 case ROLE_DOMAIN_MEMBER:
3153 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3154 break;
3155 case ROLE_DOMAIN_PDC:
3156 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3157 break;
3158 case ROLE_DOMAIN_BDC:
3159 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3160 break;
3161 case ROLE_STANDALONE:
3162 default:
3163 break;
3165 if (lp_time_server())
3166 default_server_announce |= SV_TYPE_TIME_SOURCE;
3168 if (lp_host_msdfs())
3169 default_server_announce |= SV_TYPE_DFS_SERVER;
3171 /* TODO: only announce us as print server when we are a print server */
3172 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
3175 /***********************************************************
3176 returns role of Samba server
3177 ************************************************************/
3179 int lp_server_role(void)
3181 return server_role;
3184 /***********************************************************
3185 If we are PDC then prefer us as DMB
3186 ************************************************************/
3188 BOOL lp_domain_master(void)
3190 if (Globals.bDomainMaster == Auto)
3191 return (lp_server_role() == ROLE_DOMAIN_PDC);
3193 return Globals.bDomainMaster;
3196 /***********************************************************
3197 If we are DMB then prefer us as LMB
3198 ************************************************************/
3200 BOOL lp_preferred_master(void)
3202 if (Globals.bPreferredMaster == Auto)
3203 return (lp_local_master() && lp_domain_master());
3205 return Globals.bPreferredMaster;
3208 /*******************************************************************
3209 Remove a service.
3210 ********************************************************************/
3212 void lp_remove_service(int snum)
3214 ServicePtrs[snum]->valid = False;
3217 /*******************************************************************
3218 Copy a service.
3219 ********************************************************************/
3221 void lp_copy_service(int snum, const char *new_name)
3223 const char *oldname = lp_servicename(snum);
3224 do_section(new_name);
3225 if (snum >= 0) {
3226 snum = lp_servicenumber(new_name);
3227 if (snum >= 0)
3228 lp_do_parameter(snum, "copy", oldname);
3233 /*******************************************************************
3234 Get the default server type we will announce as via nmbd.
3235 ********************************************************************/
3236 int lp_default_server_announce(void)
3238 return default_server_announce;
3241 const char *lp_printername(int snum)
3243 const char *ret = _lp_printername(snum);
3244 if (ret == NULL || (ret != NULL && *ret == '\0'))
3245 ret = lp_const_servicename(snum);
3247 return ret;
3251 /*******************************************************************
3252 Return the max print jobs per queue.
3253 ********************************************************************/
3255 int lp_maxprintjobs(int snum)
3257 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3258 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3259 maxjobs = PRINT_MAX_JOBID - 1;
3261 return maxjobs;