source: branches/samba-3.0/source/param/loadparm.c@ 124

Last change on this file since 124 was 124, checked in by Paul Smedley, 17 years ago

Update source to 3.0.28a

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