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

Last change on this file since 336 was 336, checked in by Herwig Bauernfeind, 16 years ago

Update 3.0 to 3.0.37 (unsupported security update)

File size: 197.2 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;
190char **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 },
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#if defined (__OS2__)
1464 /* search the system codepage and set OS2CodePageStr */
1465 unsigned long _System DosQueryCp (unsigned long ulLength, unsigned long *pCodePageList, unsigned long *pDataLength);
1466 pstring OS2CodePageStr;
1467 unsigned long OS2CodePage[3];
1468 unsigned long OS2CodePageLen;
1469 if ( DosQueryCp( sizeof(OS2CodePage), OS2CodePage, &OS2CodePageLen ) )
1470 slprintf(OS2CodePageStr, sizeof(OS2CodePageStr) -1, "SYSTEM");
1471 else
1472 slprintf(OS2CodePageStr, sizeof(OS2CodePageStr) -1, "IBM-%u", OS2CodePage[0]);
1473#endif
1474
1475#ifndef __OS2__
1476 /* using UTF8 by default allows us to support all chars */
1477 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1478#else
1479 /* On OS/2, using UTF8 causes problems with display of foreign
1480 characters - default to system codepage */
1481 string_set(&Globals.unix_charset, OS2CodePageStr);
1482#endif
1483
1484#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1485 /* If the system supports nl_langinfo(), try to grab the value
1486 from the user's locale */
1487#ifndef __OS2__
1488 /* this does somehow not work on OS/2 */
1489 string_set(&Globals.display_charset, "LOCALE");
1490#else
1491 /* On OS/2, using UTF8 causes problems with display of foreign
1492 characters - default to system codepage */
1493 string_set(&Globals.display_charset, OS2CodePageStr);
1494#endif
1495
1496#else
1497 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1498#endif
1499
1500#ifndef __OS2__
1501 /* Use codepage 850 as a default for the dos character set */
1502 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1503#else
1504 /* On OS/2, using UTF8 causes problems with display of foreign
1505 characters - default to system codepage */
1506 string_set(&Globals.dos_charset, OS2CodePageStr);
1507#endif
1508 /*
1509 * Allow the default PASSWD_CHAT to be overridden in local.h.
1510 */
1511 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1512
1513 set_global_myname(myhostname());
1514 string_set(&Globals.szNetbiosName,global_myname());
1515
1516 set_global_myworkgroup(WORKGROUP);
1517 string_set(&Globals.szWorkgroup, lp_workgroup());
1518
1519 string_set(&Globals.szPasswdProgram, "");
1520 string_set(&Globals.szPidDir, dyn_PIDDIR);
1521 string_set(&Globals.szLockDir, dyn_LOCKDIR);
1522 string_set(&Globals.szSocketAddress, "0.0.0.0");
1523 pstrcpy(s, "Samba ");
1524 pstrcat(s, SAMBA_VERSION_STRING);
1525 string_set(&Globals.szServerString, s);
1526 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1527 DEFAULT_MINOR_VERSION);
1528 string_set(&Globals.szAnnounceVersion, s);
1529#ifdef DEVELOPER
1530 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1531#endif
1532
1533 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1534
1535 string_set(&Globals.szLogonDrive, "");
1536 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1537 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1538 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1539
1540 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1541 string_set(&Globals.szPasswordServer, "*");
1542
1543 Globals.AlgorithmicRidBase = BASE_RID;
1544
1545 Globals.bLoadPrinters = True;
1546 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
1547
1548 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1549 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1550 Globals.max_xmit = 0x4104;
1551 Globals.max_mux = 50; /* This is *needed* for profile support. */
1552 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
1553 Globals.bDisableSpoolss = False;
1554 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1555 Globals.pwordlevel = 0;
1556 Globals.unamelevel = 0;
1557 Globals.deadtime = 0;
1558 Globals.bLargeReadwrite = True;
1559 Globals.max_log_size = 5000;
1560 Globals.max_open_files = MAX_OPEN_FILES;
1561 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1562 Globals.maxprotocol = PROTOCOL_NT1;
1563 Globals.minprotocol = PROTOCOL_CORE;
1564 Globals.security = SEC_USER;
1565 Globals.paranoid_server_security = True;
1566 Globals.bEncryptPasswords = True;
1567 Globals.bUpdateEncrypt = False;
1568 Globals.clientSchannel = Auto;
1569 Globals.serverSchannel = Auto;
1570 Globals.bReadRaw = True;
1571 Globals.bWriteRaw = True;
1572 Globals.bReadbmpx = False;
1573 Globals.bNullPasswords = False;
1574 Globals.bObeyPamRestrictions = False;
1575 Globals.syslog = 1;
1576 Globals.bSyslogOnly = False;
1577 Globals.bTimestampLogs = True;
1578 string_set(&Globals.szLogLevel, "0");
1579 Globals.bDebugPrefixTimestamp = False;
1580 Globals.bDebugHiresTimestamp = False;
1581 Globals.bDebugPid = False;
1582 Globals.bDebugUid = False;
1583 Globals.bEnableCoreFiles = True;
1584 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1585 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1586 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1587 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1588 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1589 Globals.lm_interval = 60;
1590 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1591#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1592 Globals.bNISHomeMap = False;
1593#ifdef WITH_NISPLUS_HOME
1594 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1595#else
1596 string_set(&Globals.szNISHomeMapName, "auto.home");
1597#endif
1598#endif
1599 Globals.bTimeServer = False;
1600 Globals.bBindInterfacesOnly = False;
1601 Globals.bUnixPasswdSync = False;
1602 Globals.bPamPasswordChange = False;
1603 Globals.bPasswdChatDebug = False;
1604 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1605 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
1606 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1607 Globals.bStatCache = True; /* use stat cache by default */
1608 Globals.iMaxStatCacheSize = 1024; /* one Meg by default. */
1609 Globals.restrict_anonymous = 0;
1610 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1611 Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
1612 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1613 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1614 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1615 /* Note, that we will use NTLM2 session security (which is different), if it is available */
1616
1617 Globals.map_to_guest = 0; /* By Default, "Never" */
1618 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
1619 Globals.enhanced_browsing = True;
1620 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
1621#ifdef MMAP_BLACKLIST
1622 Globals.bUseMmap = False;
1623#else
1624 Globals.bUseMmap = True;
1625#endif
1626 Globals.bUnixExtensions = True;
1627 Globals.bResetOnZeroVC = False;
1628
1629 /* hostname lookups can be very expensive and are broken on
1630 a large number of sites (tridge) */
1631 Globals.bHostnameLookups = False;
1632
1633 string_set(&Globals.szPassdbBackend, "smbpasswd");
1634 string_set(&Globals.szLdapSuffix, "");
1635 string_set(&Globals.szLdapMachineSuffix, "");
1636 string_set(&Globals.szLdapUserSuffix, "");
1637 string_set(&Globals.szLdapGroupSuffix, "");
1638 string_set(&Globals.szLdapIdmapSuffix, "");
1639
1640 string_set(&Globals.szLdapAdminDn, "");
1641 Globals.ldap_ssl = LDAP_SSL_OFF;
1642 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1643 Globals.ldap_delete_dn = False;
1644 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1645 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1646 Globals.ldap_page_size = LDAP_PAGE_SIZE;
1647
1648 Globals.ldap_debug_level = 0;
1649 Globals.ldap_debug_threshold = 10;
1650
1651 /* This is what we tell the afs client. in reality we set the token
1652 * to never expire, though, when this runs out the afs client will
1653 * forget the token. Set to 0 to get NEVERDATE.*/
1654 Globals.iAfsTokenLifetime = 604800;
1655
1656/* these parameters are set to defaults that are more appropriate
1657 for the increasing samba install base:
1658
1659 as a member of the workgroup, that will possibly become a
1660 _local_ master browser (lm = True). this is opposed to a forced
1661 local master browser startup (pm = True).
1662
1663 doesn't provide WINS server service by default (wsupp = False),
1664 and doesn't provide domain master browser services by default, either.
1665
1666*/
1667
1668 Globals.bMsAddPrinterWizard = True;
1669 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1670 Globals.os_level = 20;
1671 Globals.bLocalMaster = True;
1672 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1673 Globals.bDomainLogons = False;
1674 Globals.bBrowseList = True;
1675 Globals.bWINSsupport = False;
1676 Globals.bWINSproxy = False;
1677
1678 Globals.bDNSproxy = True;
1679
1680 /* this just means to use them if they exist */
1681 Globals.bKernelOplocks = True;
1682
1683 Globals.bAllowTrustedDomains = True;
1684
1685 string_set(&Globals.szTemplateShell, "/bin/false");
1686 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1687 string_set(&Globals.szWinbindSeparator, "\\");
1688
1689 string_set(&Globals.szCupsServer, "");
1690 string_set(&Globals.szIPrintServer, "");
1691
1692 Globals.winbind_cache_time = 300; /* 5 minutes */
1693 Globals.bWinbindEnumUsers = False;
1694 Globals.bWinbindEnumGroups = False;
1695 Globals.bWinbindUseDefaultDomain = False;
1696 Globals.bWinbindTrustedDomainsOnly = False;
1697 Globals.bWinbindNestedGroups = True;
1698 Globals.szWinbindNssInfo = str_list_make("template", NULL);
1699 Globals.bWinbindRefreshTickets = False;
1700 Globals.bWinbindOfflineLogon = False;
1701
1702 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
1703 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
1704
1705 Globals.bPassdbExpandExplicit = False;
1706
1707 Globals.name_cache_timeout = 660; /* In seconds */
1708
1709 Globals.bUseSpnego = True;
1710 Globals.bClientUseSpnego = True;
1711
1712 Globals.client_signing = Auto;
1713 Globals.server_signing = False;
1714
1715 Globals.bDeferSharingViolations = True;
1716 string_set(&Globals.smb_ports, SMB_PORTS);
1717
1718 Globals.bEnablePrivileges = True;
1719 Globals.bHostMSDfs = True;
1720 Globals.bASUSupport = False;
1721
1722 /* User defined shares. */
1723 pstrcpy(s, dyn_LOCKDIR);
1724 pstrcat(s, "/usershares");
1725 string_set(&Globals.szUsersharePath, s);
1726 string_set(&Globals.szUsershareTemplateShare, "");
1727 Globals.iUsershareMaxShares = 0;
1728 /* By default disallow sharing of directories not owned by the sharer. */
1729 Globals.bUsershareOwnerOnly = True;
1730 /* By default disallow guest access to usershares. */
1731 Globals.bUsershareAllowGuests = False;
1732}
1733
1734static TALLOC_CTX *lp_talloc;
1735
1736/******************************************************************* a
1737 Free up temporary memory - called from the main loop.
1738********************************************************************/
1739
1740void lp_TALLOC_FREE(void)
1741{
1742 if (!lp_talloc)
1743 return;
1744 TALLOC_FREE(lp_talloc);
1745 lp_talloc = NULL;
1746}
1747
1748TALLOC_CTX *tmp_talloc_ctx(void)
1749{
1750 if (lp_talloc == NULL) {
1751 lp_talloc = talloc_init("tmp_talloc_ctx");
1752 }
1753
1754 if (lp_talloc == NULL) {
1755 smb_panic("Could not create temporary talloc context\n");
1756 }
1757
1758 return lp_talloc;
1759}
1760
1761/*******************************************************************
1762 Convenience routine to grab string parameters into temporary memory
1763 and run standard_sub_basic on them. The buffers can be written to by
1764 callers without affecting the source string.
1765********************************************************************/
1766
1767static char *lp_string(const char *s)
1768{
1769 char *ret, *tmpstr;
1770
1771 /* The follow debug is useful for tracking down memory problems
1772 especially if you have an inner loop that is calling a lp_*()
1773 function that returns a string. Perhaps this debug should be
1774 present all the time? */
1775
1776#if 0
1777 DEBUG(10, ("lp_string(%s)\n", s));
1778#endif
1779
1780 if (!lp_talloc)
1781 lp_talloc = talloc_init("lp_talloc");
1782
1783 tmpstr = alloc_sub_basic(get_current_username(),
1784 current_user_info.domain, s);
1785 if (trim_char(tmpstr, '\"', '\"')) {
1786 if (strchr(tmpstr,'\"') != NULL) {
1787 SAFE_FREE(tmpstr);
1788 tmpstr = alloc_sub_basic(get_current_username(),
1789 current_user_info.domain, s);
1790 }
1791 }
1792 ret = talloc_strdup(lp_talloc, tmpstr);
1793 SAFE_FREE(tmpstr);
1794
1795 return (ret);
1796}
1797
1798/*
1799 In this section all the functions that are used to access the
1800 parameters from the rest of the program are defined
1801*/
1802
1803#define FN_GLOBAL_STRING(fn_name,ptr) \
1804 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1805#define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1806 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1807#define FN_GLOBAL_LIST(fn_name,ptr) \
1808 const char **fn_name(void) {return(*(const char ***)(ptr));}
1809#define FN_GLOBAL_BOOL(fn_name,ptr) \
1810 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1811#define FN_GLOBAL_CHAR(fn_name,ptr) \
1812 char fn_name(void) {return(*(char *)(ptr));}
1813#define FN_GLOBAL_INTEGER(fn_name,ptr) \
1814 int fn_name(void) {return(*(int *)(ptr));}
1815
1816#define FN_LOCAL_STRING(fn_name,val) \
1817 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1818#define FN_LOCAL_CONST_STRING(fn_name,val) \
1819 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1820#define FN_LOCAL_LIST(fn_name,val) \
1821 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1822#define FN_LOCAL_BOOL(fn_name,val) \
1823 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1824#define FN_LOCAL_INTEGER(fn_name,val) \
1825 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1826
1827#define FN_LOCAL_PARM_BOOL(fn_name,val) \
1828 BOOL fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1829#define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1830 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1831#define FN_LOCAL_PARM_STRING(fn_name,val) \
1832 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));}
1833#define FN_LOCAL_CHAR(fn_name,val) \
1834 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1835
1836FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1837FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1838FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1839FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1840FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1841FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1842FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1843FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1844FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1845FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1846FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1847FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1848FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1849FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1850FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1851FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1852FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1853FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1854FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1855FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1856FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1857FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1858FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1859FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1860FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1861FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1862FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1863FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1864FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1865FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1866FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1867FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1868FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1869FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1870FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1871FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1872FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1873FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1874FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1875FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1876FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1877FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1878FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1879FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1880FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1881FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1882FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1883static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1884FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1885/* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1886 * lp_passdb_backend() should be replace by the this macro again after
1887 * some releases.
1888 * */
1889const char *lp_passdb_backend(void)
1890{
1891 char *delim, *quote;
1892
1893 delim = strchr( Globals.szPassdbBackend, ' ');
1894 /* no space at all */
1895 if (delim == NULL) {
1896 goto out;
1897 }
1898
1899 quote = strchr(Globals.szPassdbBackend, '"');
1900 /* no quote char or non in the first part */
1901 if (quote == NULL || quote > delim) {
1902 *delim = '\0';
1903 goto warn;
1904 }
1905
1906 quote = strchr(quote+1, '"');
1907 if (quote == NULL) {
1908 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
1909 goto out;
1910 } else if (*(quote+1) == '\0') {
1911 /* space, fitting quote char, and one backend only */
1912 goto out;
1913 } else {
1914 /* terminate string after the fitting quote char */
1915 *(quote+1) = '\0';
1916 }
1917
1918warn:
1919 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
1920 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
1921 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
1922 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
1923
1924out:
1925 return Globals.szPassdbBackend;
1926}
1927FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1928FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1929FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1930FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1931FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1932
1933FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1934FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1935FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1936FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1937FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1938FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1939
1940FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1941
1942FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1943FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1944FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1945
1946FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1947
1948FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1949FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1950FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1951FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1952FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1953FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1954FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1955FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1956FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1957FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1958FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1959FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1960FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
1961
1962FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
1963FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
1964FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
1965FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
1966FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
1967FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1968
1969FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1970FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1971FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1972FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1973FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1974FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1975FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1976FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1977FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
1978FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
1979FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1980FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1981FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1982FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1983FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1984FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1985
1986FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1987
1988FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1989FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1990FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1991FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1992FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1993FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1994FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1995FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1996FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1997FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1998FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1999FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
2000FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
2001FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
2002FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
2003FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
2004FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
2005FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
2006FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
2007FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
2008FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
2009FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
2010FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
2011FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
2012FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
2013FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
2014FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
2015FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
2016FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
2017FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
2018FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
2019static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
2020FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
2021FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
2022FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
2023FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
2024FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
2025FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
2026FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
2027FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
2028FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
2029FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
2030FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
2031FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
2032FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
2033FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
2034FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
2035FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
2036FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
2037FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
2038FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
2039FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
2040FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
2041FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
2042FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
2043FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
2044FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
2045FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
2046FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
2047FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
2048FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
2049FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
2050FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
2051FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
2052FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
2053FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
2054FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
2055FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
2056FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
2057FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
2058FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
2059FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
2060FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
2061FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
2062FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
2063FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
2064FN_GLOBAL_INTEGER(lp_security, &Globals.security)
2065FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
2066FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
2067FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
2068FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
2069FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
2070FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
2071FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
2072static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
2073FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
2074FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
2075FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
2076FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
2077FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
2078FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
2079FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
2080
2081FN_LOCAL_STRING(lp_preexec, szPreExec)
2082FN_LOCAL_STRING(lp_postexec, szPostExec)
2083FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
2084FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
2085FN_LOCAL_STRING(lp_servicename, szService)
2086FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
2087FN_LOCAL_STRING(lp_pathname, szPath)
2088FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
2089FN_LOCAL_STRING(lp_username, szUsername)
2090FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
2091FN_LOCAL_LIST(lp_valid_users, szValidUsers)
2092FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
2093FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
2094FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
2095FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
2096FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
2097FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
2098FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
2099FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
2100FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
2101FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
2102FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
2103FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
2104static FN_LOCAL_STRING(_lp_printername, szPrintername)
2105FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
2106FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
2107FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
2108FN_LOCAL_STRING(lp_magicscript, szMagicScript)
2109FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
2110FN_LOCAL_STRING(lp_comment, comment)
2111FN_LOCAL_STRING(lp_force_user, force_user)
2112FN_LOCAL_STRING(lp_force_group, force_group)
2113FN_LOCAL_LIST(lp_readlist, readlist)
2114FN_LOCAL_LIST(lp_writelist, writelist)
2115FN_LOCAL_LIST(lp_printer_admin, printer_admin)
2116FN_LOCAL_STRING(lp_fstype, fstype)
2117FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
2118FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
2119static FN_LOCAL_STRING(lp_volume, volume)
2120FN_LOCAL_PARM_STRING(lp_mangled_map, szMangledMap)
2121FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2122FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2123FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2124FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
2125FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
2126FN_LOCAL_STRING(lp_dfree_command, szDfree)
2127FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
2128FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
2129FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
2130FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
2131FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
2132FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
2133FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
2134FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2135FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2136FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2137FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2138FN_LOCAL_BOOL(lp_readonly, bRead_only)
2139FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2140FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2141FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2142FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
2143FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2144FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2145FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2146FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2147FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2148FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
2149FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
2150FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
2151FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2152FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2153FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2154FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2155FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
2156FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2157FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2158FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2159FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2160FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2161FN_LOCAL_BOOL(lp_map_system, bMap_system)
2162FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2163FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2164FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2165FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2166FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2167FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2168FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2169FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2170FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2171FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2172FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2173FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2174FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2175FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2176FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2177FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2178FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2179FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2180FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2181FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2182FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2183FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2184FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2185FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2186FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2187FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2188FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2189FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2190FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2191FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2192FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2193FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2194FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2195FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2196FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2197FN_LOCAL_INTEGER(lp_printing, iPrinting)
2198FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2199FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2200FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2201FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2202FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2203FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2204FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2205FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2206FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2207FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2208FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
2209FN_LOCAL_CHAR(lp_magicchar, magic_char)
2210FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2211FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2212FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2213FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2214FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2215FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2216
2217/* local prototypes */
2218
2219static int map_parameter(const char *pszParmName);
2220static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
2221static int getservicebyname(const char *pszServiceName,
2222 service * pserviceDest);
2223static void copy_service(service * pserviceDest,
2224 service * pserviceSource, BOOL *pcopymapDest);
2225static BOOL service_ok(int iService);
2226static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
2227static BOOL do_section(const char *pszSectionName);
2228static void init_copymap(service * pservice);
2229static BOOL hash_a_service(const char *name, int number);
2230static void free_service_byindex(int iService);
2231static char * canonicalize_servicename(const char *name);
2232
2233/* This is a helper function for parametrical options support. */
2234/* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2235/* Actual parametrical functions are quite simple */
2236static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2237{
2238 BOOL global_section = False;
2239 char* param_key;
2240 param_opt_struct *data;
2241
2242 if (snum >= iNumServices) return NULL;
2243
2244 if (snum < 0) {
2245 data = Globals.param_opt;
2246 global_section = True;
2247 } else {
2248 data = ServicePtrs[snum]->param_opt;
2249 }
2250
2251 asprintf(&param_key, "%s:%s", type, option);
2252 if (!param_key) {
2253 DEBUG(0,("asprintf failed!\n"));
2254 return NULL;
2255 }
2256
2257 while (data) {
2258 if (strcmp(data->key, param_key) == 0) {
2259 string_free(&param_key);
2260 return data;
2261 }
2262 data = data->next;
2263 }
2264
2265 if (!global_section) {
2266 /* Try to fetch the same option but from globals */
2267 /* but only if we are not already working with Globals */
2268 data = Globals.param_opt;
2269 while (data) {
2270 if (strcmp(data->key, param_key) == 0) {
2271 string_free(&param_key);
2272 return data;
2273 }
2274 data = data->next;
2275 }
2276 }
2277
2278 string_free(&param_key);
2279
2280 return NULL;
2281}
2282
2283
2284#define MISSING_PARAMETER(name) \
2285 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2286
2287/*******************************************************************
2288convenience routine to return int parameters.
2289********************************************************************/
2290static int lp_int(const char *s)
2291{
2292
2293 if (!s || !*s) {
2294 MISSING_PARAMETER(lp_int);
2295 return (-1);
2296 }
2297
2298 return (int)strtol(s, NULL, 0);
2299}
2300
2301/*******************************************************************
2302convenience routine to return unsigned long parameters.
2303********************************************************************/
2304static unsigned long lp_ulong(const char *s)
2305{
2306
2307 if (!s || !*s) {
2308 MISSING_PARAMETER(lp_ulong);
2309 return (0);
2310 }
2311
2312 return strtoul(s, NULL, 0);
2313}
2314
2315/*******************************************************************
2316convenience routine to return boolean parameters.
2317********************************************************************/
2318static BOOL lp_bool(const char *s)
2319{
2320 BOOL ret = False;
2321
2322 if (!s || !*s) {
2323 MISSING_PARAMETER(lp_bool);
2324 return False;
2325 }
2326
2327 if (!set_boolean(&ret,s)) {
2328 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2329 return False;
2330 }
2331
2332 return ret;
2333}
2334
2335/*******************************************************************
2336convenience routine to return enum parameters.
2337********************************************************************/
2338static int lp_enum(const char *s,const struct enum_list *_enum)
2339{
2340 int i;
2341
2342 if (!s || !*s || !_enum) {
2343 MISSING_PARAMETER(lp_enum);
2344 return (-1);
2345 }
2346
2347 for (i=0; _enum[i].name; i++) {
2348 if (strequal(_enum[i].name,s))
2349 return _enum[i].value;
2350 }
2351
2352 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2353 return (-1);
2354}
2355
2356#undef MISSING_PARAMETER
2357
2358/* DO NOT USE lp_parm_string ANYMORE!!!!
2359 * use lp_parm_const_string or lp_parm_talloc_string
2360 *
2361 * lp_parm_string is only used to let old modules find this symbol
2362 */
2363#undef lp_parm_string
2364 char *lp_parm_string(const char *servicename, const char *type, const char *option);
2365 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2366{
2367 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2368}
2369
2370/* Return parametric option from a given service. Type is a part of option before ':' */
2371/* Parametric option has following syntax: 'Type: option = value' */
2372/* the returned value is talloced in lp_talloc */
2373char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2374{
2375 param_opt_struct *data = get_parametrics(snum, type, option);
2376
2377 if (data == NULL||data->value==NULL) {
2378 if (def) {
2379 return lp_string(def);
2380 } else {
2381 return NULL;
2382 }
2383 }
2384
2385 return lp_string(data->value);
2386}
2387
2388/* Return parametric option from a given service. Type is a part of option before ':' */
2389/* Parametric option has following syntax: 'Type: option = value' */
2390const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2391{
2392 param_opt_struct *data = get_parametrics(snum, type, option);
2393
2394 if (data == NULL||data->value==NULL)
2395 return def;
2396
2397 return data->value;
2398}
2399
2400/* Return parametric option from a given service. Type is a part of option before ':' */
2401/* Parametric option has following syntax: 'Type: option = value' */
2402
2403const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2404{
2405 param_opt_struct *data = get_parametrics(snum, type, option);
2406
2407 if (data == NULL||data->value==NULL)
2408 return (const char **)def;
2409
2410 if (data->list==NULL) {
2411 data->list = str_list_make(data->value, NULL);
2412 }
2413
2414 return (const char **)data->list;
2415}
2416
2417/* Return parametric option from a given service. Type is a part of option before ':' */
2418/* Parametric option has following syntax: 'Type: option = value' */
2419
2420int lp_parm_int(int snum, const char *type, const char *option, int def)
2421{
2422 param_opt_struct *data = get_parametrics(snum, type, option);
2423
2424 if (data && data->value && *data->value)
2425 return lp_int(data->value);
2426
2427 return def;
2428}
2429
2430/* Return parametric option from a given service. Type is a part of option before ':' */
2431/* Parametric option has following syntax: 'Type: option = value' */
2432
2433unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2434{
2435 param_opt_struct *data = get_parametrics(snum, type, option);
2436
2437 if (data && data->value && *data->value)
2438 return lp_ulong(data->value);
2439
2440 return def;
2441}
2442
2443/* Return parametric option from a given service. Type is a part of option before ':' */
2444/* Parametric option has following syntax: 'Type: option = value' */
2445
2446BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2447{
2448 param_opt_struct *data = get_parametrics(snum, type, option);
2449
2450 if (data && data->value && *data->value)
2451 return lp_bool(data->value);
2452
2453 return def;
2454}
2455
2456/* Return parametric option from a given service. Type is a part of option before ':' */
2457/* Parametric option has following syntax: 'Type: option = value' */
2458
2459int lp_parm_enum(int snum, const char *type, const char *option,
2460 const struct enum_list *_enum, int def)
2461{
2462 param_opt_struct *data = get_parametrics(snum, type, option);
2463
2464 if (data && data->value && *data->value && _enum)
2465 return lp_enum(data->value, _enum);
2466
2467 return def;
2468}
2469
2470
2471/***************************************************************************
2472 Initialise a service to the defaults.
2473***************************************************************************/
2474
2475static void init_service(service * pservice)
2476{
2477 memset((char *)pservice, '\0', sizeof(service));
2478 copy_service(pservice, &sDefault, NULL);
2479}
2480
2481/***************************************************************************
2482 Free the dynamically allocated parts of a service struct.
2483***************************************************************************/
2484
2485static void free_service(service *pservice)
2486{
2487 int i;
2488 param_opt_struct *data, *pdata;
2489 if (!pservice)
2490 return;
2491
2492 if (pservice->szService)
2493 DEBUG(5, ("free_service: Freeing service %s\n",
2494 pservice->szService));
2495
2496 string_free(&pservice->szService);
2497 SAFE_FREE(pservice->copymap);
2498
2499 for (i = 0; parm_table[i].label; i++) {
2500 if ((parm_table[i].type == P_STRING ||
2501 parm_table[i].type == P_USTRING) &&
2502 parm_table[i].p_class == P_LOCAL)
2503 string_free((char **)
2504 (((char *)pservice) +
2505 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2506 else if (parm_table[i].type == P_LIST &&
2507 parm_table[i].p_class == P_LOCAL)
2508 str_list_free((char ***)
2509 (((char *)pservice) +
2510 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2511 }
2512
2513 data = pservice->param_opt;
2514 if (data)
2515 DEBUG(5,("Freeing parametrics:\n"));
2516 while (data) {
2517 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2518 string_free(&data->key);
2519 string_free(&data->value);
2520 str_list_free(&data->list);
2521 pdata = data->next;
2522 SAFE_FREE(data);
2523 data = pdata;
2524 }
2525
2526 ZERO_STRUCTP(pservice);
2527}
2528
2529
2530/***************************************************************************
2531 remove a service indexed in the ServicePtrs array from the ServiceHash
2532 and free the dynamically allocated parts
2533***************************************************************************/
2534
2535static void free_service_byindex(int idx)
2536{
2537 if ( !LP_SNUM_OK(idx) )
2538 return;
2539
2540 ServicePtrs[idx]->valid = False;
2541 invalid_services[num_invalid_services++] = idx;
2542
2543 /* we have to cleanup the hash record */
2544
2545 if (ServicePtrs[idx]->szService) {
2546 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2547
2548 tdb_delete_bystring(ServiceHash, canon_name );
2549 }
2550
2551 free_service(ServicePtrs[idx]);
2552}
2553
2554/***************************************************************************
2555 Add a new service to the services array initialising it with the given
2556 service.
2557***************************************************************************/
2558
2559static int add_a_service(const service *pservice, const char *name)
2560{
2561 int i;
2562 service tservice;
2563 int num_to_alloc = iNumServices + 1;
2564 param_opt_struct *data, *pdata;
2565
2566 tservice = *pservice;
2567
2568 /* it might already exist */
2569 if (name) {
2570 i = getservicebyname(name, NULL);
2571 if (i >= 0) {
2572 /* Clean all parametric options for service */
2573 /* They will be added during parsing again */
2574 data = ServicePtrs[i]->param_opt;
2575 while (data) {
2576 string_free(&data->key);
2577 string_free(&data->value);
2578 str_list_free(&data->list);
2579 pdata = data->next;
2580 SAFE_FREE(data);
2581 data = pdata;
2582 }
2583 ServicePtrs[i]->param_opt = NULL;
2584 return (i);
2585 }
2586 }
2587
2588 /* find an invalid one */
2589 i = iNumServices;
2590 if (num_invalid_services > 0) {
2591 i = invalid_services[--num_invalid_services];
2592 }
2593
2594 /* if not, then create one */
2595 if (i == iNumServices) {
2596 service **tsp;
2597 int *tinvalid;
2598
2599 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2600 if (tsp == NULL) {
2601 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2602 return (-1);
2603 }
2604 ServicePtrs = tsp;
2605 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2606 if (!ServicePtrs[iNumServices]) {
2607 DEBUG(0,("add_a_service: out of memory!\n"));
2608 return (-1);
2609 }
2610 iNumServices++;
2611
2612 /* enlarge invalid_services here for now... */
2613 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2614 num_to_alloc);
2615 if (tinvalid == NULL) {
2616 DEBUG(0,("add_a_service: failed to enlarge "
2617 "invalid_services!\n"));
2618 return (-1);
2619 }
2620 invalid_services = tinvalid;
2621 } else {
2622 free_service_byindex(i);
2623 }
2624
2625 ServicePtrs[i]->valid = True;
2626
2627 init_service(ServicePtrs[i]);
2628 copy_service(ServicePtrs[i], &tservice, NULL);
2629 if (name)
2630 string_set(&ServicePtrs[i]->szService, name);
2631
2632 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2633 i, ServicePtrs[i]->szService));
2634
2635 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2636 return (-1);
2637 }
2638
2639 return (i);
2640}
2641
2642/***************************************************************************
2643 Convert a string to uppercase and remove whitespaces.
2644***************************************************************************/
2645
2646static char *canonicalize_servicename(const char *src)
2647{
2648 static fstring canon; /* is fstring large enough? */
2649
2650 if ( !src ) {
2651 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2652 return NULL;
2653 }
2654
2655 fstrcpy( canon, src );
2656 strlower_m( canon );
2657
2658 return canon;
2659}
2660
2661/***************************************************************************
2662 Add a name/index pair for the services array to the hash table.
2663***************************************************************************/
2664
2665static BOOL hash_a_service(const char *name, int idx)
2666{
2667 char *canon_name;
2668
2669 if ( !ServiceHash ) {
2670 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2671 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2672 (O_RDWR|O_CREAT), 0600);
2673 if ( !ServiceHash ) {
2674 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2675 return False;
2676 }
2677 }
2678
2679 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2680 idx, name));
2681
2682 if ( !(canon_name = canonicalize_servicename( name )) )
2683 return False;
2684
2685 tdb_store_int32(ServiceHash, canon_name, idx);
2686
2687 return True;
2688}
2689
2690/***************************************************************************
2691 Add a new home service, with the specified home directory, defaults coming
2692 from service ifrom.
2693***************************************************************************/
2694
2695BOOL lp_add_home(const char *pszHomename, int iDefaultService,
2696 const char *user, const char *pszHomedir)
2697{
2698 int i;
2699 pstring newHomedir;
2700
2701 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
2702 pszHomedir[0] == '\0') {
2703 return False;
2704 }
2705
2706 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2707
2708 if (i < 0)
2709 return (False);
2710
2711 if (!(*(ServicePtrs[iDefaultService]->szPath))
2712 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2713 pstrcpy(newHomedir, pszHomedir);
2714 string_set(&ServicePtrs[i]->szPath, newHomedir);
2715 }
2716
2717 if (!(*(ServicePtrs[i]->comment))) {
2718 pstring comment;
2719 slprintf(comment, sizeof(comment) - 1,
2720 "Home directory of %s", user);
2721 string_set(&ServicePtrs[i]->comment, comment);
2722 }
2723
2724 /* set the browseable flag from the global default */
2725
2726 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2727
2728 ServicePtrs[i]->autoloaded = True;
2729
2730 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2731 user, ServicePtrs[i]->szPath ));
2732
2733 return (True);
2734}
2735
2736/***************************************************************************
2737 Add a new service, based on an old one.
2738***************************************************************************/
2739
2740int lp_add_service(const char *pszService, int iDefaultService)
2741{
2742 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2743}
2744
2745/***************************************************************************
2746 Add the IPC service.
2747***************************************************************************/
2748
2749static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2750{
2751 pstring comment;
2752 int i = add_a_service(&sDefault, ipc_name);
2753
2754 if (i < 0)
2755 return (False);
2756
2757 slprintf(comment, sizeof(comment) - 1,
2758 "IPC Service (%s)", Globals.szServerString);
2759
2760 string_set(&ServicePtrs[i]->szPath, tmpdir());
2761 string_set(&ServicePtrs[i]->szUsername, "");
2762 string_set(&ServicePtrs[i]->comment, comment);
2763 string_set(&ServicePtrs[i]->fstype, "IPC");
2764 ServicePtrs[i]->iMaxConnections = 0;
2765 ServicePtrs[i]->bAvailable = True;
2766 ServicePtrs[i]->bRead_only = True;
2767 ServicePtrs[i]->bGuest_only = False;
2768 ServicePtrs[i]->bAdministrative_share = True;
2769 ServicePtrs[i]->bGuest_ok = guest_ok;
2770 ServicePtrs[i]->bPrint_ok = False;
2771 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2772
2773 DEBUG(3, ("adding IPC service\n"));
2774
2775 return (True);
2776}
2777
2778/***************************************************************************
2779 Add a new printer service, with defaults coming from service iFrom.
2780***************************************************************************/
2781
2782BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2783{
2784 const char *comment = "From Printcap";
2785 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2786
2787 if (i < 0)
2788 return (False);
2789
2790 /* note that we do NOT default the availability flag to True - */
2791 /* we take it from the default service passed. This allows all */
2792 /* dynamic printers to be disabled by disabling the [printers] */
2793 /* entry (if/when the 'available' keyword is implemented!). */
2794
2795 /* the printer name is set to the service name. */
2796 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2797 string_set(&ServicePtrs[i]->comment, comment);
2798
2799 /* set the browseable flag from the gloabl default */
2800 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2801
2802 /* Printers cannot be read_only. */
2803 ServicePtrs[i]->bRead_only = False;
2804 /* No share modes on printer services. */
2805 ServicePtrs[i]->bShareModes = False;
2806 /* No oplocks on printer services. */
2807 ServicePtrs[i]->bOpLocks = False;
2808 /* Printer services must be printable. */
2809 ServicePtrs[i]->bPrint_ok = True;
2810
2811 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2812
2813 return (True);
2814}
2815
2816/***************************************************************************
2817 Map a parameter's string representation to something we can use.
2818 Returns False if the parameter string is not recognised, else TRUE.
2819***************************************************************************/
2820
2821static int map_parameter(const char *pszParmName)
2822{
2823 int iIndex;
2824
2825 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
2826 return (-1);
2827
2828 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2829 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2830 return (iIndex);
2831
2832 /* Warn only if it isn't parametric option */
2833 if (strchr(pszParmName, ':') == NULL)
2834 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2835 /* We do return 'fail' for parametric options as well because they are
2836 stored in different storage
2837 */
2838 return (-1);
2839}
2840
2841/***************************************************************************
2842 Show all parameter's name, type, [values,] and flags.
2843***************************************************************************/
2844
2845void show_parameter_list(void)
2846{
2847 int classIndex, parmIndex, enumIndex, flagIndex;
2848 BOOL hadFlag;
2849 const char *section_names[] = { "local", "global", NULL};
2850 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2851 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2852 "P_UGSTRING", "P_ENUM", "P_SEP"};
2853 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2854 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2855 FLAG_HIDE, FLAG_DOS_STRING};
2856 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2857 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2858 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2859
2860 for ( classIndex=0; section_names[classIndex]; classIndex++) {
2861 printf("[%s]\n", section_names[classIndex]);
2862 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2863 if (parm_table[parmIndex].p_class == classIndex) {
2864 printf("%s=%s",
2865 parm_table[parmIndex].label,
2866 type[parm_table[parmIndex].type]);
2867 switch (parm_table[parmIndex].type) {
2868 case P_ENUM:
2869 printf(",");
2870 for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2871 printf("%s%s",
2872 enumIndex ? "|" : "",
2873 parm_table[parmIndex].enum_list[enumIndex].name);
2874 break;
2875 default:
2876 break;
2877 }
2878 printf(",");
2879 hadFlag = False;
2880 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2881 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2882 printf("%s%s",
2883 hadFlag ? "|" : "",
2884 flag_names[flagIndex]);
2885 hadFlag = True;
2886 }
2887 }
2888 printf("\n");
2889 }
2890 }
2891 }
2892}
2893
2894/***************************************************************************
2895 Set a boolean variable from the text value stored in the passed string.
2896 Returns True in success, False if the passed string does not correctly
2897 represent a boolean.
2898***************************************************************************/
2899
2900static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2901{
2902 BOOL bRetval;
2903
2904 bRetval = True;
2905 if (strwicmp(pszParmValue, "yes") == 0 ||
2906 strwicmp(pszParmValue, "true") == 0 ||
2907 strwicmp(pszParmValue, "1") == 0)
2908 *pb = True;
2909 else if (strwicmp(pszParmValue, "no") == 0 ||
2910 strwicmp(pszParmValue, "False") == 0 ||
2911 strwicmp(pszParmValue, "0") == 0)
2912 *pb = False;
2913 else {
2914 DEBUG(0,
2915 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2916 pszParmValue));
2917 bRetval = False;
2918 }
2919 return (bRetval);
2920}
2921
2922/***************************************************************************
2923Find a service by name. Otherwise works like get_service.
2924***************************************************************************/
2925
2926static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2927{
2928 int iService = -1;
2929 char *canon_name;
2930
2931 if (ServiceHash != NULL) {
2932 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2933 return -1;
2934
2935 iService = tdb_fetch_int32(ServiceHash, canon_name );
2936
2937 if (LP_SNUM_OK(iService)) {
2938 if (pserviceDest != NULL) {
2939 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2940 }
2941 } else {
2942 iService = -1;
2943 }
2944 }
2945
2946 return (iService);
2947}
2948
2949/***************************************************************************
2950 Copy a service structure to another.
2951 If pcopymapDest is NULL then copy all fields
2952***************************************************************************/
2953
2954static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2955{
2956 int i;
2957 BOOL bcopyall = (pcopymapDest == NULL);
2958 param_opt_struct *data, *pdata, *paramo;
2959 BOOL not_added;
2960
2961 for (i = 0; parm_table[i].label; i++)
2962 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2963 (bcopyall || pcopymapDest[i])) {
2964 void *def_ptr = parm_table[i].ptr;
2965 void *src_ptr =
2966 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2967 &sDefault);
2968 void *dest_ptr =
2969 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2970 &sDefault);
2971
2972 switch (parm_table[i].type) {
2973 case P_BOOL:
2974 case P_BOOLREV:
2975 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2976 break;
2977
2978 case P_INTEGER:
2979 case P_ENUM:
2980 case P_OCTAL:
2981 *(int *)dest_ptr = *(int *)src_ptr;
2982 break;
2983
2984 case P_CHAR:
2985 *(char *)dest_ptr = *(char *)src_ptr;
2986 break;
2987
2988 case P_STRING:
2989 string_set((char **)dest_ptr,
2990 *(char **)src_ptr);
2991 break;
2992
2993 case P_USTRING:
2994 string_set((char **)dest_ptr,
2995 *(char **)src_ptr);
2996 strupper_m(*(char **)dest_ptr);
2997 break;
2998 case P_LIST:
2999 str_list_free((char ***)dest_ptr);
3000 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
3001 break;
3002 default:
3003 break;
3004 }
3005 }
3006
3007 if (bcopyall) {
3008 init_copymap(pserviceDest);
3009 if (pserviceSource->copymap)
3010 memcpy((void *)pserviceDest->copymap,
3011 (void *)pserviceSource->copymap,
3012 sizeof(BOOL) * NUMPARAMETERS);
3013 }
3014
3015 data = pserviceSource->param_opt;
3016 while (data) {
3017 not_added = True;
3018 pdata = pserviceDest->param_opt;
3019 /* Traverse destination */
3020 while (pdata) {
3021 /* If we already have same option, override it */
3022 if (strcmp(pdata->key, data->key) == 0) {
3023 string_free(&pdata->value);
3024 str_list_free(&data->list);
3025 pdata->value = SMB_STRDUP(data->value);
3026 not_added = False;
3027 break;
3028 }
3029 pdata = pdata->next;
3030 }
3031 if (not_added) {
3032 paramo = SMB_XMALLOC_P(param_opt_struct);
3033 paramo->key = SMB_STRDUP(data->key);
3034 paramo->value = SMB_STRDUP(data->value);
3035 paramo->list = NULL;
3036 DLIST_ADD(pserviceDest->param_opt, paramo);
3037 }
3038 data = data->next;
3039 }
3040}
3041
3042/***************************************************************************
3043Check a service for consistency. Return False if the service is in any way
3044incomplete or faulty, else True.
3045***************************************************************************/
3046
3047static BOOL service_ok(int iService)
3048{
3049 BOOL bRetval;
3050
3051 bRetval = True;
3052 if (ServicePtrs[iService]->szService[0] == '\0') {
3053 DEBUG(0, ("The following message indicates an internal error:\n"));
3054 DEBUG(0, ("No service name in service entry.\n"));
3055 bRetval = False;
3056 }
3057
3058 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3059 /* I can't see why you'd want a non-printable printer service... */
3060 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3061 if (!ServicePtrs[iService]->bPrint_ok) {
3062 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3063 ServicePtrs[iService]->szService));
3064 ServicePtrs[iService]->bPrint_ok = True;
3065 }
3066 /* [printers] service must also be non-browsable. */
3067 if (ServicePtrs[iService]->bBrowseable)
3068 ServicePtrs[iService]->bBrowseable = False;
3069 }
3070
3071 if (ServicePtrs[iService]->szPath[0] == '\0' &&
3072 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3073 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3074 ) {
3075 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3076 ServicePtrs[iService]->szService));
3077 ServicePtrs[iService]->bAvailable = False;
3078 }
3079
3080 /* If a service is flagged unavailable, log the fact at level 0. */
3081 if (!ServicePtrs[iService]->bAvailable)
3082 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3083 ServicePtrs[iService]->szService));
3084
3085 return (bRetval);
3086}
3087
3088static struct file_lists {
3089 struct file_lists *next;
3090 char *name;
3091 char *subfname;
3092 time_t modtime;
3093} *file_lists = NULL;
3094
3095/*******************************************************************
3096 Keep a linked list of all config files so we know when one has changed
3097 it's date and needs to be reloaded.
3098********************************************************************/
3099
3100static void add_to_file_list(const char *fname, const char *subfname)
3101{
3102 struct file_lists *f = file_lists;
3103
3104 while (f) {
3105 if (f->name && !strcmp(f->name, fname))
3106 break;
3107 f = f->next;
3108 }
3109
3110 if (!f) {
3111 f = SMB_MALLOC_P(struct file_lists);
3112 if (!f)
3113 return;
3114 f->next = file_lists;
3115 f->name = SMB_STRDUP(fname);
3116 if (!f->name) {
3117 SAFE_FREE(f);
3118 return;
3119 }
3120 f->subfname = SMB_STRDUP(subfname);
3121 if (!f->subfname) {
3122 SAFE_FREE(f);
3123 return;
3124 }
3125 file_lists = f;
3126 f->modtime = file_modtime(subfname);
3127 } else {
3128 time_t t = file_modtime(subfname);
3129 if (t)
3130 f->modtime = t;
3131 }
3132}
3133
3134/*******************************************************************
3135 Check if a config file has changed date.
3136********************************************************************/
3137
3138BOOL lp_file_list_changed(void)
3139{
3140 struct file_lists *f = file_lists;
3141
3142 DEBUG(6, ("lp_file_list_changed()\n"));
3143
3144 while (f) {
3145 pstring n2;
3146 time_t mod_time;
3147
3148 pstrcpy(n2, f->name);
3149 standard_sub_basic( get_current_username(),
3150 current_user_info.domain,
3151 n2, sizeof(n2) );
3152
3153 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3154 f->name, n2, ctime(&f->modtime)));
3155
3156 mod_time = file_modtime(n2);
3157
3158 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3159 DEBUGADD(6,
3160 ("file %s modified: %s\n", n2,
3161 ctime(&mod_time)));
3162 f->modtime = mod_time;
3163 SAFE_FREE(f->subfname);
3164 f->subfname = SMB_STRDUP(n2);
3165 return (True);
3166 }
3167 f = f->next;
3168 }
3169 return (False);
3170}
3171
3172/***************************************************************************
3173 Run standard_sub_basic on netbios name... needed because global_myname
3174 is not accessed through any lp_ macro.
3175 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3176***************************************************************************/
3177
3178static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3179{
3180 BOOL ret;
3181 pstring netbios_name;
3182
3183 pstrcpy(netbios_name, pszParmValue);
3184
3185 standard_sub_basic(get_current_username(), current_user_info.domain,
3186 netbios_name, sizeof(netbios_name));
3187
3188 ret = set_global_myname(netbios_name);
3189 string_set(&Globals.szNetbiosName,global_myname());
3190
3191 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3192 global_myname()));
3193
3194 return ret;
3195}
3196
3197static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3198{
3199 if (strcmp(*ptr, pszParmValue) != 0) {
3200 string_set(ptr, pszParmValue);
3201 init_iconv();
3202 }
3203 return True;
3204}
3205
3206
3207
3208static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3209{
3210 BOOL ret;
3211
3212 ret = set_global_myworkgroup(pszParmValue);
3213 string_set(&Globals.szWorkgroup,lp_workgroup());
3214
3215 return ret;
3216}
3217
3218static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3219{
3220 BOOL ret;
3221
3222 ret = set_global_scope(pszParmValue);
3223 string_set(&Globals.szNetbiosScope,global_scope());
3224
3225 return ret;
3226}
3227
3228static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3229{
3230 str_list_free(&Globals.szNetbiosAliases);
3231 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3232 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3233}
3234
3235/***************************************************************************
3236 Handle the include operation.
3237***************************************************************************/
3238
3239static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3240{
3241 pstring fname;
3242 pstrcpy(fname, pszParmValue);
3243
3244 standard_sub_basic(get_current_username(), current_user_info.domain,
3245 fname,sizeof(fname));
3246
3247 add_to_file_list(pszParmValue, fname);
3248
3249 string_set(ptr, fname);
3250
3251 if (file_exist(fname, NULL))
3252 return (pm_process(fname, do_section, do_parameter));
3253
3254 DEBUG(2, ("Can't find include file %s\n", fname));
3255
3256 return (False);
3257}
3258
3259/***************************************************************************
3260 Handle the interpretation of the copy parameter.
3261***************************************************************************/
3262
3263static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3264{
3265 BOOL bRetval;
3266 int iTemp;
3267 service serviceTemp;
3268
3269 string_set(ptr, pszParmValue);
3270
3271 init_service(&serviceTemp);
3272
3273 bRetval = False;
3274
3275 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3276
3277 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3278 if (iTemp == iServiceIndex) {
3279 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3280 } else {
3281 copy_service(ServicePtrs[iServiceIndex],
3282 &serviceTemp,
3283 ServicePtrs[iServiceIndex]->copymap);
3284 bRetval = True;
3285 }
3286 } else {
3287 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3288 bRetval = False;
3289 }
3290
3291 free_service(&serviceTemp);
3292 return (bRetval);
3293}
3294
3295static BOOL handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
3296{
3297 Globals.ldap_debug_level = lp_int(pszParmValue);
3298 init_ldap_debugging();
3299 return True;
3300}
3301
3302/***************************************************************************
3303 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3304 parameters is:
3305
3306 [global]
3307
3308 idmap uid = 1000-1999
3309 idmap gid = 700-899
3310
3311 We only do simple parsing checks here. The strings are parsed into useful
3312 structures in the idmap daemon code.
3313
3314***************************************************************************/
3315
3316/* Some lp_ routines to return idmap [ug]id information */
3317
3318static uid_t idmap_uid_low, idmap_uid_high;
3319static gid_t idmap_gid_low, idmap_gid_high;
3320
3321BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3322{
3323 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3324 return False;
3325
3326 if (low)
3327 *low = idmap_uid_low;
3328
3329 if (high)
3330 *high = idmap_uid_high;
3331
3332 return True;
3333}
3334
3335BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3336{
3337 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3338 return False;
3339
3340 if (low)
3341 *low = idmap_gid_low;
3342
3343 if (high)
3344 *high = idmap_gid_high;
3345
3346 return True;
3347}
3348
3349/* Do some simple checks on "idmap [ug]id" parameter values */
3350
3351static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3352{
3353 uint32 low, high;
3354
3355 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3356 return False;
3357
3358 /* Parse OK */
3359
3360 string_set(ptr, pszParmValue);
3361
3362 idmap_uid_low = low;
3363 idmap_uid_high = high;
3364
3365 return True;
3366}
3367
3368static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3369{
3370 uint32 low, high;
3371
3372 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3373 return False;
3374
3375 /* Parse OK */
3376
3377 string_set(ptr, pszParmValue);
3378
3379 idmap_gid_low = low;
3380 idmap_gid_high = high;
3381
3382 return True;
3383}
3384
3385/***************************************************************************
3386 Handle the DEBUG level list.
3387***************************************************************************/
3388
3389static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3390{
3391 pstring pszParmValue;
3392
3393 pstrcpy(pszParmValue, pszParmValueIn);
3394 string_set(ptr, pszParmValueIn);
3395 return debug_parse_levels( pszParmValue );
3396}
3397
3398/***************************************************************************
3399 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3400***************************************************************************/
3401
3402static const char *append_ldap_suffix( const char *str )
3403{
3404 const char *suffix_string;
3405
3406
3407 if (!lp_talloc)
3408 lp_talloc = talloc_init("lp_talloc");
3409
3410 suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3411 if ( !suffix_string ) {
3412 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3413 return "";
3414 }
3415
3416 return suffix_string;
3417}
3418
3419const char *lp_ldap_machine_suffix(void)
3420{
3421 if (Globals.szLdapMachineSuffix[0])
3422 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3423
3424 return lp_string(Globals.szLdapSuffix);
3425}
3426
3427const char *lp_ldap_user_suffix(void)
3428{
3429 if (Globals.szLdapUserSuffix[0])
3430 return append_ldap_suffix(Globals.szLdapUserSuffix);
3431
3432 return lp_string(Globals.szLdapSuffix);
3433}
3434
3435const char *lp_ldap_group_suffix(void)
3436{
3437 if (Globals.szLdapGroupSuffix[0])
3438 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3439
3440 return lp_string(Globals.szLdapSuffix);
3441}
3442
3443const char *lp_ldap_idmap_suffix(void)
3444{
3445 if (Globals.szLdapIdmapSuffix[0])
3446 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3447
3448 return lp_string(Globals.szLdapSuffix);
3449}
3450
3451/****************************************************************************
3452 set the value for a P_ENUM
3453 ***************************************************************************/
3454
3455static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3456 int *ptr )
3457{
3458 int i;
3459
3460 for (i = 0; parm->enum_list[i].name; i++) {
3461 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3462 *ptr = parm->enum_list[i].value;
3463 break;
3464 }
3465 }
3466}
3467
3468/***************************************************************************
3469***************************************************************************/
3470
3471static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3472{
3473 static int parm_num = -1;
3474 service *s;
3475
3476 if ( parm_num == -1 )
3477 parm_num = map_parameter( "printing" );
3478
3479 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3480
3481 if ( snum < 0 )
3482 s = &sDefault;
3483 else
3484 s = ServicePtrs[snum];
3485
3486 init_printer_values( s );
3487
3488 return True;
3489}
3490
3491
3492/***************************************************************************
3493 Initialise a copymap.
3494***************************************************************************/
3495
3496static void init_copymap(service * pservice)
3497{
3498 int i;
3499 SAFE_FREE(pservice->copymap);
3500 pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3501 if (!pservice->copymap)
3502 DEBUG(0,
3503 ("Couldn't allocate copymap!! (size %d)\n",
3504 (int)NUMPARAMETERS));
3505 else
3506 for (i = 0; i < NUMPARAMETERS; i++)
3507 pservice->copymap[i] = True;
3508}
3509
3510/***************************************************************************
3511 Return the local pointer to a parameter given the service number and the
3512 pointer into the default structure.
3513***************************************************************************/
3514
3515void *lp_local_ptr(int snum, void *ptr)
3516{
3517 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3518}
3519
3520/***************************************************************************
3521 Process a parameter for a particular service number. If snum < 0
3522 then assume we are in the globals.
3523***************************************************************************/
3524
3525BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3526{
3527 int parmnum, i, slen;
3528 void *parm_ptr = NULL; /* where we are going to store the result */
3529 void *def_ptr = NULL;
3530 pstring param_key;
3531 char *sep;
3532 param_opt_struct *paramo, *data;
3533 BOOL not_added;
3534
3535 parmnum = map_parameter(pszParmName);
3536
3537 if (parmnum < 0) {
3538 if ((sep=strchr(pszParmName, ':')) != NULL) {
3539 *sep = '\0';
3540 ZERO_STRUCT(param_key);
3541 pstr_sprintf(param_key, "%s:", pszParmName);
3542 slen = strlen(param_key);
3543 pstrcat(param_key, sep+1);
3544 trim_char(param_key+slen, ' ', ' ');
3545 not_added = True;
3546 data = (snum < 0) ? Globals.param_opt :
3547 ServicePtrs[snum]->param_opt;
3548 /* Traverse destination */
3549 while (data) {
3550 /* If we already have same option, override it */
3551 if (strcmp(data->key, param_key) == 0) {
3552 string_free(&data->value);
3553 str_list_free(&data->list);
3554 data->value = SMB_STRDUP(pszParmValue);
3555 not_added = False;
3556 break;
3557 }
3558 data = data->next;
3559 }
3560 if (not_added) {
3561 paramo = SMB_XMALLOC_P(param_opt_struct);
3562 paramo->key = SMB_STRDUP(param_key);
3563 paramo->value = SMB_STRDUP(pszParmValue);
3564 paramo->list = NULL;
3565 if (snum < 0) {
3566 DLIST_ADD(Globals.param_opt, paramo);
3567 } else {
3568 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3569 }
3570 }
3571
3572 *sep = ':';
3573 return (True);
3574 }
3575 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3576 return (True);
3577 }
3578
3579 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3580 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3581 pszParmName));
3582 }
3583
3584 def_ptr = parm_table[parmnum].ptr;
3585
3586 /* we might point at a service, the default service or a global */
3587 if (snum < 0) {
3588 parm_ptr = def_ptr;
3589 } else {
3590 if (parm_table[parmnum].p_class == P_GLOBAL) {
3591 DEBUG(0,
3592 ("Global parameter %s found in service section!\n",
3593 pszParmName));
3594 return (True);
3595 }
3596 parm_ptr =
3597 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3598 &sDefault);
3599 }
3600
3601 if (snum >= 0) {
3602 if (!ServicePtrs[snum]->copymap)
3603 init_copymap(ServicePtrs[snum]);
3604
3605 /* this handles the aliases - set the copymap for other entries with
3606 the same data pointer */
3607 for (i = 0; parm_table[i].label; i++)
3608 if (parm_table[i].ptr == parm_table[parmnum].ptr)
3609 ServicePtrs[snum]->copymap[i] = False;
3610 }
3611
3612 /* if it is a special case then go ahead */
3613 if (parm_table[parmnum].special) {
3614 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3615 return (True);
3616 }
3617
3618 /* now switch on the type of variable it is */
3619 switch (parm_table[parmnum].type)
3620 {
3621 case P_BOOL:
3622 *(BOOL *)parm_ptr = lp_bool(pszParmValue);
3623 break;
3624
3625 case P_BOOLREV:
3626 *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
3627 break;
3628
3629 case P_INTEGER:
3630 *(int *)parm_ptr = lp_int(pszParmValue);
3631 break;
3632
3633 case P_CHAR:
3634 *(char *)parm_ptr = *pszParmValue;
3635 break;
3636
3637 case P_OCTAL:
3638 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3639 if ( i != 1 ) {
3640 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3641 }
3642 break;
3643
3644 case P_LIST:
3645 str_list_free((char ***)parm_ptr);
3646 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3647 break;
3648
3649 case P_STRING:
3650 string_set((char **)parm_ptr, pszParmValue);
3651 break;
3652
3653 case P_USTRING:
3654 string_set((char **)parm_ptr, pszParmValue);
3655 strupper_m(*(char **)parm_ptr);
3656 break;
3657
3658 case P_GSTRING:
3659 pstrcpy((char *)parm_ptr, pszParmValue);
3660 break;
3661
3662 case P_UGSTRING:
3663 pstrcpy((char *)parm_ptr, pszParmValue);
3664 strupper_m((char *)parm_ptr);
3665 break;
3666
3667 case P_ENUM:
3668 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3669 break;
3670 case P_SEP:
3671 break;
3672 }
3673
3674 return (True);
3675}
3676
3677/***************************************************************************
3678 Process a parameter.
3679***************************************************************************/
3680
3681static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3682{
3683 if (!bInGlobalSection && bGlobalOnly)
3684 return (True);
3685
3686 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3687
3688 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3689 pszParmName, pszParmValue));
3690}
3691
3692/***************************************************************************
3693 Print a parameter of the specified type.
3694***************************************************************************/
3695
3696static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3697{
3698 int i;
3699 switch (p->type)
3700 {
3701 case P_ENUM:
3702 for (i = 0; p->enum_list[i].name; i++) {
3703 if (*(int *)ptr == p->enum_list[i].value) {
3704 fprintf(f, "%s",
3705 p->enum_list[i].name);
3706 break;
3707 }
3708 }
3709 break;
3710
3711 case P_BOOL:
3712 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3713 break;
3714
3715 case P_BOOLREV:
3716 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3717 break;
3718
3719 case P_INTEGER:
3720 fprintf(f, "%d", *(int *)ptr);
3721 break;
3722
3723 case P_CHAR:
3724 fprintf(f, "%c", *(char *)ptr);
3725 break;
3726
3727 case P_OCTAL:
3728 fprintf(f, "%s", octal_string(*(int *)ptr));
3729 break;
3730
3731 case P_LIST:
3732 if ((char ***)ptr && *(char ***)ptr) {
3733 char **list = *(char ***)ptr;
3734
3735 for (; *list; list++) {
3736 /* surround strings with whitespace in double quotes */
3737 if ( strchr_m( *list, ' ' ) )
3738 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3739 else
3740 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3741 }
3742 }
3743 break;
3744
3745 case P_GSTRING:
3746 case P_UGSTRING:
3747 if ((char *)ptr) {
3748 fprintf(f, "%s", (char *)ptr);
3749 }
3750 break;
3751
3752 case P_STRING:
3753 case P_USTRING:
3754 if (*(char **)ptr) {
3755 fprintf(f, "%s", *(char **)ptr);
3756 }
3757 break;
3758 case P_SEP:
3759 break;
3760 }
3761}
3762
3763/***************************************************************************
3764 Check if two parameters are equal.
3765***************************************************************************/
3766
3767static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3768{
3769 switch (type) {
3770 case P_BOOL:
3771 case P_BOOLREV:
3772 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3773
3774 case P_INTEGER:
3775 case P_ENUM:
3776 case P_OCTAL:
3777 return (*((int *)ptr1) == *((int *)ptr2));
3778
3779 case P_CHAR:
3780 return (*((char *)ptr1) == *((char *)ptr2));
3781
3782 case P_LIST:
3783 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3784
3785 case P_GSTRING:
3786 case P_UGSTRING:
3787 {
3788 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3789 if (p1 && !*p1)
3790 p1 = NULL;
3791 if (p2 && !*p2)
3792 p2 = NULL;
3793 return (p1 == p2 || strequal(p1, p2));
3794 }
3795 case P_STRING:
3796 case P_USTRING:
3797 {
3798 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3799 if (p1 && !*p1)
3800 p1 = NULL;
3801 if (p2 && !*p2)
3802 p2 = NULL;
3803 return (p1 == p2 || strequal(p1, p2));
3804 }
3805 case P_SEP:
3806 break;
3807 }
3808 return (False);
3809}
3810
3811/***************************************************************************
3812 Initialize any local varients in the sDefault table.
3813***************************************************************************/
3814
3815void init_locals(void)
3816{
3817 /* None as yet. */
3818}
3819
3820/***************************************************************************
3821 Process a new section (service). At this stage all sections are services.
3822 Later we'll have special sections that permit server parameters to be set.
3823 Returns True on success, False on failure.
3824***************************************************************************/
3825
3826static BOOL do_section(const char *pszSectionName)
3827{
3828 BOOL bRetval;
3829 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3830 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3831 bRetval = False;
3832
3833 /* if we were in a global section then do the local inits */
3834 if (bInGlobalSection && !isglobal)
3835 init_locals();
3836
3837 /* if we've just struck a global section, note the fact. */
3838 bInGlobalSection = isglobal;
3839
3840 /* check for multiple global sections */
3841 if (bInGlobalSection) {
3842 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3843 return (True);
3844 }
3845
3846 if (!bInGlobalSection && bGlobalOnly)
3847 return (True);
3848
3849 /* if we have a current service, tidy it up before moving on */
3850 bRetval = True;
3851
3852 if (iServiceIndex >= 0)
3853 bRetval = service_ok(iServiceIndex);
3854
3855 /* if all is still well, move to the next record in the services array */
3856 if (bRetval) {
3857 /* We put this here to avoid an odd message order if messages are */
3858 /* issued by the post-processing of a previous section. */
3859 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3860
3861 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3862 < 0) {
3863 DEBUG(0, ("Failed to add a new service\n"));
3864 return (False);
3865 }
3866 }
3867
3868 return (bRetval);
3869}
3870
3871
3872/***************************************************************************
3873 Determine if a partcular base parameter is currentl set to the default value.
3874***************************************************************************/
3875
3876static BOOL is_default(int i)
3877{
3878 if (!defaults_saved)
3879 return False;
3880 switch (parm_table[i].type) {
3881 case P_LIST:
3882 return str_list_compare (parm_table[i].def.lvalue,
3883 *(char ***)parm_table[i].ptr);
3884 case P_STRING:
3885 case P_USTRING:
3886 return strequal(parm_table[i].def.svalue,
3887 *(char **)parm_table[i].ptr);
3888 case P_GSTRING:
3889 case P_UGSTRING:
3890 return strequal(parm_table[i].def.svalue,
3891 (char *)parm_table[i].ptr);
3892 case P_BOOL:
3893 case P_BOOLREV:
3894 return parm_table[i].def.bvalue ==
3895 *(BOOL *)parm_table[i].ptr;
3896 case P_CHAR:
3897 return parm_table[i].def.cvalue ==
3898 *(char *)parm_table[i].ptr;
3899 case P_INTEGER:
3900 case P_OCTAL:
3901 case P_ENUM:
3902 return parm_table[i].def.ivalue ==
3903 *(int *)parm_table[i].ptr;
3904 case P_SEP:
3905 break;
3906 }
3907 return False;
3908}
3909
3910/***************************************************************************
3911Display the contents of the global structure.
3912***************************************************************************/
3913
3914static void dump_globals(FILE *f)
3915{
3916 int i;
3917 param_opt_struct *data;
3918
3919 fprintf(f, "[global]\n");
3920
3921 for (i = 0; parm_table[i].label; i++)
3922 if (parm_table[i].p_class == P_GLOBAL &&
3923 parm_table[i].ptr &&
3924 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3925 if (defaults_saved && is_default(i))
3926 continue;
3927 fprintf(f, "\t%s = ", parm_table[i].label);
3928 print_parameter(&parm_table[i], parm_table[i].ptr, f);
3929 fprintf(f, "\n");
3930 }
3931 if (Globals.param_opt != NULL) {
3932 data = Globals.param_opt;
3933 while(data) {
3934 fprintf(f, "\t%s = %s\n", data->key, data->value);
3935 data = data->next;
3936 }
3937 }
3938
3939}
3940
3941/***************************************************************************
3942 Return True if a local parameter is currently set to the global default.
3943***************************************************************************/
3944
3945BOOL lp_is_default(int snum, struct parm_struct *parm)
3946{
3947 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3948
3949 return equal_parameter(parm->type,
3950 ((char *)ServicePtrs[snum]) + pdiff,
3951 ((char *)&sDefault) + pdiff);
3952}
3953
3954/***************************************************************************
3955 Display the contents of a single services record.
3956***************************************************************************/
3957
3958static void dump_a_service(service * pService, FILE * f)
3959{
3960 int i;
3961 param_opt_struct *data;
3962
3963 if (pService != &sDefault)
3964 fprintf(f, "[%s]\n", pService->szService);
3965
3966 for (i = 0; parm_table[i].label; i++) {
3967
3968 if (parm_table[i].p_class == P_LOCAL &&
3969 parm_table[i].ptr &&
3970 (*parm_table[i].label != '-') &&
3971 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3972 {
3973
3974 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3975
3976 if (pService == &sDefault) {
3977 if (defaults_saved && is_default(i))
3978 continue;
3979 } else {
3980 if (equal_parameter(parm_table[i].type,
3981 ((char *)pService) +
3982 pdiff,
3983 ((char *)&sDefault) +
3984 pdiff))
3985 continue;
3986 }
3987
3988 fprintf(f, "\t%s = ", parm_table[i].label);
3989 print_parameter(&parm_table[i],
3990 ((char *)pService) + pdiff, f);
3991 fprintf(f, "\n");
3992 }
3993 }
3994
3995 if (pService->param_opt != NULL) {
3996 data = pService->param_opt;
3997 while(data) {
3998 fprintf(f, "\t%s = %s\n", data->key, data->value);
3999 data = data->next;
4000 }
4001 }
4002}
4003
4004/***************************************************************************
4005 Display the contents of a parameter of a single services record.
4006***************************************************************************/
4007
4008BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
4009{
4010 int i;
4011 BOOL result = False;
4012 parm_class p_class;
4013 unsigned flag = 0;
4014 fstring local_parm_name;
4015 char *parm_opt;
4016 const char *parm_opt_value;
4017
4018 /* check for parametrical option */
4019 fstrcpy( local_parm_name, parm_name);
4020 parm_opt = strchr( local_parm_name, ':');
4021
4022 if (parm_opt) {
4023 *parm_opt = '\0';
4024 parm_opt++;
4025 if (strlen(parm_opt)) {
4026 parm_opt_value = lp_parm_const_string( snum,
4027 local_parm_name, parm_opt, NULL);
4028 if (parm_opt_value) {
4029 printf( "%s\n", parm_opt_value);
4030 result = True;
4031 }
4032 }
4033 return result;
4034 }
4035
4036 /* check for a key and print the value */
4037 if (isGlobal) {
4038 p_class = P_GLOBAL;
4039 flag = FLAG_GLOBAL;
4040 } else
4041 p_class = P_LOCAL;
4042
4043 for (i = 0; parm_table[i].label; i++) {
4044 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
4045 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
4046 parm_table[i].ptr &&
4047 (*parm_table[i].label != '-') &&
4048 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4049 {
4050 void *ptr;
4051
4052 if (isGlobal) {
4053 ptr = parm_table[i].ptr;
4054 } else {
4055 service * pService = ServicePtrs[snum];
4056 ptr = ((char *)pService) +
4057 PTR_DIFF(parm_table[i].ptr, &sDefault);
4058 }
4059
4060 print_parameter(&parm_table[i],
4061 ptr, f);
4062 fprintf(f, "\n");
4063 result = True;
4064 break;
4065 }
4066 }
4067
4068 return result;
4069}
4070
4071/***************************************************************************
4072 Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
4073 Return NULL when out of parameters.
4074***************************************************************************/
4075
4076struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
4077{
4078 if (snum < 0) {
4079 /* do the globals */
4080 for (; parm_table[*i].label; (*i)++) {
4081 if (parm_table[*i].p_class == P_SEPARATOR)
4082 return &parm_table[(*i)++];
4083
4084 if (!parm_table[*i].ptr
4085 || (*parm_table[*i].label == '-'))
4086 continue;
4087
4088 if ((*i) > 0
4089 && (parm_table[*i].ptr ==
4090 parm_table[(*i) - 1].ptr))
4091 continue;
4092
4093 return &parm_table[(*i)++];
4094 }
4095 } else {
4096 service *pService = ServicePtrs[snum];
4097
4098 for (; parm_table[*i].label; (*i)++) {
4099 if (parm_table[*i].p_class == P_SEPARATOR)
4100 return &parm_table[(*i)++];
4101
4102 if (parm_table[*i].p_class == P_LOCAL &&
4103 parm_table[*i].ptr &&
4104 (*parm_table[*i].label != '-') &&
4105 ((*i) == 0 ||
4106 (parm_table[*i].ptr !=
4107 parm_table[(*i) - 1].ptr)))
4108 {
4109 int pdiff =
4110 PTR_DIFF(parm_table[*i].ptr,
4111 &sDefault);
4112
4113 if (allparameters ||
4114 !equal_parameter(parm_table[*i].type,
4115 ((char *)pService) +
4116 pdiff,
4117 ((char *)&sDefault) +
4118 pdiff))
4119 {
4120 return &parm_table[(*i)++];
4121 }
4122 }
4123 }
4124 }
4125
4126 return NULL;
4127}
4128
4129
4130#if 0
4131/***************************************************************************
4132 Display the contents of a single copy structure.
4133***************************************************************************/
4134static void dump_copy_map(BOOL *pcopymap)
4135{
4136 int i;
4137 if (!pcopymap)
4138 return;
4139
4140 printf("\n\tNon-Copied parameters:\n");
4141
4142 for (i = 0; parm_table[i].label; i++)
4143 if (parm_table[i].p_class == P_LOCAL &&
4144 parm_table[i].ptr && !pcopymap[i] &&
4145 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4146 {
4147 printf("\t\t%s\n", parm_table[i].label);
4148 }
4149}
4150#endif
4151
4152/***************************************************************************
4153 Return TRUE if the passed service number is within range.
4154***************************************************************************/
4155
4156BOOL lp_snum_ok(int iService)
4157{
4158 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4159}
4160
4161/***************************************************************************
4162 Auto-load some home services.
4163***************************************************************************/
4164
4165static void lp_add_auto_services(char *str)
4166{
4167 char *s;
4168 char *p;
4169 int homes;
4170
4171 if (!str)
4172 return;
4173
4174 s = SMB_STRDUP(str);
4175 if (!s)
4176 return;
4177
4178 homes = lp_servicenumber(HOMES_NAME);
4179
4180 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4181 char *home = get_user_home_dir(p);
4182
4183 if (lp_servicenumber(p) >= 0)
4184 continue;
4185
4186 if (home && home[0] && homes >= 0)
4187 lp_add_home(p, homes, p, home);
4188 }
4189 SAFE_FREE(s);
4190}
4191
4192/***************************************************************************
4193 Auto-load one printer.
4194***************************************************************************/
4195
4196void lp_add_one_printer(char *name, char *comment)
4197{
4198 int printers = lp_servicenumber(PRINTERS_NAME);
4199 int i;
4200
4201 if (lp_servicenumber(name) < 0) {
4202 lp_add_printer(name, printers);
4203 if ((i = lp_servicenumber(name)) >= 0) {
4204 string_set(&ServicePtrs[i]->comment, comment);
4205 ServicePtrs[i]->autoloaded = True;
4206 }
4207 }
4208}
4209
4210/***************************************************************************
4211 Have we loaded a services file yet?
4212***************************************************************************/
4213
4214BOOL lp_loaded(void)
4215{
4216 return (bLoaded);
4217}
4218
4219/***************************************************************************
4220 Unload unused services.
4221***************************************************************************/
4222
4223void lp_killunused(BOOL (*snumused) (int))
4224{
4225 int i;
4226 for (i = 0; i < iNumServices; i++) {
4227 if (!VALID(i))
4228 continue;
4229
4230 /* don't kill autoloaded or usershare services */
4231 if ( ServicePtrs[i]->autoloaded ||
4232 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4233 continue;
4234 }
4235
4236 if (!snumused || !snumused(i)) {
4237 free_service_byindex(i);
4238 }
4239 }
4240}
4241
4242/***************************************************************************
4243 Unload a service.
4244***************************************************************************/
4245
4246void lp_killservice(int iServiceIn)
4247{
4248 if (VALID(iServiceIn)) {
4249 free_service_byindex(iServiceIn);
4250 }
4251}
4252
4253/***************************************************************************
4254 Save the curent values of all global and sDefault parameters into the
4255 defaults union. This allows swat and testparm to show only the
4256 changed (ie. non-default) parameters.
4257***************************************************************************/
4258
4259static void lp_save_defaults(void)
4260{
4261 int i;
4262 for (i = 0; parm_table[i].label; i++) {
4263 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4264 continue;
4265 switch (parm_table[i].type) {
4266 case P_LIST:
4267 str_list_copy(&(parm_table[i].def.lvalue),
4268 *(const char ***)parm_table[i].ptr);
4269 break;
4270 case P_STRING:
4271 case P_USTRING:
4272 if (parm_table[i].ptr) {
4273 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4274 } else {
4275 parm_table[i].def.svalue = NULL;
4276 }
4277 break;
4278 case P_GSTRING:
4279 case P_UGSTRING:
4280 if (parm_table[i].ptr) {
4281 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4282 } else {
4283 parm_table[i].def.svalue = NULL;
4284 }
4285 break;
4286 case P_BOOL:
4287 case P_BOOLREV:
4288 parm_table[i].def.bvalue =
4289 *(BOOL *)parm_table[i].ptr;
4290 break;
4291 case P_CHAR:
4292 parm_table[i].def.cvalue =
4293 *(char *)parm_table[i].ptr;
4294 break;
4295 case P_INTEGER:
4296 case P_OCTAL:
4297 case P_ENUM:
4298 parm_table[i].def.ivalue =
4299 *(int *)parm_table[i].ptr;
4300 break;
4301 case P_SEP:
4302 break;
4303 }
4304 }
4305 defaults_saved = True;
4306}
4307
4308/*******************************************************************
4309 Set the server type we will announce as via nmbd.
4310********************************************************************/
4311
4312static const struct srv_role_tab {
4313 uint32 role;
4314 const char *role_str;
4315} srv_role_tab [] = {
4316 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4317 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4318 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4319 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4320 { 0, NULL }
4321};
4322
4323const char* server_role_str(uint32 role)
4324{
4325 int i = 0;
4326 for (i=0; srv_role_tab[i].role_str; i++) {
4327 if (role == srv_role_tab[i].role) {
4328 return srv_role_tab[i].role_str;
4329 }
4330 }
4331 return NULL;
4332}
4333
4334static void set_server_role(void)
4335{
4336 server_role = ROLE_STANDALONE;
4337
4338 switch (lp_security()) {
4339 case SEC_SHARE:
4340 if (lp_domain_logons())
4341 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4342 break;
4343 case SEC_SERVER:
4344 if (lp_domain_logons())
4345 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4346 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4347 server_role = ROLE_STANDALONE;
4348 break;
4349 case SEC_DOMAIN:
4350 if (lp_domain_logons()) {
4351 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4352 server_role = ROLE_DOMAIN_BDC;
4353 break;
4354 }
4355 server_role = ROLE_DOMAIN_MEMBER;
4356 break;
4357 case SEC_ADS:
4358 if (lp_domain_logons()) {
4359 server_role = ROLE_DOMAIN_PDC;
4360 break;
4361 }
4362 server_role = ROLE_DOMAIN_MEMBER;
4363 break;
4364 case SEC_USER:
4365 if (lp_domain_logons()) {
4366
4367 if (Globals.bDomainMaster) /* auto or yes */
4368 server_role = ROLE_DOMAIN_PDC;
4369 else
4370 server_role = ROLE_DOMAIN_BDC;
4371 }
4372 break;
4373 default:
4374 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4375 break;
4376 }
4377
4378 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4379}
4380
4381/***********************************************************
4382 If we should send plaintext/LANMAN passwords in the clinet
4383************************************************************/
4384
4385static void set_allowed_client_auth(void)
4386{
4387 if (Globals.bClientNTLMv2Auth) {
4388 Globals.bClientLanManAuth = False;
4389 }
4390 if (!Globals.bClientLanManAuth) {
4391 Globals.bClientPlaintextAuth = False;
4392 }
4393}
4394
4395/***************************************************************************
4396 JRA.
4397 The following code allows smbd to read a user defined share file.
4398 Yes, this is my intent. Yes, I'm comfortable with that...
4399
4400 THE FOLLOWING IS SECURITY CRITICAL CODE.
4401
4402 It washes your clothes, it cleans your house, it guards you while you sleep...
4403 Do not f%^k with it....
4404***************************************************************************/
4405
4406#define MAX_USERSHARE_FILE_SIZE (10*1024)
4407
4408/***************************************************************************
4409 Check allowed stat state of a usershare file.
4410 Ensure we print out who is dicking with us so the admin can
4411 get their sorry ass fired.
4412***************************************************************************/
4413
4414static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4415{
4416 if (!S_ISREG(psbuf->st_mode)) {
4417 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4418 "not a regular file\n",
4419 fname, (unsigned int)psbuf->st_uid ));
4420 return False;
4421 }
4422
4423 /* Ensure this doesn't have the other write bit set. */
4424 if (psbuf->st_mode & S_IWOTH) {
4425 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4426 "public write. Refusing to allow as a usershare file.\n",
4427 fname, (unsigned int)psbuf->st_uid ));
4428 return False;
4429 }
4430
4431 /* Should be 10k or less. */
4432 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4433 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4434 "too large (%u) to be a user share file.\n",
4435 fname, (unsigned int)psbuf->st_uid,
4436 (unsigned int)psbuf->st_size ));
4437 return False;
4438 }
4439
4440 return True;
4441}
4442
4443/***************************************************************************
4444 Parse the contents of a usershare file.
4445***************************************************************************/
4446
4447enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4448 SMB_STRUCT_STAT *psbuf,
4449 const char *servicename,
4450 int snum,
4451 char **lines,
4452 int numlines,
4453 pstring sharepath,
4454 pstring comment,
4455 SEC_DESC **ppsd,
4456 BOOL *pallow_guest)
4457{
4458 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4459 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4460 int us_vers;
4461 SMB_STRUCT_DIR *dp;
4462 SMB_STRUCT_STAT sbuf;
4463
4464 *pallow_guest = False;
4465
4466 if (numlines < 4) {
4467 return USERSHARE_MALFORMED_FILE;
4468 }
4469
4470 if (strcmp(lines[0], "#VERSION 1") == 0) {
4471 us_vers = 1;
4472 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4473 us_vers = 2;
4474 if (numlines < 5) {
4475 return USERSHARE_MALFORMED_FILE;
4476 }
4477 } else {
4478 return USERSHARE_BAD_VERSION;
4479 }
4480
4481 if (strncmp(lines[1], "path=", 5) != 0) {
4482 return USERSHARE_MALFORMED_PATH;
4483 }
4484
4485 pstrcpy(sharepath, &lines[1][5]);
4486 trim_string(sharepath, " ", " ");
4487
4488 if (strncmp(lines[2], "comment=", 8) != 0) {
4489 return USERSHARE_MALFORMED_COMMENT_DEF;
4490 }
4491
4492 pstrcpy(comment, &lines[2][8]);
4493 trim_string(comment, " ", " ");
4494 trim_char(comment, '"', '"');
4495
4496 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4497 return USERSHARE_MALFORMED_ACL_DEF;
4498 }
4499
4500 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4501 return USERSHARE_ACL_ERR;
4502 }
4503
4504 if (us_vers == 2) {
4505 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4506 return USERSHARE_MALFORMED_ACL_DEF;
4507 }
4508 if (lines[4][9] == 'y') {
4509 *pallow_guest = True;
4510 }
4511 }
4512
4513 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4514 /* Path didn't change, no checks needed. */
4515 return USERSHARE_OK;
4516 }
4517
4518 /* The path *must* be absolute. */
4519 if (sharepath[0] != '/') {
4520 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4521 servicename, sharepath));
4522 return USERSHARE_PATH_NOT_ABSOLUTE;
4523 }
4524
4525 /* If there is a usershare prefix deny list ensure one of these paths
4526 doesn't match the start of the user given path. */
4527 if (prefixdenylist) {
4528 int i;
4529 for ( i=0; prefixdenylist[i]; i++ ) {
4530 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4531 servicename, i, prefixdenylist[i], sharepath ));
4532 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4533 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4534 "usershare prefix deny list entries.\n",
4535 servicename, sharepath));
4536 return USERSHARE_PATH_IS_DENIED;
4537 }
4538 }
4539 }
4540
4541 /* If there is a usershare prefix allow list ensure one of these paths
4542 does match the start of the user given path. */
4543
4544 if (prefixallowlist) {
4545 int i;
4546 for ( i=0; prefixallowlist[i]; i++ ) {
4547 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4548 servicename, i, prefixallowlist[i], sharepath ));
4549 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4550 break;
4551 }
4552 }
4553 if (prefixallowlist[i] == NULL) {
4554 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4555 "usershare prefix allow list entries.\n",
4556 servicename, sharepath));
4557 return USERSHARE_PATH_NOT_ALLOWED;
4558 }
4559 }
4560
4561 /* Ensure this is pointing to a directory. */
4562 dp = sys_opendir(sharepath);
4563
4564 if (!dp) {
4565 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4566 servicename, sharepath));
4567 return USERSHARE_PATH_NOT_DIRECTORY;
4568 }
4569
4570 /* Ensure the owner of the usershare file has permission to share
4571 this directory. */
4572
4573 if (sys_stat(sharepath, &sbuf) == -1) {
4574 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4575 servicename, sharepath, strerror(errno) ));
4576 sys_closedir(dp);
4577 return USERSHARE_POSIX_ERR;
4578 }
4579
4580 sys_closedir(dp);
4581
4582 if (!S_ISDIR(sbuf.st_mode)) {
4583 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4584 servicename, sharepath ));
4585 return USERSHARE_PATH_NOT_DIRECTORY;
4586 }
4587
4588 /* Check if sharing is restricted to owner-only. */
4589 /* psbuf is the stat of the usershare definition file,
4590 sbuf is the stat of the target directory to be shared. */
4591
4592 if (lp_usershare_owner_only()) {
4593 /* root can share anything. */
4594 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4595 return USERSHARE_PATH_NOT_ALLOWED;
4596 }
4597 }
4598
4599 return USERSHARE_OK;
4600}
4601
4602/***************************************************************************
4603 Deal with a usershare file.
4604 Returns:
4605 >= 0 - snum
4606 -1 - Bad name, invalid contents.
4607 - service name already existed and not a usershare, problem
4608 with permissions to share directory etc.
4609***************************************************************************/
4610
4611static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4612{
4613 SMB_STRUCT_STAT sbuf;
4614 SMB_STRUCT_STAT lsbuf;
4615 pstring fname;
4616 pstring sharepath;
4617 pstring comment;
4618 fstring service_name;
4619 char **lines = NULL;
4620 int numlines = 0;
4621 int fd = -1;
4622 int iService = -1;
4623 TALLOC_CTX *ctx = NULL;
4624 SEC_DESC *psd = NULL;
4625 BOOL guest_ok = False;
4626
4627 /* Ensure share name doesn't contain invalid characters. */
4628 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4629 DEBUG(0,("process_usershare_file: share name %s contains "
4630 "invalid characters (any of %s)\n",
4631 file_name, INVALID_SHARENAME_CHARS ));
4632 return -1;
4633 }
4634
4635 fstrcpy(service_name, file_name);
4636
4637 pstrcpy(fname, dir_name);
4638 pstrcat(fname, "/");
4639 pstrcat(fname, file_name);
4640
4641 /* Minimize the race condition by doing an lstat before we
4642 open and fstat. Ensure this isn't a symlink link. */
4643
4644 if (sys_lstat(fname, &lsbuf) != 0) {
4645 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4646 fname, strerror(errno) ));
4647 return -1;
4648 }
4649
4650 /* This must be a regular file, not a symlink, directory or
4651 other strange filetype. */
4652 if (!check_usershare_stat(fname, &lsbuf)) {
4653 return -1;
4654 }
4655
4656 /* See if there is already a servicenum for this name. */
4657 /* tdb_fetch_int32 returns -1 if not found. */
4658 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4659
4660 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4661 /* Nothing changed - Mark valid and return. */
4662 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4663 service_name ));
4664 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4665 return iService;
4666 }
4667
4668 /* Try and open the file read only - no symlinks allowed. */
4669#ifdef O_NOFOLLOW
4670 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4671#else
4672 fd = sys_open(fname, O_RDONLY, 0);
4673#endif
4674
4675 if (fd == -1) {
4676 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4677 fname, strerror(errno) ));
4678 return -1;
4679 }
4680
4681 /* Now fstat to be *SURE* it's a regular file. */
4682 if (sys_fstat(fd, &sbuf) != 0) {
4683 close(fd);
4684 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4685 fname, strerror(errno) ));
4686 return -1;
4687 }
4688
4689 /* Is it the same dev/inode as was lstated ? */
4690 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4691 close(fd);
4692 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4693 "Symlink spoofing going on ?\n", fname ));
4694 return -1;
4695 }
4696
4697 /* This must be a regular file, not a symlink, directory or
4698 other strange filetype. */
4699 if (!check_usershare_stat(fname, &sbuf)) {
4700 return -1;
4701 }
4702
4703 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4704
4705 close(fd);
4706 if (lines == NULL) {
4707 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4708 fname, (unsigned int)sbuf.st_uid ));
4709 return -1;
4710 }
4711
4712 /* Should we allow printers to be shared... ? */
4713 ctx = talloc_init("usershare_sd_xctx");
4714 if (!ctx) {
4715 file_lines_free(lines);
4716 return 1;
4717 }
4718
4719 if (parse_usershare_file(ctx, &sbuf, service_name,
4720 iService, lines, numlines, sharepath,
4721 comment, &psd, &guest_ok) != USERSHARE_OK) {
4722 talloc_destroy(ctx);
4723 file_lines_free(lines);
4724 return -1;
4725 }
4726
4727 file_lines_free(lines);
4728
4729 /* Everything ok - add the service possibly using a template. */
4730 if (iService < 0) {
4731 const service *sp = &sDefault;
4732 if (snum_template != -1) {
4733 sp = ServicePtrs[snum_template];
4734 }
4735
4736 if ((iService = add_a_service(sp, service_name)) < 0) {
4737 DEBUG(0, ("process_usershare_file: Failed to add "
4738 "new service %s\n", service_name));
4739 talloc_destroy(ctx);
4740 return -1;
4741 }
4742
4743 /* Read only is controlled by usershare ACL below. */
4744 ServicePtrs[iService]->bRead_only = False;
4745 }
4746
4747 /* Write the ACL of the new/modified share. */
4748 if (!set_share_security(service_name, psd)) {
4749 DEBUG(0, ("process_usershare_file: Failed to set share "
4750 "security for user share %s\n",
4751 service_name ));
4752 lp_remove_service(iService);
4753 talloc_destroy(ctx);
4754 return -1;
4755 }
4756
4757 talloc_destroy(ctx);
4758
4759 /* If from a template it may be marked invalid. */
4760 ServicePtrs[iService]->valid = True;
4761
4762 /* Set the service as a valid usershare. */
4763 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4764
4765 /* Set guest access. */
4766 if (lp_usershare_allow_guests()) {
4767 ServicePtrs[iService]->bGuest_ok = guest_ok;
4768 }
4769
4770 /* And note when it was loaded. */
4771 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4772 string_set(&ServicePtrs[iService]->szPath, sharepath);
4773 string_set(&ServicePtrs[iService]->comment, comment);
4774
4775 return iService;
4776}
4777
4778/***************************************************************************
4779 Checks if a usershare entry has been modified since last load.
4780***************************************************************************/
4781
4782static BOOL usershare_exists(int iService, time_t *last_mod)
4783{
4784 SMB_STRUCT_STAT lsbuf;
4785 const char *usersharepath = Globals.szUsersharePath;
4786 pstring fname;
4787
4788 pstrcpy(fname, usersharepath);
4789 pstrcat(fname, "/");
4790 pstrcat(fname, ServicePtrs[iService]->szService);
4791
4792 if (sys_lstat(fname, &lsbuf) != 0) {
4793 return False;
4794 }
4795
4796 if (!S_ISREG(lsbuf.st_mode)) {
4797 return False;
4798 }
4799
4800 *last_mod = lsbuf.st_mtime;
4801 return True;
4802}
4803
4804/***************************************************************************
4805 Load a usershare service by name. Returns a valid servicenumber or -1.
4806***************************************************************************/
4807
4808int load_usershare_service(const char *servicename)
4809{
4810 SMB_STRUCT_STAT sbuf;
4811 const char *usersharepath = Globals.szUsersharePath;
4812 int max_user_shares = Globals.iUsershareMaxShares;
4813 int snum_template = -1;
4814
4815 if (*usersharepath == 0 || max_user_shares == 0) {
4816 return -1;
4817 }
4818
4819 if (sys_stat(usersharepath, &sbuf) != 0) {
4820 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4821 usersharepath, strerror(errno) ));
4822 return -1;
4823 }
4824
4825 if (!S_ISDIR(sbuf.st_mode)) {
4826 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4827 usersharepath ));
4828 return -1;
4829 }
4830
4831 /*
4832 * This directory must be owned by root, and have the 't' bit set.
4833 * It also must not be writable by "other".
4834 */
4835
4836#ifdef S_ISVTX
4837 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4838#else
4839 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4840#endif
4841 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4842 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4843 usersharepath ));
4844 return -1;
4845 }
4846
4847 /* Ensure the template share exists if it's set. */
4848 if (Globals.szUsershareTemplateShare[0]) {
4849 /* We can't use lp_servicenumber here as we are recommending that
4850 template shares have -valid=False set. */
4851 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4852 if (ServicePtrs[snum_template]->szService &&
4853 strequal(ServicePtrs[snum_template]->szService,
4854 Globals.szUsershareTemplateShare)) {
4855 break;
4856 }
4857 }
4858
4859 if (snum_template == -1) {
4860 DEBUG(0,("load_usershare_service: usershare template share %s "
4861 "does not exist.\n",
4862 Globals.szUsershareTemplateShare ));
4863 return -1;
4864 }
4865 }
4866
4867 return process_usershare_file(usersharepath, servicename, snum_template);
4868}
4869
4870/***************************************************************************
4871 Load all user defined shares from the user share directory.
4872 We only do this if we're enumerating the share list.
4873 This is the function that can delete usershares that have
4874 been removed.
4875***************************************************************************/
4876
4877int load_usershare_shares(void)
4878{
4879 SMB_STRUCT_DIR *dp;
4880 SMB_STRUCT_STAT sbuf;
4881 SMB_STRUCT_DIRENT *de;
4882 int num_usershares = 0;
4883 int max_user_shares = Globals.iUsershareMaxShares;
4884 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4885 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4886 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4887 int iService;
4888 int snum_template = -1;
4889 const char *usersharepath = Globals.szUsersharePath;
4890 int ret = lp_numservices();
4891
4892 if (max_user_shares == 0 || *usersharepath == '\0') {
4893 return lp_numservices();
4894 }
4895
4896 if (sys_stat(usersharepath, &sbuf) != 0) {
4897 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4898 usersharepath, strerror(errno) ));
4899 return ret;
4900 }
4901
4902 /*
4903 * This directory must be owned by root, and have the 't' bit set.
4904 * It also must not be writable by "other".
4905 */
4906
4907#ifdef S_ISVTX
4908 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4909#else
4910 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4911#endif
4912 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4913 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4914 usersharepath ));
4915 return ret;
4916 }
4917
4918 /* Ensure the template share exists if it's set. */
4919 if (Globals.szUsershareTemplateShare[0]) {
4920 /* We can't use lp_servicenumber here as we are recommending that
4921 template shares have -valid=False set. */
4922 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4923 if (ServicePtrs[snum_template]->szService &&
4924 strequal(ServicePtrs[snum_template]->szService,
4925 Globals.szUsershareTemplateShare)) {
4926 break;
4927 }
4928 }
4929
4930 if (snum_template == -1) {
4931 DEBUG(0,("load_usershare_shares: usershare template share %s "
4932 "does not exist.\n",
4933 Globals.szUsershareTemplateShare ));
4934 return ret;
4935 }
4936 }
4937
4938 /* Mark all existing usershares as pending delete. */
4939 for (iService = iNumServices - 1; iService >= 0; iService--) {
4940 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4941 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4942 }
4943 }
4944
4945 dp = sys_opendir(usersharepath);
4946 if (!dp) {
4947 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4948 usersharepath, strerror(errno) ));
4949 return ret;
4950 }
4951
4952 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4953 (de = sys_readdir(dp));
4954 num_dir_entries++ ) {
4955 int r;
4956 const char *n = de->d_name;
4957
4958 /* Ignore . and .. */
4959 if (*n == '.') {
4960 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4961 continue;
4962 }
4963 }
4964
4965 if (n[0] == ':') {
4966 /* Temporary file used when creating a share. */
4967 num_tmp_dir_entries++;
4968 }
4969
4970 /* Allow 20% tmp entries. */
4971 if (num_tmp_dir_entries > allowed_tmp_entries) {
4972 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4973 "in directory %s\n",
4974 num_tmp_dir_entries, usersharepath));
4975 break;
4976 }
4977
4978 r = process_usershare_file(usersharepath, n, snum_template);
4979 if (r == 0) {
4980 /* Update the services count. */
4981 num_usershares++;
4982 if (num_usershares >= max_user_shares) {
4983 DEBUG(0,("load_usershare_shares: max user shares reached "
4984 "on file %s in directory %s\n",
4985 n, usersharepath ));
4986 break;
4987 }
4988 } else if (r == -1) {
4989 num_bad_dir_entries++;
4990 }
4991
4992 /* Allow 20% bad entries. */
4993 if (num_bad_dir_entries > allowed_bad_entries) {
4994 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4995 "in directory %s\n",
4996 num_bad_dir_entries, usersharepath));
4997 break;
4998 }
4999
5000 /* Allow 20% bad entries. */
5001 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
5002 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
5003 "in directory %s\n",
5004 num_dir_entries, usersharepath));
5005 break;
5006 }
5007 }
5008
5009 sys_closedir(dp);
5010
5011 /* Sweep through and delete any non-refreshed usershares that are
5012 not currently in use. */
5013 for (iService = iNumServices - 1; iService >= 0; iService--) {
5014 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
5015 if (conn_snum_used(iService)) {
5016 continue;
5017 }
5018 /* Remove from the share ACL db. */
5019 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
5020 lp_servicename(iService) ));
5021 delete_share_security(snum2params_static(iService));
5022 free_service_byindex(iService);
5023 }
5024 }
5025
5026 return lp_numservices();
5027}
5028
5029/********************************************************
5030 Destroy global resources allocated in this file
5031********************************************************/
5032
5033void gfree_loadparm(void)
5034{
5035 struct file_lists *f;
5036 struct file_lists *next;
5037 int i;
5038
5039 lp_TALLOC_FREE();
5040
5041 /* Free the file lists */
5042
5043 f = file_lists;
5044 while( f ) {
5045 next = f->next;
5046 SAFE_FREE( f->name );
5047 SAFE_FREE( f->subfname );
5048 SAFE_FREE( f );
5049 f = next;
5050 }
5051
5052 /* Free resources allocated to services */
5053
5054 for ( i = 0; i < iNumServices; i++ ) {
5055 if ( VALID(i) ) {
5056 free_service_byindex(i);
5057 }
5058 }
5059
5060 SAFE_FREE( ServicePtrs );
5061 iNumServices = 0;
5062
5063 /* Now release all resources allocated to global
5064 parameters and the default service */
5065
5066 for (i = 0; parm_table[i].label; i++)
5067 {
5068 if ( parm_table[i].type == P_STRING
5069 || parm_table[i].type == P_USTRING )
5070 {
5071 string_free( (char**)parm_table[i].ptr );
5072 }
5073 else if (parm_table[i].type == P_LIST) {
5074 str_list_free( (char***)parm_table[i].ptr );
5075 }
5076 }
5077}
5078
5079/***************************************************************************
5080 Load the services array from the services file. Return True on success,
5081 False on failure.
5082***************************************************************************/
5083
5084BOOL lp_load(const char *pszFname,
5085 BOOL global_only,
5086 BOOL save_defaults,
5087 BOOL add_ipc,
5088 BOOL initialize_globals)
5089{
5090 pstring n2;
5091 BOOL bRetval;
5092 param_opt_struct *data, *pdata;
5093
5094 pstrcpy(n2, pszFname);
5095
5096 standard_sub_basic( get_current_username(), current_user_info.domain,
5097 n2,sizeof(n2) );
5098
5099 add_to_file_list(pszFname, n2);
5100
5101 bRetval = False;
5102
5103 DEBUG(3, ("lp_load: refreshing parameters\n"));
5104
5105 bInGlobalSection = True;
5106 bGlobalOnly = global_only;
5107
5108 init_globals(! initialize_globals);
5109 debug_init();
5110
5111 if (save_defaults) {
5112 init_locals();
5113 lp_save_defaults();
5114 }
5115
5116 if (Globals.param_opt != NULL) {
5117 data = Globals.param_opt;
5118 while (data) {
5119 string_free(&data->key);
5120 string_free(&data->value);
5121 str_list_free(&data->list);
5122 pdata = data->next;
5123 SAFE_FREE(data);
5124 data = pdata;
5125 }
5126 Globals.param_opt = NULL;
5127 }
5128
5129 /* We get sections first, so have to start 'behind' to make up */
5130 iServiceIndex = -1;
5131 bRetval = pm_process(n2, do_section, do_parameter);
5132
5133 /* finish up the last section */
5134 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5135 if (bRetval)
5136 if (iServiceIndex >= 0)
5137 bRetval = service_ok(iServiceIndex);
5138
5139 lp_add_auto_services(lp_auto_services());
5140
5141 if (add_ipc) {
5142 /* When 'restrict anonymous = 2' guest connections to ipc$
5143 are denied */
5144 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5145 if ( lp_enable_asu_support() )
5146 lp_add_ipc("ADMIN$", False);
5147 }
5148
5149 set_server_role();
5150 set_default_server_announce_type();
5151 set_allowed_client_auth();
5152
5153 bLoaded = True;
5154
5155 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5156 /* if bWINSsupport is true and we are in the client */
5157 if (in_client && Globals.bWINSsupport) {
5158 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5159 }
5160
5161 init_iconv();
5162
5163 return (bRetval);
5164}
5165
5166/***************************************************************************
5167 Reset the max number of services.
5168***************************************************************************/
5169
5170void lp_resetnumservices(void)
5171{
5172 iNumServices = 0;
5173}
5174
5175/***************************************************************************
5176 Return the max number of services.
5177***************************************************************************/
5178
5179int lp_numservices(void)
5180{
5181 return (iNumServices);
5182}
5183
5184/***************************************************************************
5185Display the contents of the services array in human-readable form.
5186***************************************************************************/
5187
5188void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
5189{
5190 int iService;
5191
5192 if (show_defaults)
5193 defaults_saved = False;
5194
5195 dump_globals(f);
5196
5197 dump_a_service(&sDefault, f);
5198
5199 for (iService = 0; iService < maxtoprint; iService++) {
5200 fprintf(f,"\n");
5201 lp_dump_one(f, show_defaults, iService);
5202 }
5203}
5204
5205/***************************************************************************
5206Display the contents of one service in human-readable form.
5207***************************************************************************/
5208
5209void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
5210{
5211 if (VALID(snum)) {
5212 if (ServicePtrs[snum]->szService[0] == '\0')
5213 return;
5214 dump_a_service(ServicePtrs[snum], f);
5215 }
5216}
5217
5218/***************************************************************************
5219Return the number of the service with the given name, or -1 if it doesn't
5220exist. Note that this is a DIFFERENT ANIMAL from the internal function
5221getservicebyname()! This works ONLY if all services have been loaded, and
5222does not copy the found service.
5223***************************************************************************/
5224
5225int lp_servicenumber(const char *pszServiceName)
5226{
5227 int iService;
5228 fstring serviceName;
5229
5230 if (!pszServiceName) {
5231 return GLOBAL_SECTION_SNUM;
5232 }
5233
5234 for (iService = iNumServices - 1; iService >= 0; iService--) {
5235 if (VALID(iService) && ServicePtrs[iService]->szService) {
5236 /*
5237 * The substitution here is used to support %U is
5238 * service names
5239 */
5240 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5241 standard_sub_basic(get_current_username(),
5242 current_user_info.domain,
5243 serviceName,sizeof(serviceName));
5244 if (strequal(serviceName, pszServiceName)) {
5245 break;
5246 }
5247 }
5248 }
5249
5250 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5251 time_t last_mod;
5252
5253 if (!usershare_exists(iService, &last_mod)) {
5254 /* Remove the share security tdb entry for it. */
5255 delete_share_security(snum2params_static(iService));
5256 /* Remove it from the array. */
5257 free_service_byindex(iService);
5258 /* Doesn't exist anymore. */
5259 return GLOBAL_SECTION_SNUM;
5260 }
5261
5262 /* Has it been modified ? If so delete and reload. */
5263 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5264 /* Remove it from the array. */
5265 free_service_byindex(iService);
5266 /* and now reload it. */
5267 iService = load_usershare_service(pszServiceName);
5268 }
5269 }
5270
5271 if (iService < 0) {
5272 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5273 return GLOBAL_SECTION_SNUM;
5274 }
5275
5276 return (iService);
5277}
5278
5279BOOL share_defined(const char *service_name)
5280{
5281 return (lp_servicenumber(service_name) != -1);
5282}
5283
5284struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5285 const char *sharename)
5286{
5287 struct share_params *result;
5288 char *sname;
5289 int snum;
5290
5291 if (!(sname = SMB_STRDUP(sharename))) {
5292 return NULL;
5293 }
5294
5295 snum = find_service(sname);
5296 SAFE_FREE(sname);
5297
5298 if (snum < 0) {
5299 return NULL;
5300 }
5301
5302 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5303 DEBUG(0, ("talloc failed\n"));
5304 return NULL;
5305 }
5306
5307 result->service = snum;
5308 return result;
5309}
5310
5311struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5312{
5313 struct share_iterator *result;
5314
5315 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5316 DEBUG(0, ("talloc failed\n"));
5317 return NULL;
5318 }
5319
5320 result->next_id = 0;
5321 return result;
5322}
5323
5324struct share_params *next_share(struct share_iterator *list)
5325{
5326 struct share_params *result;
5327
5328 while (!lp_snum_ok(list->next_id) &&
5329 (list->next_id < lp_numservices())) {
5330 list->next_id += 1;
5331 }
5332
5333 if (list->next_id >= lp_numservices()) {
5334 return NULL;
5335 }
5336
5337 if (!(result = TALLOC_P(list, struct share_params))) {
5338 DEBUG(0, ("talloc failed\n"));
5339 return NULL;
5340 }
5341
5342 result->service = list->next_id;
5343 list->next_id += 1;
5344 return result;
5345}
5346
5347struct share_params *next_printer(struct share_iterator *list)
5348{
5349 struct share_params *result;
5350
5351 while ((result = next_share(list)) != NULL) {
5352 if (lp_print_ok(result->service)) {
5353 break;
5354 }
5355 }
5356 return result;
5357}
5358
5359/*
5360 * This is a hack for a transition period until we transformed all code from
5361 * service numbers to struct share_params.
5362 */
5363
5364struct share_params *snum2params_static(int snum)
5365{
5366 static struct share_params result;
5367 result.service = snum;
5368 return &result;
5369}
5370
5371/*******************************************************************
5372 A useful volume label function.
5373********************************************************************/
5374
5375const char *volume_label(int snum)
5376{
5377 char *ret;
5378 const char *label = lp_volume(snum);
5379 if (!*label) {
5380 label = lp_servicename(snum);
5381 }
5382
5383 /* This returns a 33 byte guarenteed null terminated string. */
5384 ret = talloc_strndup(main_loop_talloc_get(), label, 32);
5385 if (!ret) {
5386 return "";
5387 }
5388 return ret;
5389}
5390
5391/*******************************************************************
5392 Set the server type we will announce as via nmbd.
5393********************************************************************/
5394
5395static void set_default_server_announce_type(void)
5396{
5397 default_server_announce = 0;
5398 default_server_announce |= SV_TYPE_WORKSTATION;
5399 default_server_announce |= SV_TYPE_SERVER;
5400 default_server_announce |= SV_TYPE_SERVER_UNIX;
5401
5402 /* note that the flag should be set only if we have a
5403 printer service but nmbd doesn't actually load the
5404 services so we can't tell --jerry */
5405
5406 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5407
5408 switch (lp_announce_as()) {
5409 case ANNOUNCE_AS_NT_SERVER:
5410 default_server_announce |= SV_TYPE_SERVER_NT;
5411 /* fall through... */
5412 case ANNOUNCE_AS_NT_WORKSTATION:
5413 default_server_announce |= SV_TYPE_NT;
5414 break;
5415 case ANNOUNCE_AS_WIN95:
5416 default_server_announce |= SV_TYPE_WIN95_PLUS;
5417 break;
5418 case ANNOUNCE_AS_WFW:
5419 default_server_announce |= SV_TYPE_WFW;
5420 break;
5421 default:
5422 break;
5423 }
5424
5425 switch (lp_server_role()) {
5426 case ROLE_DOMAIN_MEMBER:
5427 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5428 break;
5429 case ROLE_DOMAIN_PDC:
5430 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5431 break;
5432 case ROLE_DOMAIN_BDC:
5433 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5434 break;
5435 case ROLE_STANDALONE:
5436 default:
5437 break;
5438 }
5439 if (lp_time_server())
5440 default_server_announce |= SV_TYPE_TIME_SOURCE;
5441
5442 if (lp_host_msdfs())
5443 default_server_announce |= SV_TYPE_DFS_SERVER;
5444}
5445
5446/***********************************************************
5447 returns role of Samba server
5448************************************************************/
5449
5450int lp_server_role(void)
5451{
5452 return server_role;
5453}
5454
5455/***********************************************************
5456 If we are PDC then prefer us as DMB
5457************************************************************/
5458
5459BOOL lp_domain_master(void)
5460{
5461 if (Globals.bDomainMaster == Auto)
5462 return (lp_server_role() == ROLE_DOMAIN_PDC);
5463
5464 return Globals.bDomainMaster;
5465}
5466
5467/***********************************************************
5468 If we are DMB then prefer us as LMB
5469************************************************************/
5470
5471BOOL lp_preferred_master(void)
5472{
5473 if (Globals.bPreferredMaster == Auto)
5474 return (lp_local_master() && lp_domain_master());
5475
5476 return Globals.bPreferredMaster;
5477}
5478
5479/*******************************************************************
5480 Remove a service.
5481********************************************************************/
5482
5483void lp_remove_service(int snum)
5484{
5485 ServicePtrs[snum]->valid = False;
5486 invalid_services[num_invalid_services++] = snum;
5487}
5488
5489/*******************************************************************
5490 Copy a service.
5491********************************************************************/
5492
5493void lp_copy_service(int snum, const char *new_name)
5494{
5495 do_section(new_name);
5496 if (snum >= 0) {
5497 snum = lp_servicenumber(new_name);
5498 if (snum >= 0)
5499 lp_do_parameter(snum, "copy", lp_servicename(snum));
5500 }
5501}
5502
5503
5504/*******************************************************************
5505 Get the default server type we will announce as via nmbd.
5506********************************************************************/
5507
5508int lp_default_server_announce(void)
5509{
5510 return default_server_announce;
5511}
5512
5513/*******************************************************************
5514 Split the announce version into major and minor numbers.
5515********************************************************************/
5516
5517int lp_major_announce_version(void)
5518{
5519 static BOOL got_major = False;
5520 static int major_version = DEFAULT_MAJOR_VERSION;
5521 char *vers;
5522 char *p;
5523
5524 if (got_major)
5525 return major_version;
5526
5527 got_major = True;
5528 if ((vers = lp_announce_version()) == NULL)
5529 return major_version;
5530
5531 if ((p = strchr_m(vers, '.')) == 0)
5532 return major_version;
5533
5534 *p = '\0';
5535 major_version = atoi(vers);
5536 return major_version;
5537}
5538
5539int lp_minor_announce_version(void)
5540{
5541 static BOOL got_minor = False;
5542 static int minor_version = DEFAULT_MINOR_VERSION;
5543 char *vers;
5544 char *p;
5545
5546 if (got_minor)
5547 return minor_version;
5548
5549 got_minor = True;
5550 if ((vers = lp_announce_version()) == NULL)
5551 return minor_version;
5552
5553 if ((p = strchr_m(vers, '.')) == 0)
5554 return minor_version;
5555
5556 p++;
5557 minor_version = atoi(p);
5558 return minor_version;
5559}
5560
5561/***********************************************************
5562 Set the global name resolution order (used in smbclient).
5563************************************************************/
5564
5565void lp_set_name_resolve_order(const char *new_order)
5566{
5567 string_set(&Globals.szNameResolveOrder, new_order);
5568}
5569
5570const char *lp_printername(int snum)
5571{
5572 const char *ret = _lp_printername(snum);
5573 if (ret == NULL || (ret != NULL && *ret == '\0'))
5574 ret = lp_const_servicename(snum);
5575
5576 return ret;
5577}
5578
5579
5580/***********************************************************
5581 Allow daemons such as winbindd to fix their logfile name.
5582************************************************************/
5583
5584void lp_set_logfile(const char *name)
5585{
5586 string_set(&Globals.szLogFile, name);
5587 pstrcpy(debugf, name);
5588}
5589
5590/*******************************************************************
5591 Return the max print jobs per queue.
5592********************************************************************/
5593
5594int lp_maxprintjobs(int snum)
5595{
5596 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5597 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5598 maxjobs = PRINT_MAX_JOBID - 1;
5599
5600 return maxjobs;
5601}
5602
5603const char *lp_printcapname(void)
5604{
5605 if ((Globals.szPrintcapname != NULL) &&
5606 (Globals.szPrintcapname[0] != '\0'))
5607 return Globals.szPrintcapname;
5608
5609 if (sDefault.iPrinting == PRINT_CUPS) {
5610#ifdef HAVE_CUPS
5611 return "cups";
5612#else
5613 return "lpstat";
5614#endif
5615 }
5616
5617 if (sDefault.iPrinting == PRINT_BSD)
5618 return "/etc/printcap";
5619
5620 return PRINTCAP_NAME;
5621}
5622
5623/*******************************************************************
5624 Ensure we don't use sendfile if server smb signing is active.
5625********************************************************************/
5626
5627static uint32 spoolss_state;
5628
5629BOOL lp_disable_spoolss( void )
5630{
5631 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5632 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5633
5634 return spoolss_state == SVCCTL_STOPPED ? True : False;
5635}
5636
5637void lp_set_spoolss_state( uint32 state )
5638{
5639 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5640
5641 spoolss_state = state;
5642}
5643
5644uint32 lp_get_spoolss_state( void )
5645{
5646 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5647}
5648
5649/*******************************************************************
5650 Ensure we don't use sendfile if server smb signing is active.
5651********************************************************************/
5652
5653BOOL lp_use_sendfile(int snum)
5654{
5655 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5656 if (Protocol < PROTOCOL_NT1) {
5657 return False;
5658 }
5659 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5660}
5661
5662/*******************************************************************
5663 Turn off sendfile if we find the underlying OS doesn't support it.
5664********************************************************************/
5665
5666void set_use_sendfile(int snum, BOOL val)
5667{
5668 if (LP_SNUM_OK(snum))
5669 ServicePtrs[snum]->bUseSendfile = val;
5670 else
5671 sDefault.bUseSendfile = val;
5672}
5673
5674/*******************************************************************
5675 Turn off storing DOS attributes if this share doesn't support it.
5676********************************************************************/
5677
5678void set_store_dos_attributes(int snum, BOOL val)
5679{
5680 if (!LP_SNUM_OK(snum))
5681 return;
5682 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5683}
5684
5685void lp_set_mangling_method(const char *new_method)
5686{
5687 string_set(&Globals.szManglingMethod, new_method);
5688}
5689
5690/*******************************************************************
5691 Global state for POSIX pathname processing.
5692********************************************************************/
5693
5694static BOOL posix_pathnames;
5695
5696BOOL lp_posix_pathnames(void)
5697{
5698 return posix_pathnames;
5699}
5700
5701/*******************************************************************
5702 Change everything needed to ensure POSIX pathname processing (currently
5703 not much).
5704********************************************************************/
5705
5706void lp_set_posix_pathnames(void)
5707{
5708 posix_pathnames = True;
5709}
5710
5711/*******************************************************************
5712 Global state for POSIX lock processing - CIFS unix extensions.
5713********************************************************************/
5714
5715BOOL posix_default_lock_was_set;
5716static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5717
5718enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5719{
5720 if (posix_default_lock_was_set) {
5721 return posix_cifsx_locktype;
5722 } else {
5723 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5724 }
5725}
5726
5727/*******************************************************************
5728********************************************************************/
5729
5730void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5731{
5732 posix_default_lock_was_set = True;
5733 posix_cifsx_locktype = val;
5734}
Note: See TracBrowser for help on using the repository browser.