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

Last change on this file since 311 was 307, checked in by Silvan Scherrer, 16 years ago

attemp to fix ticket 100 in the 3.0 tree

File size: 197.4 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
5
6 Largely re-written by Andrew Tridgell, September 1994
7
8 Copyright (C) Simo Sorce 2001
9 Copyright (C) Alexander Bokovoy 2002
10 Copyright (C) Stefan (metze) Metzmacher 2002
11 Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
12
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2 of the License, or
16 (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/
27
28/*
29 * Load parameters.
30 *
31 * This module provides suitable callback functions for the params
32 * module. It builds the internal table of service details which is
33 * then used by the rest of the server.
34 *
35 * To add a parameter:
36 *
37 * 1) add it to the global or service structure definition
38 * 2) add it to the parm_table
39 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40 * 4) If it's a global then initialise it in init_globals. If a local
41 * (ie. service) parameter then initialise it in the sDefault structure
42 *
43 *
44 * Notes:
45 * The configuration file is processed sequentially for speed. It is NOT
46 * accessed randomly as happens in 'real' Windows. For this reason, there
47 * is a fair bit of sequence-dependent code here - ie., code which assumes
48 * that certain things happen before others. In particular, the code which
49 * happens at the boundary between sections is delicately poised, so be
50 * careful!
51 *
52 */
53
54#include "includes.h"
55
56BOOL in_client = False; /* Not in the client by default */
57BOOL bLoaded = False;
58
59extern pstring user_socket_options;
60extern enum protocol_types Protocol;
61extern userdom_struct current_user_info;
62
63#ifndef GLOBAL_NAME
64#define GLOBAL_NAME "global"
65#endif
66
67#ifndef PRINTERS_NAME
68#define PRINTERS_NAME "printers"
69#endif
70
71#ifndef HOMES_NAME
72#define HOMES_NAME "homes"
73#endif
74
75/* some helpful bits */
76#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
77#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
78
79#define USERSHARE_VALID 1
80#define USERSHARE_PENDING_DELETE 2
81
82int keepalive = DEFAULT_KEEPALIVE;
83BOOL use_getwd_cache = True;
84
85extern int extra_time_offset;
86
87static BOOL defaults_saved = False;
88
89typedef struct _param_opt_struct param_opt_struct;
90struct _param_opt_struct {
91 param_opt_struct *prev, *next;
92 char *key;
93 char *value;
94 char **list;
95};
96
97/*
98 * This structure describes global (ie., server-wide) parameters.
99 */
100typedef struct {
101 char *smb_ports;
102 char *dos_charset;
103 char *unix_charset;
104 char *display_charset;
105 char *szPrintcapname;
106 char *szAddPortCommand;
107 char *szEnumPortsCommand;
108 char *szAddPrinterCommand;
109 char *szDeletePrinterCommand;
110 char *szOs2DriverMap;
111 char *szLockDir;
112 char *szPidDir;
113 char *szRootdir;
114 char *szDefaultService;
115 char *szGetQuota;
116 char *szSetQuota;
117 char *szMsgCommand;
118 char *szServerString;
119 char *szAutoServices;
120 char *szPasswdProgram;
121 char *szPasswdChat;
122 char *szLogFile;
123 char *szConfigFile;
124 char *szSMBPasswdFile;
125 char *szPrivateDir;
126 char *szPassdbBackend;
127 char **szPreloadModules;
128 char *szPasswordServer;
129 char *szSocketOptions;
130 char *szRealm;
131 char *szAfsUsernameMap;
132 int iAfsTokenLifetime;
133 char *szLogNtTokenCommand;
134 char *szUsernameMap;
135 char *szLogonScript;
136 char *szLogonPath;
137 char *szLogonDrive;
138 char *szLogonHome;
139 char **szWINSservers;
140 char **szInterfaces;
141 char *szRemoteAnnounce;
142 char *szRemoteBrowseSync;
143 char *szSocketAddress;
144 char *szNISHomeMapName;
145 char *szAnnounceVersion; /* This is initialised in init_globals */
146 char *szWorkgroup;
147 char *szNetbiosName;
148 char **szNetbiosAliases;
149 char *szNetbiosScope;
150 char *szNameResolveOrder;
151 char *szPanicAction;
152 char *szAddUserScript;
153 char *szRenameUserScript;
154 char *szDelUserScript;
155 char *szAddGroupScript;
156 char *szDelGroupScript;
157 char *szAddUserToGroupScript;
158 char *szDelUserFromGroupScript;
159 char *szSetPrimaryGroupScript;
160 char *szAddMachineScript;
161 char *szShutdownScript;
162 char *szAbortShutdownScript;
163 char *szUsernameMapScript;
164 char *szCheckPasswordScript;
165 char *szWINSHook;
166 char *szUtmpDir;
167 char *szWtmpDir;
168 BOOL bUtmp;
169 char *szIdmapUID;
170 char *szIdmapGID;
171 BOOL bPassdbExpandExplicit;
172 int AlgorithmicRidBase;
173 char *szTemplateHomedir;
174 char *szTemplateShell;
175 char *szWinbindSeparator;
176 BOOL bWinbindEnumUsers;
177 BOOL bWinbindEnumGroups;
178 BOOL bWinbindUseDefaultDomain;
179 BOOL bWinbindTrustedDomainsOnly;
180 BOOL bWinbindNestedGroups;
181 BOOL bWinbindRefreshTickets;
182 BOOL bWinbindOfflineLogon;
183 BOOL bWinbindNormalizeNames;
184 char **szIdmapDomains;
185 char **szIdmapBackend; /* deprecated */
186 char *szIdmapAllocBackend;
187 char *szAddShareCommand;
188 char *szChangeShareCommand;
189 char *szDeleteShareCommand;
190 char **szEventLogs;
191 char *szGuestaccount;
192 char *szManglingMethod;
193 char **szServicesList;
194 char *szUsersharePath;
195 char *szUsershareTemplateShare;
196 char **szUsersharePrefixAllowList;
197 char **szUsersharePrefixDenyList;
198 int mangle_prefix;
199 int max_log_size;
200 char *szLogLevel;
201 int max_xmit;
202 int max_mux;
203 int max_open_files;
204 int open_files_db_hash_size;
205 int pwordlevel;
206 int unamelevel;
207 int deadtime;
208 int maxprotocol;
209 int minprotocol;
210 int security;
211 char **AuthMethods;
212 BOOL paranoid_server_security;
213 int maxdisksize;
214 int lpqcachetime;
215 int iMaxSmbdProcesses;
216 BOOL bDisableSpoolss;
217 int syslog;
218 int os_level;
219 int enhanced_browsing;
220 int max_ttl;
221 int max_wins_ttl;
222 int min_wins_ttl;
223 int lm_announce;
224 int lm_interval;
225 int announce_as; /* This is initialised in init_globals */
226 int machine_password_timeout;
227 int map_to_guest;
228 int oplock_break_wait_time;
229 int winbind_cache_time;
230 int winbind_max_idle_children;
231 char **szWinbindNssInfo;
232 int iLockSpinTime;
233 char *szLdapMachineSuffix;
234 char *szLdapUserSuffix;
235 char *szLdapIdmapSuffix;
236 char *szLdapGroupSuffix;
237 int ldap_ssl;
238 char *szLdapSuffix;
239 char *szLdapAdminDn;
240 int ldap_debug_level;
241 int ldap_debug_threshold;
242 int iAclCompat;
243 char *szCupsServer;
244 char *szIPrintServer;
245 int ldap_passwd_sync;
246 int ldap_replication_sleep;
247 int ldap_timeout; /* This is initialised in init_globals */
248 int ldap_page_size;
249 BOOL ldap_delete_dn;
250 BOOL bMsAddPrinterWizard;
251 BOOL bDNSproxy;
252 BOOL bWINSsupport;
253 BOOL bWINSproxy;
254 BOOL bLocalMaster;
255 BOOL bPreferredMaster;
256 BOOL bDomainMaster;
257 BOOL bDomainLogons;
258 BOOL bEncryptPasswords;
259 BOOL bUpdateEncrypt;
260 int clientSchannel;
261 int serverSchannel;
262 BOOL bNullPasswords;
263 BOOL bObeyPamRestrictions;
264 BOOL bLoadPrinters;
265 int PrintcapCacheTime;
266 BOOL bLargeReadwrite;
267 BOOL bReadRaw;
268 BOOL bWriteRaw;
269 BOOL bReadbmpx;
270 BOOL bSyslogOnly;
271 BOOL bBrowseList;
272 BOOL bNISHomeMap;
273 BOOL bTimeServer;
274 BOOL bBindInterfacesOnly;
275 BOOL bPamPasswordChange;
276 BOOL bUnixPasswdSync;
277 BOOL bPasswdChatDebug;
278 int iPasswdChatTimeout;
279 BOOL bTimestampLogs;
280 BOOL bNTSmbSupport;
281 BOOL bNTPipeSupport;
282 BOOL bNTStatusSupport;
283 BOOL bStatCache;
284 int iMaxStatCacheSize;
285 BOOL bKernelOplocks;
286 BOOL bAllowTrustedDomains;
287 BOOL bLanmanAuth;
288 BOOL bNTLMAuth;
289 BOOL bUseSpnego;
290 BOOL bClientLanManAuth;
291 BOOL bClientNTLMv2Auth;
292 BOOL bClientPlaintextAuth;
293 BOOL bClientUseSpnego;
294 BOOL bDebugPrefixTimestamp;
295 BOOL bDebugHiresTimestamp;
296 BOOL bDebugPid;
297 BOOL bDebugUid;
298 BOOL bEnableCoreFiles;
299 BOOL bHostMSDfs;
300 BOOL bUseMmap;
301 BOOL bHostnameLookups;
302 BOOL bUnixExtensions;
303 BOOL bDisableNetbios;
304 BOOL bUseKerberosKeytab;
305 BOOL bDeferSharingViolations;
306 BOOL bEnablePrivileges;
307 BOOL bASUSupport;
308 BOOL bUsershareOwnerOnly;
309 BOOL bUsershareAllowGuests;
310 int restrict_anonymous;
311 int name_cache_timeout;
312 int client_signing;
313 int server_signing;
314 int iUsershareMaxShares;
315 int iIdmapCacheTime;
316 int iIdmapNegativeCacheTime;
317
318 BOOL bResetOnZeroVC;
319 param_opt_struct *param_opt;
320} global;
321
322static global Globals;
323
324/*
325 * This structure describes a single service.
326 */
327typedef struct {
328 BOOL valid;
329 BOOL autoloaded;
330 int usershare;
331 time_t usershare_last_mod;
332 char *szService;
333 char *szPath;
334 char *szUsername;
335 char **szInvalidUsers;
336 char **szValidUsers;
337 char **szAdminUsers;
338 char *szCopy;
339 char *szInclude;
340 char *szPreExec;
341 char *szPostExec;
342 char *szRootPreExec;
343 char *szRootPostExec;
344 char *szCupsOptions;
345 char *szPrintcommand;
346 char *szLpqcommand;
347 char *szLprmcommand;
348 char *szLppausecommand;
349 char *szLpresumecommand;
350 char *szQueuepausecommand;
351 char *szQueueresumecommand;
352 char *szPrintername;
353 char *szPrintjobUsername;
354 char *szDontdescend;
355 char **szHostsallow;
356 char **szHostsdeny;
357 char *szMagicScript;
358 char *szMagicOutput;
359 char *szMangledMap;
360 char *szVetoFiles;
361 char *szHideFiles;
362 char *szVetoOplockFiles;
363 char *comment;
364 char *force_user;
365 char *force_group;
366 char **readlist;
367 char **writelist;
368 char **printer_admin;
369 char *volume;
370 char *fstype;
371 char **szVfsObjects;
372 char *szMSDfsProxy;
373 char *szAioWriteBehind;
374 char *szDfree;
375 int iMinPrintSpace;
376 int iMaxPrintJobs;
377 int iMaxReportedPrintJobs;
378 int iWriteCacheSize;
379 int iCreate_mask;
380 int iCreate_force_mode;
381 int iSecurity_mask;
382 int iSecurity_force_mode;
383 int iDir_mask;
384 int iDir_force_mode;
385 int iDir_Security_mask;
386 int iDir_Security_force_mode;
387 int iMaxConnections;
388 int iDefaultCase;
389 int iPrinting;
390 int iOplockContentionLimit;
391 int iCSCPolicy;
392 int iBlock_size;
393 int iDfreeCacheTime;
394 BOOL bPreexecClose;
395 BOOL bRootpreexecClose;
396 int iCaseSensitive;
397 BOOL bCasePreserve;
398 BOOL bShortCasePreserve;
399 BOOL bHideDotFiles;
400 BOOL bHideSpecialFiles;
401 BOOL bHideUnReadable;
402 BOOL bHideUnWriteableFiles;
403 BOOL bBrowseable;
404 BOOL bAvailable;
405 BOOL bRead_only;
406 BOOL bNo_set_dir;
407 BOOL bGuest_only;
408 BOOL bAdministrative_share;
409 BOOL bGuest_ok;
410 BOOL bPrint_ok;
411 BOOL bMap_system;
412 BOOL bMap_hidden;
413 BOOL bMap_archive;
414 BOOL bStoreDosAttributes;
415 BOOL bDmapiSupport;
416 BOOL bLocking;
417 int iStrictLocking;
418 BOOL bPosixLocking;
419 BOOL bShareModes;
420 BOOL bOpLocks;
421 BOOL bLevel2OpLocks;
422 BOOL bOnlyUser;
423 BOOL bMangledNames;
424 BOOL bWidelinks;
425 BOOL bSymlinks;
426 BOOL bSyncAlways;
427 BOOL bStrictAllocate;
428 BOOL bStrictSync;
429 char magic_char;
430 BOOL *copymap;
431 BOOL bDeleteReadonly;
432 BOOL bFakeOplocks;
433 BOOL bDeleteVetoFiles;
434 BOOL bDosFilemode;
435 BOOL bDosFiletimes;
436 BOOL bDosFiletimeResolution;
437 BOOL bFakeDirCreateTimes;
438 BOOL bBlockingLocks;
439 BOOL bInheritPerms;
440 BOOL bInheritACLS;
441 BOOL bInheritOwner;
442 BOOL bMSDfsRoot;
443 BOOL bUseClientDriver;
444 BOOL bDefaultDevmode;
445 BOOL bForcePrintername;
446 BOOL bNTAclSupport;
447 BOOL bForceUnknownAclUser;
448 BOOL bUseSendfile;
449 BOOL bProfileAcls;
450 BOOL bMap_acl_inherit;
451 BOOL bAfs_Share;
452 BOOL bEASupport;
453 BOOL bAclCheckPermissions;
454 BOOL bAclMapFullControl;
455 BOOL bAclGroupControl;
456 BOOL bChangeNotify;
457 BOOL bKernelChangeNotify;
458 int iallocation_roundup_size;
459 int iAioReadSize;
460 int iAioWriteSize;
461 int iMap_readonly;
462 int iDirectoryNameCacheSize;
463 param_opt_struct *param_opt;
464
465 char dummy[3]; /* for alignment */
466} service;
467
468
469/* This is a default service used to prime a services structure */
470static service sDefault = {
471 True, /* valid */
472 False, /* not autoloaded */
473 0, /* not a usershare */
474 (time_t)0, /* No last mod time */
475 NULL, /* szService */
476 NULL, /* szPath */
477 NULL, /* szUsername */
478 NULL, /* szInvalidUsers */
479 NULL, /* szValidUsers */
480 NULL, /* szAdminUsers */
481 NULL, /* szCopy */
482 NULL, /* szInclude */
483 NULL, /* szPreExec */
484 NULL, /* szPostExec */
485 NULL, /* szRootPreExec */
486 NULL, /* szRootPostExec */
487 NULL, /* szCupsOptions */
488 NULL, /* szPrintcommand */
489 NULL, /* szLpqcommand */
490 NULL, /* szLprmcommand */
491 NULL, /* szLppausecommand */
492 NULL, /* szLpresumecommand */
493 NULL, /* szQueuepausecommand */
494 NULL, /* szQueueresumecommand */
495 NULL, /* szPrintername */
496 NULL, /* szPrintjobUsername */
497 NULL, /* szDontdescend */
498 NULL, /* szHostsallow */
499 NULL, /* szHostsdeny */
500 NULL, /* szMagicScript */
501 NULL, /* szMagicOutput */
502 NULL, /* szMangledMap */
503 NULL, /* szVetoFiles */
504 NULL, /* szHideFiles */
505 NULL, /* szVetoOplockFiles */
506 NULL, /* comment */
507 NULL, /* force user */
508 NULL, /* force group */
509 NULL, /* readlist */
510 NULL, /* writelist */
511 NULL, /* printer admin */
512 NULL, /* volume */
513 NULL, /* fstype */
514 NULL, /* vfs objects */
515 NULL, /* szMSDfsProxy */
516 NULL, /* szAioWriteBehind */
517 NULL, /* szDfree */
518 0, /* iMinPrintSpace */
519 1000, /* iMaxPrintJobs */
520 0, /* iMaxReportedPrintJobs */
521 0, /* iWriteCacheSize */
522 0744, /* iCreate_mask */
523 0000, /* iCreate_force_mode */
524 0777, /* iSecurity_mask */
525 0, /* iSecurity_force_mode */
526 0755, /* iDir_mask */
527 0000, /* iDir_force_mode */
528 0777, /* iDir_Security_mask */
529 0, /* iDir_Security_force_mode */
530 0, /* iMaxConnections */
531 CASE_LOWER, /* iDefaultCase */
532 DEFAULT_PRINTING, /* iPrinting */
533 2, /* iOplockContentionLimit */
534 0, /* iCSCPolicy */
535 1024, /* iBlock_size */
536 0, /* iDfreeCacheTime */
537 False, /* bPreexecClose */
538 False, /* bRootpreexecClose */
539 Auto, /* case sensitive */
540 True, /* case preserve */
541 True, /* short case preserve */
542 True, /* bHideDotFiles */
543 False, /* bHideSpecialFiles */
544 False, /* bHideUnReadable */
545 False, /* bHideUnWriteableFiles */
546 True, /* bBrowseable */
547 True, /* bAvailable */
548 True, /* bRead_only */
549 True, /* bNo_set_dir */
550 False, /* bGuest_only */
551 False, /* bAdministrative_share */
552 False, /* bGuest_ok */
553 False, /* bPrint_ok */
554 False, /* bMap_system */
555 False, /* bMap_hidden */
556 True, /* bMap_archive */
557 False, /* bStoreDosAttributes */
558 False, /* bDmapiSupport */
559 True, /* bLocking */
560 Auto, /* iStrictLocking */
561 True, /* bPosixLocking */
562 True, /* bShareModes */
563 True, /* bOpLocks */
564 True, /* bLevel2OpLocks */
565 False, /* bOnlyUser */
566 True, /* bMangledNames */
567 True, /* bWidelinks */
568 True, /* bSymlinks */
569 False, /* bSyncAlways */
570 False, /* bStrictAllocate */
571 False, /* bStrictSync */
572 '~', /* magic char */
573 NULL, /* copymap */
574 False, /* bDeleteReadonly */
575 False, /* bFakeOplocks */
576 False, /* bDeleteVetoFiles */
577 False, /* bDosFilemode */
578 True, /* bDosFiletimes */
579 False, /* bDosFiletimeResolution */
580 False, /* bFakeDirCreateTimes */
581 True, /* bBlockingLocks */
582 False, /* bInheritPerms */
583 False, /* bInheritACLS */
584 False, /* bInheritOwner */
585 False, /* bMSDfsRoot */
586 False, /* bUseClientDriver */
587 True, /* bDefaultDevmode */
588 False, /* bForcePrintername */
589 True, /* bNTAclSupport */
590 False, /* bForceUnknownAclUser */
591 False, /* bUseSendfile */
592 False, /* bProfileAcls */
593 False, /* bMap_acl_inherit */
594 False, /* bAfs_Share */
595 False, /* bEASupport */
596 True, /* bAclCheckPermissions */
597 True, /* bAclMapFullControl */
598 False, /* bAclGroupControl */
599 True, /* bChangeNotify */
600 True, /* bKernelChangeNotify */
601 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
602 0, /* iAioReadSize */
603 0, /* iAioWriteSize */
604 MAP_READONLY_YES, /* iMap_readonly */
605#ifdef BROKEN_DIRECTORY_HANDLING
606 0, /* iDirectoryNameCacheSize */
607#else
608 100, /* iDirectoryNameCacheSize */
609#endif
610 NULL, /* Parametric options */
611
612 "" /* dummy */
613};
614
615/* local variables */
616static service **ServicePtrs = NULL;
617static int iNumServices = 0;
618static int iServiceIndex = 0;
619static TDB_CONTEXT *ServiceHash;
620static int *invalid_services = NULL;
621static int num_invalid_services = 0;
622static BOOL bInGlobalSection = True;
623static BOOL bGlobalOnly = False;
624static int server_role;
625static int default_server_announce;
626
627#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
628
629/* prototypes for the special type handlers */
630static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
631static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
632static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
633static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
634static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
635static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
636static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
637static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
638static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
639static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
640static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
641static BOOL handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
642
643static void set_server_role(void);
644static void set_default_server_announce_type(void);
645static void set_allowed_client_auth(void);
646
647static const struct enum_list enum_protocol[] = {
648 {PROTOCOL_NT1, "NT1"},
649 {PROTOCOL_LANMAN2, "LANMAN2"},
650 {PROTOCOL_LANMAN1, "LANMAN1"},
651 {PROTOCOL_CORE, "CORE"},
652 {PROTOCOL_COREPLUS, "COREPLUS"},
653 {PROTOCOL_COREPLUS, "CORE+"},
654 {-1, NULL}
655};
656
657static const struct enum_list enum_security[] = {
658 {SEC_SHARE, "SHARE"},
659 {SEC_USER, "USER"},
660 {SEC_SERVER, "SERVER"},
661 {SEC_DOMAIN, "DOMAIN"},
662#ifdef HAVE_ADS
663 {SEC_ADS, "ADS"},
664#endif
665 {-1, NULL}
666};
667
668static const struct enum_list enum_printing[] = {
669 {PRINT_SYSV, "sysv"},
670 {PRINT_AIX, "aix"},
671 {PRINT_HPUX, "hpux"},
672 {PRINT_BSD, "bsd"},
673 {PRINT_QNX, "qnx"},
674 {PRINT_PLP, "plp"},
675 {PRINT_LPRNG, "lprng"},
676 {PRINT_CUPS, "cups"},
677 {PRINT_IPRINT, "iprint"},
678 {PRINT_LPRNT, "nt"},
679 {PRINT_LPROS2, "os2"},
680#ifdef DEVELOPER
681 {PRINT_TEST, "test"},
682 {PRINT_VLP, "vlp"},
683#endif /* DEVELOPER */
684 {-1, NULL}
685};
686
687static const struct enum_list enum_ldap_ssl[] = {
688 {LDAP_SSL_OFF, "no"},
689 {LDAP_SSL_OFF, "No"},
690 {LDAP_SSL_OFF, "off"},
691 {LDAP_SSL_OFF, "Off"},
692 {LDAP_SSL_START_TLS, "start tls"},
693 {LDAP_SSL_START_TLS, "Start_tls"},
694 {-1, NULL}
695};
696
697static const struct enum_list enum_ldap_passwd_sync[] = {
698 {LDAP_PASSWD_SYNC_OFF, "no"},
699 {LDAP_PASSWD_SYNC_OFF, "No"},
700 {LDAP_PASSWD_SYNC_OFF, "off"},
701 {LDAP_PASSWD_SYNC_OFF, "Off"},
702 {LDAP_PASSWD_SYNC_ON, "Yes"},
703 {LDAP_PASSWD_SYNC_ON, "yes"},
704 {LDAP_PASSWD_SYNC_ON, "on"},
705 {LDAP_PASSWD_SYNC_ON, "On"},
706 {LDAP_PASSWD_SYNC_ONLY, "Only"},
707 {LDAP_PASSWD_SYNC_ONLY, "only"},
708 {-1, NULL}
709};
710
711/* Types of machine we can announce as. */
712#define ANNOUNCE_AS_NT_SERVER 1
713#define ANNOUNCE_AS_WIN95 2
714#define ANNOUNCE_AS_WFW 3
715#define ANNOUNCE_AS_NT_WORKSTATION 4
716
717static const struct enum_list enum_announce_as[] = {
718 {ANNOUNCE_AS_NT_SERVER, "NT"},
719 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
720 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
721 {ANNOUNCE_AS_WIN95, "win95"},
722 {ANNOUNCE_AS_WFW, "WfW"},
723 {-1, NULL}
724};
725
726static const struct enum_list enum_map_readonly[] = {
727 {MAP_READONLY_NO, "no"},
728 {MAP_READONLY_NO, "false"},
729 {MAP_READONLY_NO, "0"},
730 {MAP_READONLY_YES, "yes"},
731 {MAP_READONLY_YES, "true"},
732 {MAP_READONLY_YES, "1"},
733 {MAP_READONLY_PERMISSIONS, "permissions"},
734 {MAP_READONLY_PERMISSIONS, "perms"},
735 {-1, NULL}
736};
737
738static const struct enum_list enum_case[] = {
739 {CASE_LOWER, "lower"},
740 {CASE_UPPER, "upper"},
741 {-1, NULL}
742};
743
744static const struct enum_list enum_bool_auto[] = {
745 {False, "No"},
746 {False, "False"},
747 {False, "0"},
748 {True, "Yes"},
749 {True, "True"},
750 {True, "1"},
751 {Auto, "Auto"},
752 {-1, NULL}
753};
754
755/* Client-side offline caching policy types */
756#define CSC_POLICY_MANUAL 0
757#define CSC_POLICY_DOCUMENTS 1
758#define CSC_POLICY_PROGRAMS 2
759#define CSC_POLICY_DISABLE 3
760
761static const struct enum_list enum_csc_policy[] = {
762 {CSC_POLICY_MANUAL, "manual"},
763 {CSC_POLICY_DOCUMENTS, "documents"},
764 {CSC_POLICY_PROGRAMS, "programs"},
765 {CSC_POLICY_DISABLE, "disable"},
766 {-1, NULL}
767};
768
769/* SMB signing types. */
770static const struct enum_list enum_smb_signing_vals[] = {
771 {False, "No"},
772 {False, "False"},
773 {False, "0"},
774 {False, "Off"},
775 {False, "disabled"},
776 {True, "Yes"},
777 {True, "True"},
778 {True, "1"},
779 {True, "On"},
780 {True, "enabled"},
781 {Auto, "auto"},
782 {Required, "required"},
783 {Required, "mandatory"},
784 {Required, "force"},
785 {Required, "forced"},
786 {Required, "enforced"},
787 {-1, NULL}
788};
789
790/* ACL compatibility options. */
791static const struct enum_list enum_acl_compat_vals[] = {
792 { ACL_COMPAT_AUTO, "auto" },
793 { ACL_COMPAT_WINNT, "winnt" },
794 { ACL_COMPAT_WIN2K, "win2k" },
795 { -1, NULL}
796};
797
798/*
799 Do you want session setups at user level security with a invalid
800 password to be rejected or allowed in as guest? WinNT rejects them
801 but it can be a pain as it means "net view" needs to use a password
802
803 You have 3 choices in the setting of map_to_guest:
804
805 "Never" means session setups with an invalid password
806 are rejected. This is the default.
807
808 "Bad User" means session setups with an invalid password
809 are rejected, unless the username does not exist, in which case it
810 is treated as a guest login
811
812 "Bad Password" means session setups with an invalid password
813 are treated as a guest login
814
815 Note that map_to_guest only has an effect in user or server
816 level security.
817*/
818
819static const struct enum_list enum_map_to_guest[] = {
820 {NEVER_MAP_TO_GUEST, "Never"},
821 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
822 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
823 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
824 {-1, NULL}
825};
826
827/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
828 *
829 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
830 * screen in SWAT. This is used to exclude parameters as well as to squash all
831 * parameters that have been duplicated by pseudonyms.
832 *
833 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
834 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
835 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
836 * respective views.
837 *
838 * NOTE2: Handling of duplicated (synonym) paramters:
839 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
840 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
841 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
842 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
843 */
844
845static struct parm_struct parm_table[] = {
846 {N_("Base Options"), P_SEP, P_SEPARATOR},
847
848 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
849 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
850 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
851 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
852 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
853 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
854 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
855#ifdef WITH_ADS
856 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
857#endif
858 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
859 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
860 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
861 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
862 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
863 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
864
865 {N_("Security Options"), P_SEP, P_SEPARATOR},
866
867 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
868 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
869 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
870 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
871 {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
872 {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
873 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
874 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
875 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
876 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
877 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
878 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
879 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
880 {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
881 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
882 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
883 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
884 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
885 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
886 {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
887
888 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
889 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
890 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
891 {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
892 {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
893 {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
894 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
895 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
896 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
897 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
898 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
899 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
900 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
901 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
902 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
903 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
904
905 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
906 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
907 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
908
909 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
910 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
911 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
912 {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
913 {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
914 {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED },
915 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
916 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
917 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
918
919 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
920 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
921 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
922 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
923
924 {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
925 {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE },
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 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2702
2703 if (i < 0)
2704 return (False);
2705
2706 if (!(*(ServicePtrs[iDefaultService]->szPath))
2707 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2708 pstrcpy(newHomedir, pszHomedir);
2709 string_set(&ServicePtrs[i]->szPath, newHomedir);
2710 }
2711
2712 if (!(*(ServicePtrs[i]->comment))) {
2713 pstring comment;
2714 slprintf(comment, sizeof(comment) - 1,
2715 "Home directory of %s", user);
2716 string_set(&ServicePtrs[i]->comment, comment);
2717 }
2718
2719 /* set the browseable flag from the global default */
2720
2721 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2722
2723 ServicePtrs[i]->autoloaded = True;
2724
2725 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2726 user, ServicePtrs[i]->szPath ));
2727
2728 return (True);
2729}
2730
2731/***************************************************************************
2732 Add a new service, based on an old one.
2733***************************************************************************/
2734
2735int lp_add_service(const char *pszService, int iDefaultService)
2736{
2737 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2738}
2739
2740/***************************************************************************
2741 Add the IPC service.
2742***************************************************************************/
2743
2744static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2745{
2746 pstring comment;
2747 int i = add_a_service(&sDefault, ipc_name);
2748
2749 if (i < 0)
2750 return (False);
2751
2752 slprintf(comment, sizeof(comment) - 1,
2753 "IPC Service (%s)", Globals.szServerString);
2754
2755 string_set(&ServicePtrs[i]->szPath, tmpdir());
2756 string_set(&ServicePtrs[i]->szUsername, "");
2757 string_set(&ServicePtrs[i]->comment, comment);
2758 string_set(&ServicePtrs[i]->fstype, "IPC");
2759 ServicePtrs[i]->iMaxConnections = 0;
2760 ServicePtrs[i]->bAvailable = True;
2761 ServicePtrs[i]->bRead_only = True;
2762 ServicePtrs[i]->bGuest_only = False;
2763 ServicePtrs[i]->bAdministrative_share = True;
2764 ServicePtrs[i]->bGuest_ok = guest_ok;
2765 ServicePtrs[i]->bPrint_ok = False;
2766 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2767
2768 DEBUG(3, ("adding IPC service\n"));
2769
2770 return (True);
2771}
2772
2773/***************************************************************************
2774 Add a new printer service, with defaults coming from service iFrom.
2775***************************************************************************/
2776
2777BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2778{
2779 const char *comment = "From Printcap";
2780 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2781
2782 if (i < 0)
2783 return (False);
2784
2785 /* note that we do NOT default the availability flag to True - */
2786 /* we take it from the default service passed. This allows all */
2787 /* dynamic printers to be disabled by disabling the [printers] */
2788 /* entry (if/when the 'available' keyword is implemented!). */
2789
2790 /* the printer name is set to the service name. */
2791 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2792 string_set(&ServicePtrs[i]->comment, comment);
2793
2794 /* set the browseable flag from the gloabl default */
2795 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2796
2797 /* Printers cannot be read_only. */
2798 ServicePtrs[i]->bRead_only = False;
2799 /* No share modes on printer services. */
2800 ServicePtrs[i]->bShareModes = False;
2801 /* No oplocks on printer services. */
2802 ServicePtrs[i]->bOpLocks = False;
2803 /* Printer services must be printable. */
2804 ServicePtrs[i]->bPrint_ok = True;
2805
2806 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2807
2808 return (True);
2809}
2810
2811/***************************************************************************
2812 Map a parameter's string representation to something we can use.
2813 Returns False if the parameter string is not recognised, else TRUE.
2814***************************************************************************/
2815
2816static int map_parameter(const char *pszParmName)
2817{
2818 int iIndex;
2819
2820 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
2821 return (-1);
2822
2823 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2824 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2825 return (iIndex);
2826
2827 /* Warn only if it isn't parametric option */
2828 if (strchr(pszParmName, ':') == NULL)
2829 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2830 /* We do return 'fail' for parametric options as well because they are
2831 stored in different storage
2832 */
2833 return (-1);
2834}
2835
2836/***************************************************************************
2837 Show all parameter's name, type, [values,] and flags.
2838***************************************************************************/
2839
2840void show_parameter_list(void)
2841{
2842 int classIndex, parmIndex, enumIndex, flagIndex;
2843 BOOL hadFlag;
2844 const char *section_names[] = { "local", "global", NULL};
2845 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2846 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2847 "P_UGSTRING", "P_ENUM", "P_SEP"};
2848 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2849 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2850 FLAG_HIDE, FLAG_DOS_STRING};
2851 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2852 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2853 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2854
2855 for ( classIndex=0; section_names[classIndex]; classIndex++) {
2856 printf("[%s]\n", section_names[classIndex]);
2857 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2858 if (parm_table[parmIndex].p_class == classIndex) {
2859 printf("%s=%s",
2860 parm_table[parmIndex].label,
2861 type[parm_table[parmIndex].type]);
2862 switch (parm_table[parmIndex].type) {
2863 case P_ENUM:
2864 printf(",");
2865 for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2866 printf("%s%s",
2867 enumIndex ? "|" : "",
2868 parm_table[parmIndex].enum_list[enumIndex].name);
2869 break;
2870 default:
2871 break;
2872 }
2873 printf(",");
2874 hadFlag = False;
2875 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2876 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2877 printf("%s%s",
2878 hadFlag ? "|" : "",
2879 flag_names[flagIndex]);
2880 hadFlag = True;
2881 }
2882 }
2883 printf("\n");
2884 }
2885 }
2886 }
2887}
2888
2889/***************************************************************************
2890 Set a boolean variable from the text value stored in the passed string.
2891 Returns True in success, False if the passed string does not correctly
2892 represent a boolean.
2893***************************************************************************/
2894
2895static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2896{
2897 BOOL bRetval;
2898
2899 bRetval = True;
2900 if (strwicmp(pszParmValue, "yes") == 0 ||
2901 strwicmp(pszParmValue, "true") == 0 ||
2902 strwicmp(pszParmValue, "1") == 0)
2903 *pb = True;
2904 else if (strwicmp(pszParmValue, "no") == 0 ||
2905 strwicmp(pszParmValue, "False") == 0 ||
2906 strwicmp(pszParmValue, "0") == 0)
2907 *pb = False;
2908 else {
2909 DEBUG(0,
2910 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2911 pszParmValue));
2912 bRetval = False;
2913 }
2914 return (bRetval);
2915}
2916
2917/***************************************************************************
2918Find a service by name. Otherwise works like get_service.
2919***************************************************************************/
2920
2921static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2922{
2923 int iService = -1;
2924 char *canon_name;
2925
2926 if (ServiceHash != NULL) {
2927 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2928 return -1;
2929
2930 iService = tdb_fetch_int32(ServiceHash, canon_name );
2931
2932 if (LP_SNUM_OK(iService)) {
2933 if (pserviceDest != NULL) {
2934 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2935 }
2936 } else {
2937 iService = -1;
2938 }
2939 }
2940
2941 return (iService);
2942}
2943
2944/***************************************************************************
2945 Copy a service structure to another.
2946 If pcopymapDest is NULL then copy all fields
2947***************************************************************************/
2948
2949static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2950{
2951 int i;
2952 BOOL bcopyall = (pcopymapDest == NULL);
2953 param_opt_struct *data, *pdata, *paramo;
2954 BOOL not_added;
2955
2956 for (i = 0; parm_table[i].label; i++)
2957 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2958 (bcopyall || pcopymapDest[i])) {
2959 void *def_ptr = parm_table[i].ptr;
2960 void *src_ptr =
2961 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2962 &sDefault);
2963 void *dest_ptr =
2964 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2965 &sDefault);
2966
2967 switch (parm_table[i].type) {
2968 case P_BOOL:
2969 case P_BOOLREV:
2970 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2971 break;
2972
2973 case P_INTEGER:
2974 case P_ENUM:
2975 case P_OCTAL:
2976 *(int *)dest_ptr = *(int *)src_ptr;
2977 break;
2978
2979 case P_CHAR:
2980 *(char *)dest_ptr = *(char *)src_ptr;
2981 break;
2982
2983 case P_STRING:
2984 string_set((char **)dest_ptr,
2985 *(char **)src_ptr);
2986 break;
2987
2988 case P_USTRING:
2989 string_set((char **)dest_ptr,
2990 *(char **)src_ptr);
2991 strupper_m(*(char **)dest_ptr);
2992 break;
2993 case P_LIST:
2994 str_list_free((char ***)dest_ptr);
2995 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2996 break;
2997 default:
2998 break;
2999 }
3000 }
3001
3002 if (bcopyall) {
3003 init_copymap(pserviceDest);
3004 if (pserviceSource->copymap)
3005 memcpy((void *)pserviceDest->copymap,
3006 (void *)pserviceSource->copymap,
3007 sizeof(BOOL) * NUMPARAMETERS);
3008 }
3009
3010 data = pserviceSource->param_opt;
3011 while (data) {
3012 not_added = True;
3013 pdata = pserviceDest->param_opt;
3014 /* Traverse destination */
3015 while (pdata) {
3016 /* If we already have same option, override it */
3017 if (strcmp(pdata->key, data->key) == 0) {
3018 string_free(&pdata->value);
3019 str_list_free(&data->list);
3020 pdata->value = SMB_STRDUP(data->value);
3021 not_added = False;
3022 break;
3023 }
3024 pdata = pdata->next;
3025 }
3026 if (not_added) {
3027 paramo = SMB_XMALLOC_P(param_opt_struct);
3028 paramo->key = SMB_STRDUP(data->key);
3029 paramo->value = SMB_STRDUP(data->value);
3030 paramo->list = NULL;
3031 DLIST_ADD(pserviceDest->param_opt, paramo);
3032 }
3033 data = data->next;
3034 }
3035}
3036
3037/***************************************************************************
3038Check a service for consistency. Return False if the service is in any way
3039incomplete or faulty, else True.
3040***************************************************************************/
3041
3042static BOOL service_ok(int iService)
3043{
3044 BOOL bRetval;
3045
3046 bRetval = True;
3047 if (ServicePtrs[iService]->szService[0] == '\0') {
3048 DEBUG(0, ("The following message indicates an internal error:\n"));
3049 DEBUG(0, ("No service name in service entry.\n"));
3050 bRetval = False;
3051 }
3052
3053 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3054 /* I can't see why you'd want a non-printable printer service... */
3055 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3056 if (!ServicePtrs[iService]->bPrint_ok) {
3057 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3058 ServicePtrs[iService]->szService));
3059 ServicePtrs[iService]->bPrint_ok = True;
3060 }
3061 /* [printers] service must also be non-browsable. */
3062 if (ServicePtrs[iService]->bBrowseable)
3063 ServicePtrs[iService]->bBrowseable = False;
3064 }
3065
3066 if (ServicePtrs[iService]->szPath[0] == '\0' &&
3067 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3068 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3069 ) {
3070 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3071 ServicePtrs[iService]->szService));
3072 ServicePtrs[iService]->bAvailable = False;
3073 }
3074
3075 /* If a service is flagged unavailable, log the fact at level 0. */
3076 if (!ServicePtrs[iService]->bAvailable)
3077 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3078 ServicePtrs[iService]->szService));
3079
3080 return (bRetval);
3081}
3082
3083static struct file_lists {
3084 struct file_lists *next;
3085 char *name;
3086 char *subfname;
3087 time_t modtime;
3088} *file_lists = NULL;
3089
3090/*******************************************************************
3091 Keep a linked list of all config files so we know when one has changed
3092 it's date and needs to be reloaded.
3093********************************************************************/
3094
3095static void add_to_file_list(const char *fname, const char *subfname)
3096{
3097 struct file_lists *f = file_lists;
3098
3099 while (f) {
3100 if (f->name && !strcmp(f->name, fname))
3101 break;
3102 f = f->next;
3103 }
3104
3105 if (!f) {
3106 f = SMB_MALLOC_P(struct file_lists);
3107 if (!f)
3108 return;
3109 f->next = file_lists;
3110 f->name = SMB_STRDUP(fname);
3111 if (!f->name) {
3112 SAFE_FREE(f);
3113 return;
3114 }
3115 f->subfname = SMB_STRDUP(subfname);
3116 if (!f->subfname) {
3117 SAFE_FREE(f);
3118 return;
3119 }
3120 file_lists = f;
3121 f->modtime = file_modtime(subfname);
3122 } else {
3123 time_t t = file_modtime(subfname);
3124 if (t)
3125 f->modtime = t;
3126 }
3127}
3128
3129/*******************************************************************
3130 Check if a config file has changed date.
3131********************************************************************/
3132
3133BOOL lp_file_list_changed(void)
3134{
3135 struct file_lists *f = file_lists;
3136
3137 DEBUG(6, ("lp_file_list_changed()\n"));
3138
3139 while (f) {
3140 pstring n2;
3141 time_t mod_time;
3142
3143 pstrcpy(n2, f->name);
3144 standard_sub_basic( get_current_username(),
3145 current_user_info.domain,
3146 n2, sizeof(n2) );
3147
3148 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3149 f->name, n2, ctime(&f->modtime)));
3150
3151 mod_time = file_modtime(n2);
3152
3153 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3154 DEBUGADD(6,
3155 ("file %s modified: %s\n", n2,
3156 ctime(&mod_time)));
3157 f->modtime = mod_time;
3158 SAFE_FREE(f->subfname);
3159 f->subfname = SMB_STRDUP(n2);
3160 return (True);
3161 }
3162 f = f->next;
3163 }
3164 return (False);
3165}
3166
3167/***************************************************************************
3168 Run standard_sub_basic on netbios name... needed because global_myname
3169 is not accessed through any lp_ macro.
3170 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3171***************************************************************************/
3172
3173static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3174{
3175 BOOL ret;
3176 pstring netbios_name;
3177
3178 pstrcpy(netbios_name, pszParmValue);
3179
3180 standard_sub_basic(get_current_username(), current_user_info.domain,
3181 netbios_name, sizeof(netbios_name));
3182
3183 ret = set_global_myname(netbios_name);
3184 string_set(&Globals.szNetbiosName,global_myname());
3185
3186 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3187 global_myname()));
3188
3189 return ret;
3190}
3191
3192static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3193{
3194 if (strcmp(*ptr, pszParmValue) != 0) {
3195 string_set(ptr, pszParmValue);
3196 init_iconv();
3197 }
3198 return True;
3199}
3200
3201
3202
3203static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3204{
3205 BOOL ret;
3206
3207 ret = set_global_myworkgroup(pszParmValue);
3208 string_set(&Globals.szWorkgroup,lp_workgroup());
3209
3210 return ret;
3211}
3212
3213static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3214{
3215 BOOL ret;
3216
3217 ret = set_global_scope(pszParmValue);
3218 string_set(&Globals.szNetbiosScope,global_scope());
3219
3220 return ret;
3221}
3222
3223static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3224{
3225 str_list_free(&Globals.szNetbiosAliases);
3226 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3227 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3228}
3229
3230/***************************************************************************
3231 Handle the include operation.
3232***************************************************************************/
3233
3234static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3235{
3236 pstring fname;
3237 pstrcpy(fname, pszParmValue);
3238
3239 standard_sub_basic(get_current_username(), current_user_info.domain,
3240 fname,sizeof(fname));
3241
3242 add_to_file_list(pszParmValue, fname);
3243
3244 string_set(ptr, fname);
3245
3246 if (file_exist(fname, NULL))
3247 return (pm_process(fname, do_section, do_parameter));
3248
3249 DEBUG(2, ("Can't find include file %s\n", fname));
3250
3251 return (False);
3252}
3253
3254/***************************************************************************
3255 Handle the interpretation of the copy parameter.
3256***************************************************************************/
3257
3258static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3259{
3260 BOOL bRetval;
3261 int iTemp;
3262 service serviceTemp;
3263
3264 string_set(ptr, pszParmValue);
3265
3266 init_service(&serviceTemp);
3267
3268 bRetval = False;
3269
3270 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3271
3272 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3273 if (iTemp == iServiceIndex) {
3274 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3275 } else {
3276 copy_service(ServicePtrs[iServiceIndex],
3277 &serviceTemp,
3278 ServicePtrs[iServiceIndex]->copymap);
3279 bRetval = True;
3280 }
3281 } else {
3282 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3283 bRetval = False;
3284 }
3285
3286 free_service(&serviceTemp);
3287 return (bRetval);
3288}
3289
3290static BOOL handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
3291{
3292 Globals.ldap_debug_level = lp_int(pszParmValue);
3293 init_ldap_debugging();
3294 return True;
3295}
3296
3297/***************************************************************************
3298 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3299 parameters is:
3300
3301 [global]
3302
3303 idmap uid = 1000-1999
3304 idmap gid = 700-899
3305
3306 We only do simple parsing checks here. The strings are parsed into useful
3307 structures in the idmap daemon code.
3308
3309***************************************************************************/
3310
3311/* Some lp_ routines to return idmap [ug]id information */
3312
3313static uid_t idmap_uid_low, idmap_uid_high;
3314static gid_t idmap_gid_low, idmap_gid_high;
3315
3316BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3317{
3318 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3319 return False;
3320
3321 if (low)
3322 *low = idmap_uid_low;
3323
3324 if (high)
3325 *high = idmap_uid_high;
3326
3327 return True;
3328}
3329
3330BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3331{
3332 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3333 return False;
3334
3335 if (low)
3336 *low = idmap_gid_low;
3337
3338 if (high)
3339 *high = idmap_gid_high;
3340
3341 return True;
3342}
3343
3344/* Do some simple checks on "idmap [ug]id" parameter values */
3345
3346static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3347{
3348 uint32 low, high;
3349
3350 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3351 return False;
3352
3353 /* Parse OK */
3354
3355 string_set(ptr, pszParmValue);
3356
3357 idmap_uid_low = low;
3358 idmap_uid_high = high;
3359
3360 return True;
3361}
3362
3363static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3364{
3365 uint32 low, high;
3366
3367 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3368 return False;
3369
3370 /* Parse OK */
3371
3372 string_set(ptr, pszParmValue);
3373
3374 idmap_gid_low = low;
3375 idmap_gid_high = high;
3376
3377 return True;
3378}
3379
3380/***************************************************************************
3381 Handle the DEBUG level list.
3382***************************************************************************/
3383
3384static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3385{
3386 pstring pszParmValue;
3387
3388 pstrcpy(pszParmValue, pszParmValueIn);
3389 string_set(ptr, pszParmValueIn);
3390 return debug_parse_levels( pszParmValue );
3391}
3392
3393/***************************************************************************
3394 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3395***************************************************************************/
3396
3397static const char *append_ldap_suffix( const char *str )
3398{
3399 const char *suffix_string;
3400
3401
3402 if (!lp_talloc)
3403 lp_talloc = talloc_init("lp_talloc");
3404
3405 suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3406 if ( !suffix_string ) {
3407 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3408 return "";
3409 }
3410
3411 return suffix_string;
3412}
3413
3414const char *lp_ldap_machine_suffix(void)
3415{
3416 if (Globals.szLdapMachineSuffix[0])
3417 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3418
3419 return lp_string(Globals.szLdapSuffix);
3420}
3421
3422const char *lp_ldap_user_suffix(void)
3423{
3424 if (Globals.szLdapUserSuffix[0])
3425 return append_ldap_suffix(Globals.szLdapUserSuffix);
3426
3427 return lp_string(Globals.szLdapSuffix);
3428}
3429
3430const char *lp_ldap_group_suffix(void)
3431{
3432 if (Globals.szLdapGroupSuffix[0])
3433 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3434
3435 return lp_string(Globals.szLdapSuffix);
3436}
3437
3438const char *lp_ldap_idmap_suffix(void)
3439{
3440 if (Globals.szLdapIdmapSuffix[0])
3441 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3442
3443 return lp_string(Globals.szLdapSuffix);
3444}
3445
3446/****************************************************************************
3447 set the value for a P_ENUM
3448 ***************************************************************************/
3449
3450static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3451 int *ptr )
3452{
3453 int i;
3454
3455 for (i = 0; parm->enum_list[i].name; i++) {
3456 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3457 *ptr = parm->enum_list[i].value;
3458 break;
3459 }
3460 }
3461}
3462
3463/***************************************************************************
3464***************************************************************************/
3465
3466static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3467{
3468 static int parm_num = -1;
3469 service *s;
3470
3471 if ( parm_num == -1 )
3472 parm_num = map_parameter( "printing" );
3473
3474 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3475
3476 if ( snum < 0 )
3477 s = &sDefault;
3478 else
3479 s = ServicePtrs[snum];
3480
3481 init_printer_values( s );
3482
3483 return True;
3484}
3485
3486
3487/***************************************************************************
3488 Initialise a copymap.
3489***************************************************************************/
3490
3491static void init_copymap(service * pservice)
3492{
3493 int i;
3494 SAFE_FREE(pservice->copymap);
3495 pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3496 if (!pservice->copymap)
3497 DEBUG(0,
3498 ("Couldn't allocate copymap!! (size %d)\n",
3499 (int)NUMPARAMETERS));
3500 else
3501 for (i = 0; i < NUMPARAMETERS; i++)
3502 pservice->copymap[i] = True;
3503}
3504
3505/***************************************************************************
3506 Return the local pointer to a parameter given the service number and the
3507 pointer into the default structure.
3508***************************************************************************/
3509
3510void *lp_local_ptr(int snum, void *ptr)
3511{
3512 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3513}
3514
3515/***************************************************************************
3516 Process a parameter for a particular service number. If snum < 0
3517 then assume we are in the globals.
3518***************************************************************************/
3519
3520BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3521{
3522 int parmnum, i, slen;
3523 void *parm_ptr = NULL; /* where we are going to store the result */
3524 void *def_ptr = NULL;
3525 pstring param_key;
3526 char *sep;
3527 param_opt_struct *paramo, *data;
3528 BOOL not_added;
3529
3530 parmnum = map_parameter(pszParmName);
3531
3532 if (parmnum < 0) {
3533 if ((sep=strchr(pszParmName, ':')) != NULL) {
3534 *sep = '\0';
3535 ZERO_STRUCT(param_key);
3536 pstr_sprintf(param_key, "%s:", pszParmName);
3537 slen = strlen(param_key);
3538 pstrcat(param_key, sep+1);
3539 trim_char(param_key+slen, ' ', ' ');
3540 not_added = True;
3541 data = (snum < 0) ? Globals.param_opt :
3542 ServicePtrs[snum]->param_opt;
3543 /* Traverse destination */
3544 while (data) {
3545 /* If we already have same option, override it */
3546 if (strcmp(data->key, param_key) == 0) {
3547 string_free(&data->value);
3548 str_list_free(&data->list);
3549 data->value = SMB_STRDUP(pszParmValue);
3550 not_added = False;
3551 break;
3552 }
3553 data = data->next;
3554 }
3555 if (not_added) {
3556 paramo = SMB_XMALLOC_P(param_opt_struct);
3557 paramo->key = SMB_STRDUP(param_key);
3558 paramo->value = SMB_STRDUP(pszParmValue);
3559 paramo->list = NULL;
3560 if (snum < 0) {
3561 DLIST_ADD(Globals.param_opt, paramo);
3562 } else {
3563 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3564 }
3565 }
3566
3567 *sep = ':';
3568 return (True);
3569 }
3570 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3571 return (True);
3572 }
3573
3574 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3575 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3576 pszParmName));
3577 }
3578
3579 def_ptr = parm_table[parmnum].ptr;
3580
3581 /* we might point at a service, the default service or a global */
3582 if (snum < 0) {
3583 parm_ptr = def_ptr;
3584 } else {
3585 if (parm_table[parmnum].p_class == P_GLOBAL) {
3586 DEBUG(0,
3587 ("Global parameter %s found in service section!\n",
3588 pszParmName));
3589 return (True);
3590 }
3591 parm_ptr =
3592 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3593 &sDefault);
3594 }
3595
3596 if (snum >= 0) {
3597 if (!ServicePtrs[snum]->copymap)
3598 init_copymap(ServicePtrs[snum]);
3599
3600 /* this handles the aliases - set the copymap for other entries with
3601 the same data pointer */
3602 for (i = 0; parm_table[i].label; i++)
3603 if (parm_table[i].ptr == parm_table[parmnum].ptr)
3604 ServicePtrs[snum]->copymap[i] = False;
3605 }
3606
3607 /* if it is a special case then go ahead */
3608 if (parm_table[parmnum].special) {
3609 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3610 return (True);
3611 }
3612
3613 /* now switch on the type of variable it is */
3614 switch (parm_table[parmnum].type)
3615 {
3616 case P_BOOL:
3617 *(BOOL *)parm_ptr = lp_bool(pszParmValue);
3618 break;
3619
3620 case P_BOOLREV:
3621 *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
3622 break;
3623
3624 case P_INTEGER:
3625 *(int *)parm_ptr = lp_int(pszParmValue);
3626 break;
3627
3628 case P_CHAR:
3629 *(char *)parm_ptr = *pszParmValue;
3630 break;
3631
3632 case P_OCTAL:
3633 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3634 if ( i != 1 ) {
3635 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3636 }
3637 break;
3638
3639 case P_LIST:
3640 str_list_free((char ***)parm_ptr);
3641 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3642 break;
3643
3644 case P_STRING:
3645 string_set((char **)parm_ptr, pszParmValue);
3646 break;
3647
3648 case P_USTRING:
3649 string_set((char **)parm_ptr, pszParmValue);
3650 strupper_m(*(char **)parm_ptr);
3651 break;
3652
3653 case P_GSTRING:
3654 pstrcpy((char *)parm_ptr, pszParmValue);
3655 break;
3656
3657 case P_UGSTRING:
3658 pstrcpy((char *)parm_ptr, pszParmValue);
3659 strupper_m((char *)parm_ptr);
3660 break;
3661
3662 case P_ENUM:
3663 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3664 break;
3665 case P_SEP:
3666 break;
3667 }
3668
3669 return (True);
3670}
3671
3672/***************************************************************************
3673 Process a parameter.
3674***************************************************************************/
3675
3676static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3677{
3678 if (!bInGlobalSection && bGlobalOnly)
3679 return (True);
3680
3681 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3682
3683 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3684 pszParmName, pszParmValue));
3685}
3686
3687/***************************************************************************
3688 Print a parameter of the specified type.
3689***************************************************************************/
3690
3691static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3692{
3693 int i;
3694 switch (p->type)
3695 {
3696 case P_ENUM:
3697 for (i = 0; p->enum_list[i].name; i++) {
3698 if (*(int *)ptr == p->enum_list[i].value) {
3699 fprintf(f, "%s",
3700 p->enum_list[i].name);
3701 break;
3702 }
3703 }
3704 break;
3705
3706 case P_BOOL:
3707 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3708 break;
3709
3710 case P_BOOLREV:
3711 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3712 break;
3713
3714 case P_INTEGER:
3715 fprintf(f, "%d", *(int *)ptr);
3716 break;
3717
3718 case P_CHAR:
3719 fprintf(f, "%c", *(char *)ptr);
3720 break;
3721
3722 case P_OCTAL:
3723 fprintf(f, "%s", octal_string(*(int *)ptr));
3724 break;
3725
3726 case P_LIST:
3727 if ((char ***)ptr && *(char ***)ptr) {
3728 char **list = *(char ***)ptr;
3729
3730 for (; *list; list++) {
3731 /* surround strings with whitespace in double quotes */
3732 if ( strchr_m( *list, ' ' ) )
3733 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3734 else
3735 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3736 }
3737 }
3738 break;
3739
3740 case P_GSTRING:
3741 case P_UGSTRING:
3742 if ((char *)ptr) {
3743 fprintf(f, "%s", (char *)ptr);
3744 }
3745 break;
3746
3747 case P_STRING:
3748 case P_USTRING:
3749 if (*(char **)ptr) {
3750 fprintf(f, "%s", *(char **)ptr);
3751 }
3752 break;
3753 case P_SEP:
3754 break;
3755 }
3756}
3757
3758/***************************************************************************
3759 Check if two parameters are equal.
3760***************************************************************************/
3761
3762static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3763{
3764 switch (type) {
3765 case P_BOOL:
3766 case P_BOOLREV:
3767 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3768
3769 case P_INTEGER:
3770 case P_ENUM:
3771 case P_OCTAL:
3772 return (*((int *)ptr1) == *((int *)ptr2));
3773
3774 case P_CHAR:
3775 return (*((char *)ptr1) == *((char *)ptr2));
3776
3777 case P_LIST:
3778 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3779
3780 case P_GSTRING:
3781 case P_UGSTRING:
3782 {
3783 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3784 if (p1 && !*p1)
3785 p1 = NULL;
3786 if (p2 && !*p2)
3787 p2 = NULL;
3788 return (p1 == p2 || strequal(p1, p2));
3789 }
3790 case P_STRING:
3791 case P_USTRING:
3792 {
3793 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3794 if (p1 && !*p1)
3795 p1 = NULL;
3796 if (p2 && !*p2)
3797 p2 = NULL;
3798 return (p1 == p2 || strequal(p1, p2));
3799 }
3800 case P_SEP:
3801 break;
3802 }
3803 return (False);
3804}
3805
3806/***************************************************************************
3807 Initialize any local varients in the sDefault table.
3808***************************************************************************/
3809
3810void init_locals(void)
3811{
3812 /* None as yet. */
3813}
3814
3815/***************************************************************************
3816 Process a new section (service). At this stage all sections are services.
3817 Later we'll have special sections that permit server parameters to be set.
3818 Returns True on success, False on failure.
3819***************************************************************************/
3820
3821static BOOL do_section(const char *pszSectionName)
3822{
3823 BOOL bRetval;
3824 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3825 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3826 bRetval = False;
3827
3828 /* if we were in a global section then do the local inits */
3829 if (bInGlobalSection && !isglobal)
3830 init_locals();
3831
3832 /* if we've just struck a global section, note the fact. */
3833 bInGlobalSection = isglobal;
3834
3835 /* check for multiple global sections */
3836 if (bInGlobalSection) {
3837 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3838 return (True);
3839 }
3840
3841 if (!bInGlobalSection && bGlobalOnly)
3842 return (True);
3843
3844 /* if we have a current service, tidy it up before moving on */
3845 bRetval = True;
3846
3847 if (iServiceIndex >= 0)
3848 bRetval = service_ok(iServiceIndex);
3849
3850 /* if all is still well, move to the next record in the services array */
3851 if (bRetval) {
3852 /* We put this here to avoid an odd message order if messages are */
3853 /* issued by the post-processing of a previous section. */
3854 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3855
3856 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3857 < 0) {
3858 DEBUG(0, ("Failed to add a new service\n"));
3859 return (False);
3860 }
3861 }
3862
3863 return (bRetval);
3864}
3865
3866
3867/***************************************************************************
3868 Determine if a partcular base parameter is currentl set to the default value.
3869***************************************************************************/
3870
3871static BOOL is_default(int i)
3872{
3873 if (!defaults_saved)
3874 return False;
3875 switch (parm_table[i].type) {
3876 case P_LIST:
3877 return str_list_compare (parm_table[i].def.lvalue,
3878 *(char ***)parm_table[i].ptr);
3879 case P_STRING:
3880 case P_USTRING:
3881 return strequal(parm_table[i].def.svalue,
3882 *(char **)parm_table[i].ptr);
3883 case P_GSTRING:
3884 case P_UGSTRING:
3885 return strequal(parm_table[i].def.svalue,
3886 (char *)parm_table[i].ptr);
3887 case P_BOOL:
3888 case P_BOOLREV:
3889 return parm_table[i].def.bvalue ==
3890 *(BOOL *)parm_table[i].ptr;
3891 case P_CHAR:
3892 return parm_table[i].def.cvalue ==
3893 *(char *)parm_table[i].ptr;
3894 case P_INTEGER:
3895 case P_OCTAL:
3896 case P_ENUM:
3897 return parm_table[i].def.ivalue ==
3898 *(int *)parm_table[i].ptr;
3899 case P_SEP:
3900 break;
3901 }
3902 return False;
3903}
3904
3905/***************************************************************************
3906Display the contents of the global structure.
3907***************************************************************************/
3908
3909static void dump_globals(FILE *f)
3910{
3911 int i;
3912 param_opt_struct *data;
3913
3914 fprintf(f, "[global]\n");
3915
3916 for (i = 0; parm_table[i].label; i++)
3917 if (parm_table[i].p_class == P_GLOBAL &&
3918 parm_table[i].ptr &&
3919 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3920 if (defaults_saved && is_default(i))
3921 continue;
3922 fprintf(f, "\t%s = ", parm_table[i].label);
3923 print_parameter(&parm_table[i], parm_table[i].ptr, f);
3924 fprintf(f, "\n");
3925 }
3926 if (Globals.param_opt != NULL) {
3927 data = Globals.param_opt;
3928 while(data) {
3929 fprintf(f, "\t%s = %s\n", data->key, data->value);
3930 data = data->next;
3931 }
3932 }
3933
3934}
3935
3936/***************************************************************************
3937 Return True if a local parameter is currently set to the global default.
3938***************************************************************************/
3939
3940BOOL lp_is_default(int snum, struct parm_struct *parm)
3941{
3942 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3943
3944 return equal_parameter(parm->type,
3945 ((char *)ServicePtrs[snum]) + pdiff,
3946 ((char *)&sDefault) + pdiff);
3947}
3948
3949/***************************************************************************
3950 Display the contents of a single services record.
3951***************************************************************************/
3952
3953static void dump_a_service(service * pService, FILE * f)
3954{
3955 int i;
3956 param_opt_struct *data;
3957
3958 if (pService != &sDefault)
3959 fprintf(f, "[%s]\n", pService->szService);
3960
3961 for (i = 0; parm_table[i].label; i++) {
3962
3963 if (parm_table[i].p_class == P_LOCAL &&
3964 parm_table[i].ptr &&
3965 (*parm_table[i].label != '-') &&
3966 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3967 {
3968
3969 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3970
3971 if (pService == &sDefault) {
3972 if (defaults_saved && is_default(i))
3973 continue;
3974 } else {
3975 if (equal_parameter(parm_table[i].type,
3976 ((char *)pService) +
3977 pdiff,
3978 ((char *)&sDefault) +
3979 pdiff))
3980 continue;
3981 }
3982
3983 fprintf(f, "\t%s = ", parm_table[i].label);
3984 print_parameter(&parm_table[i],
3985 ((char *)pService) + pdiff, f);
3986 fprintf(f, "\n");
3987 }
3988 }
3989
3990 if (pService->param_opt != NULL) {
3991 data = pService->param_opt;
3992 while(data) {
3993 fprintf(f, "\t%s = %s\n", data->key, data->value);
3994 data = data->next;
3995 }
3996 }
3997}
3998
3999/***************************************************************************
4000 Display the contents of a parameter of a single services record.
4001***************************************************************************/
4002
4003BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
4004{
4005 int i;
4006 BOOL result = False;
4007 parm_class p_class;
4008 unsigned flag = 0;
4009 fstring local_parm_name;
4010 char *parm_opt;
4011 const char *parm_opt_value;
4012
4013 /* check for parametrical option */
4014 fstrcpy( local_parm_name, parm_name);
4015 parm_opt = strchr( local_parm_name, ':');
4016
4017 if (parm_opt) {
4018 *parm_opt = '\0';
4019 parm_opt++;
4020 if (strlen(parm_opt)) {
4021 parm_opt_value = lp_parm_const_string( snum,
4022 local_parm_name, parm_opt, NULL);
4023 if (parm_opt_value) {
4024 printf( "%s\n", parm_opt_value);
4025 result = True;
4026 }
4027 }
4028 return result;
4029 }
4030
4031 /* check for a key and print the value */
4032 if (isGlobal) {
4033 p_class = P_GLOBAL;
4034 flag = FLAG_GLOBAL;
4035 } else
4036 p_class = P_LOCAL;
4037
4038 for (i = 0; parm_table[i].label; i++) {
4039 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
4040 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
4041 parm_table[i].ptr &&
4042 (*parm_table[i].label != '-') &&
4043 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4044 {
4045 void *ptr;
4046
4047 if (isGlobal) {
4048 ptr = parm_table[i].ptr;
4049 } else {
4050 service * pService = ServicePtrs[snum];
4051 ptr = ((char *)pService) +
4052 PTR_DIFF(parm_table[i].ptr, &sDefault);
4053 }
4054
4055 print_parameter(&parm_table[i],
4056 ptr, f);
4057 fprintf(f, "\n");
4058 result = True;
4059 break;
4060 }
4061 }
4062
4063 return result;
4064}
4065
4066/***************************************************************************
4067 Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
4068 Return NULL when out of parameters.
4069***************************************************************************/
4070
4071struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
4072{
4073 if (snum < 0) {
4074 /* do the globals */
4075 for (; parm_table[*i].label; (*i)++) {
4076 if (parm_table[*i].p_class == P_SEPARATOR)
4077 return &parm_table[(*i)++];
4078
4079 if (!parm_table[*i].ptr
4080 || (*parm_table[*i].label == '-'))
4081 continue;
4082
4083 if ((*i) > 0
4084 && (parm_table[*i].ptr ==
4085 parm_table[(*i) - 1].ptr))
4086 continue;
4087
4088 return &parm_table[(*i)++];
4089 }
4090 } else {
4091 service *pService = ServicePtrs[snum];
4092
4093 for (; parm_table[*i].label; (*i)++) {
4094 if (parm_table[*i].p_class == P_SEPARATOR)
4095 return &parm_table[(*i)++];
4096
4097 if (parm_table[*i].p_class == P_LOCAL &&
4098 parm_table[*i].ptr &&
4099 (*parm_table[*i].label != '-') &&
4100 ((*i) == 0 ||
4101 (parm_table[*i].ptr !=
4102 parm_table[(*i) - 1].ptr)))
4103 {
4104 int pdiff =
4105 PTR_DIFF(parm_table[*i].ptr,
4106 &sDefault);
4107
4108 if (allparameters ||
4109 !equal_parameter(parm_table[*i].type,
4110 ((char *)pService) +
4111 pdiff,
4112 ((char *)&sDefault) +
4113 pdiff))
4114 {
4115 return &parm_table[(*i)++];
4116 }
4117 }
4118 }
4119 }
4120
4121 return NULL;
4122}
4123
4124
4125#if 0
4126/***************************************************************************
4127 Display the contents of a single copy structure.
4128***************************************************************************/
4129static void dump_copy_map(BOOL *pcopymap)
4130{
4131 int i;
4132 if (!pcopymap)
4133 return;
4134
4135 printf("\n\tNon-Copied parameters:\n");
4136
4137 for (i = 0; parm_table[i].label; i++)
4138 if (parm_table[i].p_class == P_LOCAL &&
4139 parm_table[i].ptr && !pcopymap[i] &&
4140 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4141 {
4142 printf("\t\t%s\n", parm_table[i].label);
4143 }
4144}
4145#endif
4146
4147/***************************************************************************
4148 Return TRUE if the passed service number is within range.
4149***************************************************************************/
4150
4151BOOL lp_snum_ok(int iService)
4152{
4153 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4154}
4155
4156/***************************************************************************
4157 Auto-load some home services.
4158***************************************************************************/
4159
4160static void lp_add_auto_services(char *str)
4161{
4162 char *s;
4163 char *p;
4164 int homes;
4165
4166 if (!str)
4167 return;
4168
4169 s = SMB_STRDUP(str);
4170 if (!s)
4171 return;
4172
4173 homes = lp_servicenumber(HOMES_NAME);
4174
4175 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4176 char *home = get_user_home_dir(p);
4177
4178 if (lp_servicenumber(p) >= 0)
4179 continue;
4180
4181 if (home && homes >= 0)
4182 lp_add_home(p, homes, p, home);
4183 }
4184 SAFE_FREE(s);
4185}
4186
4187/***************************************************************************
4188 Auto-load one printer.
4189***************************************************************************/
4190
4191void lp_add_one_printer(char *name, char *comment)
4192{
4193 int printers = lp_servicenumber(PRINTERS_NAME);
4194 int i;
4195
4196 if (lp_servicenumber(name) < 0) {
4197 lp_add_printer(name, printers);
4198 if ((i = lp_servicenumber(name)) >= 0) {
4199 string_set(&ServicePtrs[i]->comment, comment);
4200 ServicePtrs[i]->autoloaded = True;
4201 }
4202 }
4203}
4204
4205/***************************************************************************
4206 Have we loaded a services file yet?
4207***************************************************************************/
4208
4209BOOL lp_loaded(void)
4210{
4211 return (bLoaded);
4212}
4213
4214/***************************************************************************
4215 Unload unused services.
4216***************************************************************************/
4217
4218void lp_killunused(BOOL (*snumused) (int))
4219{
4220 int i;
4221 for (i = 0; i < iNumServices; i++) {
4222 if (!VALID(i))
4223 continue;
4224
4225 /* don't kill autoloaded or usershare services */
4226 if ( ServicePtrs[i]->autoloaded ||
4227 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4228 continue;
4229 }
4230
4231 if (!snumused || !snumused(i)) {
4232 free_service_byindex(i);
4233 }
4234 }
4235}
4236
4237/***************************************************************************
4238 Unload a service.
4239***************************************************************************/
4240
4241void lp_killservice(int iServiceIn)
4242{
4243 if (VALID(iServiceIn)) {
4244 free_service_byindex(iServiceIn);
4245 }
4246}
4247
4248/***************************************************************************
4249 Save the curent values of all global and sDefault parameters into the
4250 defaults union. This allows swat and testparm to show only the
4251 changed (ie. non-default) parameters.
4252***************************************************************************/
4253
4254static void lp_save_defaults(void)
4255{
4256 int i;
4257 for (i = 0; parm_table[i].label; i++) {
4258 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4259 continue;
4260 switch (parm_table[i].type) {
4261 case P_LIST:
4262 str_list_copy(&(parm_table[i].def.lvalue),
4263 *(const char ***)parm_table[i].ptr);
4264 break;
4265 case P_STRING:
4266 case P_USTRING:
4267 if (parm_table[i].ptr) {
4268 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4269 } else {
4270 parm_table[i].def.svalue = NULL;
4271 }
4272 break;
4273 case P_GSTRING:
4274 case P_UGSTRING:
4275 if (parm_table[i].ptr) {
4276 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4277 } else {
4278 parm_table[i].def.svalue = NULL;
4279 }
4280 break;
4281 case P_BOOL:
4282 case P_BOOLREV:
4283 parm_table[i].def.bvalue =
4284 *(BOOL *)parm_table[i].ptr;
4285 break;
4286 case P_CHAR:
4287 parm_table[i].def.cvalue =
4288 *(char *)parm_table[i].ptr;
4289 break;
4290 case P_INTEGER:
4291 case P_OCTAL:
4292 case P_ENUM:
4293 parm_table[i].def.ivalue =
4294 *(int *)parm_table[i].ptr;
4295 break;
4296 case P_SEP:
4297 break;
4298 }
4299 }
4300 defaults_saved = True;
4301}
4302
4303/*******************************************************************
4304 Set the server type we will announce as via nmbd.
4305********************************************************************/
4306
4307static const struct srv_role_tab {
4308 uint32 role;
4309 const char *role_str;
4310} srv_role_tab [] = {
4311 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4312 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4313 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4314 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4315 { 0, NULL }
4316};
4317
4318const char* server_role_str(uint32 role)
4319{
4320 int i = 0;
4321 for (i=0; srv_role_tab[i].role_str; i++) {
4322 if (role == srv_role_tab[i].role) {
4323 return srv_role_tab[i].role_str;
4324 }
4325 }
4326 return NULL;
4327}
4328
4329static void set_server_role(void)
4330{
4331 server_role = ROLE_STANDALONE;
4332
4333 switch (lp_security()) {
4334 case SEC_SHARE:
4335 if (lp_domain_logons())
4336 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4337 break;
4338 case SEC_SERVER:
4339 if (lp_domain_logons())
4340 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4341 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4342 server_role = ROLE_STANDALONE;
4343 break;
4344 case SEC_DOMAIN:
4345 if (lp_domain_logons()) {
4346 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4347 server_role = ROLE_DOMAIN_BDC;
4348 break;
4349 }
4350 server_role = ROLE_DOMAIN_MEMBER;
4351 break;
4352 case SEC_ADS:
4353 if (lp_domain_logons()) {
4354 server_role = ROLE_DOMAIN_PDC;
4355 break;
4356 }
4357 server_role = ROLE_DOMAIN_MEMBER;
4358 break;
4359 case SEC_USER:
4360 if (lp_domain_logons()) {
4361
4362 if (Globals.bDomainMaster) /* auto or yes */
4363 server_role = ROLE_DOMAIN_PDC;
4364 else
4365 server_role = ROLE_DOMAIN_BDC;
4366 }
4367 break;
4368 default:
4369 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4370 break;
4371 }
4372
4373 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4374}
4375
4376/***********************************************************
4377 If we should send plaintext/LANMAN passwords in the clinet
4378************************************************************/
4379
4380static void set_allowed_client_auth(void)
4381{
4382 if (Globals.bClientNTLMv2Auth) {
4383 Globals.bClientLanManAuth = False;
4384 }
4385 if (!Globals.bClientLanManAuth) {
4386 Globals.bClientPlaintextAuth = False;
4387 }
4388}
4389
4390/***************************************************************************
4391 JRA.
4392 The following code allows smbd to read a user defined share file.
4393 Yes, this is my intent. Yes, I'm comfortable with that...
4394
4395 THE FOLLOWING IS SECURITY CRITICAL CODE.
4396
4397 It washes your clothes, it cleans your house, it guards you while you sleep...
4398 Do not f%^k with it....
4399***************************************************************************/
4400
4401#define MAX_USERSHARE_FILE_SIZE (10*1024)
4402
4403/***************************************************************************
4404 Check allowed stat state of a usershare file.
4405 Ensure we print out who is dicking with us so the admin can
4406 get their sorry ass fired.
4407***************************************************************************/
4408
4409static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4410{
4411 if (!S_ISREG(psbuf->st_mode)) {
4412 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4413 "not a regular file\n",
4414 fname, (unsigned int)psbuf->st_uid ));
4415 return False;
4416 }
4417
4418 /* Ensure this doesn't have the other write bit set. */
4419 if (psbuf->st_mode & S_IWOTH) {
4420 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4421 "public write. Refusing to allow as a usershare file.\n",
4422 fname, (unsigned int)psbuf->st_uid ));
4423 return False;
4424 }
4425
4426 /* Should be 10k or less. */
4427 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4428 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4429 "too large (%u) to be a user share file.\n",
4430 fname, (unsigned int)psbuf->st_uid,
4431 (unsigned int)psbuf->st_size ));
4432 return False;
4433 }
4434
4435 return True;
4436}
4437
4438/***************************************************************************
4439 Parse the contents of a usershare file.
4440***************************************************************************/
4441
4442enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4443 SMB_STRUCT_STAT *psbuf,
4444 const char *servicename,
4445 int snum,
4446 char **lines,
4447 int numlines,
4448 pstring sharepath,
4449 pstring comment,
4450 SEC_DESC **ppsd,
4451 BOOL *pallow_guest)
4452{
4453 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4454 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4455 int us_vers;
4456 SMB_STRUCT_DIR *dp;
4457 SMB_STRUCT_STAT sbuf;
4458
4459 *pallow_guest = False;
4460
4461 if (numlines < 4) {
4462 return USERSHARE_MALFORMED_FILE;
4463 }
4464
4465 if (strcmp(lines[0], "#VERSION 1") == 0) {
4466 us_vers = 1;
4467 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4468 us_vers = 2;
4469 if (numlines < 5) {
4470 return USERSHARE_MALFORMED_FILE;
4471 }
4472 } else {
4473 return USERSHARE_BAD_VERSION;
4474 }
4475
4476 if (strncmp(lines[1], "path=", 5) != 0) {
4477 return USERSHARE_MALFORMED_PATH;
4478 }
4479
4480 pstrcpy(sharepath, &lines[1][5]);
4481 trim_string(sharepath, " ", " ");
4482
4483 if (strncmp(lines[2], "comment=", 8) != 0) {
4484 return USERSHARE_MALFORMED_COMMENT_DEF;
4485 }
4486
4487 pstrcpy(comment, &lines[2][8]);
4488 trim_string(comment, " ", " ");
4489 trim_char(comment, '"', '"');
4490
4491 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4492 return USERSHARE_MALFORMED_ACL_DEF;
4493 }
4494
4495 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4496 return USERSHARE_ACL_ERR;
4497 }
4498
4499 if (us_vers == 2) {
4500 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4501 return USERSHARE_MALFORMED_ACL_DEF;
4502 }
4503 if (lines[4][9] == 'y') {
4504 *pallow_guest = True;
4505 }
4506 }
4507
4508 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4509 /* Path didn't change, no checks needed. */
4510 return USERSHARE_OK;
4511 }
4512
4513 /* The path *must* be absolute. */
4514 if (sharepath[0] != '/') {
4515 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4516 servicename, sharepath));
4517 return USERSHARE_PATH_NOT_ABSOLUTE;
4518 }
4519
4520 /* If there is a usershare prefix deny list ensure one of these paths
4521 doesn't match the start of the user given path. */
4522 if (prefixdenylist) {
4523 int i;
4524 for ( i=0; prefixdenylist[i]; i++ ) {
4525 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4526 servicename, i, prefixdenylist[i], sharepath ));
4527 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4528 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4529 "usershare prefix deny list entries.\n",
4530 servicename, sharepath));
4531 return USERSHARE_PATH_IS_DENIED;
4532 }
4533 }
4534 }
4535
4536 /* If there is a usershare prefix allow list ensure one of these paths
4537 does match the start of the user given path. */
4538
4539 if (prefixallowlist) {
4540 int i;
4541 for ( i=0; prefixallowlist[i]; i++ ) {
4542 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4543 servicename, i, prefixallowlist[i], sharepath ));
4544 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4545 break;
4546 }
4547 }
4548 if (prefixallowlist[i] == NULL) {
4549 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4550 "usershare prefix allow list entries.\n",
4551 servicename, sharepath));
4552 return USERSHARE_PATH_NOT_ALLOWED;
4553 }
4554 }
4555
4556 /* Ensure this is pointing to a directory. */
4557 dp = sys_opendir(sharepath);
4558
4559 if (!dp) {
4560 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4561 servicename, sharepath));
4562 return USERSHARE_PATH_NOT_DIRECTORY;
4563 }
4564
4565 /* Ensure the owner of the usershare file has permission to share
4566 this directory. */
4567
4568 if (sys_stat(sharepath, &sbuf) == -1) {
4569 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4570 servicename, sharepath, strerror(errno) ));
4571 sys_closedir(dp);
4572 return USERSHARE_POSIX_ERR;
4573 }
4574
4575 sys_closedir(dp);
4576
4577 if (!S_ISDIR(sbuf.st_mode)) {
4578 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4579 servicename, sharepath ));
4580 return USERSHARE_PATH_NOT_DIRECTORY;
4581 }
4582
4583 /* Check if sharing is restricted to owner-only. */
4584 /* psbuf is the stat of the usershare definition file,
4585 sbuf is the stat of the target directory to be shared. */
4586
4587 if (lp_usershare_owner_only()) {
4588 /* root can share anything. */
4589 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4590 return USERSHARE_PATH_NOT_ALLOWED;
4591 }
4592 }
4593
4594 return USERSHARE_OK;
4595}
4596
4597/***************************************************************************
4598 Deal with a usershare file.
4599 Returns:
4600 >= 0 - snum
4601 -1 - Bad name, invalid contents.
4602 - service name already existed and not a usershare, problem
4603 with permissions to share directory etc.
4604***************************************************************************/
4605
4606static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4607{
4608 SMB_STRUCT_STAT sbuf;
4609 SMB_STRUCT_STAT lsbuf;
4610 pstring fname;
4611 pstring sharepath;
4612 pstring comment;
4613 fstring service_name;
4614 char **lines = NULL;
4615 int numlines = 0;
4616 int fd = -1;
4617 int iService = -1;
4618 TALLOC_CTX *ctx = NULL;
4619 SEC_DESC *psd = NULL;
4620 BOOL guest_ok = False;
4621
4622 /* Ensure share name doesn't contain invalid characters. */
4623 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4624 DEBUG(0,("process_usershare_file: share name %s contains "
4625 "invalid characters (any of %s)\n",
4626 file_name, INVALID_SHARENAME_CHARS ));
4627 return -1;
4628 }
4629
4630 fstrcpy(service_name, file_name);
4631
4632 pstrcpy(fname, dir_name);
4633 pstrcat(fname, "/");
4634 pstrcat(fname, file_name);
4635
4636 /* Minimize the race condition by doing an lstat before we
4637 open and fstat. Ensure this isn't a symlink link. */
4638
4639 if (sys_lstat(fname, &lsbuf) != 0) {
4640 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4641 fname, strerror(errno) ));
4642 return -1;
4643 }
4644
4645 /* This must be a regular file, not a symlink, directory or
4646 other strange filetype. */
4647 if (!check_usershare_stat(fname, &lsbuf)) {
4648 return -1;
4649 }
4650
4651 /* See if there is already a servicenum for this name. */
4652 /* tdb_fetch_int32 returns -1 if not found. */
4653 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4654
4655 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4656 /* Nothing changed - Mark valid and return. */
4657 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4658 service_name ));
4659 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4660 return iService;
4661 }
4662
4663 /* Try and open the file read only - no symlinks allowed. */
4664#ifdef O_NOFOLLOW
4665 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4666#else
4667 fd = sys_open(fname, O_RDONLY, 0);
4668#endif
4669
4670 if (fd == -1) {
4671 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4672 fname, strerror(errno) ));
4673 return -1;
4674 }
4675
4676 /* Now fstat to be *SURE* it's a regular file. */
4677 if (sys_fstat(fd, &sbuf) != 0) {
4678 close(fd);
4679 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4680 fname, strerror(errno) ));
4681 return -1;
4682 }
4683
4684 /* Is it the same dev/inode as was lstated ? */
4685 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4686 close(fd);
4687 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4688 "Symlink spoofing going on ?\n", fname ));
4689 return -1;
4690 }
4691
4692 /* This must be a regular file, not a symlink, directory or
4693 other strange filetype. */
4694 if (!check_usershare_stat(fname, &sbuf)) {
4695 return -1;
4696 }
4697
4698 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4699
4700 close(fd);
4701 if (lines == NULL) {
4702 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4703 fname, (unsigned int)sbuf.st_uid ));
4704 return -1;
4705 }
4706
4707 /* Should we allow printers to be shared... ? */
4708 ctx = talloc_init("usershare_sd_xctx");
4709 if (!ctx) {
4710 file_lines_free(lines);
4711 return 1;
4712 }
4713
4714 if (parse_usershare_file(ctx, &sbuf, service_name,
4715 iService, lines, numlines, sharepath,
4716 comment, &psd, &guest_ok) != USERSHARE_OK) {
4717 talloc_destroy(ctx);
4718 file_lines_free(lines);
4719 return -1;
4720 }
4721
4722 file_lines_free(lines);
4723
4724 /* Everything ok - add the service possibly using a template. */
4725 if (iService < 0) {
4726 const service *sp = &sDefault;
4727 if (snum_template != -1) {
4728 sp = ServicePtrs[snum_template];
4729 }
4730
4731 if ((iService = add_a_service(sp, service_name)) < 0) {
4732 DEBUG(0, ("process_usershare_file: Failed to add "
4733 "new service %s\n", service_name));
4734 talloc_destroy(ctx);
4735 return -1;
4736 }
4737
4738 /* Read only is controlled by usershare ACL below. */
4739 ServicePtrs[iService]->bRead_only = False;
4740 }
4741
4742 /* Write the ACL of the new/modified share. */
4743 if (!set_share_security(service_name, psd)) {
4744 DEBUG(0, ("process_usershare_file: Failed to set share "
4745 "security for user share %s\n",
4746 service_name ));
4747 lp_remove_service(iService);
4748 talloc_destroy(ctx);
4749 return -1;
4750 }
4751
4752 talloc_destroy(ctx);
4753
4754 /* If from a template it may be marked invalid. */
4755 ServicePtrs[iService]->valid = True;
4756
4757 /* Set the service as a valid usershare. */
4758 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4759
4760 /* Set guest access. */
4761 if (lp_usershare_allow_guests()) {
4762 ServicePtrs[iService]->bGuest_ok = guest_ok;
4763 }
4764
4765 /* And note when it was loaded. */
4766 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4767 string_set(&ServicePtrs[iService]->szPath, sharepath);
4768 string_set(&ServicePtrs[iService]->comment, comment);
4769
4770 return iService;
4771}
4772
4773/***************************************************************************
4774 Checks if a usershare entry has been modified since last load.
4775***************************************************************************/
4776
4777static BOOL usershare_exists(int iService, time_t *last_mod)
4778{
4779 SMB_STRUCT_STAT lsbuf;
4780 const char *usersharepath = Globals.szUsersharePath;
4781 pstring fname;
4782
4783 pstrcpy(fname, usersharepath);
4784 pstrcat(fname, "/");
4785 pstrcat(fname, ServicePtrs[iService]->szService);
4786
4787 if (sys_lstat(fname, &lsbuf) != 0) {
4788 return False;
4789 }
4790
4791 if (!S_ISREG(lsbuf.st_mode)) {
4792 return False;
4793 }
4794
4795 *last_mod = lsbuf.st_mtime;
4796 return True;
4797}
4798
4799/***************************************************************************
4800 Load a usershare service by name. Returns a valid servicenumber or -1.
4801***************************************************************************/
4802
4803int load_usershare_service(const char *servicename)
4804{
4805 SMB_STRUCT_STAT sbuf;
4806 const char *usersharepath = Globals.szUsersharePath;
4807 int max_user_shares = Globals.iUsershareMaxShares;
4808 int snum_template = -1;
4809
4810 if (*usersharepath == 0 || max_user_shares == 0) {
4811 return -1;
4812 }
4813
4814 if (sys_stat(usersharepath, &sbuf) != 0) {
4815 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4816 usersharepath, strerror(errno) ));
4817 return -1;
4818 }
4819
4820 if (!S_ISDIR(sbuf.st_mode)) {
4821 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4822 usersharepath ));
4823 return -1;
4824 }
4825
4826 /*
4827 * This directory must be owned by root, and have the 't' bit set.
4828 * It also must not be writable by "other".
4829 */
4830
4831#ifdef S_ISVTX
4832 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4833#else
4834 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4835#endif
4836 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4837 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4838 usersharepath ));
4839 return -1;
4840 }
4841
4842 /* Ensure the template share exists if it's set. */
4843 if (Globals.szUsershareTemplateShare[0]) {
4844 /* We can't use lp_servicenumber here as we are recommending that
4845 template shares have -valid=False set. */
4846 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4847 if (ServicePtrs[snum_template]->szService &&
4848 strequal(ServicePtrs[snum_template]->szService,
4849 Globals.szUsershareTemplateShare)) {
4850 break;
4851 }
4852 }
4853
4854 if (snum_template == -1) {
4855 DEBUG(0,("load_usershare_service: usershare template share %s "
4856 "does not exist.\n",
4857 Globals.szUsershareTemplateShare ));
4858 return -1;
4859 }
4860 }
4861
4862 return process_usershare_file(usersharepath, servicename, snum_template);
4863}
4864
4865/***************************************************************************
4866 Load all user defined shares from the user share directory.
4867 We only do this if we're enumerating the share list.
4868 This is the function that can delete usershares that have
4869 been removed.
4870***************************************************************************/
4871
4872int load_usershare_shares(void)
4873{
4874 SMB_STRUCT_DIR *dp;
4875 SMB_STRUCT_STAT sbuf;
4876 SMB_STRUCT_DIRENT *de;
4877 int num_usershares = 0;
4878 int max_user_shares = Globals.iUsershareMaxShares;
4879 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4880 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4881 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4882 int iService;
4883 int snum_template = -1;
4884 const char *usersharepath = Globals.szUsersharePath;
4885 int ret = lp_numservices();
4886
4887 if (max_user_shares == 0 || *usersharepath == '\0') {
4888 return lp_numservices();
4889 }
4890
4891 if (sys_stat(usersharepath, &sbuf) != 0) {
4892 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4893 usersharepath, strerror(errno) ));
4894 return ret;
4895 }
4896
4897 /*
4898 * This directory must be owned by root, and have the 't' bit set.
4899 * It also must not be writable by "other".
4900 */
4901
4902#ifdef S_ISVTX
4903 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4904#else
4905 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4906#endif
4907 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4908 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4909 usersharepath ));
4910 return ret;
4911 }
4912
4913 /* Ensure the template share exists if it's set. */
4914 if (Globals.szUsershareTemplateShare[0]) {
4915 /* We can't use lp_servicenumber here as we are recommending that
4916 template shares have -valid=False set. */
4917 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4918 if (ServicePtrs[snum_template]->szService &&
4919 strequal(ServicePtrs[snum_template]->szService,
4920 Globals.szUsershareTemplateShare)) {
4921 break;
4922 }
4923 }
4924
4925 if (snum_template == -1) {
4926 DEBUG(0,("load_usershare_shares: usershare template share %s "
4927 "does not exist.\n",
4928 Globals.szUsershareTemplateShare ));
4929 return ret;
4930 }
4931 }
4932
4933 /* Mark all existing usershares as pending delete. */
4934 for (iService = iNumServices - 1; iService >= 0; iService--) {
4935 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4936 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4937 }
4938 }
4939
4940 dp = sys_opendir(usersharepath);
4941 if (!dp) {
4942 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4943 usersharepath, strerror(errno) ));
4944 return ret;
4945 }
4946
4947 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4948 (de = sys_readdir(dp));
4949 num_dir_entries++ ) {
4950 int r;
4951 const char *n = de->d_name;
4952
4953 /* Ignore . and .. */
4954 if (*n == '.') {
4955 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4956 continue;
4957 }
4958 }
4959
4960 if (n[0] == ':') {
4961 /* Temporary file used when creating a share. */
4962 num_tmp_dir_entries++;
4963 }
4964
4965 /* Allow 20% tmp entries. */
4966 if (num_tmp_dir_entries > allowed_tmp_entries) {
4967 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4968 "in directory %s\n",
4969 num_tmp_dir_entries, usersharepath));
4970 break;
4971 }
4972
4973 r = process_usershare_file(usersharepath, n, snum_template);
4974 if (r == 0) {
4975 /* Update the services count. */
4976 num_usershares++;
4977 if (num_usershares >= max_user_shares) {
4978 DEBUG(0,("load_usershare_shares: max user shares reached "
4979 "on file %s in directory %s\n",
4980 n, usersharepath ));
4981 break;
4982 }
4983 } else if (r == -1) {
4984 num_bad_dir_entries++;
4985 }
4986
4987 /* Allow 20% bad entries. */
4988 if (num_bad_dir_entries > allowed_bad_entries) {
4989 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4990 "in directory %s\n",
4991 num_bad_dir_entries, usersharepath));
4992 break;
4993 }
4994
4995 /* Allow 20% bad entries. */
4996 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4997 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4998 "in directory %s\n",
4999 num_dir_entries, usersharepath));
5000 break;
5001 }
5002 }
5003
5004 sys_closedir(dp);
5005
5006 /* Sweep through and delete any non-refreshed usershares that are
5007 not currently in use. */
5008 for (iService = iNumServices - 1; iService >= 0; iService--) {
5009 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
5010 if (conn_snum_used(iService)) {
5011 continue;
5012 }
5013 /* Remove from the share ACL db. */
5014 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
5015 lp_servicename(iService) ));
5016 delete_share_security(snum2params_static(iService));
5017 free_service_byindex(iService);
5018 }
5019 }
5020
5021 return lp_numservices();
5022}
5023
5024/********************************************************
5025 Destroy global resources allocated in this file
5026********************************************************/
5027
5028void gfree_loadparm(void)
5029{
5030 struct file_lists *f;
5031 struct file_lists *next;
5032 int i;
5033
5034 lp_TALLOC_FREE();
5035
5036 /* Free the file lists */
5037
5038 f = file_lists;
5039 while( f ) {
5040 next = f->next;
5041 SAFE_FREE( f->name );
5042 SAFE_FREE( f->subfname );
5043 SAFE_FREE( f );
5044 f = next;
5045 }
5046
5047 /* Free resources allocated to services */
5048
5049 for ( i = 0; i < iNumServices; i++ ) {
5050 if ( VALID(i) ) {
5051 free_service_byindex(i);
5052 }
5053 }
5054
5055 SAFE_FREE( ServicePtrs );
5056 iNumServices = 0;
5057
5058 /* Now release all resources allocated to global
5059 parameters and the default service */
5060
5061 for (i = 0; parm_table[i].label; i++)
5062 {
5063 if ( parm_table[i].type == P_STRING
5064 || parm_table[i].type == P_USTRING )
5065 {
5066 string_free( (char**)parm_table[i].ptr );
5067 }
5068 else if (parm_table[i].type == P_LIST) {
5069 str_list_free( (char***)parm_table[i].ptr );
5070 }
5071 }
5072}
5073
5074/***************************************************************************
5075 Load the services array from the services file. Return True on success,
5076 False on failure.
5077***************************************************************************/
5078
5079BOOL lp_load(const char *pszFname,
5080 BOOL global_only,
5081 BOOL save_defaults,
5082 BOOL add_ipc,
5083 BOOL initialize_globals)
5084{
5085 pstring n2;
5086 BOOL bRetval;
5087 param_opt_struct *data, *pdata;
5088
5089 pstrcpy(n2, pszFname);
5090
5091 standard_sub_basic( get_current_username(), current_user_info.domain,
5092 n2,sizeof(n2) );
5093
5094 add_to_file_list(pszFname, n2);
5095
5096 bRetval = False;
5097
5098 DEBUG(3, ("lp_load: refreshing parameters\n"));
5099
5100 bInGlobalSection = True;
5101 bGlobalOnly = global_only;
5102
5103 init_globals(! initialize_globals);
5104 debug_init();
5105
5106 if (save_defaults) {
5107 init_locals();
5108 lp_save_defaults();
5109 }
5110
5111 if (Globals.param_opt != NULL) {
5112 data = Globals.param_opt;
5113 while (data) {
5114 string_free(&data->key);
5115 string_free(&data->value);
5116 str_list_free(&data->list);
5117 pdata = data->next;
5118 SAFE_FREE(data);
5119 data = pdata;
5120 }
5121 Globals.param_opt = NULL;
5122 }
5123
5124 /* We get sections first, so have to start 'behind' to make up */
5125 iServiceIndex = -1;
5126 bRetval = pm_process(n2, do_section, do_parameter);
5127
5128 /* finish up the last section */
5129 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5130 if (bRetval)
5131 if (iServiceIndex >= 0)
5132 bRetval = service_ok(iServiceIndex);
5133
5134 lp_add_auto_services(lp_auto_services());
5135
5136 if (add_ipc) {
5137 /* When 'restrict anonymous = 2' guest connections to ipc$
5138 are denied */
5139 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5140 if ( lp_enable_asu_support() )
5141 lp_add_ipc("ADMIN$", False);
5142 }
5143
5144 set_server_role();
5145 set_default_server_announce_type();
5146 set_allowed_client_auth();
5147
5148 bLoaded = True;
5149
5150 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5151 /* if bWINSsupport is true and we are in the client */
5152 if (in_client && Globals.bWINSsupport) {
5153 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5154 }
5155
5156 init_iconv();
5157
5158 return (bRetval);
5159}
5160
5161/***************************************************************************
5162 Reset the max number of services.
5163***************************************************************************/
5164
5165void lp_resetnumservices(void)
5166{
5167 iNumServices = 0;
5168}
5169
5170/***************************************************************************
5171 Return the max number of services.
5172***************************************************************************/
5173
5174int lp_numservices(void)
5175{
5176 return (iNumServices);
5177}
5178
5179/***************************************************************************
5180Display the contents of the services array in human-readable form.
5181***************************************************************************/
5182
5183void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
5184{
5185 int iService;
5186
5187 if (show_defaults)
5188 defaults_saved = False;
5189
5190 dump_globals(f);
5191
5192 dump_a_service(&sDefault, f);
5193
5194 for (iService = 0; iService < maxtoprint; iService++) {
5195 fprintf(f,"\n");
5196 lp_dump_one(f, show_defaults, iService);
5197 }
5198}
5199
5200/***************************************************************************
5201Display the contents of one service in human-readable form.
5202***************************************************************************/
5203
5204void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
5205{
5206 if (VALID(snum)) {
5207 if (ServicePtrs[snum]->szService[0] == '\0')
5208 return;
5209 dump_a_service(ServicePtrs[snum], f);
5210 }
5211}
5212
5213/***************************************************************************
5214Return the number of the service with the given name, or -1 if it doesn't
5215exist. Note that this is a DIFFERENT ANIMAL from the internal function
5216getservicebyname()! This works ONLY if all services have been loaded, and
5217does not copy the found service.
5218***************************************************************************/
5219
5220int lp_servicenumber(const char *pszServiceName)
5221{
5222 int iService;
5223 fstring serviceName;
5224
5225 if (!pszServiceName) {
5226 return GLOBAL_SECTION_SNUM;
5227 }
5228
5229 for (iService = iNumServices - 1; iService >= 0; iService--) {
5230 if (VALID(iService) && ServicePtrs[iService]->szService) {
5231 /*
5232 * The substitution here is used to support %U is
5233 * service names
5234 */
5235 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5236 standard_sub_basic(get_current_username(),
5237 current_user_info.domain,
5238 serviceName,sizeof(serviceName));
5239 if (strequal(serviceName, pszServiceName)) {
5240 break;
5241 }
5242 }
5243 }
5244
5245 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5246 time_t last_mod;
5247
5248 if (!usershare_exists(iService, &last_mod)) {
5249 /* Remove the share security tdb entry for it. */
5250 delete_share_security(snum2params_static(iService));
5251 /* Remove it from the array. */
5252 free_service_byindex(iService);
5253 /* Doesn't exist anymore. */
5254 return GLOBAL_SECTION_SNUM;
5255 }
5256
5257 /* Has it been modified ? If so delete and reload. */
5258 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5259 /* Remove it from the array. */
5260 free_service_byindex(iService);
5261 /* and now reload it. */
5262 iService = load_usershare_service(pszServiceName);
5263 }
5264 }
5265
5266 if (iService < 0) {
5267 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5268 return GLOBAL_SECTION_SNUM;
5269 }
5270
5271 return (iService);
5272}
5273
5274BOOL share_defined(const char *service_name)
5275{
5276 return (lp_servicenumber(service_name) != -1);
5277}
5278
5279struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5280 const char *sharename)
5281{
5282 struct share_params *result;
5283 char *sname;
5284 int snum;
5285
5286 if (!(sname = SMB_STRDUP(sharename))) {
5287 return NULL;
5288 }
5289
5290 snum = find_service(sname);
5291 SAFE_FREE(sname);
5292
5293 if (snum < 0) {
5294 return NULL;
5295 }
5296
5297 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5298 DEBUG(0, ("talloc failed\n"));
5299 return NULL;
5300 }
5301
5302 result->service = snum;
5303 return result;
5304}
5305
5306struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5307{
5308 struct share_iterator *result;
5309
5310 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5311 DEBUG(0, ("talloc failed\n"));
5312 return NULL;
5313 }
5314
5315 result->next_id = 0;
5316 return result;
5317}
5318
5319struct share_params *next_share(struct share_iterator *list)
5320{
5321 struct share_params *result;
5322
5323 while (!lp_snum_ok(list->next_id) &&
5324 (list->next_id < lp_numservices())) {
5325 list->next_id += 1;
5326 }
5327
5328 if (list->next_id >= lp_numservices()) {
5329 return NULL;
5330 }
5331
5332 if (!(result = TALLOC_P(list, struct share_params))) {
5333 DEBUG(0, ("talloc failed\n"));
5334 return NULL;
5335 }
5336
5337 result->service = list->next_id;
5338 list->next_id += 1;
5339 return result;
5340}
5341
5342struct share_params *next_printer(struct share_iterator *list)
5343{
5344 struct share_params *result;
5345
5346 while ((result = next_share(list)) != NULL) {
5347 if (lp_print_ok(result->service)) {
5348 break;
5349 }
5350 }
5351 return result;
5352}
5353
5354/*
5355 * This is a hack for a transition period until we transformed all code from
5356 * service numbers to struct share_params.
5357 */
5358
5359struct share_params *snum2params_static(int snum)
5360{
5361 static struct share_params result;
5362 result.service = snum;
5363 return &result;
5364}
5365
5366/*******************************************************************
5367 A useful volume label function.
5368********************************************************************/
5369
5370const char *volume_label(int snum)
5371{
5372 char *ret;
5373 const char *label = lp_volume(snum);
5374 if (!*label) {
5375 label = lp_servicename(snum);
5376 }
5377
5378 /* This returns a 33 byte guarenteed null terminated string. */
5379 ret = talloc_strndup(main_loop_talloc_get(), label, 32);
5380 if (!ret) {
5381 return "";
5382 }
5383 return ret;
5384}
5385
5386/*******************************************************************
5387 Set the server type we will announce as via nmbd.
5388********************************************************************/
5389
5390static void set_default_server_announce_type(void)
5391{
5392 default_server_announce = 0;
5393 default_server_announce |= SV_TYPE_WORKSTATION;
5394 default_server_announce |= SV_TYPE_SERVER;
5395 default_server_announce |= SV_TYPE_SERVER_UNIX;
5396
5397 /* note that the flag should be set only if we have a
5398 printer service but nmbd doesn't actually load the
5399 services so we can't tell --jerry */
5400
5401 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5402
5403 switch (lp_announce_as()) {
5404 case ANNOUNCE_AS_NT_SERVER:
5405 default_server_announce |= SV_TYPE_SERVER_NT;
5406 /* fall through... */
5407 case ANNOUNCE_AS_NT_WORKSTATION:
5408 default_server_announce |= SV_TYPE_NT;
5409 break;
5410 case ANNOUNCE_AS_WIN95:
5411 default_server_announce |= SV_TYPE_WIN95_PLUS;
5412 break;
5413 case ANNOUNCE_AS_WFW:
5414 default_server_announce |= SV_TYPE_WFW;
5415 break;
5416 default:
5417 break;
5418 }
5419
5420 switch (lp_server_role()) {
5421 case ROLE_DOMAIN_MEMBER:
5422 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5423 break;
5424 case ROLE_DOMAIN_PDC:
5425 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5426 break;
5427 case ROLE_DOMAIN_BDC:
5428 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5429 break;
5430 case ROLE_STANDALONE:
5431 default:
5432 break;
5433 }
5434 if (lp_time_server())
5435 default_server_announce |= SV_TYPE_TIME_SOURCE;
5436
5437 if (lp_host_msdfs())
5438 default_server_announce |= SV_TYPE_DFS_SERVER;
5439}
5440
5441/***********************************************************
5442 returns role of Samba server
5443************************************************************/
5444
5445int lp_server_role(void)
5446{
5447 return server_role;
5448}
5449
5450/***********************************************************
5451 If we are PDC then prefer us as DMB
5452************************************************************/
5453
5454BOOL lp_domain_master(void)
5455{
5456 if (Globals.bDomainMaster == Auto)
5457 return (lp_server_role() == ROLE_DOMAIN_PDC);
5458
5459 return Globals.bDomainMaster;
5460}
5461
5462/***********************************************************
5463 If we are DMB then prefer us as LMB
5464************************************************************/
5465
5466BOOL lp_preferred_master(void)
5467{
5468 if (Globals.bPreferredMaster == Auto)
5469 return (lp_local_master() && lp_domain_master());
5470
5471 return Globals.bPreferredMaster;
5472}
5473
5474/*******************************************************************
5475 Remove a service.
5476********************************************************************/
5477
5478void lp_remove_service(int snum)
5479{
5480 ServicePtrs[snum]->valid = False;
5481 invalid_services[num_invalid_services++] = snum;
5482}
5483
5484/*******************************************************************
5485 Copy a service.
5486********************************************************************/
5487
5488void lp_copy_service(int snum, const char *new_name)
5489{
5490 do_section(new_name);
5491 if (snum >= 0) {
5492 snum = lp_servicenumber(new_name);
5493 if (snum >= 0)
5494 lp_do_parameter(snum, "copy", lp_servicename(snum));
5495 }
5496}
5497
5498
5499/*******************************************************************
5500 Get the default server type we will announce as via nmbd.
5501********************************************************************/
5502
5503int lp_default_server_announce(void)
5504{
5505 return default_server_announce;
5506}
5507
5508/*******************************************************************
5509 Split the announce version into major and minor numbers.
5510********************************************************************/
5511
5512int lp_major_announce_version(void)
5513{
5514 static BOOL got_major = False;
5515 static int major_version = DEFAULT_MAJOR_VERSION;
5516 char *vers;
5517 char *p;
5518
5519 if (got_major)
5520 return major_version;
5521
5522 got_major = True;
5523 if ((vers = lp_announce_version()) == NULL)
5524 return major_version;
5525
5526 if ((p = strchr_m(vers, '.')) == 0)
5527 return major_version;
5528
5529 *p = '\0';
5530 major_version = atoi(vers);
5531 return major_version;
5532}
5533
5534int lp_minor_announce_version(void)
5535{
5536 static BOOL got_minor = False;
5537 static int minor_version = DEFAULT_MINOR_VERSION;
5538 char *vers;
5539 char *p;
5540
5541 if (got_minor)
5542 return minor_version;
5543
5544 got_minor = True;
5545 if ((vers = lp_announce_version()) == NULL)
5546 return minor_version;
5547
5548 if ((p = strchr_m(vers, '.')) == 0)
5549 return minor_version;
5550
5551 p++;
5552 minor_version = atoi(p);
5553 return minor_version;
5554}
5555
5556/***********************************************************
5557 Set the global name resolution order (used in smbclient).
5558************************************************************/
5559
5560void lp_set_name_resolve_order(const char *new_order)
5561{
5562 string_set(&Globals.szNameResolveOrder, new_order);
5563}
5564
5565const char *lp_printername(int snum)
5566{
5567 const char *ret = _lp_printername(snum);
5568 if (ret == NULL || (ret != NULL && *ret == '\0'))
5569 ret = lp_const_servicename(snum);
5570
5571 return ret;
5572}
5573
5574
5575/***********************************************************
5576 Allow daemons such as winbindd to fix their logfile name.
5577************************************************************/
5578
5579void lp_set_logfile(const char *name)
5580{
5581 string_set(&Globals.szLogFile, name);
5582 pstrcpy(debugf, name);
5583}
5584
5585/*******************************************************************
5586 Return the max print jobs per queue.
5587********************************************************************/
5588
5589int lp_maxprintjobs(int snum)
5590{
5591 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5592 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5593 maxjobs = PRINT_MAX_JOBID - 1;
5594
5595 return maxjobs;
5596}
5597
5598const char *lp_printcapname(void)
5599{
5600 if ((Globals.szPrintcapname != NULL) &&
5601 (Globals.szPrintcapname[0] != '\0'))
5602 return Globals.szPrintcapname;
5603
5604 if (sDefault.iPrinting == PRINT_CUPS) {
5605#ifdef HAVE_CUPS
5606 return "cups";
5607#else
5608 return "lpstat";
5609#endif
5610 }
5611
5612 if (sDefault.iPrinting == PRINT_BSD)
5613 return "/etc/printcap";
5614
5615 return PRINTCAP_NAME;
5616}
5617
5618/*******************************************************************
5619 Ensure we don't use sendfile if server smb signing is active.
5620********************************************************************/
5621
5622static uint32 spoolss_state;
5623
5624BOOL lp_disable_spoolss( void )
5625{
5626 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5627 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5628
5629 return spoolss_state == SVCCTL_STOPPED ? True : False;
5630}
5631
5632void lp_set_spoolss_state( uint32 state )
5633{
5634 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5635
5636 spoolss_state = state;
5637}
5638
5639uint32 lp_get_spoolss_state( void )
5640{
5641 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5642}
5643
5644/*******************************************************************
5645 Ensure we don't use sendfile if server smb signing is active.
5646********************************************************************/
5647
5648BOOL lp_use_sendfile(int snum)
5649{
5650 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5651 if (Protocol < PROTOCOL_NT1) {
5652 return False;
5653 }
5654 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5655}
5656
5657/*******************************************************************
5658 Turn off sendfile if we find the underlying OS doesn't support it.
5659********************************************************************/
5660
5661void set_use_sendfile(int snum, BOOL val)
5662{
5663 if (LP_SNUM_OK(snum))
5664 ServicePtrs[snum]->bUseSendfile = val;
5665 else
5666 sDefault.bUseSendfile = val;
5667}
5668
5669/*******************************************************************
5670 Turn off storing DOS attributes if this share doesn't support it.
5671********************************************************************/
5672
5673void set_store_dos_attributes(int snum, BOOL val)
5674{
5675 if (!LP_SNUM_OK(snum))
5676 return;
5677 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5678}
5679
5680void lp_set_mangling_method(const char *new_method)
5681{
5682 string_set(&Globals.szManglingMethod, new_method);
5683}
5684
5685/*******************************************************************
5686 Global state for POSIX pathname processing.
5687********************************************************************/
5688
5689static BOOL posix_pathnames;
5690
5691BOOL lp_posix_pathnames(void)
5692{
5693 return posix_pathnames;
5694}
5695
5696/*******************************************************************
5697 Change everything needed to ensure POSIX pathname processing (currently
5698 not much).
5699********************************************************************/
5700
5701void lp_set_posix_pathnames(void)
5702{
5703 posix_pathnames = True;
5704}
5705
5706/*******************************************************************
5707 Global state for POSIX lock processing - CIFS unix extensions.
5708********************************************************************/
5709
5710BOOL posix_default_lock_was_set;
5711static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5712
5713enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5714{
5715 if (posix_default_lock_was_set) {
5716 return posix_cifsx_locktype;
5717 } else {
5718 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5719 }
5720}
5721
5722/*******************************************************************
5723********************************************************************/
5724
5725void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5726{
5727 posix_default_lock_was_set = True;
5728 posix_cifsx_locktype = val;
5729}
Note: See TracBrowser for help on using the repository browser.