r4339: - rename auth_guest to auth_anonymous
[Samba/aatanasov.git] / source / param / loadparm.c
blob059b7b1cb24772168b82806a389735abe8bf679b
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 "dynconfig.h"
57 #include "system/time.h"
58 #include "system/iconv.h"
59 #include "system/network.h"
60 #include "system/printing.h"
61 #include "librpc/gen_ndr/ndr_svcctl.h"
62 #include "dlinklist.h"
64 BOOL in_client = False; /* Not in the client by default */
65 static BOOL bLoaded = False;
67 #ifndef GLOBAL_NAME
68 #define GLOBAL_NAME "global"
69 #endif
71 #ifndef PRINTERS_NAME
72 #define PRINTERS_NAME "printers"
73 #endif
75 #ifndef HOMES_NAME
76 #define HOMES_NAME "homes"
77 #endif
79 /* some helpful bits */
80 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && ServicePtrs[(i)]->valid)
81 #define VALID(i) ServicePtrs[i]->valid
83 static BOOL do_parameter(const char *, const char *);
84 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...);
86 static BOOL defaults_saved = False;
89 #define FLAG_BASIC 0x0001 /* fundamental options */
90 #define FLAG_SHARE 0x0002 /* file sharing options */
91 #define FLAG_PRINT 0x0004 /* printing options */
92 #define FLAG_GLOBAL 0x0008 /* local options that should be globally settable in SWAT */
93 #define FLAG_WIZARD 0x0010 /* Parameters that the wizard will operate on */
94 #define FLAG_ADVANCED 0x0020 /* Parameters that the wizard will operate on */
95 #define FLAG_DEVELOPER 0x0040 /* Parameters that the wizard will operate on */
96 #define FLAG_DEPRECATED 0x1000 /* options that should no longer be used */
97 #define FLAG_HIDE 0x2000 /* options that should be hidden in SWAT */
98 #define FLAG_DOS_STRING 0x4000 /* convert from UNIX to DOS codepage when reading this string. */
99 #define FLAG_CMDLINE 0x8000 /* this option was set from the command line */
102 /* the following are used by loadparm for option lists */
103 typedef enum
105 P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_LIST,
106 P_STRING,P_USTRING,P_ENUM,P_SEP
107 } parm_type;
109 typedef enum
111 P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
112 } parm_class;
114 struct enum_list {
115 int value;
116 const char *name;
119 struct parm_struct
121 const char *label;
122 parm_type type;
123 parm_class class;
124 void *ptr;
125 BOOL (*special)(const char *, char **);
126 const struct enum_list *enum_list;
127 uint_t flags;
128 union {
129 BOOL bvalue;
130 int ivalue;
131 char *svalue;
132 char cvalue;
133 char **lvalue;
134 } def;
138 struct param_opt {
139 struct param_opt *prev, *next;
140 char *key;
141 char *value;
142 int flags;
146 * This structure describes global (ie., server-wide) parameters.
148 typedef struct
150 char **smb_ports;
151 char *dos_charset;
152 char *unix_charset;
153 char *ncalrpc_dir;
154 char *display_charset;
155 char *szPrintcapname;
156 char *szLockDir;
157 char *szPidDir;
158 char *szRootdir;
159 char *szDefaultService;
160 char *szHostsEquiv;
161 char *szServerString;
162 char *szAutoServices;
163 char *szPasswdProgram;
164 char *szPasswdChat;
165 char *szLogFile;
166 char *szConfigFile;
167 char *szSMBPasswdFile;
168 char *szSAM_URL;
169 char *szSPOOLSS_URL;
170 char *szPrivateDir;
171 char **szPreloadModules;
172 char *szPasswordServer;
173 char *szSocketOptions;
174 char *szRealm;
175 char *szADSserver;
176 char *szLogonScript;
177 char *szLogonPath;
178 char *szLogonDrive;
179 char *szLogonHome;
180 char **szWINSservers;
181 char **szInterfaces;
182 char *szRemoteAnnounce;
183 char *szRemoteBrowseSync;
184 char *szSocketAddress;
185 char *szAnnounceVersion; /* This is initialised in init_globals */
186 char *szWorkgroup;
187 char *szNetbiosName;
188 char **szNetbiosAliases;
189 char *szNetbiosScope;
190 char *szDomainOtherSIDs;
191 char *szNameResolveOrder;
192 char *szPanicAction;
193 char *szAddUserScript;
194 char *szAddMachineScript;
195 char *szWINSHook;
196 char *szWINSPartners;
197 char **dcerpc_ep_servers;
198 char **server_services;
199 char *szWinbindUID;
200 char *szWinbindGID;
201 char *szNonUnixAccountRange;
202 char *szTemplateHomedir;
203 char *szTemplateShell;
204 char *szWinbindSeparator;
205 BOOL bWinbindEnumUsers;
206 BOOL bWinbindEnumGroups;
207 BOOL bWinbindUseDefaultDomain;
208 char *szIDMapBackend;
209 char *szGuestaccount;
210 int max_mux;
211 int max_xmit;
212 int pwordlevel;
213 int unamelevel;
214 int maxprotocol;
215 int minprotocol;
216 int security;
217 char **AuthMethods;
218 BOOL paranoid_server_security;
219 int lpqcachetime;
220 BOOL bDisableSpoolss;
221 int os_level;
222 int enhanced_browsing;
223 int time_offset;
224 int max_ttl;
225 int max_wins_ttl;
226 int min_wins_ttl;
227 int lm_announce;
228 int lm_interval;
229 int announce_as; /* This is initialised in init_globals */
230 int machine_password_timeout;
231 int winbind_cache_time;
232 int iLockSpinCount;
233 int iLockSpinTime;
234 char *socket_options;
235 BOOL bDNSproxy;
236 BOOL bWINSsupport;
237 BOOL bWINSproxy;
238 BOOL bLocalMaster;
239 BOOL bPreferredMaster;
240 BOOL bDomainMaster;
241 BOOL bDomainLogons;
242 BOOL bEncryptPasswords;
243 BOOL bNullPasswords;
244 BOOL bObeyPamRestrictions;
245 BOOL bLoadPrinters;
246 BOOL bLargeReadwrite;
247 BOOL bReadRaw;
248 BOOL bWriteRaw;
249 BOOL bTimeServer;
250 BOOL bBindInterfacesOnly;
251 BOOL bPamPasswordChange;
252 BOOL bNTSmbSupport;
253 BOOL bNTStatusSupport;
254 BOOL bAllowTrustedDomains;
255 BOOL bLanmanAuth;
256 BOOL bNTLMAuth;
257 BOOL bUseSpnego;
258 int server_signing;
259 int client_signing;
260 BOOL bClientLanManAuth;
261 BOOL bClientNTLMv2Auth;
262 BOOL bHostMSDfs;
263 BOOL bHideLocalUsers;
264 BOOL bUnicode;
265 BOOL bUseMmap;
266 BOOL bHostnameLookups;
267 BOOL bUnixExtensions;
268 BOOL bDisableNetbios;
269 BOOL bRpcBigEndian;
270 int restrict_anonymous;
271 int name_cache_timeout;
272 struct param_opt *param_opt;
274 global;
276 static global Globals;
279 * This structure describes a single service.
281 typedef struct
283 BOOL valid;
284 BOOL autoloaded;
285 char *szService;
286 char *szPath;
287 char *szUsername;
288 char **szInvalidUsers;
289 char **szValidUsers;
290 char **szAdminUsers;
291 char *szCopy;
292 char *szInclude;
293 char *szPrintcommand;
294 char *szLpqcommand;
295 char *szLprmcommand;
296 char *szLppausecommand;
297 char *szLpresumecommand;
298 char *szQueuepausecommand;
299 char *szQueueresumecommand;
300 char *szPrintername;
301 char **szHostsallow;
302 char **szHostsdeny;
303 char *comment;
304 char *volume;
305 char *fstype;
306 char *szMSDfsProxy;
307 char **ntvfs_handler;
308 int iMinPrintSpace;
309 int iMaxPrintJobs;
310 int iMaxConnections;
311 int iPrinting;
312 int iCSCPolicy;
313 BOOL bAvailable;
314 BOOL bBrowseable;
315 BOOL bRead_only;
316 BOOL bPrint_ok;
317 BOOL bMap_system;
318 BOOL bMap_hidden;
319 BOOL bMap_archive;
320 BOOL bLocking;
321 BOOL bStrictLocking;
322 BOOL bPosixLocking;
323 BOOL bOpLocks;
324 BOOL bLevel2OpLocks;
325 BOOL bOnlyUser;
326 BOOL bGuest_only;
327 BOOL bGuest_ok;
328 BOOL *copymap;
329 BOOL bMSDfsRoot;
330 BOOL bShareModes;
331 BOOL bStrictSync;
332 BOOL bCIFileSystem;
333 struct param_opt *param_opt;
335 char dummy[3]; /* for alignment */
337 service;
340 /* This is a default service used to prime a services structure */
341 static service sDefault = {
342 True, /* valid */
343 False, /* not autoloaded */
344 NULL, /* szService */
345 NULL, /* szPath */
346 NULL, /* szUsername */
347 NULL, /* szInvalidUsers */
348 NULL, /* szValidUsers */
349 NULL, /* szAdminUsers */
350 NULL, /* szCopy */
351 NULL, /* szInclude */
352 NULL, /* szPrintcommand */
353 NULL, /* szLpqcommand */
354 NULL, /* szLprmcommand */
355 NULL, /* szLppausecommand */
356 NULL, /* szLpresumecommand */
357 NULL, /* szQueuepausecommand */
358 NULL, /* szQueueresumecommand */
359 NULL, /* szPrintername */
360 NULL, /* szHostsallow */
361 NULL, /* szHostsdeny */
362 NULL, /* comment */
363 NULL, /* volume */
364 NULL, /* fstype */
365 NULL, /* szMSDfsProxy */
366 NULL, /* ntvfs_handler */
367 0, /* iMinPrintSpace */
368 1000, /* iMaxPrintJobs */
369 0, /* iMaxConnections */
370 DEFAULT_PRINTING, /* iPrinting */
371 0, /* iCSCPolicy */
372 True, /* bAvailable */
373 True, /* bBrowseable */
374 True, /* bRead_only */
375 False, /* bPrint_ok */
376 False, /* bMap_system */
377 False, /* bMap_hidden */
378 True, /* bMap_archive */
379 True, /* bLocking */
380 True, /* bStrictLocking */
381 True, /* bPosixLocking */
382 True, /* bOpLocks */
383 True, /* bLevel2OpLocks */
384 False, /* bOnlyUser */
385 False, /* bGuest_only */
386 False, /* bGuest_ok */
387 NULL, /* copymap */
388 False, /* bMSDfsRoot */
389 True, /* bShareModes */
390 False, /* bStrictSync */
391 False, /* bCIFileSystem */
392 NULL, /* Parametric options */
394 "" /* dummy */
397 /* local variables */
398 static service **ServicePtrs = NULL;
399 static int iNumServices = 0;
400 static int iServiceIndex = 0;
401 static BOOL bInGlobalSection = True;
402 static BOOL bGlobalOnly = False;
403 static int server_role;
404 static int default_server_announce;
406 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
408 /* prototypes for the special type handlers */
409 static BOOL handle_include(const char *pszParmValue, char **ptr);
410 static BOOL handle_copy(const char *pszParmValue, char **ptr);
411 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr);
412 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr);
413 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr);
415 static void set_server_role(void);
416 static void set_default_server_announce_type(void);
418 static const struct enum_list enum_protocol[] = {
419 {PROTOCOL_NT1, "NT1"},
420 {PROTOCOL_LANMAN2, "LANMAN2"},
421 {PROTOCOL_LANMAN1, "LANMAN1"},
422 {PROTOCOL_CORE, "CORE"},
423 {PROTOCOL_COREPLUS, "COREPLUS"},
424 {PROTOCOL_COREPLUS, "CORE+"},
425 {-1, NULL}
428 static const struct enum_list enum_security[] = {
429 {SEC_SHARE, "SHARE"},
430 {SEC_USER, "USER"},
431 {SEC_SERVER, "SERVER"},
432 {SEC_DOMAIN, "DOMAIN"},
433 #ifdef HAVE_ADS
434 {SEC_ADS, "ADS"},
435 #endif
436 {-1, NULL}
439 static const struct enum_list enum_printing[] = {
440 {PRINT_SYSV, "sysv"},
441 {PRINT_AIX, "aix"},
442 {PRINT_HPUX, "hpux"},
443 {PRINT_BSD, "bsd"},
444 {PRINT_QNX, "qnx"},
445 {PRINT_PLP, "plp"},
446 {PRINT_LPRNG, "lprng"},
447 {PRINT_SOFTQ, "softq"},
448 {PRINT_CUPS, "cups"},
449 {PRINT_LPRNT, "nt"},
450 {PRINT_LPROS2, "os2"},
451 #ifdef DEVELOPER
452 {PRINT_TEST, "test"},
453 {PRINT_VLP, "vlp"},
454 #endif /* DEVELOPER */
455 {-1, NULL}
458 /* Types of machine we can announce as. */
459 #define ANNOUNCE_AS_NT_SERVER 1
460 #define ANNOUNCE_AS_WIN95 2
461 #define ANNOUNCE_AS_WFW 3
462 #define ANNOUNCE_AS_NT_WORKSTATION 4
464 static const struct enum_list enum_announce_as[] = {
465 {ANNOUNCE_AS_NT_SERVER, "NT"},
466 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
467 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
468 {ANNOUNCE_AS_WIN95, "win95"},
469 {ANNOUNCE_AS_WFW, "WfW"},
470 {-1, NULL}
473 static const struct enum_list enum_bool_auto[] = {
474 {False, "No"},
475 {False, "False"},
476 {False, "0"},
477 {True, "Yes"},
478 {True, "True"},
479 {True, "1"},
480 {Auto, "Auto"},
481 {-1, NULL}
484 /* Client-side offline caching policy types */
485 #define CSC_POLICY_MANUAL 0
486 #define CSC_POLICY_DOCUMENTS 1
487 #define CSC_POLICY_PROGRAMS 2
488 #define CSC_POLICY_DISABLE 3
490 static const struct enum_list enum_csc_policy[] = {
491 {CSC_POLICY_MANUAL, "manual"},
492 {CSC_POLICY_DOCUMENTS, "documents"},
493 {CSC_POLICY_PROGRAMS, "programs"},
494 {CSC_POLICY_DISABLE, "disable"},
495 {-1, NULL}
498 /* SMB signing types. */
499 static const struct enum_list enum_smb_signing_vals[] = {
500 {SMB_SIGNING_OFF, "No"},
501 {SMB_SIGNING_OFF, "False"},
502 {SMB_SIGNING_OFF, "0"},
503 {SMB_SIGNING_OFF, "Off"},
504 {SMB_SIGNING_OFF, "disabled"},
505 {SMB_SIGNING_SUPPORTED, "Yes"},
506 {SMB_SIGNING_SUPPORTED, "True"},
507 {SMB_SIGNING_SUPPORTED, "1"},
508 {SMB_SIGNING_SUPPORTED, "On"},
509 {SMB_SIGNING_SUPPORTED, "enabled"},
510 {SMB_SIGNING_REQUIRED, "required"},
511 {SMB_SIGNING_REQUIRED, "mandatory"},
512 {SMB_SIGNING_REQUIRED, "force"},
513 {SMB_SIGNING_REQUIRED, "forced"},
514 {SMB_SIGNING_REQUIRED, "enforced"},
515 {SMB_SIGNING_AUTO, "auto"},
516 {-1, NULL}
520 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
522 * Note: We have a flag called FLAG_DEVELOPER but is not used at this time, it
523 * is implied in current control logic. This may change at some later time. A
524 * flag value of 0 means - show as development option only.
526 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
527 * screen in SWAT. This is used to exclude parameters as well as to squash all
528 * parameters that have been duplicated by pseudonyms.
530 static struct parm_struct parm_table[] = {
531 {"Base Options", P_SEP, P_SEPARATOR},
533 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
534 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
535 {"ncalrpc dir", P_STRING, P_GLOBAL, &Globals.ncalrpc_dir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
536 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
537 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
538 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
539 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
540 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
541 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
542 {"ADS server", P_STRING, P_GLOBAL, &Globals.szADSserver, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
543 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
544 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
545 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
546 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
547 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
548 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
549 {"ntvfs handler", P_LIST, P_LOCAL, &sDefault.ntvfs_handler, NULL, NULL, FLAG_ADVANCED},
550 {"dcerpc endpoint servers", P_LIST, P_GLOBAL, &Globals.dcerpc_ep_servers, NULL, NULL, FLAG_ADVANCED},
551 {"server services", P_LIST, P_GLOBAL, &Globals.server_services, NULL, NULL, FLAG_ADVANCED},
553 {"Security Options", P_SEP, P_SEPARATOR},
555 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
556 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
557 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
558 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
559 {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
560 {"idmap backend", P_STRING, P_GLOBAL, &Globals.szIDMapBackend, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
561 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
562 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
563 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
564 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
565 {"sam database", P_STRING, P_GLOBAL, &Globals.szSAM_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
566 {"spoolss database", P_STRING, P_GLOBAL, &Globals.szSPOOLSS_URL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
567 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
568 {"non unix account range", P_STRING, P_GLOBAL, &Globals.szNonUnixAccountRange, handle_non_unix_account_range, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
569 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
570 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
571 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE | FLAG_DEVELOPER},
572 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
574 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
575 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
576 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
577 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
578 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
579 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
580 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
581 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
582 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
583 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
585 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
586 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
587 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
589 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
590 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
591 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
593 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
595 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
597 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
599 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
600 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
601 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
602 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_BASIC | FLAG_GLOBAL},
604 {"Logging Options", P_SEP, P_SEPARATOR},
606 {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
607 {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_HIDE},
608 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
610 {"Protocol Options", P_SEP, P_SEPARATOR},
612 {"smb ports", P_LIST, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
613 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_DEVELOPER},
614 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
615 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_DEVELOPER},
616 {"unicode", P_BOOL, P_GLOBAL, &Globals.bUnicode, NULL, NULL, FLAG_DEVELOPER},
617 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_DEVELOPER},
618 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_DEVELOPER},
619 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
621 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
623 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_DEVELOPER},
624 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_DEVELOPER},
625 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
626 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
628 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
629 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
630 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
631 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
632 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
633 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
634 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_DEVELOPER},
635 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
636 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
637 {"rpc big endian", P_BOOL, P_GLOBAL, &Globals.bRpcBigEndian, NULL, NULL, FLAG_DEVELOPER},
639 {"Tuning Options", P_SEP, P_SEPARATOR},
641 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_DEVELOPER},
642 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
643 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_DEVELOPER},
644 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
646 {"socket options", P_STRING, P_GLOBAL, &Globals.socket_options, NULL, NULL, FLAG_DEVELOPER},
647 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_DEVELOPER},
648 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
650 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
651 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
652 {"case insensitive filesystem", P_BOOL, P_LOCAL, &sDefault.bCIFileSystem, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
654 {"Printing Options", P_SEP, P_SEPARATOR},
656 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_PRINT},
657 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
658 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT | FLAG_DEVELOPER},
659 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
660 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
661 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
662 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT | FLAG_GLOBAL},
663 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
664 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
665 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
666 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
667 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
668 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
669 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
670 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT | FLAG_GLOBAL},
672 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
673 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
675 {"Filename Handling", P_SEP, P_SEPARATOR},
677 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
678 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
679 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
681 {"Domain Options", P_SEP, P_SEPARATOR},
683 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
685 {"Logon Options", P_SEP, P_SEPARATOR},
687 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
688 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
690 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
691 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
692 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
693 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
694 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
696 {"Browse Options", P_SEP, P_SEPARATOR},
698 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
699 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_DEVELOPER},
700 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
701 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
702 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
703 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
704 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED | FLAG_DEVELOPER},
705 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT | FLAG_DEVELOPER},
706 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
707 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_DEVELOPER | FLAG_ADVANCED},
709 {"WINS Options", P_SEP, P_SEPARATOR},
710 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
711 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
713 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
714 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
715 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
716 {"wins partners", P_STRING, P_GLOBAL, &Globals.szWINSPartners, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD | FLAG_DEVELOPER},
718 {"Locking Options", P_SEP, P_SEPARATOR},
720 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_SHARE | FLAG_GLOBAL},
721 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
722 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_GLOBAL},
723 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_GLOBAL},
725 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
726 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
727 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
728 {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE | FLAG_GLOBAL},
729 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
731 {"Miscellaneous Options", P_SEP, P_SEPARATOR},
733 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
734 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
735 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
736 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
737 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
738 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
740 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
741 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_DEVELOPER},
742 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
743 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
744 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_DEVELOPER},
745 {"time offset", P_INTEGER, P_GLOBAL, &Globals.time_offset, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
746 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
748 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
749 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
751 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
752 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE },
753 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
755 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
756 {"hide local users", P_BOOL, P_GLOBAL, &Globals.bHideLocalUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
758 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_SHARE},
759 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_SHARE},
760 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
761 {"Winbind options", P_SEP, P_SEPARATOR},
763 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szWinbindUID, handle_winbind_uid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
764 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szWinbindGID, handle_winbind_gid, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
765 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
766 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
767 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
768 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
769 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
770 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
771 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED | FLAG_DEVELOPER},
773 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
776 /***************************************************************************
777 Initialise the sDefault parameter structure for the printer values.
778 ***************************************************************************/
780 static void init_printer_values(void)
782 /* choose defaults depending on the type of printing */
783 switch (sDefault.iPrinting) {
784 case PRINT_BSD:
785 case PRINT_AIX:
786 case PRINT_LPRNT:
787 case PRINT_LPROS2:
788 do_parameter("Lpqcommand", "lpq -P'%p'");
789 do_parameter("Lprmcommand", "lprm -P'%p' %j");
790 do_parameter("Printcommand",
791 "lpr -r -P'%p' %s");
792 break;
794 case PRINT_LPRNG:
795 case PRINT_PLP:
796 do_parameter("Lpqcommand", "lpq -P'%p'");
797 do_parameter("Lprmcommand", "lprm -P'%p' %j");
798 do_parameter("Printcommand",
799 "lpr -r -P'%p' %s");
800 do_parameter("Queuepausecommand",
801 "lpc stop '%p'");
802 do_parameter("Queueresumecommand",
803 "lpc start '%p'");
804 do_parameter("Lppausecommand",
805 "lpc hold '%p' %j");
806 do_parameter("Lpresumecommand",
807 "lpc release '%p' %j");
808 break;
810 case PRINT_CUPS:
811 #ifdef HAVE_CUPS
812 do_parameter("Lpqcommand", "");
813 do_parameter("Lprmcommand", "");
814 do_parameter("Printcommand", "");
815 do_parameter("Lppausecommand", "");
816 do_parameter("Lpresumecommand", "");
817 do_parameter("Queuepausecommand", "");
818 do_parameter("Queueresumecommand", "");
820 do_parameter("Printcapname", "cups");
821 #else
822 do_parameter("Lpqcommand",
823 "/usr/bin/lpstat -o '%p'");
824 do_parameter("Lprmcommand",
825 "/usr/bin/cancel '%p-%j'");
826 do_parameter("Printcommand",
827 "/usr/bin/lp -d '%p' %s; rm %s");
828 do_parameter("Lppausecommand",
829 "lp -i '%p-%j' -H hold");
830 do_parameter("Lpresumecommand",
831 "lp -i '%p-%j' -H resume");
832 do_parameter("Queuepausecommand",
833 "/usr/bin/disable '%p'");
834 do_parameter("Queueresumecommand",
835 "/usr/bin/enable '%p'");
836 do_parameter("Printcapname", "lpstat");
837 #endif /* HAVE_CUPS */
838 break;
840 case PRINT_SYSV:
841 case PRINT_HPUX:
842 do_parameter("Lpqcommand", "lpstat -o%p");
843 do_parameter("Lprmcommand", "cancel %p-%j");
844 do_parameter("Printcommand",
845 "lp -c -d%p %s; rm %s");
846 do_parameter("Queuepausecommand",
847 "disable %p");
848 do_parameter("Queueresumecommand",
849 "enable %p");
850 #ifndef HPUX
851 do_parameter("Lppausecommand",
852 "lp -i %p-%j -H hold");
853 do_parameter("Lpresumecommand",
854 "lp -i %p-%j -H resume");
855 #endif /* HPUX */
856 break;
858 case PRINT_QNX:
859 do_parameter("Lpqcommand", "lpq -P%p");
860 do_parameter("Lprmcommand", "lprm -P%p %j");
861 do_parameter("Printcommand", "lp -r -P%p %s");
862 break;
864 case PRINT_SOFTQ:
865 do_parameter("Lpqcommand", "qstat -l -d%p");
866 do_parameter("Lprmcommand",
867 "qstat -s -j%j -c");
868 do_parameter("Printcommand",
869 "lp -d%p -s %s; rm %s");
870 do_parameter("Lppausecommand",
871 "qstat -s -j%j -h");
872 do_parameter("Lpresumecommand",
873 "qstat -s -j%j -r");
874 break;
875 #ifdef DEVELOPER
876 case PRINT_TEST:
877 case PRINT_VLP:
878 do_parameter("Printcommand", "vlp print %p %s");
879 do_parameter("Lpqcommand", "vlp lpq %p");
880 do_parameter("Lprmcommand", "vlp lprm %p %j");
881 do_parameter("Lppausecommand", "vlp lppause %p %j");
882 do_parameter("Lpresumecommand", "vlp lpresum %p %j");
883 do_parameter("Queuepausecommand", "vlp queuepause %p");
884 do_parameter("Queueresumecommand", "vlp queueresume %p");
885 break;
886 #endif /* DEVELOPER */
892 /***************************************************************************
893 Initialise the global parameter structure.
894 ***************************************************************************/
895 static void init_globals(void)
897 int i;
899 DEBUG(3, ("Initialising global parameters\n"));
901 for (i = 0; parm_table[i].label; i++) {
902 if ((parm_table[i].type == P_STRING ||
903 parm_table[i].type == P_USTRING) &&
904 parm_table[i].ptr &&
905 !(parm_table[i].flags & FLAG_CMDLINE)) {
906 string_set(parm_table[i].ptr, "");
910 /* options that can be set on the command line must be initialised via
911 the slower do_parameter() to ensure that FLAG_CMDLINE is obeyed */
912 #ifdef TCP_NODELAY
913 do_parameter("socket options", "TCP_NODELAY");
914 #endif
915 do_parameter("workgroup", DEFAULT_WORKGROUP);
916 do_parameter("netbios name", get_myname());
917 do_parameter("max protocol", "NT1");
918 do_parameter("name resolve order", "lmhosts wins host bcast");
920 init_printer_values();
922 do_parameter("fstype", FSTYPE_STRING);
923 do_parameter("ntvfs handler", "unixuid default");
925 do_parameter("dcerpc endpoint servers", "epmapper srvsvc wkssvc rpcecho samr netlogon lsarpc spoolss drsuapi winreg IOXIDResolver IRemoteActivation");
926 do_parameter("server services", "smb rpc");
927 do_parameter("auth methods", "anonymous sam_ignoredomain");
928 do_parameter("smb passwd file", dyn_SMB_PASSWD_FILE);
929 do_parameter("private dir", dyn_PRIVATE_DIR);
930 do_parameter_var("sam database", "tdb://%s/sam.ldb", dyn_PRIVATE_DIR);
931 do_parameter_var("spoolss database", "tdb://%s/spoolss.ldb", dyn_PRIVATE_DIR);
932 do_parameter("guest account", GUEST_ACCOUNT);
934 /* using UTF8 by default allows us to support all chars */
935 do_parameter("unix charset", "UTF8");
937 /* Use codepage 850 as a default for the dos character set */
938 do_parameter("dos charset", "CP850");
941 * Allow the default PASSWD_CHAT to be overridden in local.h.
943 do_parameter("passwd chat", DEFAULT_PASSWD_CHAT);
945 do_parameter("passwd program", "");
946 do_parameter("printcap name", PRINTCAP_NAME);
948 do_parameter("pid directory", dyn_PIDDIR);
949 do_parameter("lock dir", dyn_LOCKDIR);
950 do_parameter("ncalrpc dir", dyn_NCALRPCDIR);
952 do_parameter("socket address", "0.0.0.0");
953 do_parameter_var("server string", "Samba %s", SAMBA_VERSION_STRING);
955 do_parameter_var("announce version", "%d.%d",
956 DEFAULT_MAJOR_VERSION,
957 DEFAULT_MINOR_VERSION);
959 do_parameter("logon drive", "");
961 do_parameter("logon home", "\\\\%N\\%U");
962 do_parameter("logon path", "\\\\%N\\%U\\profile");
963 do_parameter("password server", "*");
965 do_parameter("load printers", "True");
967 do_parameter("max mux", "50");
968 do_parameter("max xmit", "12288");
969 do_parameter("lpqcachetime", "10");
970 do_parameter("DisableSpoolss", "False");
971 do_parameter("password level", "0");
972 do_parameter("username level", "0");
973 do_parameter("LargeReadwrite", "True");
974 do_parameter("minprotocol", "CORE");
975 do_parameter("security", "USER");
976 do_parameter("paranoid server security", "True");
977 do_parameter("EncryptPasswords", "True");
978 do_parameter("ReadRaw", "True");
979 do_parameter("WriteRaw", "True");
980 do_parameter("NullPasswords", "False");
981 do_parameter("ObeyPamRestrictions", "False");
982 do_parameter("lm announce", "Auto");
983 do_parameter("lm interval", "60");
984 do_parameter("announce as", "NT SERVER");
986 do_parameter("TimeServer", "False");
987 do_parameter("BindInterfacesOnly", "False");
988 do_parameter("PamPasswordChange", "False");
989 do_parameter("Unicode", "True");
990 do_parameter("restrict anonymous", "0");
991 do_parameter("ClientLanManAuth", "True");
992 do_parameter("LanmanAuth", "True");
993 do_parameter("NTLMAuth", "True");
995 do_parameter("enhanced browsing", "True");
996 do_parameter("LockSpinCount", "3");
997 do_parameter("LockSpinTime", "10");
998 #ifdef MMAP_BLACKLIST
999 do_parameter("UseMmap", "False");
1000 #else
1001 do_parameter("UseMmap", "True");
1002 #endif
1003 do_parameter("UnixExtensions", "False");
1005 /* hostname lookups can be very expensive and are broken on
1006 a large number of sites (tridge) */
1007 do_parameter("HostnameLookups", "False");
1009 do_parameter("PreferredMaster", "Auto");
1010 do_parameter("os level", "20");
1011 do_parameter("LocalMaster", "True");
1012 do_parameter("DomainMaster", "Auto"); /* depending on bDomainLogons */
1013 do_parameter("DomainLogons", "False");
1014 do_parameter("WINSsupport", "False");
1015 do_parameter("WINSproxy", "False");
1017 do_parameter("DNSproxy", "True");
1019 do_parameter("AllowTrustedDomains", "True");
1021 do_parameter("TemplateShell", "/bin/false");
1022 do_parameter("TemplateHomedir", "/home/%D/%U");
1023 do_parameter("WinbindSeparator", "\\");
1025 do_parameter("winbind cache time", "15");
1026 do_parameter("WinbindEnumUsers", "True");
1027 do_parameter("WinbindEnumGroups", "True");
1028 do_parameter("WinbindUseDefaultDomain", "False");
1030 do_parameter("IDMapBackend", "tdb");
1032 do_parameter("name cache timeout", "660"); /* In seconds */
1034 do_parameter("client signing", "Yes");
1035 do_parameter("server signing", "auto");
1037 do_parameter("use spnego", "True");
1039 do_parameter("smb ports", SMB_PORTS);
1041 do_parameter("nt status support", "True");
1044 static TALLOC_CTX *lp_talloc;
1046 /******************************************************************* a
1047 Free up temporary memory - called from the main loop.
1048 ********************************************************************/
1050 void lp_talloc_free(void)
1052 if (!lp_talloc)
1053 return;
1054 talloc_free(lp_talloc);
1055 lp_talloc = NULL;
1058 /*******************************************************************
1059 Convenience routine to grab string parameters into temporary memory
1060 and run standard_sub_basic on them. The buffers can be written to by
1061 callers without affecting the source string.
1062 ********************************************************************/
1064 static const char *lp_string(const char *s)
1066 #if 0 /* until REWRITE done to make thread-safe */
1067 size_t len = s ? strlen(s) : 0;
1068 char *ret;
1069 #endif
1071 /* The follow debug is useful for tracking down memory problems
1072 especially if you have an inner loop that is calling a lp_*()
1073 function that returns a string. Perhaps this debug should be
1074 present all the time? */
1076 #if 0
1077 DEBUG(10, ("lp_string(%s)\n", s));
1078 #endif
1080 #if 0 /* until REWRITE done to make thread-safe */
1081 if (!lp_talloc)
1082 lp_talloc = talloc_init("lp_talloc");
1084 ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
1086 if (!ret)
1087 return NULL;
1089 if (!s)
1090 *ret = 0;
1091 else
1092 StrnCpy(ret, s, len);
1094 if (trim_string(ret, "\"", "\"")) {
1095 if (strchr(ret,'"') != NULL)
1096 StrnCpy(ret, s, len);
1099 standard_sub_basic(ret,len+100);
1100 return (ret);
1101 #endif
1102 return s;
1106 In this section all the functions that are used to access the
1107 parameters from the rest of the program are defined
1110 #define FN_GLOBAL_STRING(fn_name,ptr) \
1111 const char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1112 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1113 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1114 #define FN_GLOBAL_LIST(fn_name,ptr) \
1115 const char **fn_name(void) {return(*(const char ***)(ptr));}
1116 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1117 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1118 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1119 char fn_name(void) {return(*(char *)(ptr));}
1120 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1121 int fn_name(void) {return(*(int *)(ptr));}
1123 #define FN_LOCAL_STRING(fn_name,val) \
1124 const char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1125 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1126 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1127 #define FN_LOCAL_LIST(fn_name,val) \
1128 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1129 #define FN_LOCAL_BOOL(fn_name,val) \
1130 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1131 #define FN_LOCAL_CHAR(fn_name,val) \
1132 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1133 #define FN_LOCAL_INTEGER(fn_name,val) \
1134 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1136 FN_GLOBAL_LIST(lp_smb_ports, &Globals.smb_ports)
1137 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1138 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1139 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1140 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1141 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1142 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1143 FN_GLOBAL_STRING(lp_sam_url, &Globals.szSAM_URL)
1144 FN_GLOBAL_STRING(lp_spoolss_url, &Globals.szSPOOLSS_URL)
1145 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1146 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1147 FN_GLOBAL_STRING(lp_printcapname, &Globals.szPrintcapname)
1148 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1149 FN_GLOBAL_STRING(lp_ncalrpc_dir, &Globals.ncalrpc_dir)
1150 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1151 FN_GLOBAL_LIST(lp_dcerpc_endpoint_servers, &Globals.dcerpc_ep_servers)
1152 FN_GLOBAL_LIST(lp_server_services, &Globals.server_services)
1153 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1154 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1155 FN_GLOBAL_STRING(lp_hosts_equiv, &Globals.szHostsEquiv)
1156 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1157 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1158 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1159 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1160 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1161 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1162 FN_GLOBAL_STRING(lp_ads_server, &Globals.szADSserver)
1163 FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
1164 FN_GLOBAL_STRING(lp_workgroup, &Globals.szWorkgroup)
1165 FN_GLOBAL_STRING(lp_netbios_name, &Globals.szNetbiosName)
1166 FN_GLOBAL_STRING(lp_netbios_scope, &Globals.szNetbiosScope)
1167 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1168 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1169 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1170 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1171 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1172 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1173 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1174 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1175 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1176 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1177 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1178 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1179 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1181 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1183 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1185 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1186 FN_GLOBAL_STRING(lp_wins_partners, &Globals.szWINSPartners)
1187 FN_GLOBAL_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1188 FN_GLOBAL_STRING(lp_template_shell, &Globals.szTemplateShell)
1189 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1190 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1191 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1192 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1193 FN_GLOBAL_STRING(lp_idmap_backend, &Globals.szIDMapBackend)
1195 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1196 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1197 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1198 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1199 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1200 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1201 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1202 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1203 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1204 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1205 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1206 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1207 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1208 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1209 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1210 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1211 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1212 FN_GLOBAL_BOOL(lp_unicode, &Globals.bUnicode)
1213 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1214 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1215 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1216 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1217 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1218 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1219 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1220 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1221 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1222 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1223 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1224 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1225 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1226 FN_GLOBAL_BOOL(lp_rpc_big_endian, &Globals.bRpcBigEndian)
1227 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1228 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1229 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1230 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1231 FN_GLOBAL_INTEGER(lp_time_offset, &Globals.time_offset)
1232 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1233 FN_GLOBAL_INTEGER(lp_max_xmit, &Globals.max_xmit)
1234 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1235 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1236 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1237 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1238 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1239 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1240 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1241 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1242 FN_GLOBAL_INTEGER(lp_disable_spoolss, &Globals.bDisableSpoolss)
1243 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1244 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1245 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1246 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1247 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1248 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1249 FN_LOCAL_STRING(lp_servicename, szService)
1250 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1251 FN_LOCAL_STRING(lp_pathname, szPath)
1252 FN_LOCAL_STRING(lp_username, szUsername)
1253 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1254 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1255 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1256 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1257 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1258 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1259 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1260 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1261 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1262 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1263 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1264 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1265 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1266 FN_LOCAL_STRING(lp_comment, comment)
1267 FN_LOCAL_STRING(lp_fstype, fstype)
1268 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1269 static FN_LOCAL_STRING(lp_volume, volume)
1270 FN_LOCAL_LIST(lp_ntvfs_handler, ntvfs_handler)
1271 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1272 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1273 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
1274 FN_LOCAL_BOOL(lp_readonly, bRead_only)
1275 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
1276 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
1277 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
1278 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
1279 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
1280 FN_LOCAL_BOOL(lp_locking, bLocking)
1281 FN_LOCAL_BOOL(lp_strict_locking, bStrictLocking)
1282 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
1283 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
1284 FN_LOCAL_BOOL(lp_ci_filesystem, bCIFileSystem)
1285 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
1286 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
1287 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
1288 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
1289 FN_LOCAL_BOOL(lp_map_system, bMap_system)
1290 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
1291 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
1292 FN_LOCAL_INTEGER(lp_printing, iPrinting)
1293 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
1294 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
1295 FN_GLOBAL_BOOL(lp_hide_local_users, &Globals.bHideLocalUsers)
1296 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
1297 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
1298 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
1300 /* local prototypes */
1302 static int map_parameter(const char *pszParmName);
1303 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
1304 static int getservicebyname(const char *pszServiceName,
1305 service * pserviceDest);
1306 static void copy_service(service * pserviceDest,
1307 service * pserviceSource, BOOL *pcopymapDest);
1308 static BOOL service_ok(int iService);
1309 static BOOL do_section(const char *pszSectionName);
1310 static void init_copymap(service * pservice);
1312 /* This is a helper function for parametrical options support. */
1313 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
1314 /* Actual parametrical functions are quite simple */
1315 static const char *get_parametrics(int lookup_service, const char *type, const char *option)
1317 char *vfskey;
1318 struct param_opt *data;
1320 if (lookup_service >= iNumServices) return NULL;
1322 data = (lookup_service < 0) ?
1323 Globals.param_opt : ServicePtrs[lookup_service]->param_opt;
1325 asprintf(&vfskey, "%s:%s", type, option);
1326 strlower(vfskey);
1328 while (data) {
1329 if (strcmp(data->key, vfskey) == 0) {
1330 free(vfskey);
1331 return data->value;
1333 data = data->next;
1336 if (lookup_service >= 0) {
1337 /* Try to fetch the same option but from globals */
1338 /* but only if we are not already working with Globals */
1339 data = Globals.param_opt;
1340 while (data) {
1341 if (strcmp(data->key, vfskey) == 0) {
1342 free(vfskey);
1343 return data->value;
1345 data = data->next;
1349 free(vfskey);
1351 return NULL;
1355 /*******************************************************************
1356 convenience routine to return int parameters.
1357 ********************************************************************/
1358 static int lp_int(const char *s)
1361 if (!s) {
1362 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1363 return (-1);
1366 return atoi(s);
1369 /*******************************************************************
1370 convenience routine to return unsigned long parameters.
1371 ********************************************************************/
1372 static int lp_ulong(const char *s)
1375 if (!s) {
1376 DEBUG(0,("lp_int(%s): is called with NULL!\n",s));
1377 return (-1);
1380 return strtoul(s, NULL, 10);
1383 /*******************************************************************
1384 convenience routine to return boolean parameters.
1385 ********************************************************************/
1386 static BOOL lp_bool(const char *s)
1388 BOOL ret = False;
1390 if (!s) {
1391 DEBUG(0,("lp_bool(%s): is called with NULL!\n",s));
1392 return False;
1395 if (!set_boolean(&ret,s)) {
1396 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
1397 return False;
1400 return ret;
1404 /* Return parametric option from a given service. Type is a part of option before ':' */
1405 /* Parametric option has following syntax: 'Type: option = value' */
1406 /* Returned value is allocated in 'lp_talloc' context */
1408 const char *lp_parm_string(int lookup_service, const char *type, const char *option)
1410 const char *value = get_parametrics(lookup_service, type, option);
1412 if (value)
1413 return lp_string(value);
1415 return NULL;
1418 /* Return parametric option from a given service. Type is a part of option before ':' */
1419 /* Parametric option has following syntax: 'Type: option = value' */
1420 /* Returned value is allocated in 'lp_talloc' context */
1422 char **lp_parm_string_list(int lookup_service, const char *type, const char *option,
1423 const char *separator)
1425 const char *value = get_parametrics(lookup_service, type, option);
1427 if (value)
1428 return str_list_make(value, separator);
1430 return NULL;
1433 /* Return parametric option from a given service. Type is a part of option before ':' */
1434 /* Parametric option has following syntax: 'Type: option = value' */
1436 int lp_parm_int(int lookup_service, const char *type, const char *option)
1438 const char *value = get_parametrics(lookup_service, type, option);
1440 if (value)
1441 return lp_int(value);
1443 return (-1);
1446 /* Return parametric option from a given service. Type is a part of option before ':' */
1447 /* Parametric option has following syntax: 'Type: option = value' */
1449 unsigned long lp_parm_ulong(int lookup_service, const char *type, const char *option)
1451 const char *value = get_parametrics(lookup_service, type, option);
1453 if (value)
1454 return lp_ulong(value);
1456 return (0);
1459 /* Return parametric option from a given service. Type is a part of option before ':' */
1460 /* Parametric option has following syntax: 'Type: option = value' */
1462 BOOL lp_parm_bool(int lookup_service, const char *type, const char *option, BOOL default_v)
1464 const char *value = get_parametrics(lookup_service, type, option);
1466 if (value)
1467 return lp_bool(value);
1469 return default_v;
1473 /***************************************************************************
1474 Initialise a service to the defaults.
1475 ***************************************************************************/
1477 static void init_service(service * pservice)
1479 memset((char *)pservice, '\0', sizeof(service));
1480 copy_service(pservice, &sDefault, NULL);
1483 /***************************************************************************
1484 Free the dynamically allocated parts of a service struct.
1485 ***************************************************************************/
1487 static void free_service(service *pservice)
1489 int i;
1490 struct param_opt *data, *pdata;
1491 if (!pservice)
1492 return;
1494 if (pservice->szService)
1495 DEBUG(5, ("free_service: Freeing service %s\n",
1496 pservice->szService));
1498 string_free(&pservice->szService);
1499 SAFE_FREE(pservice->copymap);
1501 for (i = 0; parm_table[i].label; i++) {
1502 if ((parm_table[i].type == P_STRING ||
1503 parm_table[i].type == P_USTRING) &&
1504 parm_table[i].class == P_LOCAL)
1505 string_free((char **)
1506 (((char *)pservice) +
1507 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1508 else if (parm_table[i].type == P_LIST &&
1509 parm_table[i].class == P_LOCAL)
1510 str_list_free((char ***)
1511 (((char *)pservice) +
1512 PTR_DIFF(parm_table[i].ptr, &sDefault)));
1515 DEBUG(5,("Freeing parametrics:\n"));
1516 data = pservice->param_opt;
1517 while (data) {
1518 DEBUG(5,("[%s = %s]\n", data->key, data->value));
1519 string_free(&data->key);
1520 string_free(&data->value);
1521 pdata = data->next;
1522 SAFE_FREE(data);
1523 data = pdata;
1526 ZERO_STRUCTP(pservice);
1529 /***************************************************************************
1530 Add a new service to the services array initialising it with the given
1531 service.
1532 ***************************************************************************/
1534 static int add_a_service(const service *pservice, const char *name)
1536 int i;
1537 service tservice;
1538 int num_to_alloc = iNumServices + 1;
1539 struct param_opt *data, *pdata;
1541 tservice = *pservice;
1543 /* it might already exist */
1544 if (name) {
1545 i = getservicebyname(name, NULL);
1546 if (i >= 0) {
1547 /* Clean all parametric options for service */
1548 /* They will be added during parsing again */
1549 data = ServicePtrs[i]->param_opt;
1550 while (data) {
1551 string_free(&data->key);
1552 string_free(&data->value);
1553 pdata = data->next;
1554 SAFE_FREE(data);
1555 data = pdata;
1557 ServicePtrs[i]->param_opt = NULL;
1558 return (i);
1562 /* find an invalid one */
1563 for (i = 0; i < iNumServices; i++)
1564 if (!ServicePtrs[i]->valid)
1565 break;
1567 /* if not, then create one */
1568 if (i == iNumServices) {
1569 service **tsp;
1571 tsp = realloc_p(ServicePtrs, service *, num_to_alloc);
1573 if (!tsp) {
1574 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
1575 return (-1);
1577 else {
1578 ServicePtrs = tsp;
1579 ServicePtrs[iNumServices] = malloc_p(service);
1581 if (!ServicePtrs[iNumServices]) {
1582 DEBUG(0,("add_a_service: out of memory!\n"));
1583 return (-1);
1586 iNumServices++;
1587 } else
1588 free_service(ServicePtrs[i]);
1590 ServicePtrs[i]->valid = True;
1592 init_service(ServicePtrs[i]);
1593 copy_service(ServicePtrs[i], &tservice, NULL);
1594 if (name)
1595 string_set(&ServicePtrs[i]->szService, name);
1596 return (i);
1599 /***************************************************************************
1600 Add a new home service, with the specified home directory, defaults coming
1601 from service ifrom.
1602 ***************************************************************************/
1604 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
1605 const char *user, const char *pszHomedir)
1607 int i;
1608 pstring newHomedir;
1610 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
1612 if (i < 0)
1613 return (False);
1615 if (!(*(ServicePtrs[iDefaultService]->szPath))
1616 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(-1))) {
1617 pstrcpy(newHomedir, pszHomedir);
1618 } else {
1619 pstrcpy(newHomedir, lp_pathname(iDefaultService));
1620 string_sub(newHomedir,"%H", pszHomedir, sizeof(newHomedir));
1623 string_set(&ServicePtrs[i]->szPath, newHomedir);
1625 if (!(*(ServicePtrs[i]->comment))) {
1626 pstring comment;
1627 slprintf(comment, sizeof(comment) - 1,
1628 "Home directory of %s", user);
1629 string_set(&ServicePtrs[i]->comment, comment);
1631 ServicePtrs[i]->bAvailable = sDefault.bAvailable;
1632 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1634 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
1635 user, newHomedir));
1637 return (True);
1640 /***************************************************************************
1641 Add a new service, based on an old one.
1642 ***************************************************************************/
1644 int lp_add_service(const char *pszService, int iDefaultService)
1646 return (add_a_service(ServicePtrs[iDefaultService], pszService));
1649 /***************************************************************************
1650 Add the IPC service.
1651 ***************************************************************************/
1653 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
1655 pstring comment;
1656 int i = add_a_service(&sDefault, ipc_name);
1658 if (i < 0)
1659 return (False);
1661 slprintf(comment, sizeof(comment) - 1,
1662 "IPC Service (%s)", Globals.szServerString);
1664 string_set(&ServicePtrs[i]->szPath, tmpdir());
1665 string_set(&ServicePtrs[i]->szUsername, "");
1666 string_set(&ServicePtrs[i]->comment, comment);
1667 string_set(&ServicePtrs[i]->fstype, "IPC");
1668 ServicePtrs[i]->iMaxConnections = 0;
1669 ServicePtrs[i]->bAvailable = True;
1670 ServicePtrs[i]->bRead_only = True;
1671 ServicePtrs[i]->bGuest_only = False;
1672 ServicePtrs[i]->bGuest_ok = guest_ok;
1673 ServicePtrs[i]->bPrint_ok = False;
1674 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1676 lp_do_parameter(i, "ntvfs handler", "default");
1678 DEBUG(3, ("adding IPC service\n"));
1680 return (True);
1683 /***************************************************************************
1684 Add a new printer service, with defaults coming from service iFrom.
1685 ***************************************************************************/
1687 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
1689 const char *comment = "From Printcap";
1690 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
1692 if (i < 0)
1693 return (False);
1695 /* note that we do NOT default the availability flag to True - */
1696 /* we take it from the default service passed. This allows all */
1697 /* dynamic printers to be disabled by disabling the [printers] */
1698 /* entry (if/when the 'available' keyword is implemented!). */
1700 /* the printer name is set to the service name. */
1701 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
1702 string_set(&ServicePtrs[i]->comment, comment);
1703 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
1704 /* Printers cannot be read_only. */
1705 ServicePtrs[i]->bRead_only = False;
1706 /* No share modes on printer services. */
1707 ServicePtrs[i]->bShareModes = False;
1708 /* No oplocks on printer services. */
1709 ServicePtrs[i]->bOpLocks = False;
1710 /* Printer services must be printable. */
1711 ServicePtrs[i]->bPrint_ok = True;
1713 DEBUG(3, ("adding printer service %s\n", pszPrintername));
1715 update_server_announce_as_printserver();
1717 return (True);
1720 /***************************************************************************
1721 Map a parameter's string representation to something we can use.
1722 Returns False if the parameter string is not recognised, else TRUE.
1723 ***************************************************************************/
1725 static int map_parameter(const char *pszParmName)
1727 int iIndex;
1729 if (*pszParmName == '-')
1730 return (-1);
1732 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
1733 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
1734 return (iIndex);
1736 /* Warn only if it isn't parametric option */
1737 if (strchr(pszParmName, ':') == NULL)
1738 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
1739 /* We do return 'fail' for parametric options as well because they are
1740 stored in different storage
1742 return (-1);
1745 /***************************************************************************
1746 Set a boolean variable from the text value stored in the passed string.
1747 Returns True in success, False if the passed string does not correctly
1748 represent a boolean.
1749 ***************************************************************************/
1751 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
1753 BOOL bRetval;
1755 bRetval = True;
1756 if (strwicmp(pszParmValue, "yes") == 0 ||
1757 strwicmp(pszParmValue, "true") == 0 ||
1758 strwicmp(pszParmValue, "1") == 0)
1759 *pb = True;
1760 else if (strwicmp(pszParmValue, "no") == 0 ||
1761 strwicmp(pszParmValue, "False") == 0 ||
1762 strwicmp(pszParmValue, "0") == 0)
1763 *pb = False;
1764 else {
1765 DEBUG(0,
1766 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
1767 pszParmValue));
1768 bRetval = False;
1770 return (bRetval);
1773 /***************************************************************************
1774 Find a service by name. Otherwise works like get_service.
1775 ***************************************************************************/
1777 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
1779 int iService;
1781 for (iService = iNumServices - 1; iService >= 0; iService--)
1782 if (VALID(iService) &&
1783 strwicmp(ServicePtrs[iService]->szService, pszServiceName) == 0) {
1784 if (pserviceDest != NULL)
1785 copy_service(pserviceDest, ServicePtrs[iService], NULL);
1786 break;
1789 return (iService);
1792 /***************************************************************************
1793 Copy a service structure to another.
1794 If pcopymapDest is NULL then copy all fields
1795 ***************************************************************************/
1797 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
1799 int i;
1800 BOOL bcopyall = (pcopymapDest == NULL);
1801 struct param_opt *data, *pdata, *paramo;
1802 BOOL not_added;
1804 for (i = 0; parm_table[i].label; i++)
1805 if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
1806 (bcopyall || pcopymapDest[i])) {
1807 void *def_ptr = parm_table[i].ptr;
1808 void *src_ptr =
1809 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
1810 &sDefault);
1811 void *dest_ptr =
1812 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
1813 &sDefault);
1815 switch (parm_table[i].type) {
1816 case P_BOOL:
1817 case P_BOOLREV:
1818 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
1819 break;
1821 case P_INTEGER:
1822 case P_ENUM:
1823 case P_OCTAL:
1824 *(int *)dest_ptr = *(int *)src_ptr;
1825 break;
1827 case P_CHAR:
1828 *(char *)dest_ptr = *(char *)src_ptr;
1829 break;
1831 case P_STRING:
1832 string_set(dest_ptr,
1833 *(char **)src_ptr);
1834 break;
1836 case P_USTRING:
1837 string_set(dest_ptr,
1838 *(char **)src_ptr);
1839 strupper(*(char **)dest_ptr);
1840 break;
1841 case P_LIST:
1842 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
1843 break;
1844 default:
1845 break;
1849 if (bcopyall) {
1850 init_copymap(pserviceDest);
1851 if (pserviceSource->copymap)
1852 memcpy((void *)pserviceDest->copymap,
1853 (void *)pserviceSource->copymap,
1854 sizeof(BOOL) * NUMPARAMETERS);
1857 data = pserviceSource->param_opt;
1858 while (data) {
1859 not_added = True;
1860 pdata = pserviceDest->param_opt;
1861 /* Traverse destination */
1862 while (pdata) {
1863 /* If we already have same option, override it */
1864 if (strcmp(pdata->key, data->key) == 0) {
1865 string_free(&pdata->value);
1866 pdata->value = strdup(data->value);
1867 not_added = False;
1868 break;
1870 pdata = pdata->next;
1872 if (not_added) {
1873 paramo = smb_xmalloc_p(struct param_opt);
1874 paramo->key = strdup(data->key);
1875 paramo->value = strdup(data->value);
1876 DLIST_ADD(pserviceDest->param_opt, paramo);
1878 data = data->next;
1882 /***************************************************************************
1883 Check a service for consistency. Return False if the service is in any way
1884 incomplete or faulty, else True.
1885 ***************************************************************************/
1887 static BOOL service_ok(int iService)
1889 BOOL bRetval;
1891 bRetval = True;
1892 if (ServicePtrs[iService]->szService[0] == '\0') {
1893 DEBUG(0, ("The following message indicates an internal error:\n"));
1894 DEBUG(0, ("No service name in service entry.\n"));
1895 bRetval = False;
1898 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
1899 /* I can't see why you'd want a non-printable printer service... */
1900 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
1901 if (!ServicePtrs[iService]->bPrint_ok) {
1902 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
1903 ServicePtrs[iService]->szService));
1904 ServicePtrs[iService]->bPrint_ok = True;
1906 /* [printers] service must also be non-browsable. */
1907 if (ServicePtrs[iService]->bBrowseable)
1908 ServicePtrs[iService]->bBrowseable = False;
1911 /* If a service is flagged unavailable, log the fact at level 0. */
1912 if (!ServicePtrs[iService]->bAvailable)
1913 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
1914 ServicePtrs[iService]->szService));
1916 return (bRetval);
1919 static struct file_lists {
1920 struct file_lists *next;
1921 char *name;
1922 char *subfname;
1923 time_t modtime;
1924 } *file_lists = NULL;
1926 /*******************************************************************
1927 Keep a linked list of all config files so we know when one has changed
1928 it's date and needs to be reloaded.
1929 ********************************************************************/
1931 static void add_to_file_list(const char *fname, const char *subfname)
1933 struct file_lists *f = file_lists;
1935 while (f) {
1936 if (f->name && !strcmp(f->name, fname))
1937 break;
1938 f = f->next;
1941 if (!f) {
1942 f = malloc_p(struct file_lists);
1943 if (!f)
1944 return;
1945 f->next = file_lists;
1946 f->name = strdup(fname);
1947 if (!f->name) {
1948 SAFE_FREE(f);
1949 return;
1951 f->subfname = strdup(subfname);
1952 if (!f->subfname) {
1953 SAFE_FREE(f);
1954 return;
1956 file_lists = f;
1957 f->modtime = file_modtime(subfname);
1958 } else {
1959 time_t t = file_modtime(subfname);
1960 if (t)
1961 f->modtime = t;
1965 /*******************************************************************
1966 Check if a config file has changed date.
1967 ********************************************************************/
1969 BOOL lp_file_list_changed(void)
1971 struct file_lists *f = file_lists;
1972 DEBUG(6, ("lp_file_list_changed()\n"));
1974 while (f) {
1975 pstring n2;
1976 time_t mod_time;
1978 pstrcpy(n2, f->name);
1979 standard_sub_basic(n2,sizeof(n2));
1981 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
1982 f->name, n2, ctime(&f->modtime)));
1984 mod_time = file_modtime(n2);
1986 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
1987 DEBUGADD(6,
1988 ("file %s modified: %s\n", n2,
1989 ctime(&mod_time)));
1990 f->modtime = mod_time;
1991 SAFE_FREE(f->subfname);
1992 f->subfname = strdup(n2);
1993 return (True);
1995 f = f->next;
1997 return (False);
2000 /***************************************************************************
2001 Handle the include operation.
2002 ***************************************************************************/
2004 static BOOL handle_include(const char *pszParmValue, char **ptr)
2006 pstring fname;
2007 pstrcpy(fname, pszParmValue);
2009 standard_sub_basic(fname,sizeof(fname));
2011 add_to_file_list(pszParmValue, fname);
2013 string_set(ptr, fname);
2015 if (file_exist(fname, NULL))
2016 return (pm_process(fname, do_section, do_parameter));
2018 DEBUG(2, ("Can't find include file %s\n", fname));
2020 return (False);
2023 /***************************************************************************
2024 Handle the interpretation of the copy parameter.
2025 ***************************************************************************/
2027 static BOOL handle_copy(const char *pszParmValue, char **ptr)
2029 BOOL bRetval;
2030 int iTemp;
2031 service serviceTemp;
2033 string_set(ptr, pszParmValue);
2035 init_service(&serviceTemp);
2037 bRetval = False;
2039 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
2041 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
2042 if (iTemp == iServiceIndex) {
2043 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
2044 } else {
2045 copy_service(ServicePtrs[iServiceIndex],
2046 &serviceTemp,
2047 ServicePtrs[iServiceIndex]->copymap);
2048 bRetval = True;
2050 } else {
2051 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
2052 bRetval = False;
2055 free_service(&serviceTemp);
2056 return (bRetval);
2059 /***************************************************************************
2060 Handle winbind/non unix account uid and gid allocation parameters. The format of these
2061 parameters is:
2063 [global]
2065 winbind uid = 1000-1999
2066 winbind gid = 700-899
2068 We only do simple parsing checks here. The strings are parsed into useful
2069 structures in the winbind daemon code.
2071 ***************************************************************************/
2073 /* Some lp_ routines to return winbind [ug]id information */
2075 static uid_t winbind_uid_low, winbind_uid_high;
2076 static gid_t winbind_gid_low, winbind_gid_high;
2077 static uint32_t non_unix_account_low, non_unix_account_high;
2079 BOOL lp_winbind_uid(uid_t *low, uid_t *high)
2081 if (winbind_uid_low == 0 || winbind_uid_high == 0)
2082 return False;
2084 if (low)
2085 *low = winbind_uid_low;
2087 if (high)
2088 *high = winbind_uid_high;
2090 return True;
2093 BOOL lp_winbind_gid(gid_t *low, gid_t *high)
2095 if (winbind_gid_low == 0 || winbind_gid_high == 0)
2096 return False;
2098 if (low)
2099 *low = winbind_gid_low;
2101 if (high)
2102 *high = winbind_gid_high;
2104 return True;
2107 BOOL lp_non_unix_account_range(uint32_t *low, uint32_t *high)
2109 if (non_unix_account_low == 0 || non_unix_account_high == 0)
2110 return False;
2112 if (low)
2113 *low = non_unix_account_low;
2115 if (high)
2116 *high = non_unix_account_high;
2118 return True;
2121 /* Do some simple checks on "winbind [ug]id" parameter values */
2123 static BOOL handle_winbind_uid(const char *pszParmValue, char **ptr)
2125 uint32_t low, high;
2127 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2128 return False;
2130 /* Parse OK */
2132 string_set(ptr, pszParmValue);
2134 winbind_uid_low = low;
2135 winbind_uid_high = high;
2137 return True;
2140 static BOOL handle_winbind_gid(const char *pszParmValue, char **ptr)
2142 uint32_t low, high;
2144 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2145 return False;
2147 /* Parse OK */
2149 string_set(ptr, pszParmValue);
2151 winbind_gid_low = low;
2152 winbind_gid_high = high;
2154 return True;
2157 /***************************************************************************
2158 Do some simple checks on "non unix account range" parameter values.
2159 ***************************************************************************/
2161 static BOOL handle_non_unix_account_range(const char *pszParmValue, char **ptr)
2163 uint32_t low, high;
2165 if (sscanf(pszParmValue, "%u-%u", &low, &high) != 2 || high < low)
2166 return False;
2168 /* Parse OK */
2170 string_set(ptr, pszParmValue);
2172 non_unix_account_low = low;
2173 non_unix_account_high = high;
2175 return True;
2179 /***************************************************************************
2180 Initialise a copymap.
2181 ***************************************************************************/
2183 static void init_copymap(service * pservice)
2185 int i;
2186 SAFE_FREE(pservice->copymap);
2187 pservice->copymap = malloc_array_p(BOOL, NUMPARAMETERS);
2188 if (!pservice->copymap)
2189 DEBUG(0,
2190 ("Couldn't allocate copymap!! (size %d)\n",
2191 (int)NUMPARAMETERS));
2192 else
2193 for (i = 0; i < NUMPARAMETERS; i++)
2194 pservice->copymap[i] = True;
2197 /***************************************************************************
2198 Return the local pointer to a parameter given the service number and the
2199 pointer into the default structure.
2200 ***************************************************************************/
2202 void *lp_local_ptr(int snum, void *ptr)
2204 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
2208 /***************************************************************************
2209 Process a parametric option
2210 ***************************************************************************/
2211 static BOOL lp_do_parameter_parametric(int snum, const char *pszParmName, const char *pszParmValue, int flags)
2213 struct param_opt *paramo, *data;
2214 char *name;
2216 while (isspace(*pszParmName)) {
2217 pszParmName++;
2220 name = strdup(pszParmName);
2221 if (!name) return False;
2223 strlower(name);
2225 if (snum < 0) {
2226 data = Globals.param_opt;
2227 } else {
2228 data = ServicePtrs[snum]->param_opt;
2231 /* Traverse destination */
2232 for (paramo=data; paramo; paramo=paramo->next) {
2233 /* If we already have the option set, override it unless
2234 it was a command line option and the new one isn't */
2235 if (strcmp(paramo->key, name) == 0) {
2236 if ((paramo->flags & FLAG_CMDLINE) &&
2237 !(flags & FLAG_CMDLINE)) {
2238 return True;
2241 free(paramo->value);
2242 paramo->value = strdup(pszParmValue);
2243 paramo->flags = flags;
2244 free(name);
2245 return True;
2249 paramo = smb_xmalloc_p(struct param_opt);
2250 paramo->key = strdup(name);
2251 paramo->value = strdup(pszParmValue);
2252 paramo->flags = flags;
2253 if (snum < 0) {
2254 DLIST_ADD(Globals.param_opt, paramo);
2255 } else {
2256 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
2259 free(name);
2261 return True;
2264 /***************************************************************************
2265 Process a parameter for a particular service number. If snum < 0
2266 then assume we are in the globals.
2267 ***************************************************************************/
2268 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
2270 int parmnum, i;
2271 void *parm_ptr = NULL; /* where we are going to store the result */
2272 void *def_ptr = NULL;
2274 parmnum = map_parameter(pszParmName);
2276 if (parmnum < 0) {
2277 if (strchr(pszParmName, ':')) {
2278 return lp_do_parameter_parametric(snum, pszParmName, pszParmValue, 0);
2280 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
2281 return (True);
2284 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
2285 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
2286 pszParmName));
2289 /* if the flag has been set on the command line, then don't allow override,
2290 but don't report an error */
2291 if (parm_table[parmnum].flags & FLAG_CMDLINE) {
2292 return True;
2295 def_ptr = parm_table[parmnum].ptr;
2297 /* we might point at a service, the default service or a global */
2298 if (snum < 0) {
2299 parm_ptr = def_ptr;
2300 } else {
2301 if (parm_table[parmnum].class == P_GLOBAL) {
2302 DEBUG(0,
2303 ("Global parameter %s found in service section!\n",
2304 pszParmName));
2305 return (True);
2307 parm_ptr =
2308 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
2309 &sDefault);
2312 if (snum >= 0) {
2313 if (!ServicePtrs[snum]->copymap)
2314 init_copymap(ServicePtrs[snum]);
2316 /* this handles the aliases - set the copymap for other entries with
2317 the same data pointer */
2318 for (i = 0; parm_table[i].label; i++)
2319 if (parm_table[i].ptr == parm_table[parmnum].ptr)
2320 ServicePtrs[snum]->copymap[i] = False;
2323 /* if it is a special case then go ahead */
2324 if (parm_table[parmnum].special) {
2325 parm_table[parmnum].special(pszParmValue, (char **)parm_ptr);
2326 return (True);
2329 /* now switch on the type of variable it is */
2330 switch (parm_table[parmnum].type)
2332 case P_BOOL:
2333 set_boolean(parm_ptr, pszParmValue);
2334 break;
2336 case P_BOOLREV:
2337 set_boolean(parm_ptr, pszParmValue);
2338 *(BOOL *)parm_ptr = !*(BOOL *)parm_ptr;
2339 break;
2341 case P_INTEGER:
2342 *(int *)parm_ptr = atoi(pszParmValue);
2343 break;
2345 case P_CHAR:
2346 *(char *)parm_ptr = *pszParmValue;
2347 break;
2349 case P_OCTAL:
2350 sscanf(pszParmValue, "%o", (int *)parm_ptr);
2351 break;
2353 case P_LIST:
2354 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
2355 break;
2357 case P_STRING:
2358 string_set(parm_ptr, pszParmValue);
2359 break;
2361 case P_USTRING:
2362 string_set(parm_ptr, pszParmValue);
2363 strupper(*(char **)parm_ptr);
2364 break;
2366 case P_ENUM:
2367 for (i = 0; parm_table[parmnum].enum_list[i].name; i++) {
2368 if (strequal
2369 (pszParmValue,
2370 parm_table[parmnum].enum_list[i].name)) {
2371 *(int *)parm_ptr =
2372 parm_table[parmnum].
2373 enum_list[i].value;
2374 break;
2377 if (!parm_table[parmnum].enum_list[i].name) {
2378 DEBUG(0,("Unknown enumerated value '%s' for '%s'\n",
2379 pszParmValue, pszParmName));
2380 return False;
2382 break;
2383 case P_SEP:
2384 break;
2387 return (True);
2390 /***************************************************************************
2391 Process a parameter.
2392 ***************************************************************************/
2394 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
2396 if (!bInGlobalSection && bGlobalOnly)
2397 return (True);
2399 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
2400 pszParmName, pszParmValue));
2404 variable argument do parameter
2406 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
2408 static BOOL do_parameter_var(const char *pszParmName, const char *fmt, ...)
2410 char *s;
2411 BOOL ret;
2412 va_list ap;
2414 va_start(ap, fmt);
2415 s = talloc_vasprintf(NULL, fmt, ap);
2416 va_end(ap);
2417 ret = do_parameter(pszParmName, s);
2418 talloc_free(s);
2419 return ret;
2424 set a parameter from the commandline - this is called from command line parameter
2425 parsing code. It sets the parameter then marks the parameter as unable to be modified
2426 by smb.conf processing
2428 BOOL lp_set_cmdline(const char *pszParmName, const char *pszParmValue)
2430 int parmnum = map_parameter(pszParmName);
2431 int i;
2433 while (isspace(*pszParmValue)) pszParmValue++;
2436 if (parmnum < 0 && strchr(pszParmName, ':')) {
2437 /* set a parametric option */
2438 return lp_do_parameter_parametric(-1, pszParmName, pszParmValue, FLAG_CMDLINE);
2441 if (parmnum < 0) {
2442 DEBUG(0,("Unknown option '%s'\n", pszParmName));
2443 return False;
2446 /* reset the CMDLINE flag in case this has been called before */
2447 parm_table[parmnum].flags &= ~FLAG_CMDLINE;
2449 if (!lp_do_parameter(-2, pszParmName, pszParmValue)) {
2450 return False;
2453 parm_table[parmnum].flags |= FLAG_CMDLINE;
2455 /* we have to also set FLAG_CMDLINE on aliases */
2456 for (i=parmnum-1;i>=0 && parm_table[i].ptr == parm_table[parmnum].ptr;i--) {
2457 parm_table[i].flags |= FLAG_CMDLINE;
2459 for (i=parmnum+1;i<NUMPARAMETERS && parm_table[i].ptr == parm_table[parmnum].ptr;i++) {
2460 parm_table[i].flags |= FLAG_CMDLINE;
2463 return True;
2467 set a option from the commandline in 'a=b' format. Use to support --option
2469 BOOL lp_set_option(const char *option)
2471 char *p, *s;
2472 BOOL ret;
2474 s = strdup(option);
2475 if (!s) {
2476 return False;
2479 p = strchr(s, '=');
2480 if (!p) {
2481 free(s);
2482 return False;
2485 *p = 0;
2487 ret = lp_set_cmdline(s, p+1);
2488 free(s);
2489 return ret;
2493 /***************************************************************************
2494 Print a parameter of the specified type.
2495 ***************************************************************************/
2497 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
2499 int i;
2500 switch (p->type)
2502 case P_ENUM:
2503 for (i = 0; p->enum_list[i].name; i++) {
2504 if (*(int *)ptr == p->enum_list[i].value) {
2505 fprintf(f, "%s",
2506 p->enum_list[i].name);
2507 break;
2510 break;
2512 case P_BOOL:
2513 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
2514 break;
2516 case P_BOOLREV:
2517 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
2518 break;
2520 case P_INTEGER:
2521 fprintf(f, "%d", *(int *)ptr);
2522 break;
2524 case P_CHAR:
2525 fprintf(f, "%c", *(char *)ptr);
2526 break;
2528 case P_OCTAL:
2529 if (*(int *)ptr == -1) {
2530 fprintf(f, "-1");
2531 } else {
2532 fprintf(f, "0%o", *(int *)ptr);
2534 break;
2536 case P_LIST:
2537 if ((char ***)ptr && *(char ***)ptr) {
2538 char **list = *(char ***)ptr;
2540 for (; *list; list++)
2541 fprintf(f, "%s%s", *list,
2542 ((*(list+1))?", ":""));
2544 break;
2546 case P_STRING:
2547 case P_USTRING:
2548 if (*(char **)ptr) {
2549 fprintf(f, "%s", *(char **)ptr);
2551 break;
2552 case P_SEP:
2553 break;
2557 /***************************************************************************
2558 Check if two parameters are equal.
2559 ***************************************************************************/
2561 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
2563 switch (type) {
2564 case P_BOOL:
2565 case P_BOOLREV:
2566 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
2568 case P_INTEGER:
2569 case P_ENUM:
2570 case P_OCTAL:
2571 return (*((int *)ptr1) == *((int *)ptr2));
2573 case P_CHAR:
2574 return (*((char *)ptr1) == *((char *)ptr2));
2576 case P_LIST:
2577 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
2579 case P_STRING:
2580 case P_USTRING:
2582 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
2583 if (p1 && !*p1)
2584 p1 = NULL;
2585 if (p2 && !*p2)
2586 p2 = NULL;
2587 return (p1 == p2 || strequal(p1, p2));
2589 case P_SEP:
2590 break;
2592 return (False);
2595 /***************************************************************************
2596 Process a new section (service). At this stage all sections are services.
2597 Later we'll have special sections that permit server parameters to be set.
2598 Returns True on success, False on failure.
2599 ***************************************************************************/
2601 static BOOL do_section(const char *pszSectionName)
2603 BOOL bRetval;
2604 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
2605 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
2606 bRetval = False;
2608 /* if we've just struck a global section, note the fact. */
2609 bInGlobalSection = isglobal;
2611 /* check for multiple global sections */
2612 if (bInGlobalSection) {
2613 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
2614 return (True);
2617 if (!bInGlobalSection && bGlobalOnly)
2618 return (True);
2620 /* if we have a current service, tidy it up before moving on */
2621 bRetval = True;
2623 if (iServiceIndex >= 0)
2624 bRetval = service_ok(iServiceIndex);
2626 /* if all is still well, move to the next record in the services array */
2627 if (bRetval) {
2628 /* We put this here to avoid an odd message order if messages are */
2629 /* issued by the post-processing of a previous section. */
2630 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
2632 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
2633 < 0) {
2634 DEBUG(0, ("Failed to add a new service\n"));
2635 return (False);
2639 return (bRetval);
2643 /***************************************************************************
2644 Determine if a partcular base parameter is currentl set to the default value.
2645 ***************************************************************************/
2647 static BOOL is_default(int i)
2649 if (!defaults_saved)
2650 return False;
2651 switch (parm_table[i].type) {
2652 case P_LIST:
2653 return str_list_compare (parm_table[i].def.lvalue,
2654 *(char ***)parm_table[i].ptr);
2655 case P_STRING:
2656 case P_USTRING:
2657 return strequal(parm_table[i].def.svalue,
2658 *(char **)parm_table[i].ptr);
2659 case P_BOOL:
2660 case P_BOOLREV:
2661 return parm_table[i].def.bvalue ==
2662 *(BOOL *)parm_table[i].ptr;
2663 case P_CHAR:
2664 return parm_table[i].def.cvalue ==
2665 *(char *)parm_table[i].ptr;
2666 case P_INTEGER:
2667 case P_OCTAL:
2668 case P_ENUM:
2669 return parm_table[i].def.ivalue ==
2670 *(int *)parm_table[i].ptr;
2671 case P_SEP:
2672 break;
2674 return False;
2677 /***************************************************************************
2678 Display the contents of the global structure.
2679 ***************************************************************************/
2681 static void dump_globals(FILE *f)
2683 int i;
2684 struct param_opt *data;
2686 fprintf(f, "# Global parameters\n[global]\n");
2688 for (i = 0; parm_table[i].label; i++)
2689 if (parm_table[i].class == P_GLOBAL &&
2690 parm_table[i].ptr &&
2691 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2692 if (defaults_saved && is_default(i))
2693 continue;
2694 fprintf(f, "\t%s = ", parm_table[i].label);
2695 print_parameter(&parm_table[i], parm_table[i].ptr, f);
2696 fprintf(f, "\n");
2698 if (Globals.param_opt != NULL) {
2699 data = Globals.param_opt;
2700 while(data) {
2701 fprintf(f, "\t%s = %s\n", data->key, data->value);
2702 data = data->next;
2708 /***************************************************************************
2709 Display the contents of a single services record.
2710 ***************************************************************************/
2712 static void dump_a_service(service * pService, FILE * f)
2714 int i;
2715 struct param_opt *data;
2717 if (pService != &sDefault)
2718 fprintf(f, "\n[%s]\n", pService->szService);
2720 for (i = 0; parm_table[i].label; i++)
2721 if (parm_table[i].class == P_LOCAL &&
2722 parm_table[i].ptr &&
2723 (*parm_table[i].label != '-') &&
2724 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
2725 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
2727 if (pService == &sDefault) {
2728 if (defaults_saved && is_default(i))
2729 continue;
2730 } else {
2731 if (equal_parameter(parm_table[i].type,
2732 ((char *)pService) +
2733 pdiff,
2734 ((char *)&sDefault) +
2735 pdiff))
2736 continue;
2739 fprintf(f, "\t%s = ", parm_table[i].label);
2740 print_parameter(&parm_table[i],
2741 ((char *)pService) + pdiff, f);
2742 fprintf(f, "\n");
2744 if (pService->param_opt != NULL) {
2745 data = pService->param_opt;
2746 while(data) {
2747 fprintf(f, "\t%s = %s\n", data->key, data->value);
2748 data = data->next;
2754 /***************************************************************************
2755 Return info about the next service in a service. snum==-1 gives the globals.
2756 Return NULL when out of parameters.
2757 ***************************************************************************/
2759 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
2761 if (snum == -1) {
2762 /* do the globals */
2763 for (; parm_table[*i].label; (*i)++) {
2764 if (parm_table[*i].class == P_SEPARATOR)
2765 return &parm_table[(*i)++];
2767 if (!parm_table[*i].ptr
2768 || (*parm_table[*i].label == '-'))
2769 continue;
2771 if ((*i) > 0
2772 && (parm_table[*i].ptr ==
2773 parm_table[(*i) - 1].ptr))
2774 continue;
2776 return &parm_table[(*i)++];
2778 } else {
2779 service *pService = ServicePtrs[snum];
2781 for (; parm_table[*i].label; (*i)++) {
2782 if (parm_table[*i].class == P_SEPARATOR)
2783 return &parm_table[(*i)++];
2785 if (parm_table[*i].class == P_LOCAL &&
2786 parm_table[*i].ptr &&
2787 (*parm_table[*i].label != '-') &&
2788 ((*i) == 0 ||
2789 (parm_table[*i].ptr !=
2790 parm_table[(*i) - 1].ptr)))
2792 int pdiff =
2793 PTR_DIFF(parm_table[*i].ptr,
2794 &sDefault);
2796 if (allparameters ||
2797 !equal_parameter(parm_table[*i].type,
2798 ((char *)pService) +
2799 pdiff,
2800 ((char *)&sDefault) +
2801 pdiff))
2803 return &parm_table[(*i)++];
2809 return NULL;
2813 /***************************************************************************
2814 Return TRUE if the passed service number is within range.
2815 ***************************************************************************/
2817 BOOL lp_snum_ok(int iService)
2819 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
2822 /***************************************************************************
2823 Auto-load some home services.
2824 ***************************************************************************/
2826 static void lp_add_auto_services(const char *str)
2828 return;
2831 /***************************************************************************
2832 Auto-load one printer.
2833 ***************************************************************************/
2835 void lp_add_one_printer(char *name, char *comment)
2837 int printers = lp_servicenumber(PRINTERS_NAME);
2838 int i;
2840 if (lp_servicenumber(name) < 0) {
2841 lp_add_printer(name, printers);
2842 if ((i = lp_servicenumber(name)) >= 0) {
2843 string_set(&ServicePtrs[i]->comment, comment);
2844 ServicePtrs[i]->autoloaded = True;
2849 /***************************************************************************
2850 Announce ourselves as a print server.
2851 ***************************************************************************/
2853 void update_server_announce_as_printserver(void)
2855 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
2858 /***************************************************************************
2859 Have we loaded a services file yet?
2860 ***************************************************************************/
2862 BOOL lp_loaded(void)
2864 return (bLoaded);
2867 /***************************************************************************
2868 Unload unused services.
2869 ***************************************************************************/
2871 void lp_killunused(struct smbsrv_connection *smb, BOOL (*snumused) (struct smbsrv_connection *, int))
2873 int i;
2874 for (i = 0; i < iNumServices; i++) {
2875 if (!VALID(i))
2876 continue;
2878 if (!snumused || !snumused(smb, i)) {
2879 ServicePtrs[i]->valid = False;
2880 free_service(ServicePtrs[i]);
2885 /***************************************************************************
2886 Unload a service.
2887 ***************************************************************************/
2889 void lp_killservice(int iServiceIn)
2891 if (VALID(iServiceIn)) {
2892 ServicePtrs[iServiceIn]->valid = False;
2893 free_service(ServicePtrs[iServiceIn]);
2897 /***************************************************************************
2898 Save the curent values of all global and sDefault parameters into the
2899 defaults union. This allows swat and testparm to show only the
2900 changed (ie. non-default) parameters.
2901 ***************************************************************************/
2903 static void lp_save_defaults(void)
2905 int i;
2906 for (i = 0; parm_table[i].label; i++) {
2907 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
2908 continue;
2909 switch (parm_table[i].type) {
2910 case P_LIST:
2911 str_list_copy(&(parm_table[i].def.lvalue),
2912 *(const char ***)parm_table[i].ptr);
2913 break;
2914 case P_STRING:
2915 case P_USTRING:
2916 if (parm_table[i].ptr) {
2917 parm_table[i].def.svalue = strdup(*(char **)parm_table[i].ptr);
2918 } else {
2919 parm_table[i].def.svalue = NULL;
2921 break;
2922 case P_BOOL:
2923 case P_BOOLREV:
2924 parm_table[i].def.bvalue =
2925 *(BOOL *)parm_table[i].ptr;
2926 break;
2927 case P_CHAR:
2928 parm_table[i].def.cvalue =
2929 *(char *)parm_table[i].ptr;
2930 break;
2931 case P_INTEGER:
2932 case P_OCTAL:
2933 case P_ENUM:
2934 parm_table[i].def.ivalue =
2935 *(int *)parm_table[i].ptr;
2936 break;
2937 case P_SEP:
2938 break;
2941 defaults_saved = True;
2944 /*******************************************************************
2945 Set the server type we will announce as via nmbd.
2946 ********************************************************************/
2948 static void set_server_role(void)
2950 server_role = ROLE_STANDALONE;
2952 switch (lp_security()) {
2953 case SEC_SHARE:
2954 if (lp_domain_logons())
2955 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
2956 break;
2957 case SEC_SERVER:
2958 case SEC_DOMAIN:
2959 case SEC_ADS:
2960 if (lp_domain_logons()) {
2961 server_role = ROLE_DOMAIN_PDC;
2962 break;
2964 server_role = ROLE_DOMAIN_MEMBER;
2965 break;
2966 case SEC_USER:
2967 if (lp_domain_logons()) {
2969 if (Globals.bDomainMaster) /* auto or yes */
2970 server_role = ROLE_DOMAIN_PDC;
2971 else
2972 server_role = ROLE_DOMAIN_BDC;
2974 break;
2975 default:
2976 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
2977 break;
2980 DEBUG(10, ("set_server_role: role = "));
2982 switch(server_role) {
2983 case ROLE_STANDALONE:
2984 DEBUGADD(10, ("ROLE_STANDALONE\n"));
2985 break;
2986 case ROLE_DOMAIN_MEMBER:
2987 DEBUGADD(10, ("ROLE_DOMAIN_MEMBER\n"));
2988 break;
2989 case ROLE_DOMAIN_BDC:
2990 DEBUGADD(10, ("ROLE_DOMAIN_BDC\n"));
2991 break;
2992 case ROLE_DOMAIN_PDC:
2993 DEBUGADD(10, ("ROLE_DOMAIN_PDC\n"));
2994 break;
2998 /***************************************************************************
2999 Load the services array from the services file. Return True on success,
3000 False on failure.
3001 ***************************************************************************/
3003 BOOL lp_load(const char *pszFname, BOOL global_only, BOOL save_defaults,
3004 BOOL add_ipc)
3006 pstring n2;
3007 BOOL bRetval;
3008 struct param_opt *data;
3010 pstrcpy(n2, pszFname);
3011 standard_sub_basic(n2,sizeof(n2));
3013 add_to_file_list(pszFname, n2);
3015 bRetval = False;
3017 DEBUG(2, ("lp_load: refreshing parameters from %s\n", pszFname));
3019 bInGlobalSection = True;
3020 bGlobalOnly = global_only;
3022 init_globals();
3024 if (save_defaults)
3026 lp_save_defaults();
3029 if (Globals.param_opt != NULL) {
3030 struct param_opt *next;
3031 for (data=Globals.param_opt; data; data=next) {
3032 next = data->next;
3033 if (data->flags & FLAG_CMDLINE) continue;
3034 free(data->key);
3035 free(data->value);
3036 DLIST_REMOVE(Globals.param_opt, data);
3037 free(data);
3041 /* We get sections first, so have to start 'behind' to make up */
3042 iServiceIndex = -1;
3043 bRetval = pm_process(n2, do_section, do_parameter);
3045 /* finish up the last section */
3046 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
3047 if (bRetval)
3048 if (iServiceIndex >= 0)
3049 bRetval = service_ok(iServiceIndex);
3051 lp_add_auto_services(lp_auto_services());
3053 if (add_ipc) {
3054 /* When 'restrict anonymous = 2' guest connections to ipc$
3055 are denied */
3056 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
3057 lp_add_ipc("ADMIN$", False);
3060 set_server_role();
3061 set_default_server_announce_type();
3063 bLoaded = True;
3065 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
3066 /* if bWINSsupport is true and we are in the client */
3067 if (in_client && Globals.bWINSsupport) {
3068 lp_do_parameter(-1, "wins server", "127.0.0.1");
3071 lp_do_parameter(-1, "gensec:krb5", "False");
3072 lp_do_parameter(-1, "gensec:ms_krb5", "False");
3074 init_iconv();
3076 return (bRetval);
3079 /***************************************************************************
3080 Reset the max number of services.
3081 ***************************************************************************/
3083 void lp_resetnumservices(void)
3085 iNumServices = 0;
3088 /***************************************************************************
3089 Return the max number of services.
3090 ***************************************************************************/
3092 int lp_numservices(void)
3094 return (iNumServices);
3097 /***************************************************************************
3098 Display the contents of the services array in human-readable form.
3099 ***************************************************************************/
3101 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
3103 int iService;
3105 if (show_defaults)
3106 defaults_saved = False;
3108 dump_globals(f);
3110 dump_a_service(&sDefault, f);
3112 for (iService = 0; iService < maxtoprint; iService++)
3113 lp_dump_one(f, show_defaults, iService);
3116 /***************************************************************************
3117 Display the contents of one service in human-readable form.
3118 ***************************************************************************/
3120 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
3122 if (VALID(snum)) {
3123 if (ServicePtrs[snum]->szService[0] == '\0')
3124 return;
3125 dump_a_service(ServicePtrs[snum], f);
3129 /***************************************************************************
3130 Return the number of the service with the given name, or -1 if it doesn't
3131 exist. Note that this is a DIFFERENT ANIMAL from the internal function
3132 getservicebyname()! This works ONLY if all services have been loaded, and
3133 does not copy the found service.
3134 ***************************************************************************/
3136 int lp_servicenumber(const char *pszServiceName)
3138 int iService;
3139 fstring serviceName;
3142 for (iService = iNumServices - 1; iService >= 0; iService--) {
3143 if (VALID(iService) && ServicePtrs[iService]->szService) {
3145 * The substitution here is used to support %U is
3146 * service names
3148 fstrcpy(serviceName, ServicePtrs[iService]->szService);
3149 standard_sub_basic(serviceName,sizeof(serviceName));
3150 if (strequal(serviceName, pszServiceName))
3151 break;
3155 if (iService < 0)
3156 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
3158 return (iService);
3161 /*******************************************************************
3162 A useful volume label function.
3163 ********************************************************************/
3164 const char *volume_label(int snum)
3166 const char *ret = lp_volume(snum);
3167 if (!*ret)
3168 return lp_servicename(snum);
3169 return (ret);
3173 /*******************************************************************
3174 Set the server type we will announce as via nmbd.
3175 ********************************************************************/
3177 static void set_default_server_announce_type(void)
3179 default_server_announce = 0;
3180 default_server_announce |= SV_TYPE_WORKSTATION;
3181 default_server_announce |= SV_TYPE_SERVER;
3182 default_server_announce |= SV_TYPE_SERVER_UNIX;
3184 switch (lp_announce_as()) {
3185 case ANNOUNCE_AS_NT_SERVER:
3186 default_server_announce |= SV_TYPE_SERVER_NT;
3187 /* fall through... */
3188 case ANNOUNCE_AS_NT_WORKSTATION:
3189 default_server_announce |= SV_TYPE_NT;
3190 break;
3191 case ANNOUNCE_AS_WIN95:
3192 default_server_announce |= SV_TYPE_WIN95_PLUS;
3193 break;
3194 case ANNOUNCE_AS_WFW:
3195 default_server_announce |= SV_TYPE_WFW;
3196 break;
3197 default:
3198 break;
3201 switch (lp_server_role()) {
3202 case ROLE_DOMAIN_MEMBER:
3203 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
3204 break;
3205 case ROLE_DOMAIN_PDC:
3206 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
3207 break;
3208 case ROLE_DOMAIN_BDC:
3209 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
3210 break;
3211 case ROLE_STANDALONE:
3212 default:
3213 break;
3215 if (lp_time_server())
3216 default_server_announce |= SV_TYPE_TIME_SOURCE;
3218 if (lp_host_msdfs())
3219 default_server_announce |= SV_TYPE_DFS_SERVER;
3222 /***********************************************************
3223 returns role of Samba server
3224 ************************************************************/
3226 int lp_server_role(void)
3228 return server_role;
3231 /***********************************************************
3232 If we are PDC then prefer us as DMB
3233 ************************************************************/
3235 BOOL lp_domain_master(void)
3237 if (Globals.bDomainMaster == Auto)
3238 return (lp_server_role() == ROLE_DOMAIN_PDC);
3240 return Globals.bDomainMaster;
3243 /***********************************************************
3244 If we are DMB then prefer us as LMB
3245 ************************************************************/
3247 BOOL lp_preferred_master(void)
3249 if (Globals.bPreferredMaster == Auto)
3250 return (lp_local_master() && lp_domain_master());
3252 return Globals.bPreferredMaster;
3255 /*******************************************************************
3256 Remove a service.
3257 ********************************************************************/
3259 void lp_remove_service(int snum)
3261 ServicePtrs[snum]->valid = False;
3264 /*******************************************************************
3265 Copy a service.
3266 ********************************************************************/
3268 void lp_copy_service(int snum, const char *new_name)
3270 const char *oldname = lp_servicename(snum);
3271 do_section(new_name);
3272 if (snum >= 0) {
3273 snum = lp_servicenumber(new_name);
3274 if (snum >= 0)
3275 lp_do_parameter(snum, "copy", oldname);
3280 /*******************************************************************
3281 Get the default server type we will announce as via nmbd.
3282 ********************************************************************/
3283 int lp_default_server_announce(void)
3285 return default_server_announce;
3288 const char *lp_printername(int snum)
3290 const char *ret = _lp_printername(snum);
3291 if (ret == NULL || (ret != NULL && *ret == '\0'))
3292 ret = lp_const_servicename(snum);
3294 return ret;
3298 /*******************************************************************
3299 Return the max print jobs per queue.
3300 ********************************************************************/
3302 int lp_maxprintjobs(int snum)
3304 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
3305 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
3306 maxjobs = PRINT_MAX_JOBID - 1;
3308 return maxjobs;