source: branches/samba-3.3.x/source/param/loadparm.c@ 221

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

Update Samba 3.3 to 3.3.1

File size: 253.0 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 Copyright (C) Michael Adam 2008
13
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; either version 3 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
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#include "printing.h"
56
57bool bLoaded = False;
58
59extern enum protocol_types Protocol;
60extern userdom_struct current_user_info;
61
62#ifndef GLOBAL_NAME
63#define GLOBAL_NAME "global"
64#endif
65
66#ifndef PRINTERS_NAME
67#define PRINTERS_NAME "printers"
68#endif
69
70#ifndef HOMES_NAME
71#define HOMES_NAME "homes"
72#endif
73
74/* the special value for the include parameter
75 * to be interpreted not as a file name but to
76 * trigger loading of the global smb.conf options
77 * from registry. */
78#ifndef INCLUDE_REGISTRY_NAME
79#define INCLUDE_REGISTRY_NAME "registry"
80#endif
81
82static bool in_client = False; /* Not in the client by default */
83static struct smbconf_csn conf_last_csn;
84
85#define CONFIG_BACKEND_FILE 0
86#define CONFIG_BACKEND_REGISTRY 1
87
88static int config_backend = CONFIG_BACKEND_FILE;
89
90/* some helpful bits */
91#define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
92#define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
93
94#define USERSHARE_VALID 1
95#define USERSHARE_PENDING_DELETE 2
96
97extern int extra_time_offset;
98
99static bool defaults_saved = False;
100
101struct param_opt_struct {
102 struct param_opt_struct *prev, *next;
103 char *key;
104 char *value;
105 char **list;
106};
107
108/*
109 * This structure describes global (ie., server-wide) parameters.
110 */
111struct global {
112 int ConfigBackend;
113 char *smb_ports;
114 char *dos_charset;
115 char *unix_charset;
116 char *display_charset;
117 char *szPrintcapname;
118 char *szAddPortCommand;
119 char *szEnumPortsCommand;
120 char *szAddPrinterCommand;
121 char *szDeletePrinterCommand;
122 char *szOs2DriverMap;
123 char *szLockDir;
124 char *szPidDir;
125 char *szRootdir;
126 char *szDefaultService;
127 char *szGetQuota;
128 char *szSetQuota;
129 char *szMsgCommand;
130 char *szServerString;
131 char *szAutoServices;
132 char *szPasswdProgram;
133 char *szPasswdChat;
134 char *szLogFile;
135 char *szConfigFile;
136 char *szSMBPasswdFile;
137 char *szPrivateDir;
138 char *szPassdbBackend;
139 char **szPreloadModules;
140 char *szPasswordServer;
141 char *szSocketOptions;
142 char *szRealm;
143 char *szAfsUsernameMap;
144 int iAfsTokenLifetime;
145 char *szLogNtTokenCommand;
146 char *szUsernameMap;
147 char *szLogonScript;
148 char *szLogonPath;
149 char *szLogonDrive;
150 char *szLogonHome;
151 char **szWINSservers;
152 char **szInterfaces;
153 char *szRemoteAnnounce;
154 char *szRemoteBrowseSync;
155 char *szSocketAddress;
156 char *szNISHomeMapName;
157 char *szAnnounceVersion; /* This is initialised in init_globals */
158 char *szWorkgroup;
159 char *szNetbiosName;
160 char **szNetbiosAliases;
161 char *szNetbiosScope;
162 char *szNameResolveOrder;
163 char *szPanicAction;
164 char *szAddUserScript;
165 char *szRenameUserScript;
166 char *szDelUserScript;
167 char *szAddGroupScript;
168 char *szDelGroupScript;
169 char *szAddUserToGroupScript;
170 char *szDelUserFromGroupScript;
171 char *szSetPrimaryGroupScript;
172 char *szAddMachineScript;
173 char *szShutdownScript;
174 char *szAbortShutdownScript;
175 char *szUsernameMapScript;
176 char *szCheckPasswordScript;
177 char *szWINSHook;
178 char *szUtmpDir;
179 char *szWtmpDir;
180 bool bUtmp;
181 char *szIdmapUID;
182 char *szIdmapGID;
183 bool bPassdbExpandExplicit;
184 int AlgorithmicRidBase;
185 char *szTemplateHomedir;
186 char *szTemplateShell;
187 char *szWinbindSeparator;
188 bool bWinbindEnumUsers;
189 bool bWinbindEnumGroups;
190 bool bWinbindUseDefaultDomain;
191 bool bWinbindTrustedDomainsOnly;
192 bool bWinbindNestedGroups;
193 int winbind_expand_groups;
194 bool bWinbindRefreshTickets;
195 bool bWinbindOfflineLogon;
196 bool bWinbindNormalizeNames;
197 bool bWinbindRpcOnly;
198 char *szIdmapBackend;
199 char *szIdmapAllocBackend;
200 char *szAddShareCommand;
201 char *szChangeShareCommand;
202 char *szDeleteShareCommand;
203 char **szEventLogs;
204 char *szGuestaccount;
205 char *szManglingMethod;
206 char **szServicesList;
207 char *szUsersharePath;
208 char *szUsershareTemplateShare;
209 char **szUsersharePrefixAllowList;
210 char **szUsersharePrefixDenyList;
211 int mangle_prefix;
212 int max_log_size;
213 char *szLogLevel;
214 int max_xmit;
215 int max_mux;
216 int max_open_files;
217 int open_files_db_hash_size;
218 int pwordlevel;
219 int unamelevel;
220 int deadtime;
221 bool getwd_cache;
222 int maxprotocol;
223 int minprotocol;
224 int security;
225 char **AuthMethods;
226 bool paranoid_server_security;
227 int maxdisksize;
228 int lpqcachetime;
229 int iMaxSmbdProcesses;
230 bool bDisableSpoolss;
231 int syslog;
232 int os_level;
233 bool enhanced_browsing;
234 int max_ttl;
235 int max_wins_ttl;
236 int min_wins_ttl;
237 int lm_announce;
238 int lm_interval;
239 int announce_as; /* This is initialised in init_globals */
240 int machine_password_timeout;
241 int map_to_guest;
242 int oplock_break_wait_time;
243 int winbind_cache_time;
244 int winbind_reconnect_delay;
245 int winbind_max_idle_children;
246 char **szWinbindNssInfo;
247 int iLockSpinTime;
248 char *szLdapMachineSuffix;
249 char *szLdapUserSuffix;
250 char *szLdapIdmapSuffix;
251 char *szLdapGroupSuffix;
252 int ldap_ssl;
253 bool ldap_ssl_ads;
254 char *szLdapSuffix;
255 char *szLdapAdminDn;
256 int ldap_debug_level;
257 int ldap_debug_threshold;
258 int iAclCompat;
259 char *szCupsServer;
260 char *szIPrintServer;
261 char *ctdbdSocket;
262 char **szClusterAddresses;
263 bool clustering;
264 int ldap_passwd_sync;
265 int ldap_replication_sleep;
266 int ldap_timeout; /* This is initialised in init_globals */
267 int ldap_connection_timeout;
268 int ldap_page_size;
269 bool ldap_delete_dn;
270 bool bMsAddPrinterWizard;
271 bool bDNSproxy;
272 bool bWINSsupport;
273 bool bWINSproxy;
274 bool bLocalMaster;
275 int iPreferredMaster;
276 int iDomainMaster;
277 bool bDomainLogons;
278 char **szInitLogonDelayedHosts;
279 int InitLogonDelay;
280 bool bEncryptPasswords;
281 bool bUpdateEncrypt;
282 int clientSchannel;
283 int serverSchannel;
284 bool bNullPasswords;
285 bool bObeyPamRestrictions;
286 bool bLoadPrinters;
287 int PrintcapCacheTime;
288 bool bLargeReadwrite;
289 bool bReadRaw;
290 bool bWriteRaw;
291 bool bSyslogOnly;
292 bool bBrowseList;
293 bool bNISHomeMap;
294 bool bTimeServer;
295 bool bBindInterfacesOnly;
296 bool bPamPasswordChange;
297 bool bUnixPasswdSync;
298 bool bPasswdChatDebug;
299 int iPasswdChatTimeout;
300 bool bTimestampLogs;
301 bool bNTSmbSupport;
302 bool bNTPipeSupport;
303 bool bNTStatusSupport;
304 bool bStatCache;
305 int iMaxStatCacheSize;
306 bool bKernelOplocks;
307 bool bAllowTrustedDomains;
308 bool bLanmanAuth;
309 bool bNTLMAuth;
310 bool bUseSpnego;
311 bool bClientLanManAuth;
312 bool bClientNTLMv2Auth;
313 bool bClientPlaintextAuth;
314 bool bClientUseSpnego;
315 bool bDebugPrefixTimestamp;
316 bool bDebugHiresTimestamp;
317 bool bDebugPid;
318 bool bDebugUid;
319 bool bDebugClass;
320 bool bEnableCoreFiles;
321 bool bHostMSDfs;
322 bool bUseMmap;
323 bool bHostnameLookups;
324 bool bUnixExtensions;
325 bool bDisableNetbios;
326 bool bUseKerberosKeytab;
327 bool bDeferSharingViolations;
328 bool bEnablePrivileges;
329 bool bASUSupport;
330 bool bUsershareOwnerOnly;
331 bool bUsershareAllowGuests;
332 bool bRegistryShares;
333 int restrict_anonymous;
334 int name_cache_timeout;
335 int client_signing;
336 int server_signing;
337 int client_ldap_sasl_wrapping;
338 int iUsershareMaxShares;
339 int iIdmapCacheTime;
340 int iIdmapNegativeCacheTime;
341 bool bResetOnZeroVC;
342 int iKeepalive;
343 int iminreceivefile;
344 struct param_opt_struct *param_opt;
345 int cups_connection_timeout;
346};
347
348static struct global Globals;
349
350/*
351 * This structure describes a single service.
352 */
353struct service {
354 bool valid;
355 bool autoloaded;
356 int usershare;
357 time_t usershare_last_mod;
358 char *szService;
359 char *szPath;
360 char *szUsername;
361 char **szInvalidUsers;
362 char **szValidUsers;
363 char **szAdminUsers;
364 char *szCopy;
365 char *szInclude;
366 char *szPreExec;
367 char *szPostExec;
368 char *szRootPreExec;
369 char *szRootPostExec;
370 char *szCupsOptions;
371 char *szPrintcommand;
372 char *szLpqcommand;
373 char *szLprmcommand;
374 char *szLppausecommand;
375 char *szLpresumecommand;
376 char *szQueuepausecommand;
377 char *szQueueresumecommand;
378 char *szPrintername;
379 char *szPrintjobUsername;
380 char *szDontdescend;
381 char **szHostsallow;
382 char **szHostsdeny;
383 char *szMagicScript;
384 char *szMagicOutput;
385 char *szVetoFiles;
386 char *szHideFiles;
387 char *szVetoOplockFiles;
388 char *comment;
389 char *force_user;
390 char *force_group;
391 char **readlist;
392 char **writelist;
393 char **printer_admin;
394 char *volume;
395 char *fstype;
396 char **szVfsObjects;
397 char *szMSDfsProxy;
398 char *szAioWriteBehind;
399 char *szDfree;
400 int iMinPrintSpace;
401 int iMaxPrintJobs;
402 int iMaxReportedPrintJobs;
403 int iWriteCacheSize;
404 int iCreate_mask;
405 int iCreate_force_mode;
406 int iSecurity_mask;
407 int iSecurity_force_mode;
408 int iDir_mask;
409 int iDir_force_mode;
410 int iDir_Security_mask;
411 int iDir_Security_force_mode;
412 int iMaxConnections;
413 int iDefaultCase;
414 int iPrinting;
415 int iOplockContentionLimit;
416 int iCSCPolicy;
417 int iBlock_size;
418 int iDfreeCacheTime;
419 bool bPreexecClose;
420 bool bRootpreexecClose;
421 int iCaseSensitive;
422 bool bCasePreserve;
423 bool bShortCasePreserve;
424 bool bHideDotFiles;
425 bool bHideSpecialFiles;
426 bool bHideUnReadable;
427 bool bHideUnWriteableFiles;
428 bool bBrowseable;
429 bool bAvailable;
430 bool bRead_only;
431 bool bNo_set_dir;
432 bool bGuest_only;
433 bool bAdministrative_share;
434 bool bGuest_ok;
435 bool bPrint_ok;
436 bool bMap_system;
437 bool bMap_hidden;
438 bool bMap_archive;
439 bool bStoreDosAttributes;
440 bool bDmapiSupport;
441 bool bLocking;
442 int iStrictLocking;
443 bool bPosixLocking;
444 bool bShareModes;
445 bool bOpLocks;
446 bool bLevel2OpLocks;
447 bool bOnlyUser;
448 bool bMangledNames;
449 bool bWidelinks;
450 bool bSymlinks;
451 bool bSyncAlways;
452 bool bStrictAllocate;
453 bool bStrictSync;
454 char magic_char;
455 struct bitmap *copymap;
456 bool bDeleteReadonly;
457 bool bFakeOplocks;
458 bool bDeleteVetoFiles;
459 bool bDosFilemode;
460 bool bDosFiletimes;
461 bool bDosFiletimeResolution;
462 bool bFakeDirCreateTimes;
463 bool bBlockingLocks;
464 bool bInheritPerms;
465 bool bInheritACLS;
466 bool bInheritOwner;
467 bool bMSDfsRoot;
468 bool bUseClientDriver;
469 bool bDefaultDevmode;
470 bool bForcePrintername;
471 bool bNTAclSupport;
472 bool bForceUnknownAclUser;
473 bool bUseSendfile;
474 bool bProfileAcls;
475 bool bMap_acl_inherit;
476 bool bAfs_Share;
477 bool bEASupport;
478 bool bAclCheckPermissions;
479 bool bAclMapFullControl;
480 bool bAclGroupControl;
481 bool bChangeNotify;
482 bool bKernelChangeNotify;
483 int iallocation_roundup_size;
484 int iAioReadSize;
485 int iAioWriteSize;
486 int iMap_readonly;
487 int iDirectoryNameCacheSize;
488 int ismb_encrypt;
489 struct param_opt_struct *param_opt;
490
491 char dummy[3]; /* for alignment */
492};
493
494
495/* This is a default service used to prime a services structure */
496static struct service sDefault = {
497 True, /* valid */
498 False, /* not autoloaded */
499 0, /* not a usershare */
500 (time_t)0, /* No last mod time */
501 NULL, /* szService */
502 NULL, /* szPath */
503 NULL, /* szUsername */
504 NULL, /* szInvalidUsers */
505 NULL, /* szValidUsers */
506 NULL, /* szAdminUsers */
507 NULL, /* szCopy */
508 NULL, /* szInclude */
509 NULL, /* szPreExec */
510 NULL, /* szPostExec */
511 NULL, /* szRootPreExec */
512 NULL, /* szRootPostExec */
513 NULL, /* szCupsOptions */
514 NULL, /* szPrintcommand */
515 NULL, /* szLpqcommand */
516 NULL, /* szLprmcommand */
517 NULL, /* szLppausecommand */
518 NULL, /* szLpresumecommand */
519 NULL, /* szQueuepausecommand */
520 NULL, /* szQueueresumecommand */
521 NULL, /* szPrintername */
522 NULL, /* szPrintjobUsername */
523 NULL, /* szDontdescend */
524 NULL, /* szHostsallow */
525 NULL, /* szHostsdeny */
526 NULL, /* szMagicScript */
527 NULL, /* szMagicOutput */
528 NULL, /* szVetoFiles */
529 NULL, /* szHideFiles */
530 NULL, /* szVetoOplockFiles */
531 NULL, /* comment */
532 NULL, /* force user */
533 NULL, /* force group */
534 NULL, /* readlist */
535 NULL, /* writelist */
536 NULL, /* printer admin */
537 NULL, /* volume */
538 NULL, /* fstype */
539 NULL, /* vfs objects */
540 NULL, /* szMSDfsProxy */
541 NULL, /* szAioWriteBehind */
542 NULL, /* szDfree */
543 0, /* iMinPrintSpace */
544 1000, /* iMaxPrintJobs */
545 0, /* iMaxReportedPrintJobs */
546 0, /* iWriteCacheSize */
547 0744, /* iCreate_mask */
548 0000, /* iCreate_force_mode */
549 0777, /* iSecurity_mask */
550 0, /* iSecurity_force_mode */
551 0755, /* iDir_mask */
552 0000, /* iDir_force_mode */
553 0777, /* iDir_Security_mask */
554 0, /* iDir_Security_force_mode */
555 0, /* iMaxConnections */
556 CASE_LOWER, /* iDefaultCase */
557 DEFAULT_PRINTING, /* iPrinting */
558 2, /* iOplockContentionLimit */
559 0, /* iCSCPolicy */
560 1024, /* iBlock_size */
561 0, /* iDfreeCacheTime */
562 False, /* bPreexecClose */
563 False, /* bRootpreexecClose */
564 Auto, /* case sensitive */
565 True, /* case preserve */
566 True, /* short case preserve */
567 True, /* bHideDotFiles */
568 False, /* bHideSpecialFiles */
569 False, /* bHideUnReadable */
570 False, /* bHideUnWriteableFiles */
571 True, /* bBrowseable */
572 True, /* bAvailable */
573 True, /* bRead_only */
574 True, /* bNo_set_dir */
575 False, /* bGuest_only */
576 False, /* bAdministrative_share */
577 False, /* bGuest_ok */
578 False, /* bPrint_ok */
579 False, /* bMap_system */
580 False, /* bMap_hidden */
581 True, /* bMap_archive */
582 False, /* bStoreDosAttributes */
583 False, /* bDmapiSupport */
584 True, /* bLocking */
585 Auto, /* iStrictLocking */
586 True, /* bPosixLocking */
587 True, /* bShareModes */
588 True, /* bOpLocks */
589 True, /* bLevel2OpLocks */
590 False, /* bOnlyUser */
591 True, /* bMangledNames */
592 True, /* bWidelinks */
593 True, /* bSymlinks */
594 False, /* bSyncAlways */
595 False, /* bStrictAllocate */
596 False, /* bStrictSync */
597 '~', /* magic char */
598 NULL, /* copymap */
599 False, /* bDeleteReadonly */
600 False, /* bFakeOplocks */
601 False, /* bDeleteVetoFiles */
602 False, /* bDosFilemode */
603 True, /* bDosFiletimes */
604 False, /* bDosFiletimeResolution */
605 False, /* bFakeDirCreateTimes */
606 True, /* bBlockingLocks */
607 False, /* bInheritPerms */
608 False, /* bInheritACLS */
609 False, /* bInheritOwner */
610 False, /* bMSDfsRoot */
611 False, /* bUseClientDriver */
612 True, /* bDefaultDevmode */
613 False, /* bForcePrintername */
614 True, /* bNTAclSupport */
615 False, /* bForceUnknownAclUser */
616 False, /* bUseSendfile */
617 False, /* bProfileAcls */
618 False, /* bMap_acl_inherit */
619 False, /* bAfs_Share */
620 False, /* bEASupport */
621 True, /* bAclCheckPermissions */
622 True, /* bAclMapFullControl */
623 False, /* bAclGroupControl */
624 True, /* bChangeNotify */
625 True, /* bKernelChangeNotify */
626 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
627 0, /* iAioReadSize */
628 0, /* iAioWriteSize */
629 MAP_READONLY_YES, /* iMap_readonly */
630#ifdef BROKEN_DIRECTORY_HANDLING
631 0, /* iDirectoryNameCacheSize */
632#else
633 100, /* iDirectoryNameCacheSize */
634#endif
635 Auto, /* ismb_encrypt */
636 NULL, /* Parametric options */
637
638 "" /* dummy */
639};
640
641/* local variables */
642static struct service **ServicePtrs = NULL;
643static int iNumServices = 0;
644static int iServiceIndex = 0;
645static struct db_context *ServiceHash;
646static int *invalid_services = NULL;
647static int num_invalid_services = 0;
648static bool bInGlobalSection = True;
649static bool bGlobalOnly = False;
650static int server_role;
651static int default_server_announce;
652
653#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
654
655/* prototypes for the special type handlers */
656static bool handle_include( int snum, const char *pszParmValue, char **ptr);
657static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
658static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
659static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
660static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
661static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
662static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
663static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
664static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
665static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
666static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
667static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
668
669static void set_server_role(void);
670static void set_default_server_announce_type(void);
671static void set_allowed_client_auth(void);
672
673static const struct enum_list enum_protocol[] = {
674 {PROTOCOL_NT1, "NT1"},
675 {PROTOCOL_LANMAN2, "LANMAN2"},
676 {PROTOCOL_LANMAN1, "LANMAN1"},
677 {PROTOCOL_CORE, "CORE"},
678 {PROTOCOL_COREPLUS, "COREPLUS"},
679 {PROTOCOL_COREPLUS, "CORE+"},
680 {-1, NULL}
681};
682
683static const struct enum_list enum_security[] = {
684 {SEC_SHARE, "SHARE"},
685 {SEC_USER, "USER"},
686 {SEC_SERVER, "SERVER"},
687 {SEC_DOMAIN, "DOMAIN"},
688#ifdef HAVE_ADS
689 {SEC_ADS, "ADS"},
690#endif
691 {-1, NULL}
692};
693
694static const struct enum_list enum_printing[] = {
695 {PRINT_SYSV, "sysv"},
696 {PRINT_AIX, "aix"},
697 {PRINT_HPUX, "hpux"},
698 {PRINT_BSD, "bsd"},
699 {PRINT_QNX, "qnx"},
700 {PRINT_PLP, "plp"},
701 {PRINT_LPRNG, "lprng"},
702 {PRINT_CUPS, "cups"},
703 {PRINT_IPRINT, "iprint"},
704 {PRINT_LPRNT, "nt"},
705 {PRINT_LPROS2, "os2"},
706#ifdef DEVELOPER
707 {PRINT_TEST, "test"},
708 {PRINT_VLP, "vlp"},
709#endif /* DEVELOPER */
710 {-1, NULL}
711};
712
713static const struct enum_list enum_ldap_sasl_wrapping[] = {
714 {0, "plain"},
715 {ADS_AUTH_SASL_SIGN, "sign"},
716 {ADS_AUTH_SASL_SEAL, "seal"},
717 {-1, NULL}
718};
719
720static const struct enum_list enum_ldap_ssl[] = {
721 {LDAP_SSL_OFF, "no"},
722 {LDAP_SSL_OFF, "off"},
723 {LDAP_SSL_START_TLS, "start tls"},
724 {LDAP_SSL_START_TLS, "start_tls"},
725 {-1, NULL}
726};
727
728static const struct enum_list enum_ldap_passwd_sync[] = {
729 {LDAP_PASSWD_SYNC_OFF, "no"},
730 {LDAP_PASSWD_SYNC_OFF, "off"},
731 {LDAP_PASSWD_SYNC_ON, "yes"},
732 {LDAP_PASSWD_SYNC_ON, "on"},
733 {LDAP_PASSWD_SYNC_ONLY, "only"},
734 {-1, NULL}
735};
736
737/* Types of machine we can announce as. */
738#define ANNOUNCE_AS_NT_SERVER 1
739#define ANNOUNCE_AS_WIN95 2
740#define ANNOUNCE_AS_WFW 3
741#define ANNOUNCE_AS_NT_WORKSTATION 4
742
743static const struct enum_list enum_announce_as[] = {
744 {ANNOUNCE_AS_NT_SERVER, "NT"},
745 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
746 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
747 {ANNOUNCE_AS_WIN95, "win95"},
748 {ANNOUNCE_AS_WFW, "WfW"},
749 {-1, NULL}
750};
751
752static const struct enum_list enum_map_readonly[] = {
753 {MAP_READONLY_NO, "no"},
754 {MAP_READONLY_NO, "false"},
755 {MAP_READONLY_NO, "0"},
756 {MAP_READONLY_YES, "yes"},
757 {MAP_READONLY_YES, "true"},
758 {MAP_READONLY_YES, "1"},
759 {MAP_READONLY_PERMISSIONS, "permissions"},
760 {MAP_READONLY_PERMISSIONS, "perms"},
761 {-1, NULL}
762};
763
764static const struct enum_list enum_case[] = {
765 {CASE_LOWER, "lower"},
766 {CASE_UPPER, "upper"},
767 {-1, NULL}
768};
769
770static const struct enum_list enum_bool_auto[] = {
771 {False, "No"},
772 {False, "False"},
773 {False, "0"},
774 {True, "Yes"},
775 {True, "True"},
776 {True, "1"},
777 {Auto, "Auto"},
778 {-1, NULL}
779};
780
781/* Client-side offline caching policy types */
782#define CSC_POLICY_MANUAL 0
783#define CSC_POLICY_DOCUMENTS 1
784#define CSC_POLICY_PROGRAMS 2
785#define CSC_POLICY_DISABLE 3
786
787static const struct enum_list enum_csc_policy[] = {
788 {CSC_POLICY_MANUAL, "manual"},
789 {CSC_POLICY_DOCUMENTS, "documents"},
790 {CSC_POLICY_PROGRAMS, "programs"},
791 {CSC_POLICY_DISABLE, "disable"},
792 {-1, NULL}
793};
794
795/* SMB signing types. */
796static const struct enum_list enum_smb_signing_vals[] = {
797 {False, "No"},
798 {False, "False"},
799 {False, "0"},
800 {False, "Off"},
801 {False, "disabled"},
802 {True, "Yes"},
803 {True, "True"},
804 {True, "1"},
805 {True, "On"},
806 {True, "enabled"},
807 {Auto, "auto"},
808 {Required, "required"},
809 {Required, "mandatory"},
810 {Required, "force"},
811 {Required, "forced"},
812 {Required, "enforced"},
813 {-1, NULL}
814};
815
816/* ACL compatibility options. */
817static const struct enum_list enum_acl_compat_vals[] = {
818 { ACL_COMPAT_AUTO, "auto" },
819 { ACL_COMPAT_WINNT, "winnt" },
820 { ACL_COMPAT_WIN2K, "win2k" },
821 { -1, NULL}
822};
823
824/*
825 Do you want session setups at user level security with a invalid
826 password to be rejected or allowed in as guest? WinNT rejects them
827 but it can be a pain as it means "net view" needs to use a password
828
829 You have 3 choices in the setting of map_to_guest:
830
831 "Never" means session setups with an invalid password
832 are rejected. This is the default.
833
834 "Bad User" means session setups with an invalid password
835 are rejected, unless the username does not exist, in which case it
836 is treated as a guest login
837
838 "Bad Password" means session setups with an invalid password
839 are treated as a guest login
840
841 Note that map_to_guest only has an effect in user or server
842 level security.
843*/
844
845static const struct enum_list enum_map_to_guest[] = {
846 {NEVER_MAP_TO_GUEST, "Never"},
847 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
848 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
849 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
850 {-1, NULL}
851};
852
853/* Config backend options */
854
855static const struct enum_list enum_config_backend[] = {
856 {CONFIG_BACKEND_FILE, "file"},
857 {CONFIG_BACKEND_REGISTRY, "registry"},
858 {-1, NULL}
859};
860
861/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
862 *
863 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
864 * screen in SWAT. This is used to exclude parameters as well as to squash all
865 * parameters that have been duplicated by pseudonyms.
866 *
867 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
868 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
869 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
870 * respective views.
871 *
872 * NOTE2: Handling of duplicated (synonym) paramters:
873 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
874 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
875 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
876 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
877 */
878
879static struct parm_struct parm_table[] = {
880 {N_("Base Options"), P_SEP, P_SEPARATOR},
881
882 {
883 .label = "dos charset",
884 .type = P_STRING,
885 .p_class = P_GLOBAL,
886 .ptr = &Globals.dos_charset,
887 .special = handle_charset,
888 .enum_list = NULL,
889 .flags = FLAG_ADVANCED
890 },
891 {
892 .label = "unix charset",
893 .type = P_STRING,
894 .p_class = P_GLOBAL,
895 .ptr = &Globals.unix_charset,
896 .special = handle_charset,
897 .enum_list = NULL,
898 .flags = FLAG_ADVANCED
899 },
900 {
901 .label = "display charset",
902 .type = P_STRING,
903 .p_class = P_GLOBAL,
904 .ptr = &Globals.display_charset,
905 .special = handle_charset,
906 .enum_list = NULL,
907 .flags = FLAG_ADVANCED
908 },
909 {
910 .label = "comment",
911 .type = P_STRING,
912 .p_class = P_LOCAL,
913 .ptr = &sDefault.comment,
914 .special = NULL,
915 .enum_list = NULL,
916 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
917 },
918 {
919 .label = "path",
920 .type = P_STRING,
921 .p_class = P_LOCAL,
922 .ptr = &sDefault.szPath,
923 .special = NULL,
924 .enum_list = NULL,
925 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
926 },
927 {
928 .label = "directory",
929 .type = P_STRING,
930 .p_class = P_LOCAL,
931 .ptr = &sDefault.szPath,
932 .special = NULL,
933 .enum_list = NULL,
934 .flags = FLAG_HIDE,
935 },
936 {
937 .label = "workgroup",
938 .type = P_USTRING,
939 .p_class = P_GLOBAL,
940 .ptr = &Globals.szWorkgroup,
941 .special = handle_workgroup,
942 .enum_list = NULL,
943 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
944 },
945#ifdef WITH_ADS
946 {
947 .label = "realm",
948 .type = P_USTRING,
949 .p_class = P_GLOBAL,
950 .ptr = &Globals.szRealm,
951 .special = NULL,
952 .enum_list = NULL,
953 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
954 },
955#endif
956 {
957 .label = "netbios name",
958 .type = P_USTRING,
959 .p_class = P_GLOBAL,
960 .ptr = &Globals.szNetbiosName,
961 .special = handle_netbios_name,
962 .enum_list = NULL,
963 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
964 },
965 {
966 .label = "netbios aliases",
967 .type = P_LIST,
968 .p_class = P_GLOBAL,
969 .ptr = &Globals.szNetbiosAliases,
970 .special = handle_netbios_aliases,
971 .enum_list = NULL,
972 .flags = FLAG_ADVANCED,
973 },
974 {
975 .label = "netbios scope",
976 .type = P_USTRING,
977 .p_class = P_GLOBAL,
978 .ptr = &Globals.szNetbiosScope,
979 .special = handle_netbios_scope,
980 .enum_list = NULL,
981 .flags = FLAG_ADVANCED,
982 },
983 {
984 .label = "server string",
985 .type = P_STRING,
986 .p_class = P_GLOBAL,
987 .ptr = &Globals.szServerString,
988 .special = NULL,
989 .enum_list = NULL,
990 .flags = FLAG_BASIC | FLAG_ADVANCED,
991 },
992 {
993 .label = "interfaces",
994 .type = P_LIST,
995 .p_class = P_GLOBAL,
996 .ptr = &Globals.szInterfaces,
997 .special = NULL,
998 .enum_list = NULL,
999 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1000 },
1001 {
1002 .label = "bind interfaces only",
1003 .type = P_BOOL,
1004 .p_class = P_GLOBAL,
1005 .ptr = &Globals.bBindInterfacesOnly,
1006 .special = NULL,
1007 .enum_list = NULL,
1008 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1009 },
1010 {
1011 .label = "config backend",
1012 .type = P_ENUM,
1013 .p_class = P_GLOBAL,
1014 .ptr = &Globals.ConfigBackend,
1015 .special = NULL,
1016 .enum_list = enum_config_backend,
1017 .flags = FLAG_ADVANCED,
1018 },
1019
1020 {N_("Security Options"), P_SEP, P_SEPARATOR},
1021
1022 {
1023 .label = "security",
1024 .type = P_ENUM,
1025 .p_class = P_GLOBAL,
1026 .ptr = &Globals.security,
1027 .special = NULL,
1028 .enum_list = enum_security,
1029 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1030 },
1031 {
1032 .label = "auth methods",
1033 .type = P_LIST,
1034 .p_class = P_GLOBAL,
1035 .ptr = &Globals.AuthMethods,
1036 .special = NULL,
1037 .enum_list = NULL,
1038 .flags = FLAG_ADVANCED,
1039 },
1040 {
1041 .label = "encrypt passwords",
1042 .type = P_BOOL,
1043 .p_class = P_GLOBAL,
1044 .ptr = &Globals.bEncryptPasswords,
1045 .special = NULL,
1046 .enum_list = NULL,
1047 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1048 },
1049 {
1050 .label = "update encrypted",
1051 .type = P_BOOL,
1052 .p_class = P_GLOBAL,
1053 .ptr = &Globals.bUpdateEncrypt,
1054 .special = NULL,
1055 .enum_list = NULL,
1056 .flags = FLAG_ADVANCED,
1057 },
1058 {
1059 .label = "client schannel",
1060 .type = P_ENUM,
1061 .p_class = P_GLOBAL,
1062 .ptr = &Globals.clientSchannel,
1063 .special = NULL,
1064 .enum_list = enum_bool_auto,
1065 .flags = FLAG_BASIC | FLAG_ADVANCED,
1066 },
1067 {
1068 .label = "server schannel",
1069 .type = P_ENUM,
1070 .p_class = P_GLOBAL,
1071 .ptr = &Globals.serverSchannel,
1072 .special = NULL,
1073 .enum_list = enum_bool_auto,
1074 .flags = FLAG_BASIC | FLAG_ADVANCED,
1075 },
1076 {
1077 .label = "allow trusted domains",
1078 .type = P_BOOL,
1079 .p_class = P_GLOBAL,
1080 .ptr = &Globals.bAllowTrustedDomains,
1081 .special = NULL,
1082 .enum_list = NULL,
1083 .flags = FLAG_ADVANCED,
1084 },
1085 {
1086 .label = "map to guest",
1087 .type = P_ENUM,
1088 .p_class = P_GLOBAL,
1089 .ptr = &Globals.map_to_guest,
1090 .special = NULL,
1091 .enum_list = enum_map_to_guest,
1092 .flags = FLAG_ADVANCED,
1093 },
1094 {
1095 .label = "null passwords",
1096 .type = P_BOOL,
1097 .p_class = P_GLOBAL,
1098 .ptr = &Globals.bNullPasswords,
1099 .special = NULL,
1100 .enum_list = NULL,
1101 .flags = FLAG_ADVANCED,
1102 },
1103 {
1104 .label = "obey pam restrictions",
1105 .type = P_BOOL,
1106 .p_class = P_GLOBAL,
1107 .ptr = &Globals.bObeyPamRestrictions,
1108 .special = NULL,
1109 .enum_list = NULL,
1110 .flags = FLAG_ADVANCED,
1111 },
1112 {
1113 .label = "password server",
1114 .type = P_STRING,
1115 .p_class = P_GLOBAL,
1116 .ptr = &Globals.szPasswordServer,
1117 .special = NULL,
1118 .enum_list = NULL,
1119 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1120 },
1121 {
1122 .label = "smb passwd file",
1123 .type = P_STRING,
1124 .p_class = P_GLOBAL,
1125 .ptr = &Globals.szSMBPasswdFile,
1126 .special = NULL,
1127 .enum_list = NULL,
1128 .flags = FLAG_ADVANCED,
1129 },
1130 {
1131 .label = "private dir",
1132 .type = P_STRING,
1133 .p_class = P_GLOBAL,
1134 .ptr = &Globals.szPrivateDir,
1135 .special = NULL,
1136 .enum_list = NULL,
1137 .flags = FLAG_ADVANCED,
1138 },
1139 {
1140 .label = "passdb backend",
1141 .type = P_STRING,
1142 .p_class = P_GLOBAL,
1143 .ptr = &Globals.szPassdbBackend,
1144 .special = NULL,
1145 .enum_list = NULL,
1146 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1147 },
1148 {
1149 .label = "algorithmic rid base",
1150 .type = P_INTEGER,
1151 .p_class = P_GLOBAL,
1152 .ptr = &Globals.AlgorithmicRidBase,
1153 .special = NULL,
1154 .enum_list = NULL,
1155 .flags = FLAG_ADVANCED,
1156 },
1157 {
1158 .label = "root directory",
1159 .type = P_STRING,
1160 .p_class = P_GLOBAL,
1161 .ptr = &Globals.szRootdir,
1162 .special = NULL,
1163 .enum_list = NULL,
1164 .flags = FLAG_ADVANCED,
1165 },
1166 {
1167 .label = "root dir",
1168 .type = P_STRING,
1169 .p_class = P_GLOBAL,
1170 .ptr = &Globals.szRootdir,
1171 .special = NULL,
1172 .enum_list = NULL,
1173 .flags = FLAG_HIDE,
1174 },
1175 {
1176 .label = "root",
1177 .type = P_STRING,
1178 .p_class = P_GLOBAL,
1179 .ptr = &Globals.szRootdir,
1180 .special = NULL,
1181 .enum_list = NULL,
1182 .flags = FLAG_HIDE,
1183 },
1184 {
1185 .label = "guest account",
1186 .type = P_STRING,
1187 .p_class = P_GLOBAL,
1188 .ptr = &Globals.szGuestaccount,
1189 .special = NULL,
1190 .enum_list = NULL,
1191 .flags = FLAG_BASIC | FLAG_ADVANCED,
1192 },
1193 {
1194 .label = "enable privileges",
1195 .type = P_BOOL,
1196 .p_class = P_GLOBAL,
1197 .ptr = &Globals.bEnablePrivileges,
1198 .special = NULL,
1199 .enum_list = NULL,
1200 .flags = FLAG_ADVANCED,
1201 },
1202
1203 {
1204 .label = "pam password change",
1205 .type = P_BOOL,
1206 .p_class = P_GLOBAL,
1207 .ptr = &Globals.bPamPasswordChange,
1208 .special = NULL,
1209 .enum_list = NULL,
1210 .flags = FLAG_ADVANCED,
1211 },
1212 {
1213 .label = "passwd program",
1214 .type = P_STRING,
1215 .p_class = P_GLOBAL,
1216 .ptr = &Globals.szPasswdProgram,
1217 .special = NULL,
1218 .enum_list = NULL,
1219 .flags = FLAG_ADVANCED,
1220 },
1221 {
1222 .label = "passwd chat",
1223 .type = P_STRING,
1224 .p_class = P_GLOBAL,
1225 .ptr = &Globals.szPasswdChat,
1226 .special = NULL,
1227 .enum_list = NULL,
1228 .flags = FLAG_ADVANCED,
1229 },
1230 {
1231 .label = "passwd chat debug",
1232 .type = P_BOOL,
1233 .p_class = P_GLOBAL,
1234 .ptr = &Globals.bPasswdChatDebug,
1235 .special = NULL,
1236 .enum_list = NULL,
1237 .flags = FLAG_ADVANCED,
1238 },
1239 {
1240 .label = "passwd chat timeout",
1241 .type = P_INTEGER,
1242 .p_class = P_GLOBAL,
1243 .ptr = &Globals.iPasswdChatTimeout,
1244 .special = NULL,
1245 .enum_list = NULL,
1246 .flags = FLAG_ADVANCED,
1247 },
1248 {
1249 .label = "check password script",
1250 .type = P_STRING,
1251 .p_class = P_GLOBAL,
1252 .ptr = &Globals.szCheckPasswordScript,
1253 .special = NULL,
1254 .enum_list = NULL,
1255 .flags = FLAG_ADVANCED,
1256 },
1257 {
1258 .label = "username map",
1259 .type = P_STRING,
1260 .p_class = P_GLOBAL,
1261 .ptr = &Globals.szUsernameMap,
1262 .special = NULL,
1263 .enum_list = NULL,
1264 .flags = FLAG_ADVANCED,
1265 },
1266 {
1267 .label = "password level",
1268 .type = P_INTEGER,
1269 .p_class = P_GLOBAL,
1270 .ptr = &Globals.pwordlevel,
1271 .special = NULL,
1272 .enum_list = NULL,
1273 .flags = FLAG_ADVANCED,
1274 },
1275 {
1276 .label = "username level",
1277 .type = P_INTEGER,
1278 .p_class = P_GLOBAL,
1279 .ptr = &Globals.unamelevel,
1280 .special = NULL,
1281 .enum_list = NULL,
1282 .flags = FLAG_ADVANCED,
1283 },
1284 {
1285 .label = "unix password sync",
1286 .type = P_BOOL,
1287 .p_class = P_GLOBAL,
1288 .ptr = &Globals.bUnixPasswdSync,
1289 .special = NULL,
1290 .enum_list = NULL,
1291 .flags = FLAG_ADVANCED,
1292 },
1293 {
1294 .label = "restrict anonymous",
1295 .type = P_INTEGER,
1296 .p_class = P_GLOBAL,
1297 .ptr = &Globals.restrict_anonymous,
1298 .special = NULL,
1299 .enum_list = NULL,
1300 .flags = FLAG_ADVANCED,
1301 },
1302 {
1303 .label = "lanman auth",
1304 .type = P_BOOL,
1305 .p_class = P_GLOBAL,
1306 .ptr = &Globals.bLanmanAuth,
1307 .special = NULL,
1308 .enum_list = NULL,
1309 .flags = FLAG_ADVANCED,
1310 },
1311 {
1312 .label = "ntlm auth",
1313 .type = P_BOOL,
1314 .p_class = P_GLOBAL,
1315 .ptr = &Globals.bNTLMAuth,
1316 .special = NULL,
1317 .enum_list = NULL,
1318 .flags = FLAG_ADVANCED,
1319 },
1320 {
1321 .label = "client NTLMv2 auth",
1322 .type = P_BOOL,
1323 .p_class = P_GLOBAL,
1324 .ptr = &Globals.bClientNTLMv2Auth,
1325 .special = NULL,
1326 .enum_list = NULL,
1327 .flags = FLAG_ADVANCED,
1328 },
1329 {
1330 .label = "client lanman auth",
1331 .type = P_BOOL,
1332 .p_class = P_GLOBAL,
1333 .ptr = &Globals.bClientLanManAuth,
1334 .special = NULL,
1335 .enum_list = NULL,
1336 .flags = FLAG_ADVANCED,
1337 },
1338 {
1339 .label = "client plaintext auth",
1340 .type = P_BOOL,
1341 .p_class = P_GLOBAL,
1342 .ptr = &Globals.bClientPlaintextAuth,
1343 .special = NULL,
1344 .enum_list = NULL,
1345 .flags = FLAG_ADVANCED,
1346 },
1347 {
1348 .label = "username",
1349 .type = P_STRING,
1350 .p_class = P_LOCAL,
1351 .ptr = &sDefault.szUsername,
1352 .special = NULL,
1353 .enum_list = NULL,
1354 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1355 },
1356 {
1357 .label = "user",
1358 .type = P_STRING,
1359 .p_class = P_LOCAL,
1360 .ptr = &sDefault.szUsername,
1361 .special = NULL,
1362 .enum_list = NULL,
1363 .flags = FLAG_HIDE,
1364 },
1365 {
1366 .label = "users",
1367 .type = P_STRING,
1368 .p_class = P_LOCAL,
1369 .ptr = &sDefault.szUsername,
1370 .special = NULL,
1371 .enum_list = NULL,
1372 .flags = FLAG_HIDE,
1373 },
1374 {
1375 .label = "invalid users",
1376 .type = P_LIST,
1377 .p_class = P_LOCAL,
1378 .ptr = &sDefault.szInvalidUsers,
1379 .special = NULL,
1380 .enum_list = NULL,
1381 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1382 },
1383 {
1384 .label = "valid users",
1385 .type = P_LIST,
1386 .p_class = P_LOCAL,
1387 .ptr = &sDefault.szValidUsers,
1388 .special = NULL,
1389 .enum_list = NULL,
1390 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1391 },
1392 {
1393 .label = "admin users",
1394 .type = P_LIST,
1395 .p_class = P_LOCAL,
1396 .ptr = &sDefault.szAdminUsers,
1397 .special = NULL,
1398 .enum_list = NULL,
1399 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1400 },
1401 {
1402 .label = "read list",
1403 .type = P_LIST,
1404 .p_class = P_LOCAL,
1405 .ptr = &sDefault.readlist,
1406 .special = NULL,
1407 .enum_list = NULL,
1408 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1409 },
1410 {
1411 .label = "write list",
1412 .type = P_LIST,
1413 .p_class = P_LOCAL,
1414 .ptr = &sDefault.writelist,
1415 .special = NULL,
1416 .enum_list = NULL,
1417 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1418 },
1419 {
1420 .label = "printer admin",
1421 .type = P_LIST,
1422 .p_class = P_LOCAL,
1423 .ptr = &sDefault.printer_admin,
1424 .special = NULL,
1425 .enum_list = NULL,
1426 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1427 },
1428 {
1429 .label = "force user",
1430 .type = P_STRING,
1431 .p_class = P_LOCAL,
1432 .ptr = &sDefault.force_user,
1433 .special = NULL,
1434 .enum_list = NULL,
1435 .flags = FLAG_ADVANCED | FLAG_SHARE,
1436 },
1437 {
1438 .label = "force group",
1439 .type = P_STRING,
1440 .p_class = P_LOCAL,
1441 .ptr = &sDefault.force_group,
1442 .special = NULL,
1443 .enum_list = NULL,
1444 .flags = FLAG_ADVANCED | FLAG_SHARE,
1445 },
1446 {
1447 .label = "group",
1448 .type = P_STRING,
1449 .p_class = P_LOCAL,
1450 .ptr = &sDefault.force_group,
1451 .special = NULL,
1452 .enum_list = NULL,
1453 .flags = FLAG_ADVANCED,
1454 },
1455 {
1456 .label = "read only",
1457 .type = P_BOOL,
1458 .p_class = P_LOCAL,
1459 .ptr = &sDefault.bRead_only,
1460 .special = NULL,
1461 .enum_list = NULL,
1462 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1463 },
1464 {
1465 .label = "write ok",
1466 .type = P_BOOLREV,
1467 .p_class = P_LOCAL,
1468 .ptr = &sDefault.bRead_only,
1469 .special = NULL,
1470 .enum_list = NULL,
1471 .flags = FLAG_HIDE,
1472 },
1473 {
1474 .label = "writeable",
1475 .type = P_BOOLREV,
1476 .p_class = P_LOCAL,
1477 .ptr = &sDefault.bRead_only,
1478 .special = NULL,
1479 .enum_list = NULL,
1480 .flags = FLAG_HIDE,
1481 },
1482 {
1483 .label = "writable",
1484 .type = P_BOOLREV,
1485 .p_class = P_LOCAL,
1486 .ptr = &sDefault.bRead_only,
1487 .special = NULL,
1488 .enum_list = NULL,
1489 .flags = FLAG_HIDE,
1490 },
1491 {
1492 .label = "acl check permissions",
1493 .type = P_BOOL,
1494 .p_class = P_LOCAL,
1495 .ptr = &sDefault.bAclCheckPermissions,
1496 .special = NULL,
1497 .enum_list = NULL,
1498 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1499 },
1500 {
1501 .label = "acl group control",
1502 .type = P_BOOL,
1503 .p_class = P_LOCAL,
1504 .ptr = &sDefault.bAclGroupControl,
1505 .special = NULL,
1506 .enum_list = NULL,
1507 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1508 },
1509 {
1510 .label = "acl map full control",
1511 .type = P_BOOL,
1512 .p_class = P_LOCAL,
1513 .ptr = &sDefault.bAclMapFullControl,
1514 .special = NULL,
1515 .enum_list = NULL,
1516 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1517 },
1518 {
1519 .label = "create mask",
1520 .type = P_OCTAL,
1521 .p_class = P_LOCAL,
1522 .ptr = &sDefault.iCreate_mask,
1523 .special = NULL,
1524 .enum_list = NULL,
1525 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1526 },
1527 {
1528 .label = "create mode",
1529 .type = P_OCTAL,
1530 .p_class = P_LOCAL,
1531 .ptr = &sDefault.iCreate_mask,
1532 .special = NULL,
1533 .enum_list = NULL,
1534 .flags = FLAG_HIDE,
1535 },
1536 {
1537 .label = "force create mode",
1538 .type = P_OCTAL,
1539 .p_class = P_LOCAL,
1540 .ptr = &sDefault.iCreate_force_mode,
1541 .special = NULL,
1542 .enum_list = NULL,
1543 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1544 },
1545 {
1546 .label = "security mask",
1547 .type = P_OCTAL,
1548 .p_class = P_LOCAL,
1549 .ptr = &sDefault.iSecurity_mask,
1550 .special = NULL,
1551 .enum_list = NULL,
1552 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1553 },
1554 {
1555 .label = "force security mode",
1556 .type = P_OCTAL,
1557 .p_class = P_LOCAL,
1558 .ptr = &sDefault.iSecurity_force_mode,
1559 .special = NULL,
1560 .enum_list = NULL,
1561 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1562 },
1563 {
1564 .label = "directory mask",
1565 .type = P_OCTAL,
1566 .p_class = P_LOCAL,
1567 .ptr = &sDefault.iDir_mask,
1568 .special = NULL,
1569 .enum_list = NULL,
1570 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1571 },
1572 {
1573 .label = "directory mode",
1574 .type = P_OCTAL,
1575 .p_class = P_LOCAL,
1576 .ptr = &sDefault.iDir_mask,
1577 .special = NULL,
1578 .enum_list = NULL,
1579 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1580 },
1581 {
1582 .label = "force directory mode",
1583 .type = P_OCTAL,
1584 .p_class = P_LOCAL,
1585 .ptr = &sDefault.iDir_force_mode,
1586 .special = NULL,
1587 .enum_list = NULL,
1588 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1589 },
1590 {
1591 .label = "directory security mask",
1592 .type = P_OCTAL,
1593 .p_class = P_LOCAL,
1594 .ptr = &sDefault.iDir_Security_mask,
1595 .special = NULL,
1596 .enum_list = NULL,
1597 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1598 },
1599 {
1600 .label = "force directory security mode",
1601 .type = P_OCTAL,
1602 .p_class = P_LOCAL,
1603 .ptr = &sDefault.iDir_Security_force_mode,
1604 .special = NULL,
1605 .enum_list = NULL,
1606 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1607 },
1608 {
1609 .label = "force unknown acl user",
1610 .type = P_BOOL,
1611 .p_class = P_LOCAL,
1612 .ptr = &sDefault.bForceUnknownAclUser,
1613 .special = NULL,
1614 .enum_list = NULL,
1615 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1616 },
1617 {
1618 .label = "inherit permissions",
1619 .type = P_BOOL,
1620 .p_class = P_LOCAL,
1621 .ptr = &sDefault.bInheritPerms,
1622 .special = NULL,
1623 .enum_list = NULL,
1624 .flags = FLAG_ADVANCED | FLAG_SHARE,
1625 },
1626 {
1627 .label = "inherit acls",
1628 .type = P_BOOL,
1629 .p_class = P_LOCAL,
1630 .ptr = &sDefault.bInheritACLS,
1631 .special = NULL,
1632 .enum_list = NULL,
1633 .flags = FLAG_ADVANCED | FLAG_SHARE,
1634 },
1635 {
1636 .label = "inherit owner",
1637 .type = P_BOOL,
1638 .p_class = P_LOCAL,
1639 .ptr = &sDefault.bInheritOwner,
1640 .special = NULL,
1641 .enum_list = NULL,
1642 .flags = FLAG_ADVANCED | FLAG_SHARE,
1643 },
1644 {
1645 .label = "guest only",
1646 .type = P_BOOL,
1647 .p_class = P_LOCAL,
1648 .ptr = &sDefault.bGuest_only,
1649 .special = NULL,
1650 .enum_list = NULL,
1651 .flags = FLAG_ADVANCED | FLAG_SHARE,
1652 },
1653 {
1654 .label = "only guest",
1655 .type = P_BOOL,
1656 .p_class = P_LOCAL,
1657 .ptr = &sDefault.bGuest_only,
1658 .special = NULL,
1659 .enum_list = NULL,
1660 .flags = FLAG_HIDE,
1661 },
1662 {
1663 .label = "administrative share",
1664 .type = P_BOOL,
1665 .p_class = P_LOCAL,
1666 .ptr = &sDefault.bAdministrative_share,
1667 .special = NULL,
1668 .enum_list = NULL,
1669 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1670 },
1671
1672 {
1673 .label = "guest ok",
1674 .type = P_BOOL,
1675 .p_class = P_LOCAL,
1676 .ptr = &sDefault.bGuest_ok,
1677 .special = NULL,
1678 .enum_list = NULL,
1679 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1680 },
1681 {
1682 .label = "public",
1683 .type = P_BOOL,
1684 .p_class = P_LOCAL,
1685 .ptr = &sDefault.bGuest_ok,
1686 .special = NULL,
1687 .enum_list = NULL,
1688 .flags = FLAG_HIDE,
1689 },
1690 {
1691 .label = "only user",
1692 .type = P_BOOL,
1693 .p_class = P_LOCAL,
1694 .ptr = &sDefault.bOnlyUser,
1695 .special = NULL,
1696 .enum_list = NULL,
1697 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1698 },
1699 {
1700 .label = "hosts allow",
1701 .type = P_LIST,
1702 .p_class = P_LOCAL,
1703 .ptr = &sDefault.szHostsallow,
1704 .special = NULL,
1705 .enum_list = NULL,
1706 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1707 },
1708 {
1709 .label = "allow hosts",
1710 .type = P_LIST,
1711 .p_class = P_LOCAL,
1712 .ptr = &sDefault.szHostsallow,
1713 .special = NULL,
1714 .enum_list = NULL,
1715 .flags = FLAG_HIDE,
1716 },
1717 {
1718 .label = "hosts deny",
1719 .type = P_LIST,
1720 .p_class = P_LOCAL,
1721 .ptr = &sDefault.szHostsdeny,
1722 .special = NULL,
1723 .enum_list = NULL,
1724 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1725 },
1726 {
1727 .label = "deny hosts",
1728 .type = P_LIST,
1729 .p_class = P_LOCAL,
1730 .ptr = &sDefault.szHostsdeny,
1731 .special = NULL,
1732 .enum_list = NULL,
1733 .flags = FLAG_HIDE,
1734 },
1735 {
1736 .label = "preload modules",
1737 .type = P_LIST,
1738 .p_class = P_GLOBAL,
1739 .ptr = &Globals.szPreloadModules,
1740 .special = NULL,
1741 .enum_list = NULL,
1742 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1743 },
1744 {
1745 .label = "use kerberos keytab",
1746 .type = P_BOOL,
1747 .p_class = P_GLOBAL,
1748 .ptr = &Globals.bUseKerberosKeytab,
1749 .special = NULL,
1750 .enum_list = NULL,
1751 .flags = FLAG_ADVANCED,
1752 },
1753
1754 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1755
1756 {
1757 .label = "log level",
1758 .type = P_STRING,
1759 .p_class = P_GLOBAL,
1760 .ptr = &Globals.szLogLevel,
1761 .special = handle_debug_list,
1762 .enum_list = NULL,
1763 .flags = FLAG_ADVANCED,
1764 },
1765 {
1766 .label = "debuglevel",
1767 .type = P_STRING,
1768 .p_class = P_GLOBAL,
1769 .ptr = &Globals.szLogLevel,
1770 .special = handle_debug_list,
1771 .enum_list = NULL,
1772 .flags = FLAG_HIDE,
1773 },
1774 {
1775 .label = "syslog",
1776 .type = P_INTEGER,
1777 .p_class = P_GLOBAL,
1778 .ptr = &Globals.syslog,
1779 .special = NULL,
1780 .enum_list = NULL,
1781 .flags = FLAG_ADVANCED,
1782 },
1783 {
1784 .label = "syslog only",
1785 .type = P_BOOL,
1786 .p_class = P_GLOBAL,
1787 .ptr = &Globals.bSyslogOnly,
1788 .special = NULL,
1789 .enum_list = NULL,
1790 .flags = FLAG_ADVANCED,
1791 },
1792 {
1793 .label = "log file",
1794 .type = P_STRING,
1795 .p_class = P_GLOBAL,
1796 .ptr = &Globals.szLogFile,
1797 .special = NULL,
1798 .enum_list = NULL,
1799 .flags = FLAG_ADVANCED,
1800 },
1801 {
1802 .label = "max log size",
1803 .type = P_INTEGER,
1804 .p_class = P_GLOBAL,
1805 .ptr = &Globals.max_log_size,
1806 .special = NULL,
1807 .enum_list = NULL,
1808 .flags = FLAG_ADVANCED,
1809 },
1810 {
1811 .label = "debug timestamp",
1812 .type = P_BOOL,
1813 .p_class = P_GLOBAL,
1814 .ptr = &Globals.bTimestampLogs,
1815 .special = NULL,
1816 .enum_list = NULL,
1817 .flags = FLAG_ADVANCED,
1818 },
1819 {
1820 .label = "timestamp logs",
1821 .type = P_BOOL,
1822 .p_class = P_GLOBAL,
1823 .ptr = &Globals.bTimestampLogs,
1824 .special = NULL,
1825 .enum_list = NULL,
1826 .flags = FLAG_ADVANCED,
1827 },
1828 {
1829 .label = "debug prefix timestamp",
1830 .type = P_BOOL,
1831 .p_class = P_GLOBAL,
1832 .ptr = &Globals.bDebugPrefixTimestamp,
1833 .special = NULL,
1834 .enum_list = NULL,
1835 .flags = FLAG_ADVANCED,
1836 },
1837 {
1838 .label = "debug hires timestamp",
1839 .type = P_BOOL,
1840 .p_class = P_GLOBAL,
1841 .ptr = &Globals.bDebugHiresTimestamp,
1842 .special = NULL,
1843 .enum_list = NULL,
1844 .flags = FLAG_ADVANCED,
1845 },
1846 {
1847 .label = "debug pid",
1848 .type = P_BOOL,
1849 .p_class = P_GLOBAL,
1850 .ptr = &Globals.bDebugPid,
1851 .special = NULL,
1852 .enum_list = NULL,
1853 .flags = FLAG_ADVANCED,
1854 },
1855 {
1856 .label = "debug uid",
1857 .type = P_BOOL,
1858 .p_class = P_GLOBAL,
1859 .ptr = &Globals.bDebugUid,
1860 .special = NULL,
1861 .enum_list = NULL,
1862 .flags = FLAG_ADVANCED,
1863 },
1864 {
1865 .label = "debug class",
1866 .type = P_BOOL,
1867 .p_class = P_GLOBAL,
1868 .ptr = &Globals.bDebugClass,
1869 .special = NULL,
1870 .enum_list = NULL,
1871 .flags = FLAG_ADVANCED,
1872 },
1873 {
1874 .label = "enable core files",
1875 .type = P_BOOL,
1876 .p_class = P_GLOBAL,
1877 .ptr = &Globals.bEnableCoreFiles,
1878 .special = NULL,
1879 .enum_list = NULL,
1880 .flags = FLAG_ADVANCED,
1881 },
1882
1883 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1884
1885 {
1886 .label = "allocation roundup size",
1887 .type = P_INTEGER,
1888 .p_class = P_LOCAL,
1889 .ptr = &sDefault.iallocation_roundup_size,
1890 .special = NULL,
1891 .enum_list = NULL,
1892 .flags = FLAG_ADVANCED,
1893 },
1894 {
1895 .label = "aio read size",
1896 .type = P_INTEGER,
1897 .p_class = P_LOCAL,
1898 .ptr = &sDefault.iAioReadSize,
1899 .special = NULL,
1900 .enum_list = NULL,
1901 .flags = FLAG_ADVANCED,
1902 },
1903 {
1904 .label = "aio write size",
1905 .type = P_INTEGER,
1906 .p_class = P_LOCAL,
1907 .ptr = &sDefault.iAioWriteSize,
1908 .special = NULL,
1909 .enum_list = NULL,
1910 .flags = FLAG_ADVANCED,
1911 },
1912 {
1913 .label = "aio write behind",
1914 .type = P_STRING,
1915 .p_class = P_LOCAL,
1916 .ptr = &sDefault.szAioWriteBehind,
1917 .special = NULL,
1918 .enum_list = NULL,
1919 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1920 },
1921 {
1922 .label = "smb ports",
1923 .type = P_STRING,
1924 .p_class = P_GLOBAL,
1925 .ptr = &Globals.smb_ports,
1926 .special = NULL,
1927 .enum_list = NULL,
1928 .flags = FLAG_ADVANCED,
1929 },
1930 {
1931 .label = "large readwrite",
1932 .type = P_BOOL,
1933 .p_class = P_GLOBAL,
1934 .ptr = &Globals.bLargeReadwrite,
1935 .special = NULL,
1936 .enum_list = NULL,
1937 .flags = FLAG_ADVANCED,
1938 },
1939 {
1940 .label = "max protocol",
1941 .type = P_ENUM,
1942 .p_class = P_GLOBAL,
1943 .ptr = &Globals.maxprotocol,
1944 .special = NULL,
1945 .enum_list = enum_protocol,
1946 .flags = FLAG_ADVANCED,
1947 },
1948 {
1949 .label = "protocol",
1950 .type = P_ENUM,
1951 .p_class = P_GLOBAL,
1952 .ptr = &Globals.maxprotocol,
1953 .special = NULL,
1954 .enum_list = enum_protocol,
1955 .flags = FLAG_ADVANCED,
1956 },
1957 {
1958 .label = "min protocol",
1959 .type = P_ENUM,
1960 .p_class = P_GLOBAL,
1961 .ptr = &Globals.minprotocol,
1962 .special = NULL,
1963 .enum_list = enum_protocol,
1964 .flags = FLAG_ADVANCED,
1965 },
1966 {
1967 .label = "min receivefile size",
1968 .type = P_INTEGER,
1969 .p_class = P_GLOBAL,
1970 .ptr = &Globals.iminreceivefile,
1971 .special = NULL,
1972 .enum_list = NULL,
1973 .flags = FLAG_ADVANCED,
1974 },
1975 {
1976 .label = "read raw",
1977 .type = P_BOOL,
1978 .p_class = P_GLOBAL,
1979 .ptr = &Globals.bReadRaw,
1980 .special = NULL,
1981 .enum_list = NULL,
1982 .flags = FLAG_ADVANCED,
1983 },
1984 {
1985 .label = "write raw",
1986 .type = P_BOOL,
1987 .p_class = P_GLOBAL,
1988 .ptr = &Globals.bWriteRaw,
1989 .special = NULL,
1990 .enum_list = NULL,
1991 .flags = FLAG_ADVANCED,
1992 },
1993 {
1994 .label = "disable netbios",
1995 .type = P_BOOL,
1996 .p_class = P_GLOBAL,
1997 .ptr = &Globals.bDisableNetbios,
1998 .special = NULL,
1999 .enum_list = NULL,
2000 .flags = FLAG_ADVANCED,
2001 },
2002 {
2003 .label = "reset on zero vc",
2004 .type = P_BOOL,
2005 .p_class = P_GLOBAL,
2006 .ptr = &Globals.bResetOnZeroVC,
2007 .special = NULL,
2008 .enum_list = NULL,
2009 .flags = FLAG_ADVANCED,
2010 },
2011 {
2012 .label = "acl compatibility",
2013 .type = P_ENUM,
2014 .p_class = P_GLOBAL,
2015 .ptr = &Globals.iAclCompat,
2016 .special = NULL,
2017 .enum_list = enum_acl_compat_vals,
2018 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2019 },
2020 {
2021 .label = "defer sharing violations",
2022 .type = P_BOOL,
2023 .p_class = P_GLOBAL,
2024 .ptr = &Globals.bDeferSharingViolations,
2025 .special = NULL,
2026 .enum_list = NULL,
2027 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2028 },
2029 {
2030 .label = "ea support",
2031 .type = P_BOOL,
2032 .p_class = P_LOCAL,
2033 .ptr = &sDefault.bEASupport,
2034 .special = NULL,
2035 .enum_list = NULL,
2036 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2037 },
2038 {
2039 .label = "nt acl support",
2040 .type = P_BOOL,
2041 .p_class = P_LOCAL,
2042 .ptr = &sDefault.bNTAclSupport,
2043 .special = NULL,
2044 .enum_list = NULL,
2045 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2046 },
2047 {
2048 .label = "nt pipe support",
2049 .type = P_BOOL,
2050 .p_class = P_GLOBAL,
2051 .ptr = &Globals.bNTPipeSupport,
2052 .special = NULL,
2053 .enum_list = NULL,
2054 .flags = FLAG_ADVANCED,
2055 },
2056 {
2057 .label = "nt status support",
2058 .type = P_BOOL,
2059 .p_class = P_GLOBAL,
2060 .ptr = &Globals.bNTStatusSupport,
2061 .special = NULL,
2062 .enum_list = NULL,
2063 .flags = FLAG_ADVANCED,
2064 },
2065 {
2066 .label = "profile acls",
2067 .type = P_BOOL,
2068 .p_class = P_LOCAL,
2069 .ptr = &sDefault.bProfileAcls,
2070 .special = NULL,
2071 .enum_list = NULL,
2072 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2073 },
2074 {
2075 .label = "announce version",
2076 .type = P_STRING,
2077 .p_class = P_GLOBAL,
2078 .ptr = &Globals.szAnnounceVersion,
2079 .special = NULL,
2080 .enum_list = NULL,
2081 .flags = FLAG_ADVANCED,
2082 },
2083 {
2084 .label = "announce as",
2085 .type = P_ENUM,
2086 .p_class = P_GLOBAL,
2087 .ptr = &Globals.announce_as,
2088 .special = NULL,
2089 .enum_list = enum_announce_as,
2090 .flags = FLAG_ADVANCED,
2091 },
2092 {
2093 .label = "map acl inherit",
2094 .type = P_BOOL,
2095 .p_class = P_LOCAL,
2096 .ptr = &sDefault.bMap_acl_inherit,
2097 .special = NULL,
2098 .enum_list = NULL,
2099 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2100 },
2101 {
2102 .label = "afs share",
2103 .type = P_BOOL,
2104 .p_class = P_LOCAL,
2105 .ptr = &sDefault.bAfs_Share,
2106 .special = NULL,
2107 .enum_list = NULL,
2108 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2109 },
2110 {
2111 .label = "max mux",
2112 .type = P_INTEGER,
2113 .p_class = P_GLOBAL,
2114 .ptr = &Globals.max_mux,
2115 .special = NULL,
2116 .enum_list = NULL,
2117 .flags = FLAG_ADVANCED,
2118 },
2119 {
2120 .label = "max xmit",
2121 .type = P_INTEGER,
2122 .p_class = P_GLOBAL,
2123 .ptr = &Globals.max_xmit,
2124 .special = NULL,
2125 .enum_list = NULL,
2126 .flags = FLAG_ADVANCED,
2127 },
2128 {
2129 .label = "name resolve order",
2130 .type = P_STRING,
2131 .p_class = P_GLOBAL,
2132 .ptr = &Globals.szNameResolveOrder,
2133 .special = NULL,
2134 .enum_list = NULL,
2135 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2136 },
2137 {
2138 .label = "max ttl",
2139 .type = P_INTEGER,
2140 .p_class = P_GLOBAL,
2141 .ptr = &Globals.max_ttl,
2142 .special = NULL,
2143 .enum_list = NULL,
2144 .flags = FLAG_ADVANCED,
2145 },
2146 {
2147 .label = "max wins ttl",
2148 .type = P_INTEGER,
2149 .p_class = P_GLOBAL,
2150 .ptr = &Globals.max_wins_ttl,
2151 .special = NULL,
2152 .enum_list = NULL,
2153 .flags = FLAG_ADVANCED,
2154 },
2155 {
2156 .label = "min wins ttl",
2157 .type = P_INTEGER,
2158 .p_class = P_GLOBAL,
2159 .ptr = &Globals.min_wins_ttl,
2160 .special = NULL,
2161 .enum_list = NULL,
2162 .flags = FLAG_ADVANCED,
2163 },
2164 {
2165 .label = "time server",
2166 .type = P_BOOL,
2167 .p_class = P_GLOBAL,
2168 .ptr = &Globals.bTimeServer,
2169 .special = NULL,
2170 .enum_list = NULL,
2171 .flags = FLAG_ADVANCED,
2172 },
2173 {
2174 .label = "unix extensions",
2175 .type = P_BOOL,
2176 .p_class = P_GLOBAL,
2177 .ptr = &Globals.bUnixExtensions,
2178 .special = NULL,
2179 .enum_list = NULL,
2180 .flags = FLAG_ADVANCED,
2181 },
2182 {
2183 .label = "use spnego",
2184 .type = P_BOOL,
2185 .p_class = P_GLOBAL,
2186 .ptr = &Globals.bUseSpnego,
2187 .special = NULL,
2188 .enum_list = NULL,
2189 .flags = FLAG_ADVANCED,
2190 },
2191 {
2192 .label = "client signing",
2193 .type = P_ENUM,
2194 .p_class = P_GLOBAL,
2195 .ptr = &Globals.client_signing,
2196 .special = NULL,
2197 .enum_list = enum_smb_signing_vals,
2198 .flags = FLAG_ADVANCED,
2199 },
2200 {
2201 .label = "server signing",
2202 .type = P_ENUM,
2203 .p_class = P_GLOBAL,
2204 .ptr = &Globals.server_signing,
2205 .special = NULL,
2206 .enum_list = enum_smb_signing_vals,
2207 .flags = FLAG_ADVANCED,
2208 },
2209 {
2210 .label = "smb encrypt",
2211 .type = P_ENUM,
2212 .p_class = P_LOCAL,
2213 .ptr = &sDefault.ismb_encrypt,
2214 .special = NULL,
2215 .enum_list = enum_smb_signing_vals,
2216 .flags = FLAG_ADVANCED,
2217 },
2218 {
2219 .label = "client use spnego",
2220 .type = P_BOOL,
2221 .p_class = P_GLOBAL,
2222 .ptr = &Globals.bClientUseSpnego,
2223 .special = NULL,
2224 .enum_list = NULL,
2225 .flags = FLAG_ADVANCED,
2226 },
2227 {
2228 .label = "client ldap sasl wrapping",
2229 .type = P_ENUM,
2230 .p_class = P_GLOBAL,
2231 .ptr = &Globals.client_ldap_sasl_wrapping,
2232 .special = NULL,
2233 .enum_list = enum_ldap_sasl_wrapping,
2234 .flags = FLAG_ADVANCED,
2235 },
2236 {
2237 .label = "enable asu support",
2238 .type = P_BOOL,
2239 .p_class = P_GLOBAL,
2240 .ptr = &Globals.bASUSupport,
2241 .special = NULL,
2242 .enum_list = NULL,
2243 .flags = FLAG_ADVANCED,
2244 },
2245 {
2246 .label = "svcctl list",
2247 .type = P_LIST,
2248 .p_class = P_GLOBAL,
2249 .ptr = &Globals.szServicesList,
2250 .special = NULL,
2251 .enum_list = NULL,
2252 .flags = FLAG_ADVANCED,
2253 },
2254
2255 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2256
2257 {
2258 .label = "block size",
2259 .type = P_INTEGER,
2260 .p_class = P_LOCAL,
2261 .ptr = &sDefault.iBlock_size,
2262 .special = NULL,
2263 .enum_list = NULL,
2264 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2265 },
2266 {
2267 .label = "deadtime",
2268 .type = P_INTEGER,
2269 .p_class = P_GLOBAL,
2270 .ptr = &Globals.deadtime,
2271 .special = NULL,
2272 .enum_list = NULL,
2273 .flags = FLAG_ADVANCED,
2274 },
2275 {
2276 .label = "getwd cache",
2277 .type = P_BOOL,
2278 .p_class = P_GLOBAL,
2279 .ptr = &Globals.getwd_cache,
2280 .special = NULL,
2281 .enum_list = NULL,
2282 .flags = FLAG_ADVANCED,
2283 },
2284 {
2285 .label = "keepalive",
2286 .type = P_INTEGER,
2287 .p_class = P_GLOBAL,
2288 .ptr = &Globals.iKeepalive,
2289 .special = NULL,
2290 .enum_list = NULL,
2291 .flags = FLAG_ADVANCED,
2292 },
2293 {
2294 .label = "change notify",
2295 .type = P_BOOL,
2296 .p_class = P_LOCAL,
2297 .ptr = &sDefault.bChangeNotify,
2298 .special = NULL,
2299 .enum_list = NULL,
2300 .flags = FLAG_ADVANCED | FLAG_SHARE,
2301 },
2302 {
2303 .label = "directory name cache size",
2304 .type = P_INTEGER,
2305 .p_class = P_LOCAL,
2306 .ptr = &sDefault.iDirectoryNameCacheSize,
2307 .special = NULL,
2308 .enum_list = NULL,
2309 .flags = FLAG_ADVANCED | FLAG_SHARE,
2310 },
2311 {
2312 .label = "kernel change notify",
2313 .type = P_BOOL,
2314 .p_class = P_LOCAL,
2315 .ptr = &sDefault.bKernelChangeNotify,
2316 .special = NULL,
2317 .enum_list = NULL,
2318 .flags = FLAG_ADVANCED | FLAG_SHARE,
2319 },
2320 {
2321 .label = "lpq cache time",
2322 .type = P_INTEGER,
2323 .p_class = P_GLOBAL,
2324 .ptr = &Globals.lpqcachetime,
2325 .special = NULL,
2326 .enum_list = NULL,
2327 .flags = FLAG_ADVANCED,
2328 },
2329 {
2330 .label = "max smbd processes",
2331 .type = P_INTEGER,
2332 .p_class = P_GLOBAL,
2333 .ptr = &Globals.iMaxSmbdProcesses,
2334 .special = NULL,
2335 .enum_list = NULL,
2336 .flags = FLAG_ADVANCED,
2337 },
2338 {
2339 .label = "max connections",
2340 .type = P_INTEGER,
2341 .p_class = P_LOCAL,
2342 .ptr = &sDefault.iMaxConnections,
2343 .special = NULL,
2344 .enum_list = NULL,
2345 .flags = FLAG_ADVANCED | FLAG_SHARE,
2346 },
2347 {
2348 .label = "paranoid server security",
2349 .type = P_BOOL,
2350 .p_class = P_GLOBAL,
2351 .ptr = &Globals.paranoid_server_security,
2352 .special = NULL,
2353 .enum_list = NULL,
2354 .flags = FLAG_ADVANCED,
2355 },
2356 {
2357 .label = "max disk size",
2358 .type = P_INTEGER,
2359 .p_class = P_GLOBAL,
2360 .ptr = &Globals.maxdisksize,
2361 .special = NULL,
2362 .enum_list = NULL,
2363 .flags = FLAG_ADVANCED,
2364 },
2365 {
2366 .label = "max open files",
2367 .type = P_INTEGER,
2368 .p_class = P_GLOBAL,
2369 .ptr = &Globals.max_open_files,
2370 .special = NULL,
2371 .enum_list = NULL,
2372 .flags = FLAG_ADVANCED,
2373 },
2374 {
2375 .label = "min print space",
2376 .type = P_INTEGER,
2377 .p_class = P_LOCAL,
2378 .ptr = &sDefault.iMinPrintSpace,
2379 .special = NULL,
2380 .enum_list = NULL,
2381 .flags = FLAG_ADVANCED | FLAG_PRINT,
2382 },
2383 {
2384 .label = "socket options",
2385 .type = P_STRING,
2386 .p_class = P_GLOBAL,
2387 .ptr = &Globals.szSocketOptions,
2388 .special = NULL,
2389 .enum_list = NULL,
2390 .flags = FLAG_ADVANCED,
2391 },
2392 {
2393 .label = "strict allocate",
2394 .type = P_BOOL,
2395 .p_class = P_LOCAL,
2396 .ptr = &sDefault.bStrictAllocate,
2397 .special = NULL,
2398 .enum_list = NULL,
2399 .flags = FLAG_ADVANCED | FLAG_SHARE,
2400 },
2401 {
2402 .label = "strict sync",
2403 .type = P_BOOL,
2404 .p_class = P_LOCAL,
2405 .ptr = &sDefault.bStrictSync,
2406 .special = NULL,
2407 .enum_list = NULL,
2408 .flags = FLAG_ADVANCED | FLAG_SHARE,
2409 },
2410 {
2411 .label = "sync always",
2412 .type = P_BOOL,
2413 .p_class = P_LOCAL,
2414 .ptr = &sDefault.bSyncAlways,
2415 .special = NULL,
2416 .enum_list = NULL,
2417 .flags = FLAG_ADVANCED | FLAG_SHARE,
2418 },
2419 {
2420 .label = "use mmap",
2421 .type = P_BOOL,
2422 .p_class = P_GLOBAL,
2423 .ptr = &Globals.bUseMmap,
2424 .special = NULL,
2425 .enum_list = NULL,
2426 .flags = FLAG_ADVANCED,
2427 },
2428 {
2429 .label = "use sendfile",
2430 .type = P_BOOL,
2431 .p_class = P_LOCAL,
2432 .ptr = &sDefault.bUseSendfile,
2433 .special = NULL,
2434 .enum_list = NULL,
2435 .flags = FLAG_ADVANCED | FLAG_SHARE,
2436 },
2437 {
2438 .label = "hostname lookups",
2439 .type = P_BOOL,
2440 .p_class = P_GLOBAL,
2441 .ptr = &Globals.bHostnameLookups,
2442 .special = NULL,
2443 .enum_list = NULL,
2444 .flags = FLAG_ADVANCED,
2445 },
2446 {
2447 .label = "write cache size",
2448 .type = P_INTEGER,
2449 .p_class = P_LOCAL,
2450 .ptr = &sDefault.iWriteCacheSize,
2451 .special = NULL,
2452 .enum_list = NULL,
2453 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2454 },
2455 {
2456 .label = "name cache timeout",
2457 .type = P_INTEGER,
2458 .p_class = P_GLOBAL,
2459 .ptr = &Globals.name_cache_timeout,
2460 .special = NULL,
2461 .enum_list = NULL,
2462 .flags = FLAG_ADVANCED,
2463 },
2464 {
2465 .label = "ctdbd socket",
2466 .type = P_STRING,
2467 .p_class = P_GLOBAL,
2468 .ptr = &Globals.ctdbdSocket,
2469 .special = NULL,
2470 .enum_list = NULL,
2471 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2472 },
2473 {
2474 .label = "cluster addresses",
2475 .type = P_LIST,
2476 .p_class = P_GLOBAL,
2477 .ptr = &Globals.szClusterAddresses,
2478 .special = NULL,
2479 .enum_list = NULL,
2480 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2481 },
2482 {
2483 .label = "clustering",
2484 .type = P_BOOL,
2485 .p_class = P_GLOBAL,
2486 .ptr = &Globals.clustering,
2487 .special = NULL,
2488 .enum_list = NULL,
2489 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2490 },
2491
2492 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2493
2494 {
2495 .label = "max reported print jobs",
2496 .type = P_INTEGER,
2497 .p_class = P_LOCAL,
2498 .ptr = &sDefault.iMaxReportedPrintJobs,
2499 .special = NULL,
2500 .enum_list = NULL,
2501 .flags = FLAG_ADVANCED | FLAG_PRINT,
2502 },
2503 {
2504 .label = "max print jobs",
2505 .type = P_INTEGER,
2506 .p_class = P_LOCAL,
2507 .ptr = &sDefault.iMaxPrintJobs,
2508 .special = NULL,
2509 .enum_list = NULL,
2510 .flags = FLAG_ADVANCED | FLAG_PRINT,
2511 },
2512 {
2513 .label = "load printers",
2514 .type = P_BOOL,
2515 .p_class = P_GLOBAL,
2516 .ptr = &Globals.bLoadPrinters,
2517 .special = NULL,
2518 .enum_list = NULL,
2519 .flags = FLAG_ADVANCED | FLAG_PRINT,
2520 },
2521 {
2522 .label = "printcap cache time",
2523 .type = P_INTEGER,
2524 .p_class = P_GLOBAL,
2525 .ptr = &Globals.PrintcapCacheTime,
2526 .special = NULL,
2527 .enum_list = NULL,
2528 .flags = FLAG_ADVANCED | FLAG_PRINT,
2529 },
2530 {
2531 .label = "printcap name",
2532 .type = P_STRING,
2533 .p_class = P_GLOBAL,
2534 .ptr = &Globals.szPrintcapname,
2535 .special = NULL,
2536 .enum_list = NULL,
2537 .flags = FLAG_ADVANCED | FLAG_PRINT,
2538 },
2539 {
2540 .label = "printcap",
2541 .type = P_STRING,
2542 .p_class = P_GLOBAL,
2543 .ptr = &Globals.szPrintcapname,
2544 .special = NULL,
2545 .enum_list = NULL,
2546 .flags = FLAG_HIDE,
2547 },
2548 {
2549 .label = "printable",
2550 .type = P_BOOL,
2551 .p_class = P_LOCAL,
2552 .ptr = &sDefault.bPrint_ok,
2553 .special = NULL,
2554 .enum_list = NULL,
2555 .flags = FLAG_ADVANCED | FLAG_PRINT,
2556 },
2557 {
2558 .label = "print ok",
2559 .type = P_BOOL,
2560 .p_class = P_LOCAL,
2561 .ptr = &sDefault.bPrint_ok,
2562 .special = NULL,
2563 .enum_list = NULL,
2564 .flags = FLAG_HIDE,
2565 },
2566 {
2567 .label = "printing",
2568 .type = P_ENUM,
2569 .p_class = P_LOCAL,
2570 .ptr = &sDefault.iPrinting,
2571 .special = handle_printing,
2572 .enum_list = enum_printing,
2573 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2574 },
2575 {
2576 .label = "cups options",
2577 .type = P_STRING,
2578 .p_class = P_LOCAL,
2579 .ptr = &sDefault.szCupsOptions,
2580 .special = NULL,
2581 .enum_list = NULL,
2582 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2583 },
2584 {
2585 .label = "cups server",
2586 .type = P_STRING,
2587 .p_class = P_GLOBAL,
2588 .ptr = &Globals.szCupsServer,
2589 .special = NULL,
2590 .enum_list = NULL,
2591 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2592 },
2593 {
2594 .label = "cups connection timeout",
2595 .type = P_INTEGER,
2596 .p_class = P_GLOBAL,
2597 .ptr = &Globals.cups_connection_timeout,
2598 .special = NULL,
2599 .enum_list = NULL,
2600 .flags = FLAG_ADVANCED,
2601 },
2602 {
2603 .label = "iprint server",
2604 .type = P_STRING,
2605 .p_class = P_GLOBAL,
2606 .ptr = &Globals.szIPrintServer,
2607 .special = NULL,
2608 .enum_list = NULL,
2609 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2610 },
2611 {
2612 .label = "print command",
2613 .type = P_STRING,
2614 .p_class = P_LOCAL,
2615 .ptr = &sDefault.szPrintcommand,
2616 .special = NULL,
2617 .enum_list = NULL,
2618 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2619 },
2620 {
2621 .label = "disable spoolss",
2622 .type = P_BOOL,
2623 .p_class = P_GLOBAL,
2624 .ptr = &Globals.bDisableSpoolss,
2625 .special = NULL,
2626 .enum_list = NULL,
2627 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2628 },
2629 {
2630 .label = "enable spoolss",
2631 .type = P_BOOLREV,
2632 .p_class = P_GLOBAL,
2633 .ptr = &Globals.bDisableSpoolss,
2634 .special = NULL,
2635 .enum_list = NULL,
2636 .flags = FLAG_HIDE,
2637 },
2638 {
2639 .label = "lpq command",
2640 .type = P_STRING,
2641 .p_class = P_LOCAL,
2642 .ptr = &sDefault.szLpqcommand,
2643 .special = NULL,
2644 .enum_list = NULL,
2645 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2646 },
2647 {
2648 .label = "lprm command",
2649 .type = P_STRING,
2650 .p_class = P_LOCAL,
2651 .ptr = &sDefault.szLprmcommand,
2652 .special = NULL,
2653 .enum_list = NULL,
2654 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2655 },
2656 {
2657 .label = "lppause command",
2658 .type = P_STRING,
2659 .p_class = P_LOCAL,
2660 .ptr = &sDefault.szLppausecommand,
2661 .special = NULL,
2662 .enum_list = NULL,
2663 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2664 },
2665 {
2666 .label = "lpresume command",
2667 .type = P_STRING,
2668 .p_class = P_LOCAL,
2669 .ptr = &sDefault.szLpresumecommand,
2670 .special = NULL,
2671 .enum_list = NULL,
2672 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2673 },
2674 {
2675 .label = "queuepause command",
2676 .type = P_STRING,
2677 .p_class = P_LOCAL,
2678 .ptr = &sDefault.szQueuepausecommand,
2679 .special = NULL,
2680 .enum_list = NULL,
2681 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2682 },
2683 {
2684 .label = "queueresume command",
2685 .type = P_STRING,
2686 .p_class = P_LOCAL,
2687 .ptr = &sDefault.szQueueresumecommand,
2688 .special = NULL,
2689 .enum_list = NULL,
2690 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2691 },
2692 {
2693 .label = "addport command",
2694 .type = P_STRING,
2695 .p_class = P_GLOBAL,
2696 .ptr = &Globals.szAddPortCommand,
2697 .special = NULL,
2698 .enum_list = NULL,
2699 .flags = FLAG_ADVANCED,
2700 },
2701 {
2702 .label = "enumports command",
2703 .type = P_STRING,
2704 .p_class = P_GLOBAL,
2705 .ptr = &Globals.szEnumPortsCommand,
2706 .special = NULL,
2707 .enum_list = NULL,
2708 .flags = FLAG_ADVANCED,
2709 },
2710 {
2711 .label = "addprinter command",
2712 .type = P_STRING,
2713 .p_class = P_GLOBAL,
2714 .ptr = &Globals.szAddPrinterCommand,
2715 .special = NULL,
2716 .enum_list = NULL,
2717 .flags = FLAG_ADVANCED,
2718 },
2719 {
2720 .label = "deleteprinter command",
2721 .type = P_STRING,
2722 .p_class = P_GLOBAL,
2723 .ptr = &Globals.szDeletePrinterCommand,
2724 .special = NULL,
2725 .enum_list = NULL,
2726 .flags = FLAG_ADVANCED,
2727 },
2728 {
2729 .label = "show add printer wizard",
2730 .type = P_BOOL,
2731 .p_class = P_GLOBAL,
2732 .ptr = &Globals.bMsAddPrinterWizard,
2733 .special = NULL,
2734 .enum_list = NULL,
2735 .flags = FLAG_ADVANCED,
2736 },
2737 {
2738 .label = "os2 driver map",
2739 .type = P_STRING,
2740 .p_class = P_GLOBAL,
2741 .ptr = &Globals.szOs2DriverMap,
2742 .special = NULL,
2743 .enum_list = NULL,
2744 .flags = FLAG_ADVANCED,
2745 },
2746
2747 {
2748 .label = "printer name",
2749 .type = P_STRING,
2750 .p_class = P_LOCAL,
2751 .ptr = &sDefault.szPrintername,
2752 .special = NULL,
2753 .enum_list = NULL,
2754 .flags = FLAG_ADVANCED | FLAG_PRINT,
2755 },
2756 {
2757 .label = "printer",
2758 .type = P_STRING,
2759 .p_class = P_LOCAL,
2760 .ptr = &sDefault.szPrintername,
2761 .special = NULL,
2762 .enum_list = NULL,
2763 .flags = FLAG_HIDE,
2764 },
2765 {
2766 .label = "use client driver",
2767 .type = P_BOOL,
2768 .p_class = P_LOCAL,
2769 .ptr = &sDefault.bUseClientDriver,
2770 .special = NULL,
2771 .enum_list = NULL,
2772 .flags = FLAG_ADVANCED | FLAG_PRINT,
2773 },
2774 {
2775 .label = "default devmode",
2776 .type = P_BOOL,
2777 .p_class = P_LOCAL,
2778 .ptr = &sDefault.bDefaultDevmode,
2779 .special = NULL,
2780 .enum_list = NULL,
2781 .flags = FLAG_ADVANCED | FLAG_PRINT,
2782 },
2783 {
2784 .label = "force printername",
2785 .type = P_BOOL,
2786 .p_class = P_LOCAL,
2787 .ptr = &sDefault.bForcePrintername,
2788 .special = NULL,
2789 .enum_list = NULL,
2790 .flags = FLAG_ADVANCED | FLAG_PRINT,
2791 },
2792 {
2793 .label = "printjob username",
2794 .type = P_STRING,
2795 .p_class = P_LOCAL,
2796 .ptr = &sDefault.szPrintjobUsername,
2797 .special = NULL,
2798 .enum_list = NULL,
2799 .flags = FLAG_ADVANCED | FLAG_PRINT,
2800 },
2801
2802 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2803
2804 {
2805 .label = "mangling method",
2806 .type = P_STRING,
2807 .p_class = P_GLOBAL,
2808 .ptr = &Globals.szManglingMethod,
2809 .special = NULL,
2810 .enum_list = NULL,
2811 .flags = FLAG_ADVANCED,
2812 },
2813 {
2814 .label = "mangle prefix",
2815 .type = P_INTEGER,
2816 .p_class = P_GLOBAL,
2817 .ptr = &Globals.mangle_prefix,
2818 .special = NULL,
2819 .enum_list = NULL,
2820 .flags = FLAG_ADVANCED,
2821 },
2822
2823 {
2824 .label = "default case",
2825 .type = P_ENUM,
2826 .p_class = P_LOCAL,
2827 .ptr = &sDefault.iDefaultCase,
2828 .special = NULL,
2829 .enum_list = enum_case,
2830 .flags = FLAG_ADVANCED | FLAG_SHARE,
2831 },
2832 {
2833 .label = "case sensitive",
2834 .type = P_ENUM,
2835 .p_class = P_LOCAL,
2836 .ptr = &sDefault.iCaseSensitive,
2837 .special = NULL,
2838 .enum_list = enum_bool_auto,
2839 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2840 },
2841 {
2842 .label = "casesignames",
2843 .type = P_ENUM,
2844 .p_class = P_LOCAL,
2845 .ptr = &sDefault.iCaseSensitive,
2846 .special = NULL,
2847 .enum_list = enum_bool_auto,
2848 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2849 },
2850 {
2851 .label = "preserve case",
2852 .type = P_BOOL,
2853 .p_class = P_LOCAL,
2854 .ptr = &sDefault.bCasePreserve,
2855 .special = NULL,
2856 .enum_list = NULL,
2857 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2858 },
2859 {
2860 .label = "short preserve case",
2861 .type = P_BOOL,
2862 .p_class = P_LOCAL,
2863 .ptr = &sDefault.bShortCasePreserve,
2864 .special = NULL,
2865 .enum_list = NULL,
2866 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2867 },
2868 {
2869 .label = "mangling char",
2870 .type = P_CHAR,
2871 .p_class = P_LOCAL,
2872 .ptr = &sDefault.magic_char,
2873 .special = NULL,
2874 .enum_list = NULL,
2875 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2876 },
2877 {
2878 .label = "hide dot files",
2879 .type = P_BOOL,
2880 .p_class = P_LOCAL,
2881 .ptr = &sDefault.bHideDotFiles,
2882 .special = NULL,
2883 .enum_list = NULL,
2884 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2885 },
2886 {
2887 .label = "hide special files",
2888 .type = P_BOOL,
2889 .p_class = P_LOCAL,
2890 .ptr = &sDefault.bHideSpecialFiles,
2891 .special = NULL,
2892 .enum_list = NULL,
2893 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2894 },
2895 {
2896 .label = "hide unreadable",
2897 .type = P_BOOL,
2898 .p_class = P_LOCAL,
2899 .ptr = &sDefault.bHideUnReadable,
2900 .special = NULL,
2901 .enum_list = NULL,
2902 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2903 },
2904 {
2905 .label = "hide unwriteable files",
2906 .type = P_BOOL,
2907 .p_class = P_LOCAL,
2908 .ptr = &sDefault.bHideUnWriteableFiles,
2909 .special = NULL,
2910 .enum_list = NULL,
2911 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2912 },
2913 {
2914 .label = "delete veto files",
2915 .type = P_BOOL,
2916 .p_class = P_LOCAL,
2917 .ptr = &sDefault.bDeleteVetoFiles,
2918 .special = NULL,
2919 .enum_list = NULL,
2920 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2921 },
2922 {
2923 .label = "veto files",
2924 .type = P_STRING,
2925 .p_class = P_LOCAL,
2926 .ptr = &sDefault.szVetoFiles,
2927 .special = NULL,
2928 .enum_list = NULL,
2929 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2930 },
2931 {
2932 .label = "hide files",
2933 .type = P_STRING,
2934 .p_class = P_LOCAL,
2935 .ptr = &sDefault.szHideFiles,
2936 .special = NULL,
2937 .enum_list = NULL,
2938 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2939 },
2940 {
2941 .label = "veto oplock files",
2942 .type = P_STRING,
2943 .p_class = P_LOCAL,
2944 .ptr = &sDefault.szVetoOplockFiles,
2945 .special = NULL,
2946 .enum_list = NULL,
2947 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2948 },
2949 {
2950 .label = "map archive",
2951 .type = P_BOOL,
2952 .p_class = P_LOCAL,
2953 .ptr = &sDefault.bMap_archive,
2954 .special = NULL,
2955 .enum_list = NULL,
2956 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2957 },
2958 {
2959 .label = "map hidden",
2960 .type = P_BOOL,
2961 .p_class = P_LOCAL,
2962 .ptr = &sDefault.bMap_hidden,
2963 .special = NULL,
2964 .enum_list = NULL,
2965 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2966 },
2967 {
2968 .label = "map system",
2969 .type = P_BOOL,
2970 .p_class = P_LOCAL,
2971 .ptr = &sDefault.bMap_system,
2972 .special = NULL,
2973 .enum_list = NULL,
2974 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2975 },
2976 {
2977 .label = "map readonly",
2978 .type = P_ENUM,
2979 .p_class = P_LOCAL,
2980 .ptr = &sDefault.iMap_readonly,
2981 .special = NULL,
2982 .enum_list = enum_map_readonly,
2983 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2984 },
2985 {
2986 .label = "mangled names",
2987 .type = P_BOOL,
2988 .p_class = P_LOCAL,
2989 .ptr = &sDefault.bMangledNames,
2990 .special = NULL,
2991 .enum_list = NULL,
2992 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2993 },
2994 {
2995 .label = "max stat cache size",
2996 .type = P_INTEGER,
2997 .p_class = P_GLOBAL,
2998 .ptr = &Globals.iMaxStatCacheSize,
2999 .special = NULL,
3000 .enum_list = NULL,
3001 .flags = FLAG_ADVANCED,
3002 },
3003 {
3004 .label = "stat cache",
3005 .type = P_BOOL,
3006 .p_class = P_GLOBAL,
3007 .ptr = &Globals.bStatCache,
3008 .special = NULL,
3009 .enum_list = NULL,
3010 .flags = FLAG_ADVANCED,
3011 },
3012 {
3013 .label = "store dos attributes",
3014 .type = P_BOOL,
3015 .p_class = P_LOCAL,
3016 .ptr = &sDefault.bStoreDosAttributes,
3017 .special = NULL,
3018 .enum_list = NULL,
3019 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3020 },
3021 {
3022 .label = "dmapi support",
3023 .type = P_BOOL,
3024 .p_class = P_LOCAL,
3025 .ptr = &sDefault.bDmapiSupport,
3026 .special = NULL,
3027 .enum_list = NULL,
3028 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3029 },
3030
3031
3032 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3033
3034 {
3035 .label = "machine password timeout",
3036 .type = P_INTEGER,
3037 .p_class = P_GLOBAL,
3038 .ptr = &Globals.machine_password_timeout,
3039 .special = NULL,
3040 .enum_list = NULL,
3041 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3042 },
3043
3044 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3045
3046 {
3047 .label = "add user script",
3048 .type = P_STRING,
3049 .p_class = P_GLOBAL,
3050 .ptr = &Globals.szAddUserScript,
3051 .special = NULL,
3052 .enum_list = NULL,
3053 .flags = FLAG_ADVANCED,
3054 },
3055 {
3056 .label = "rename user script",
3057 .type = P_STRING,
3058 .p_class = P_GLOBAL,
3059 .ptr = &Globals.szRenameUserScript,
3060 .special = NULL,
3061 .enum_list = NULL,
3062 .flags = FLAG_ADVANCED,
3063 },
3064 {
3065 .label = "delete user script",
3066 .type = P_STRING,
3067 .p_class = P_GLOBAL,
3068 .ptr = &Globals.szDelUserScript,
3069 .special = NULL,
3070 .enum_list = NULL,
3071 .flags = FLAG_ADVANCED,
3072 },
3073 {
3074 .label = "add group script",
3075 .type = P_STRING,
3076 .p_class = P_GLOBAL,
3077 .ptr = &Globals.szAddGroupScript,
3078 .special = NULL,
3079 .enum_list = NULL,
3080 .flags = FLAG_ADVANCED,
3081 },
3082 {
3083 .label = "delete group script",
3084 .type = P_STRING,
3085 .p_class = P_GLOBAL,
3086 .ptr = &Globals.szDelGroupScript,
3087 .special = NULL,
3088 .enum_list = NULL,
3089 .flags = FLAG_ADVANCED,
3090 },
3091 {
3092 .label = "add user to group script",
3093 .type = P_STRING,
3094 .p_class = P_GLOBAL,
3095 .ptr = &Globals.szAddUserToGroupScript,
3096 .special = NULL,
3097 .enum_list = NULL,
3098 .flags = FLAG_ADVANCED,
3099 },
3100 {
3101 .label = "delete user from group script",
3102 .type = P_STRING,
3103 .p_class = P_GLOBAL,
3104 .ptr = &Globals.szDelUserFromGroupScript,
3105 .special = NULL,
3106 .enum_list = NULL,
3107 .flags = FLAG_ADVANCED,
3108 },
3109 {
3110 .label = "set primary group script",
3111 .type = P_STRING,
3112 .p_class = P_GLOBAL,
3113 .ptr = &Globals.szSetPrimaryGroupScript,
3114 .special = NULL,
3115 .enum_list = NULL,
3116 .flags = FLAG_ADVANCED,
3117 },
3118 {
3119 .label = "add machine script",
3120 .type = P_STRING,
3121 .p_class = P_GLOBAL,
3122 .ptr = &Globals.szAddMachineScript,
3123 .special = NULL,
3124 .enum_list = NULL,
3125 .flags = FLAG_ADVANCED,
3126 },
3127 {
3128 .label = "shutdown script",
3129 .type = P_STRING,
3130 .p_class = P_GLOBAL,
3131 .ptr = &Globals.szShutdownScript,
3132 .special = NULL,
3133 .enum_list = NULL,
3134 .flags = FLAG_ADVANCED,
3135 },
3136 {
3137 .label = "abort shutdown script",
3138 .type = P_STRING,
3139 .p_class = P_GLOBAL,
3140 .ptr = &Globals.szAbortShutdownScript,
3141 .special = NULL,
3142 .enum_list = NULL,
3143 .flags = FLAG_ADVANCED,
3144 },
3145 {
3146 .label = "username map script",
3147 .type = P_STRING,
3148 .p_class = P_GLOBAL,
3149 .ptr = &Globals.szUsernameMapScript,
3150 .special = NULL,
3151 .enum_list = NULL,
3152 .flags = FLAG_ADVANCED,
3153 },
3154 {
3155 .label = "logon script",
3156 .type = P_STRING,
3157 .p_class = P_GLOBAL,
3158 .ptr = &Globals.szLogonScript,
3159 .special = NULL,
3160 .enum_list = NULL,
3161 .flags = FLAG_ADVANCED,
3162 },
3163 {
3164 .label = "logon path",
3165 .type = P_STRING,
3166 .p_class = P_GLOBAL,
3167 .ptr = &Globals.szLogonPath,
3168 .special = NULL,
3169 .enum_list = NULL,
3170 .flags = FLAG_ADVANCED,
3171 },
3172 {
3173 .label = "logon drive",
3174 .type = P_STRING,
3175 .p_class = P_GLOBAL,
3176 .ptr = &Globals.szLogonDrive,
3177 .special = NULL,
3178 .enum_list = NULL,
3179 .flags = FLAG_ADVANCED,
3180 },
3181 {
3182 .label = "logon home",
3183 .type = P_STRING,
3184 .p_class = P_GLOBAL,
3185 .ptr = &Globals.szLogonHome,
3186 .special = NULL,
3187 .enum_list = NULL,
3188 .flags = FLAG_ADVANCED,
3189 },
3190 {
3191 .label = "domain logons",
3192 .type = P_BOOL,
3193 .p_class = P_GLOBAL,
3194 .ptr = &Globals.bDomainLogons,
3195 .special = NULL,
3196 .enum_list = NULL,
3197 .flags = FLAG_ADVANCED,
3198 },
3199
3200 {
3201 .label = "init logon delayed hosts",
3202 .type = P_LIST,
3203 .p_class = P_GLOBAL,
3204 .ptr = &Globals.szInitLogonDelayedHosts,
3205 .flags = FLAG_ADVANCED,
3206 },
3207
3208 {
3209 .label = "init logon delay",
3210 .type = P_INTEGER,
3211 .p_class = P_GLOBAL,
3212 .ptr = &Globals.InitLogonDelay,
3213 .flags = FLAG_ADVANCED,
3214
3215 },
3216
3217 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3218
3219 {
3220 .label = "os level",
3221 .type = P_INTEGER,
3222 .p_class = P_GLOBAL,
3223 .ptr = &Globals.os_level,
3224 .special = NULL,
3225 .enum_list = NULL,
3226 .flags = FLAG_BASIC | FLAG_ADVANCED,
3227 },
3228 {
3229 .label = "lm announce",
3230 .type = P_ENUM,
3231 .p_class = P_GLOBAL,
3232 .ptr = &Globals.lm_announce,
3233 .special = NULL,
3234 .enum_list = enum_bool_auto,
3235 .flags = FLAG_ADVANCED,
3236 },
3237 {
3238 .label = "lm interval",
3239 .type = P_INTEGER,
3240 .p_class = P_GLOBAL,
3241 .ptr = &Globals.lm_interval,
3242 .special = NULL,
3243 .enum_list = NULL,
3244 .flags = FLAG_ADVANCED,
3245 },
3246 {
3247 .label = "preferred master",
3248 .type = P_ENUM,
3249 .p_class = P_GLOBAL,
3250 .ptr = &Globals.iPreferredMaster,
3251 .special = NULL,
3252 .enum_list = enum_bool_auto,
3253 .flags = FLAG_BASIC | FLAG_ADVANCED,
3254 },
3255 {
3256 .label = "prefered master",
3257 .type = P_ENUM,
3258 .p_class = P_GLOBAL,
3259 .ptr = &Globals.iPreferredMaster,
3260 .special = NULL,
3261 .enum_list = enum_bool_auto,
3262 .flags = FLAG_HIDE,
3263 },
3264 {
3265 .label = "local master",
3266 .type = P_BOOL,
3267 .p_class = P_GLOBAL,
3268 .ptr = &Globals.bLocalMaster,
3269 .special = NULL,
3270 .enum_list = NULL,
3271 .flags = FLAG_BASIC | FLAG_ADVANCED,
3272 },
3273 {
3274 .label = "domain master",
3275 .type = P_ENUM,
3276 .p_class = P_GLOBAL,
3277 .ptr = &Globals.iDomainMaster,
3278 .special = NULL,
3279 .enum_list = enum_bool_auto,
3280 .flags = FLAG_BASIC | FLAG_ADVANCED,
3281 },
3282 {
3283 .label = "browse list",
3284 .type = P_BOOL,
3285 .p_class = P_GLOBAL,
3286 .ptr = &Globals.bBrowseList,
3287 .special = NULL,
3288 .enum_list = NULL,
3289 .flags = FLAG_ADVANCED,
3290 },
3291 {
3292 .label = "browseable",
3293 .type = P_BOOL,
3294 .p_class = P_LOCAL,
3295 .ptr = &sDefault.bBrowseable,
3296 .special = NULL,
3297 .enum_list = NULL,
3298 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3299 },
3300 {
3301 .label = "browsable",
3302 .type = P_BOOL,
3303 .p_class = P_LOCAL,
3304 .ptr = &sDefault.bBrowseable,
3305 .special = NULL,
3306 .enum_list = NULL,
3307 .flags = FLAG_HIDE,
3308 },
3309 {
3310 .label = "enhanced browsing",
3311 .type = P_BOOL,
3312 .p_class = P_GLOBAL,
3313 .ptr = &Globals.enhanced_browsing,
3314 .special = NULL,
3315 .enum_list = NULL,
3316 .flags = FLAG_ADVANCED,
3317 },
3318
3319 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3320
3321 {
3322 .label = "dns proxy",
3323 .type = P_BOOL,
3324 .p_class = P_GLOBAL,
3325 .ptr = &Globals.bDNSproxy,
3326 .special = NULL,
3327 .enum_list = NULL,
3328 .flags = FLAG_ADVANCED,
3329 },
3330 {
3331 .label = "wins proxy",
3332 .type = P_BOOL,
3333 .p_class = P_GLOBAL,
3334 .ptr = &Globals.bWINSproxy,
3335 .special = NULL,
3336 .enum_list = NULL,
3337 .flags = FLAG_ADVANCED,
3338 },
3339 {
3340 .label = "wins server",
3341 .type = P_LIST,
3342 .p_class = P_GLOBAL,
3343 .ptr = &Globals.szWINSservers,
3344 .special = NULL,
3345 .enum_list = NULL,
3346 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3347 },
3348 {
3349 .label = "wins support",
3350 .type = P_BOOL,
3351 .p_class = P_GLOBAL,
3352 .ptr = &Globals.bWINSsupport,
3353 .special = NULL,
3354 .enum_list = NULL,
3355 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3356 },
3357 {
3358 .label = "wins hook",
3359 .type = P_STRING,
3360 .p_class = P_GLOBAL,
3361 .ptr = &Globals.szWINSHook,
3362 .special = NULL,
3363 .enum_list = NULL,
3364 .flags = FLAG_ADVANCED,
3365 },
3366
3367 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3368
3369 {
3370 .label = "blocking locks",
3371 .type = P_BOOL,
3372 .p_class = P_LOCAL,
3373 .ptr = &sDefault.bBlockingLocks,
3374 .special = NULL,
3375 .enum_list = NULL,
3376 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3377 },
3378 {
3379 .label = "csc policy",
3380 .type = P_ENUM,
3381 .p_class = P_LOCAL,
3382 .ptr = &sDefault.iCSCPolicy,
3383 .special = NULL,
3384 .enum_list = enum_csc_policy,
3385 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3386 },
3387 {
3388 .label = "fake oplocks",
3389 .type = P_BOOL,
3390 .p_class = P_LOCAL,
3391 .ptr = &sDefault.bFakeOplocks,
3392 .special = NULL,
3393 .enum_list = NULL,
3394 .flags = FLAG_ADVANCED | FLAG_SHARE,
3395 },
3396 {
3397 .label = "kernel oplocks",
3398 .type = P_BOOL,
3399 .p_class = P_GLOBAL,
3400 .ptr = &Globals.bKernelOplocks,
3401 .special = NULL,
3402 .enum_list = NULL,
3403 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3404 },
3405 {
3406 .label = "locking",
3407 .type = P_BOOL,
3408 .p_class = P_LOCAL,
3409 .ptr = &sDefault.bLocking,
3410 .special = NULL,
3411 .enum_list = NULL,
3412 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3413 },
3414 {
3415 .label = "lock spin time",
3416 .type = P_INTEGER,
3417 .p_class = P_GLOBAL,
3418 .ptr = &Globals.iLockSpinTime,
3419 .special = NULL,
3420 .enum_list = NULL,
3421 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3422 },
3423 {
3424 .label = "oplocks",
3425 .type = P_BOOL,
3426 .p_class = P_LOCAL,
3427 .ptr = &sDefault.bOpLocks,
3428 .special = NULL,
3429 .enum_list = NULL,
3430 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3431 },
3432 {
3433 .label = "level2 oplocks",
3434 .type = P_BOOL,
3435 .p_class = P_LOCAL,
3436 .ptr = &sDefault.bLevel2OpLocks,
3437 .special = NULL,
3438 .enum_list = NULL,
3439 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3440 },
3441 {
3442 .label = "oplock break wait time",
3443 .type = P_INTEGER,
3444 .p_class = P_GLOBAL,
3445 .ptr = &Globals.oplock_break_wait_time,
3446 .special = NULL,
3447 .enum_list = NULL,
3448 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3449 },
3450 {
3451 .label = "oplock contention limit",
3452 .type = P_INTEGER,
3453 .p_class = P_LOCAL,
3454 .ptr = &sDefault.iOplockContentionLimit,
3455 .special = NULL,
3456 .enum_list = NULL,
3457 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3458 },
3459 {
3460 .label = "posix locking",
3461 .type = P_BOOL,
3462 .p_class = P_LOCAL,
3463 .ptr = &sDefault.bPosixLocking,
3464 .special = NULL,
3465 .enum_list = NULL,
3466 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3467 },
3468 {
3469 .label = "strict locking",
3470 .type = P_ENUM,
3471 .p_class = P_LOCAL,
3472 .ptr = &sDefault.iStrictLocking,
3473 .special = NULL,
3474 .enum_list = enum_bool_auto,
3475 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3476 },
3477 {
3478 .label = "share modes",
3479 .type = P_BOOL,
3480 .p_class = P_LOCAL,
3481 .ptr = &sDefault.bShareModes,
3482 .special = NULL,
3483 .enum_list = NULL,
3484 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3485 },
3486
3487 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3488
3489 {
3490 .label = "ldap admin dn",
3491 .type = P_STRING,
3492 .p_class = P_GLOBAL,
3493 .ptr = &Globals.szLdapAdminDn,
3494 .special = NULL,
3495 .enum_list = NULL,
3496 .flags = FLAG_ADVANCED,
3497 },
3498 {
3499 .label = "ldap delete dn",
3500 .type = P_BOOL,
3501 .p_class = P_GLOBAL,
3502 .ptr = &Globals.ldap_delete_dn,
3503 .special = NULL,
3504 .enum_list = NULL,
3505 .flags = FLAG_ADVANCED,
3506 },
3507 {
3508 .label = "ldap group suffix",
3509 .type = P_STRING,
3510 .p_class = P_GLOBAL,
3511 .ptr = &Globals.szLdapGroupSuffix,
3512 .special = NULL,
3513 .enum_list = NULL,
3514 .flags = FLAG_ADVANCED,
3515 },
3516 {
3517 .label = "ldap idmap suffix",
3518 .type = P_STRING,
3519 .p_class = P_GLOBAL,
3520 .ptr = &Globals.szLdapIdmapSuffix,
3521 .special = NULL,
3522 .enum_list = NULL,
3523 .flags = FLAG_ADVANCED,
3524 },
3525 {
3526 .label = "ldap machine suffix",
3527 .type = P_STRING,
3528 .p_class = P_GLOBAL,
3529 .ptr = &Globals.szLdapMachineSuffix,
3530 .special = NULL,
3531 .enum_list = NULL,
3532 .flags = FLAG_ADVANCED,
3533 },
3534 {
3535 .label = "ldap passwd sync",
3536 .type = P_ENUM,
3537 .p_class = P_GLOBAL,
3538 .ptr = &Globals.ldap_passwd_sync,
3539 .special = NULL,
3540 .enum_list = enum_ldap_passwd_sync,
3541 .flags = FLAG_ADVANCED,
3542 },
3543 {
3544 .label = "ldap password sync",
3545 .type = P_ENUM,
3546 .p_class = P_GLOBAL,
3547 .ptr = &Globals.ldap_passwd_sync,
3548 .special = NULL,
3549 .enum_list = enum_ldap_passwd_sync,
3550 .flags = FLAG_HIDE,
3551 },
3552 {
3553 .label = "ldap replication sleep",
3554 .type = P_INTEGER,
3555 .p_class = P_GLOBAL,
3556 .ptr = &Globals.ldap_replication_sleep,
3557 .special = NULL,
3558 .enum_list = NULL,
3559 .flags = FLAG_ADVANCED,
3560 },
3561 {
3562 .label = "ldap suffix",
3563 .type = P_STRING,
3564 .p_class = P_GLOBAL,
3565 .ptr = &Globals.szLdapSuffix,
3566 .special = NULL,
3567 .enum_list = NULL,
3568 .flags = FLAG_ADVANCED,
3569 },
3570 {
3571 .label = "ldap ssl",
3572 .type = P_ENUM,
3573 .p_class = P_GLOBAL,
3574 .ptr = &Globals.ldap_ssl,
3575 .special = NULL,
3576 .enum_list = enum_ldap_ssl,
3577 .flags = FLAG_ADVANCED,
3578 },
3579 {
3580 .label = "ldap ssl ads",
3581 .type = P_BOOL,
3582 .p_class = P_GLOBAL,
3583 .ptr = &Globals.ldap_ssl_ads,
3584 .special = NULL,
3585 .enum_list = NULL,
3586 .flags = FLAG_ADVANCED,
3587 },
3588 {
3589 .label = "ldap timeout",
3590 .type = P_INTEGER,
3591 .p_class = P_GLOBAL,
3592 .ptr = &Globals.ldap_timeout,
3593 .special = NULL,
3594 .enum_list = NULL,
3595 .flags = FLAG_ADVANCED,
3596 },
3597 {
3598 .label = "ldap connection timeout",
3599 .type = P_INTEGER,
3600 .p_class = P_GLOBAL,
3601 .ptr = &Globals.ldap_connection_timeout,
3602 .special = NULL,
3603 .enum_list = NULL,
3604 .flags = FLAG_ADVANCED,
3605 },
3606 {
3607 .label = "ldap page size",
3608 .type = P_INTEGER,
3609 .p_class = P_GLOBAL,
3610 .ptr = &Globals.ldap_page_size,
3611 .special = NULL,
3612 .enum_list = NULL,
3613 .flags = FLAG_ADVANCED,
3614 },
3615 {
3616 .label = "ldap user suffix",
3617 .type = P_STRING,
3618 .p_class = P_GLOBAL,
3619 .ptr = &Globals.szLdapUserSuffix,
3620 .special = NULL,
3621 .enum_list = NULL,
3622 .flags = FLAG_ADVANCED,
3623 },
3624 {
3625 .label = "ldap debug level",
3626 .type = P_INTEGER,
3627 .p_class = P_GLOBAL,
3628 .ptr = &Globals.ldap_debug_level,
3629 .special = handle_ldap_debug_level,
3630 .enum_list = NULL,
3631 .flags = FLAG_ADVANCED,
3632 },
3633 {
3634 .label = "ldap debug threshold",
3635 .type = P_INTEGER,
3636 .p_class = P_GLOBAL,
3637 .ptr = &Globals.ldap_debug_threshold,
3638 .special = NULL,
3639 .enum_list = NULL,
3640 .flags = FLAG_ADVANCED,
3641 },
3642
3643 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3644
3645 {
3646 .label = "eventlog list",
3647 .type = P_LIST,
3648 .p_class = P_GLOBAL,
3649 .ptr = &Globals.szEventLogs,
3650 .special = NULL,
3651 .enum_list = NULL,
3652 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3653 },
3654
3655 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3656
3657 {
3658 .label = "add share command",
3659 .type = P_STRING,
3660 .p_class = P_GLOBAL,
3661 .ptr = &Globals.szAddShareCommand,
3662 .special = NULL,
3663 .enum_list = NULL,
3664 .flags = FLAG_ADVANCED,
3665 },
3666 {
3667 .label = "change share command",
3668 .type = P_STRING,
3669 .p_class = P_GLOBAL,
3670 .ptr = &Globals.szChangeShareCommand,
3671 .special = NULL,
3672 .enum_list = NULL,
3673 .flags = FLAG_ADVANCED,
3674 },
3675 {
3676 .label = "delete share command",
3677 .type = P_STRING,
3678 .p_class = P_GLOBAL,
3679 .ptr = &Globals.szDeleteShareCommand,
3680 .special = NULL,
3681 .enum_list = NULL,
3682 .flags = FLAG_ADVANCED,
3683 },
3684 {
3685 .label = "config file",
3686 .type = P_STRING,
3687 .p_class = P_GLOBAL,
3688 .ptr = &Globals.szConfigFile,
3689 .special = NULL,
3690 .enum_list = NULL,
3691 .flags = FLAG_HIDE,
3692 },
3693 {
3694 .label = "preload",
3695 .type = P_STRING,
3696 .p_class = P_GLOBAL,
3697 .ptr = &Globals.szAutoServices,
3698 .special = NULL,
3699 .enum_list = NULL,
3700 .flags = FLAG_ADVANCED,
3701 },
3702 {
3703 .label = "auto services",
3704 .type = P_STRING,
3705 .p_class = P_GLOBAL,
3706 .ptr = &Globals.szAutoServices,
3707 .special = NULL,
3708 .enum_list = NULL,
3709 .flags = FLAG_ADVANCED,
3710 },
3711 {
3712 .label = "lock directory",
3713 .type = P_STRING,
3714 .p_class = P_GLOBAL,
3715 .ptr = &Globals.szLockDir,
3716 .special = NULL,
3717 .enum_list = NULL,
3718 .flags = FLAG_ADVANCED,
3719 },
3720 {
3721 .label = "lock dir",
3722 .type = P_STRING,
3723 .p_class = P_GLOBAL,
3724 .ptr = &Globals.szLockDir,
3725 .special = NULL,
3726 .enum_list = NULL,
3727 .flags = FLAG_HIDE,
3728 },
3729 {
3730 .label = "pid directory",
3731 .type = P_STRING,
3732 .p_class = P_GLOBAL,
3733 .ptr = &Globals.szPidDir,
3734 .special = NULL,
3735 .enum_list = NULL,
3736 .flags = FLAG_ADVANCED,
3737 },
3738#ifdef WITH_UTMP
3739 {
3740 .label = "utmp directory",
3741 .type = P_STRING,
3742 .p_class = P_GLOBAL,
3743 .ptr = &Globals.szUtmpDir,
3744 .special = NULL,
3745 .enum_list = NULL,
3746 .flags = FLAG_ADVANCED,
3747 },
3748 {
3749 .label = "wtmp directory",
3750 .type = P_STRING,
3751 .p_class = P_GLOBAL,
3752 .ptr = &Globals.szWtmpDir,
3753 .special = NULL,
3754 .enum_list = NULL,
3755 .flags = FLAG_ADVANCED,
3756 },
3757 {
3758 .label = "utmp",
3759 .type = P_BOOL,
3760 .p_class = P_GLOBAL,
3761 .ptr = &Globals.bUtmp,
3762 .special = NULL,
3763 .enum_list = NULL,
3764 .flags = FLAG_ADVANCED,
3765 },
3766#endif
3767 {
3768 .label = "default service",
3769 .type = P_STRING,
3770 .p_class = P_GLOBAL,
3771 .ptr = &Globals.szDefaultService,
3772 .special = NULL,
3773 .enum_list = NULL,
3774 .flags = FLAG_ADVANCED,
3775 },
3776 {
3777 .label = "default",
3778 .type = P_STRING,
3779 .p_class = P_GLOBAL,
3780 .ptr = &Globals.szDefaultService,
3781 .special = NULL,
3782 .enum_list = NULL,
3783 .flags = FLAG_ADVANCED,
3784 },
3785 {
3786 .label = "message command",
3787 .type = P_STRING,
3788 .p_class = P_GLOBAL,
3789 .ptr = &Globals.szMsgCommand,
3790 .special = NULL,
3791 .enum_list = NULL,
3792 .flags = FLAG_ADVANCED,
3793 },
3794 {
3795 .label = "dfree cache time",
3796 .type = P_INTEGER,
3797 .p_class = P_LOCAL,
3798 .ptr = &sDefault.iDfreeCacheTime,
3799 .special = NULL,
3800 .enum_list = NULL,
3801 .flags = FLAG_ADVANCED,
3802 },
3803 {
3804 .label = "dfree command",
3805 .type = P_STRING,
3806 .p_class = P_LOCAL,
3807 .ptr = &sDefault.szDfree,
3808 .special = NULL,
3809 .enum_list = NULL,
3810 .flags = FLAG_ADVANCED,
3811 },
3812 {
3813 .label = "get quota command",
3814 .type = P_STRING,
3815 .p_class = P_GLOBAL,
3816 .ptr = &Globals.szGetQuota,
3817 .special = NULL,
3818 .enum_list = NULL,
3819 .flags = FLAG_ADVANCED,
3820 },
3821 {
3822 .label = "set quota command",
3823 .type = P_STRING,
3824 .p_class = P_GLOBAL,
3825 .ptr = &Globals.szSetQuota,
3826 .special = NULL,
3827 .enum_list = NULL,
3828 .flags = FLAG_ADVANCED,
3829 },
3830 {
3831 .label = "remote announce",
3832 .type = P_STRING,
3833 .p_class = P_GLOBAL,
3834 .ptr = &Globals.szRemoteAnnounce,
3835 .special = NULL,
3836 .enum_list = NULL,
3837 .flags = FLAG_ADVANCED,
3838 },
3839 {
3840 .label = "remote browse sync",
3841 .type = P_STRING,
3842 .p_class = P_GLOBAL,
3843 .ptr = &Globals.szRemoteBrowseSync,
3844 .special = NULL,
3845 .enum_list = NULL,
3846 .flags = FLAG_ADVANCED,
3847 },
3848 {
3849 .label = "socket address",
3850 .type = P_STRING,
3851 .p_class = P_GLOBAL,
3852 .ptr = &Globals.szSocketAddress,
3853 .special = NULL,
3854 .enum_list = NULL,
3855 .flags = FLAG_ADVANCED,
3856 },
3857 {
3858 .label = "homedir map",
3859 .type = P_STRING,
3860 .p_class = P_GLOBAL,
3861 .ptr = &Globals.szNISHomeMapName,
3862 .special = NULL,
3863 .enum_list = NULL,
3864 .flags = FLAG_ADVANCED,
3865 },
3866 {
3867 .label = "afs username map",
3868 .type = P_STRING,
3869 .p_class = P_GLOBAL,
3870 .ptr = &Globals.szAfsUsernameMap,
3871 .special = NULL,
3872 .enum_list = NULL,
3873 .flags = FLAG_ADVANCED,
3874 },
3875 {
3876 .label = "afs token lifetime",
3877 .type = P_INTEGER,
3878 .p_class = P_GLOBAL,
3879 .ptr = &Globals.iAfsTokenLifetime,
3880 .special = NULL,
3881 .enum_list = NULL,
3882 .flags = FLAG_ADVANCED,
3883 },
3884 {
3885 .label = "log nt token command",
3886 .type = P_STRING,
3887 .p_class = P_GLOBAL,
3888 .ptr = &Globals.szLogNtTokenCommand,
3889 .special = NULL,
3890 .enum_list = NULL,
3891 .flags = FLAG_ADVANCED,
3892 },
3893 {
3894 .label = "time offset",
3895 .type = P_INTEGER,
3896 .p_class = P_GLOBAL,
3897 .ptr = &extra_time_offset,
3898 .special = NULL,
3899 .enum_list = NULL,
3900 .flags = FLAG_ADVANCED,
3901 },
3902 {
3903 .label = "NIS homedir",
3904 .type = P_BOOL,
3905 .p_class = P_GLOBAL,
3906 .ptr = &Globals.bNISHomeMap,
3907 .special = NULL,
3908 .enum_list = NULL,
3909 .flags = FLAG_ADVANCED,
3910 },
3911 {
3912 .label = "-valid",
3913 .type = P_BOOL,
3914 .p_class = P_LOCAL,
3915 .ptr = &sDefault.valid,
3916 .special = NULL,
3917 .enum_list = NULL,
3918 .flags = FLAG_HIDE,
3919 },
3920 {
3921 .label = "copy",
3922 .type = P_STRING,
3923 .p_class = P_LOCAL,
3924 .ptr = &sDefault.szCopy,
3925 .special = handle_copy,
3926 .enum_list = NULL,
3927 .flags = FLAG_HIDE,
3928 },
3929 {
3930 .label = "include",
3931 .type = P_STRING,
3932 .p_class = P_LOCAL,
3933 .ptr = &sDefault.szInclude,
3934 .special = handle_include,
3935 .enum_list = NULL,
3936 .flags = FLAG_HIDE,
3937 },
3938 {
3939 .label = "preexec",
3940 .type = P_STRING,
3941 .p_class = P_LOCAL,
3942 .ptr = &sDefault.szPreExec,
3943 .special = NULL,
3944 .enum_list = NULL,
3945 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3946 },
3947 {
3948 .label = "exec",
3949 .type = P_STRING,
3950 .p_class = P_LOCAL,
3951 .ptr = &sDefault.szPreExec,
3952 .special = NULL,
3953 .enum_list = NULL,
3954 .flags = FLAG_ADVANCED,
3955 },
3956 {
3957 .label = "preexec close",
3958 .type = P_BOOL,
3959 .p_class = P_LOCAL,
3960 .ptr = &sDefault.bPreexecClose,
3961 .special = NULL,
3962 .enum_list = NULL,
3963 .flags = FLAG_ADVANCED | FLAG_SHARE,
3964 },
3965 {
3966 .label = "postexec",
3967 .type = P_STRING,
3968 .p_class = P_LOCAL,
3969 .ptr = &sDefault.szPostExec,
3970 .special = NULL,
3971 .enum_list = NULL,
3972 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3973 },
3974 {
3975 .label = "root preexec",
3976 .type = P_STRING,
3977 .p_class = P_LOCAL,
3978 .ptr = &sDefault.szRootPreExec,
3979 .special = NULL,
3980 .enum_list = NULL,
3981 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3982 },
3983 {
3984 .label = "root preexec close",
3985 .type = P_BOOL,
3986 .p_class = P_LOCAL,
3987 .ptr = &sDefault.bRootpreexecClose,
3988 .special = NULL,
3989 .enum_list = NULL,
3990 .flags = FLAG_ADVANCED | FLAG_SHARE,
3991 },
3992 {
3993 .label = "root postexec",
3994 .type = P_STRING,
3995 .p_class = P_LOCAL,
3996 .ptr = &sDefault.szRootPostExec,
3997 .special = NULL,
3998 .enum_list = NULL,
3999 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4000 },
4001 {
4002 .label = "available",
4003 .type = P_BOOL,
4004 .p_class = P_LOCAL,
4005 .ptr = &sDefault.bAvailable,
4006 .special = NULL,
4007 .enum_list = NULL,
4008 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4009 },
4010 {
4011 .label = "registry shares",
4012 .type = P_BOOL,
4013 .p_class = P_GLOBAL,
4014 .ptr = &Globals.bRegistryShares,
4015 .special = NULL,
4016 .enum_list = NULL,
4017 .flags = FLAG_ADVANCED,
4018 },
4019 {
4020 .label = "usershare allow guests",
4021 .type = P_BOOL,
4022 .p_class = P_GLOBAL,
4023 .ptr = &Globals.bUsershareAllowGuests,
4024 .special = NULL,
4025 .enum_list = NULL,
4026 .flags = FLAG_ADVANCED,
4027 },
4028 {
4029 .label = "usershare max shares",
4030 .type = P_INTEGER,
4031 .p_class = P_GLOBAL,
4032 .ptr = &Globals.iUsershareMaxShares,
4033 .special = NULL,
4034 .enum_list = NULL,
4035 .flags = FLAG_ADVANCED,
4036 },
4037 {
4038 .label = "usershare owner only",
4039 .type = P_BOOL,
4040 .p_class = P_GLOBAL,
4041 .ptr = &Globals.bUsershareOwnerOnly,
4042 .special = NULL,
4043 .enum_list = NULL,
4044 .flags = FLAG_ADVANCED,
4045 },
4046 {
4047 .label = "usershare path",
4048 .type = P_STRING,
4049 .p_class = P_GLOBAL,
4050 .ptr = &Globals.szUsersharePath,
4051 .special = NULL,
4052 .enum_list = NULL,
4053 .flags = FLAG_ADVANCED,
4054 },
4055 {
4056 .label = "usershare prefix allow list",
4057 .type = P_LIST,
4058 .p_class = P_GLOBAL,
4059 .ptr = &Globals.szUsersharePrefixAllowList,
4060 .special = NULL,
4061 .enum_list = NULL,
4062 .flags = FLAG_ADVANCED,
4063 },
4064 {
4065 .label = "usershare prefix deny list",
4066 .type = P_LIST,
4067 .p_class = P_GLOBAL,
4068 .ptr = &Globals.szUsersharePrefixDenyList,
4069 .special = NULL,
4070 .enum_list = NULL,
4071 .flags = FLAG_ADVANCED,
4072 },
4073 {
4074 .label = "usershare template share",
4075 .type = P_STRING,
4076 .p_class = P_GLOBAL,
4077 .ptr = &Globals.szUsershareTemplateShare,
4078 .special = NULL,
4079 .enum_list = NULL,
4080 .flags = FLAG_ADVANCED,
4081 },
4082 {
4083 .label = "volume",
4084 .type = P_STRING,
4085 .p_class = P_LOCAL,
4086 .ptr = &sDefault.volume,
4087 .special = NULL,
4088 .enum_list = NULL,
4089 .flags = FLAG_ADVANCED | FLAG_SHARE,
4090 },
4091 {
4092 .label = "fstype",
4093 .type = P_STRING,
4094 .p_class = P_LOCAL,
4095 .ptr = &sDefault.fstype,
4096 .special = NULL,
4097 .enum_list = NULL,
4098 .flags = FLAG_ADVANCED | FLAG_SHARE,
4099 },
4100 {
4101 .label = "set directory",
4102 .type = P_BOOLREV,
4103 .p_class = P_LOCAL,
4104 .ptr = &sDefault.bNo_set_dir,
4105 .special = NULL,
4106 .enum_list = NULL,
4107 .flags = FLAG_ADVANCED | FLAG_SHARE,
4108 },
4109 {
4110 .label = "wide links",
4111 .type = P_BOOL,
4112 .p_class = P_LOCAL,
4113 .ptr = &sDefault.bWidelinks,
4114 .special = NULL,
4115 .enum_list = NULL,
4116 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4117 },
4118 {
4119 .label = "follow symlinks",
4120 .type = P_BOOL,
4121 .p_class = P_LOCAL,
4122 .ptr = &sDefault.bSymlinks,
4123 .special = NULL,
4124 .enum_list = NULL,
4125 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4126 },
4127 {
4128 .label = "dont descend",
4129 .type = P_STRING,
4130 .p_class = P_LOCAL,
4131 .ptr = &sDefault.szDontdescend,
4132 .special = NULL,
4133 .enum_list = NULL,
4134 .flags = FLAG_ADVANCED | FLAG_SHARE,
4135 },
4136 {
4137 .label = "magic script",
4138 .type = P_STRING,
4139 .p_class = P_LOCAL,
4140 .ptr = &sDefault.szMagicScript,
4141 .special = NULL,
4142 .enum_list = NULL,
4143 .flags = FLAG_ADVANCED | FLAG_SHARE,
4144 },
4145 {
4146 .label = "magic output",
4147 .type = P_STRING,
4148 .p_class = P_LOCAL,
4149 .ptr = &sDefault.szMagicOutput,
4150 .special = NULL,
4151 .enum_list = NULL,
4152 .flags = FLAG_ADVANCED | FLAG_SHARE,
4153 },
4154 {
4155 .label = "delete readonly",
4156 .type = P_BOOL,
4157 .p_class = P_LOCAL,
4158 .ptr = &sDefault.bDeleteReadonly,
4159 .special = NULL,
4160 .enum_list = NULL,
4161 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4162 },
4163 {
4164 .label = "dos filemode",
4165 .type = P_BOOL,
4166 .p_class = P_LOCAL,
4167 .ptr = &sDefault.bDosFilemode,
4168 .special = NULL,
4169 .enum_list = NULL,
4170 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4171 },
4172 {
4173 .label = "dos filetimes",
4174 .type = P_BOOL,
4175 .p_class = P_LOCAL,
4176 .ptr = &sDefault.bDosFiletimes,
4177 .special = NULL,
4178 .enum_list = NULL,
4179 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4180 },
4181 {
4182 .label = "dos filetime resolution",
4183 .type = P_BOOL,
4184 .p_class = P_LOCAL,
4185 .ptr = &sDefault.bDosFiletimeResolution,
4186 .special = NULL,
4187 .enum_list = NULL,
4188 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4189 },
4190 {
4191 .label = "fake directory create times",
4192 .type = P_BOOL,
4193 .p_class = P_LOCAL,
4194 .ptr = &sDefault.bFakeDirCreateTimes,
4195 .special = NULL,
4196 .enum_list = NULL,
4197 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4198 },
4199 {
4200 .label = "panic action",
4201 .type = P_STRING,
4202 .p_class = P_GLOBAL,
4203 .ptr = &Globals.szPanicAction,
4204 .special = NULL,
4205 .enum_list = NULL,
4206 .flags = FLAG_ADVANCED,
4207 },
4208
4209 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4210
4211 {
4212 .label = "vfs objects",
4213 .type = P_LIST,
4214 .p_class = P_LOCAL,
4215 .ptr = &sDefault.szVfsObjects,
4216 .special = NULL,
4217 .enum_list = NULL,
4218 .flags = FLAG_ADVANCED | FLAG_SHARE,
4219 },
4220 {
4221 .label = "vfs object",
4222 .type = P_LIST,
4223 .p_class = P_LOCAL,
4224 .ptr = &sDefault.szVfsObjects,
4225 .special = NULL,
4226 .enum_list = NULL,
4227 .flags = FLAG_HIDE,
4228 },
4229
4230
4231 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4232
4233 {
4234 .label = "msdfs root",
4235 .type = P_BOOL,
4236 .p_class = P_LOCAL,
4237 .ptr = &sDefault.bMSDfsRoot,
4238 .special = NULL,
4239 .enum_list = NULL,
4240 .flags = FLAG_ADVANCED | FLAG_SHARE,
4241 },
4242 {
4243 .label = "msdfs proxy",
4244 .type = P_STRING,
4245 .p_class = P_LOCAL,
4246 .ptr = &sDefault.szMSDfsProxy,
4247 .special = NULL,
4248 .enum_list = NULL,
4249 .flags = FLAG_ADVANCED | FLAG_SHARE,
4250 },
4251 {
4252 .label = "host msdfs",
4253 .type = P_BOOL,
4254 .p_class = P_GLOBAL,
4255 .ptr = &Globals.bHostMSDfs,
4256 .special = NULL,
4257 .enum_list = NULL,
4258 .flags = FLAG_ADVANCED,
4259 },
4260
4261 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4262
4263 {
4264 .label = "passdb expand explicit",
4265 .type = P_BOOL,
4266 .p_class = P_GLOBAL,
4267 .ptr = &Globals.bPassdbExpandExplicit,
4268 .special = NULL,
4269 .enum_list = NULL,
4270 .flags = FLAG_ADVANCED,
4271 },
4272 {
4273 .label = "idmap backend",
4274 .type = P_STRING,
4275 .p_class = P_GLOBAL,
4276 .ptr = &Globals.szIdmapBackend,
4277 .special = NULL,
4278 .enum_list = NULL,
4279 .flags = FLAG_ADVANCED,
4280 },
4281 {
4282 .label = "idmap alloc backend",
4283 .type = P_STRING,
4284 .p_class = P_GLOBAL,
4285 .ptr = &Globals.szIdmapAllocBackend,
4286 .special = NULL,
4287 .enum_list = NULL,
4288 .flags = FLAG_ADVANCED,
4289 },
4290 {
4291 .label = "idmap cache time",
4292 .type = P_INTEGER,
4293 .p_class = P_GLOBAL,
4294 .ptr = &Globals.iIdmapCacheTime,
4295 .special = NULL,
4296 .enum_list = NULL,
4297 .flags = FLAG_ADVANCED,
4298 },
4299 {
4300 .label = "idmap negative cache time",
4301 .type = P_INTEGER,
4302 .p_class = P_GLOBAL,
4303 .ptr = &Globals.iIdmapNegativeCacheTime,
4304 .special = NULL,
4305 .enum_list = NULL,
4306 .flags = FLAG_ADVANCED,
4307 },
4308 {
4309 .label = "idmap uid",
4310 .type = P_STRING,
4311 .p_class = P_GLOBAL,
4312 .ptr = &Globals.szIdmapUID,
4313 .special = handle_idmap_uid,
4314 .enum_list = NULL,
4315 .flags = FLAG_ADVANCED,
4316 },
4317 {
4318 .label = "winbind uid",
4319 .type = P_STRING,
4320 .p_class = P_GLOBAL,
4321 .ptr = &Globals.szIdmapUID,
4322 .special = handle_idmap_uid,
4323 .enum_list = NULL,
4324 .flags = FLAG_HIDE,
4325 },
4326 {
4327 .label = "idmap gid",
4328 .type = P_STRING,
4329 .p_class = P_GLOBAL,
4330 .ptr = &Globals.szIdmapGID,
4331 .special = handle_idmap_gid,
4332 .enum_list = NULL,
4333 .flags = FLAG_ADVANCED,
4334 },
4335 {
4336 .label = "winbind gid",
4337 .type = P_STRING,
4338 .p_class = P_GLOBAL,
4339 .ptr = &Globals.szIdmapGID,
4340 .special = handle_idmap_gid,
4341 .enum_list = NULL,
4342 .flags = FLAG_HIDE,
4343 },
4344 {
4345 .label = "template homedir",
4346 .type = P_STRING,
4347 .p_class = P_GLOBAL,
4348 .ptr = &Globals.szTemplateHomedir,
4349 .special = NULL,
4350 .enum_list = NULL,
4351 .flags = FLAG_ADVANCED,
4352 },
4353 {
4354 .label = "template shell",
4355 .type = P_STRING,
4356 .p_class = P_GLOBAL,
4357 .ptr = &Globals.szTemplateShell,
4358 .special = NULL,
4359 .enum_list = NULL,
4360 .flags = FLAG_ADVANCED,
4361 },
4362 {
4363 .label = "winbind separator",
4364 .type = P_STRING,
4365 .p_class = P_GLOBAL,
4366 .ptr = &Globals.szWinbindSeparator,
4367 .special = NULL,
4368 .enum_list = NULL,
4369 .flags = FLAG_ADVANCED,
4370 },
4371 {
4372 .label = "winbind cache time",
4373 .type = P_INTEGER,
4374 .p_class = P_GLOBAL,
4375 .ptr = &Globals.winbind_cache_time,
4376 .special = NULL,
4377 .enum_list = NULL,
4378 .flags = FLAG_ADVANCED,
4379 },
4380 {
4381 .label = "winbind reconnect delay",
4382 .type = P_INTEGER,
4383 .p_class = P_GLOBAL,
4384 .ptr = &Globals.winbind_reconnect_delay,
4385 .special = NULL,
4386 .enum_list = NULL,
4387 .flags = FLAG_ADVANCED,
4388 },
4389 {
4390 .label = "winbind enum users",
4391 .type = P_BOOL,
4392 .p_class = P_GLOBAL,
4393 .ptr = &Globals.bWinbindEnumUsers,
4394 .special = NULL,
4395 .enum_list = NULL,
4396 .flags = FLAG_ADVANCED,
4397 },
4398 {
4399 .label = "winbind enum groups",
4400 .type = P_BOOL,
4401 .p_class = P_GLOBAL,
4402 .ptr = &Globals.bWinbindEnumGroups,
4403 .special = NULL,
4404 .enum_list = NULL,
4405 .flags = FLAG_ADVANCED,
4406 },
4407 {
4408 .label = "winbind use default domain",
4409 .type = P_BOOL,
4410 .p_class = P_GLOBAL,
4411 .ptr = &Globals.bWinbindUseDefaultDomain,
4412 .special = NULL,
4413 .enum_list = NULL,
4414 .flags = FLAG_ADVANCED,
4415 },
4416 {
4417 .label = "winbind trusted domains only",
4418 .type = P_BOOL,
4419 .p_class = P_GLOBAL,
4420 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4421 .special = NULL,
4422 .enum_list = NULL,
4423 .flags = FLAG_ADVANCED,
4424 },
4425 {
4426 .label = "winbind nested groups",
4427 .type = P_BOOL,
4428 .p_class = P_GLOBAL,
4429 .ptr = &Globals.bWinbindNestedGroups,
4430 .special = NULL,
4431 .enum_list = NULL,
4432 .flags = FLAG_ADVANCED,
4433 },
4434 {
4435 .label = "winbind expand groups",
4436 .type = P_INTEGER,
4437 .p_class = P_GLOBAL,
4438 .ptr = &Globals.winbind_expand_groups,
4439 .special = NULL,
4440 .enum_list = NULL,
4441 .flags = FLAG_ADVANCED,
4442 },
4443 {
4444 .label = "winbind nss info",
4445 .type = P_LIST,
4446 .p_class = P_GLOBAL,
4447 .ptr = &Globals.szWinbindNssInfo,
4448 .special = NULL,
4449 .enum_list = NULL,
4450 .flags = FLAG_ADVANCED,
4451 },
4452 {
4453 .label = "winbind refresh tickets",
4454 .type = P_BOOL,
4455 .p_class = P_GLOBAL,
4456 .ptr = &Globals.bWinbindRefreshTickets,
4457 .special = NULL,
4458 .enum_list = NULL,
4459 .flags = FLAG_ADVANCED,
4460 },
4461 {
4462 .label = "winbind offline logon",
4463 .type = P_BOOL,
4464 .p_class = P_GLOBAL,
4465 .ptr = &Globals.bWinbindOfflineLogon,
4466 .special = NULL,
4467 .enum_list = NULL,
4468 .flags = FLAG_ADVANCED,
4469 },
4470 {
4471 .label = "winbind normalize names",
4472 .type = P_BOOL,
4473 .p_class = P_GLOBAL,
4474 .ptr = &Globals.bWinbindNormalizeNames,
4475 .special = NULL,
4476 .enum_list = NULL,
4477 .flags = FLAG_ADVANCED,
4478 },
4479 {
4480 .label = "winbind rpc only",
4481 .type = P_BOOL,
4482 .p_class = P_GLOBAL,
4483 .ptr = &Globals.bWinbindRpcOnly,
4484 .special = NULL,
4485 .enum_list = NULL,
4486 .flags = FLAG_ADVANCED,
4487 },
4488
4489 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4490};
4491
4492/***************************************************************************
4493 Initialise the sDefault parameter structure for the printer values.
4494***************************************************************************/
4495
4496static void init_printer_values(struct service *pService)
4497{
4498 /* choose defaults depending on the type of printing */
4499 switch (pService->iPrinting) {
4500 case PRINT_BSD:
4501 case PRINT_AIX:
4502 case PRINT_LPRNT:
4503#ifndef __OS2__
4504 case PRINT_LPROS2:
4505#endif
4506 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4507 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4508 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4509 break;
4510#ifdef __OS2__
4511 case PRINT_LPROS2:
4512 string_set(&pService->szLpqcommand, "lpq.exe -s %i -p %p");
4513 string_set(&pService->szLprmcommand, "lprm.exe -s %i -p %p %j");
4514 string_set(&pService->szPrintcommand, "lpr.exe -b -s %i -p %p %s & cmd.exe /c del %s");
4515 break;
4516#endif
4517
4518 case PRINT_LPRNG:
4519 case PRINT_PLP:
4520 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4521 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4522 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4523 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4524 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4525 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4526 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4527 break;
4528
4529 case PRINT_CUPS:
4530 case PRINT_IPRINT:
4531#ifdef HAVE_CUPS
4532 /* set the lpq command to contain the destination printer
4533 name only. This is used by cups_queue_get() */
4534 string_set(&pService->szLpqcommand, "%p");
4535 string_set(&pService->szLprmcommand, "");
4536 string_set(&pService->szPrintcommand, "");
4537 string_set(&pService->szLppausecommand, "");
4538 string_set(&pService->szLpresumecommand, "");
4539 string_set(&pService->szQueuepausecommand, "");
4540 string_set(&pService->szQueueresumecommand, "");
4541#else
4542 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4543 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4544 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4545 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4546 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4547 string_set(&pService->szQueuepausecommand, "disable '%p'");
4548 string_set(&pService->szQueueresumecommand, "enable '%p'");
4549#endif /* HAVE_CUPS */
4550 break;
4551
4552 case PRINT_SYSV:
4553 case PRINT_HPUX:
4554 string_set(&pService->szLpqcommand, "lpstat -o%p");
4555 string_set(&pService->szLprmcommand, "cancel %p-%j");
4556 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4557 string_set(&pService->szQueuepausecommand, "disable %p");
4558 string_set(&pService->szQueueresumecommand, "enable %p");
4559#ifndef HPUX
4560 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4561 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4562#endif /* HPUX */
4563 break;
4564
4565 case PRINT_QNX:
4566 string_set(&pService->szLpqcommand, "lpq -P%p");
4567 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4568 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4569 break;
4570
4571#ifdef DEVELOPER
4572 case PRINT_TEST:
4573 case PRINT_VLP:
4574 string_set(&pService->szPrintcommand, "vlp print %p %s");
4575 string_set(&pService->szLpqcommand, "vlp lpq %p");
4576 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4577 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4578 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
4579 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4580 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4581 break;
4582#endif /* DEVELOPER */
4583
4584 }
4585}
4586
4587/***************************************************************************
4588 Initialise the global parameter structure.
4589***************************************************************************/
4590
4591static void init_globals(bool first_time_only)
4592{
4593 static bool done_init = False;
4594 char *s = NULL;
4595 int i;
4596
4597 /* If requested to initialize only once and we've already done it... */
4598 if (first_time_only && done_init) {
4599 /* ... then we have nothing more to do */
4600 return;
4601 }
4602
4603 if (!done_init) {
4604 /* The logfile can be set before this is invoked. Free it if so. */
4605 if (Globals.szLogFile != NULL) {
4606 string_free(&Globals.szLogFile);
4607 Globals.szLogFile = NULL;
4608 }
4609 done_init = True;
4610 } else {
4611 for (i = 0; parm_table[i].label; i++) {
4612 if ((parm_table[i].type == P_STRING ||
4613 parm_table[i].type == P_USTRING) &&
4614 parm_table[i].ptr)
4615 {
4616 string_free((char **)parm_table[i].ptr);
4617 }
4618 }
4619 }
4620
4621 memset((void *)&Globals, '\0', sizeof(Globals));
4622
4623 for (i = 0; parm_table[i].label; i++) {
4624 if ((parm_table[i].type == P_STRING ||
4625 parm_table[i].type == P_USTRING) &&
4626 parm_table[i].ptr)
4627 {
4628 string_set((char **)parm_table[i].ptr, "");
4629 }
4630 }
4631
4632 string_set(&sDefault.fstype, FSTYPE_STRING);
4633 string_set(&sDefault.szPrintjobUsername, "%U");
4634
4635 init_printer_values(&sDefault);
4636
4637
4638 DEBUG(3, ("Initialising global parameters\n"));
4639
4640 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4641 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4642
4643 /* use the new 'hash2' method by default, with a prefix of 1 */
4644 string_set(&Globals.szManglingMethod, "hash2");
4645 Globals.mangle_prefix = 1;
4646
4647 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4648
4649#ifndef __OS2__
4650 /* using UTF8 by default allows us to support all chars */
4651 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4652#else
4653 /* On OS/2, using UTF8 causes problems with display of foreign characters - default to SYSTEM codepage */
4654 string_set(&Globals.unix_charset, "SYSTEM");
4655#endif
4656
4657#if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4658 /* If the system supports nl_langinfo(), try to grab the value
4659 from the user's locale */
4660 string_set(&Globals.display_charset, "LOCALE");
4661#else
4662 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4663#endif
4664
4665#ifndef __OS2__
4666 /* Use codepage 850 as a default for the dos character set */
4667 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4668#else
4669 /* On OS/2, using UTF8 causes problems with display of foreign characters - default to SYSTEM codepage */
4670 string_set(&Globals.dos_charset, "SYSTEM");
4671#endif
4672 /*
4673 * Allow the default PASSWD_CHAT to be overridden in local.h.
4674 */
4675 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4676
4677 set_global_myname(myhostname());
4678 string_set(&Globals.szNetbiosName,global_myname());
4679
4680 set_global_myworkgroup(WORKGROUP);
4681 string_set(&Globals.szWorkgroup, lp_workgroup());
4682
4683 string_set(&Globals.szPasswdProgram, "");
4684 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4685 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4686 string_set(&Globals.szSocketAddress, "0.0.0.0");
4687
4688 if (asprintf(&s, "Samba %s", SAMBA_VERSION_STRING) < 0) {
4689 smb_panic("init_globals: ENOMEM");
4690 }
4691 string_set(&Globals.szServerString, s);
4692 SAFE_FREE(s);
4693 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4694 DEFAULT_MINOR_VERSION) < 0) {
4695 smb_panic("init_globals: ENOMEM");
4696 }
4697 string_set(&Globals.szAnnounceVersion, s);
4698 SAFE_FREE(s);
4699#ifdef DEVELOPER
4700 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4701#endif
4702
4703 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4704
4705 string_set(&Globals.szLogonDrive, "");
4706 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4707 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4708 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4709
4710 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4711 string_set(&Globals.szPasswordServer, "*");
4712
4713 Globals.AlgorithmicRidBase = BASE_RID;
4714
4715 Globals.bLoadPrinters = True;
4716 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4717
4718 Globals.ConfigBackend = config_backend;
4719
4720 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4721 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4722 Globals.max_xmit = 0x4104;
4723 Globals.max_mux = 50; /* This is *needed* for profile support. */
4724 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4725 Globals.bDisableSpoolss = False;
4726 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4727 Globals.pwordlevel = 0;
4728 Globals.unamelevel = 0;
4729 Globals.deadtime = 0;
4730 Globals.getwd_cache = true;
4731 Globals.bLargeReadwrite = True;
4732 Globals.max_log_size = 5000;
4733 Globals.max_open_files = MAX_OPEN_FILES;
4734 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4735 Globals.maxprotocol = PROTOCOL_NT1;
4736 Globals.minprotocol = PROTOCOL_CORE;
4737 Globals.security = SEC_USER;
4738 Globals.paranoid_server_security = True;
4739 Globals.bEncryptPasswords = True;
4740 Globals.bUpdateEncrypt = False;
4741 Globals.clientSchannel = Auto;
4742 Globals.serverSchannel = Auto;
4743 Globals.bReadRaw = True;
4744 Globals.bWriteRaw = True;
4745 Globals.bNullPasswords = False;
4746 Globals.bObeyPamRestrictions = False;
4747 Globals.syslog = 1;
4748 Globals.bSyslogOnly = False;
4749 Globals.bTimestampLogs = True;
4750 string_set(&Globals.szLogLevel, "0");
4751 Globals.bDebugPrefixTimestamp = False;
4752 Globals.bDebugHiresTimestamp = False;
4753 Globals.bDebugPid = False;
4754 Globals.bDebugUid = False;
4755 Globals.bDebugClass = False;
4756 Globals.bEnableCoreFiles = True;
4757 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4758 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4759 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4760 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4761 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4762 Globals.lm_interval = 60;
4763 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4764#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4765 Globals.bNISHomeMap = False;
4766#ifdef WITH_NISPLUS_HOME
4767 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4768#else
4769 string_set(&Globals.szNISHomeMapName, "auto.home");
4770#endif
4771#endif
4772 Globals.bTimeServer = False;
4773 Globals.bBindInterfacesOnly = False;
4774 Globals.bUnixPasswdSync = False;
4775 Globals.bPamPasswordChange = False;
4776 Globals.bPasswdChatDebug = False;
4777 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4778 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4779 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4780 Globals.bStatCache = True; /* use stat cache by default */
4781 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4782 Globals.restrict_anonymous = 0;
4783 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4784 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4785 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4786 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4787 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4788 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4789
4790 Globals.map_to_guest = 0; /* By Default, "Never" */
4791 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4792 Globals.enhanced_browsing = true;
4793 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4794#ifdef MMAP_BLACKLIST
4795 Globals.bUseMmap = False;
4796#else
4797 Globals.bUseMmap = True;
4798#endif
4799 Globals.bUnixExtensions = True;
4800 Globals.bResetOnZeroVC = False;
4801
4802 /* hostname lookups can be very expensive and are broken on
4803 a large number of sites (tridge) */
4804 Globals.bHostnameLookups = False;
4805
4806 string_set(&Globals.szPassdbBackend, "smbpasswd");
4807 string_set(&Globals.szLdapSuffix, "");
4808 string_set(&Globals.szLdapMachineSuffix, "");
4809 string_set(&Globals.szLdapUserSuffix, "");
4810 string_set(&Globals.szLdapGroupSuffix, "");
4811 string_set(&Globals.szLdapIdmapSuffix, "");
4812
4813 string_set(&Globals.szLdapAdminDn, "");
4814 Globals.ldap_ssl = LDAP_SSL_START_TLS;
4815 Globals.ldap_ssl_ads = False;
4816 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
4817 Globals.ldap_delete_dn = False;
4818 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
4819 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
4820 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
4821 Globals.ldap_page_size = LDAP_PAGE_SIZE;
4822
4823 Globals.ldap_debug_level = 0;
4824 Globals.ldap_debug_threshold = 10;
4825
4826 /* This is what we tell the afs client. in reality we set the token
4827 * to never expire, though, when this runs out the afs client will
4828 * forget the token. Set to 0 to get NEVERDATE.*/
4829 Globals.iAfsTokenLifetime = 604800;
4830 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
4831
4832/* these parameters are set to defaults that are more appropriate
4833 for the increasing samba install base:
4834
4835 as a member of the workgroup, that will possibly become a
4836 _local_ master browser (lm = True). this is opposed to a forced
4837 local master browser startup (pm = True).
4838
4839 doesn't provide WINS server service by default (wsupp = False),
4840 and doesn't provide domain master browser services by default, either.
4841
4842*/
4843
4844 Globals.bMsAddPrinterWizard = True;
4845 Globals.os_level = 20;
4846 Globals.bLocalMaster = True;
4847 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
4848 Globals.bDomainLogons = False;
4849 Globals.bBrowseList = True;
4850 Globals.bWINSsupport = False;
4851 Globals.bWINSproxy = False;
4852
4853 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
4854 Globals.InitLogonDelay = 100; /* 100 ms default delay */
4855
4856 Globals.bDNSproxy = True;
4857
4858 /* this just means to use them if they exist */
4859 Globals.bKernelOplocks = True;
4860
4861 Globals.bAllowTrustedDomains = True;
4862 string_set(&Globals.szIdmapBackend, "tdb");
4863
4864 string_set(&Globals.szTemplateShell, "/bin/false");
4865 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
4866 string_set(&Globals.szWinbindSeparator, "\\");
4867
4868 string_set(&Globals.szCupsServer, "");
4869 string_set(&Globals.szIPrintServer, "");
4870
4871 string_set(&Globals.ctdbdSocket, "");
4872 Globals.szClusterAddresses = NULL;
4873 Globals.clustering = False;
4874
4875 Globals.winbind_cache_time = 300; /* 5 minutes */
4876 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
4877 Globals.bWinbindEnumUsers = False;
4878 Globals.bWinbindEnumGroups = False;
4879 Globals.bWinbindUseDefaultDomain = False;
4880 Globals.bWinbindTrustedDomainsOnly = False;
4881 Globals.bWinbindNestedGroups = True;
4882 Globals.winbind_expand_groups = 1;
4883 Globals.szWinbindNssInfo = str_list_make(talloc_autofree_context(), "template", NULL);
4884 Globals.bWinbindRefreshTickets = False;
4885 Globals.bWinbindOfflineLogon = False;
4886
4887 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
4888 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
4889
4890 Globals.bPassdbExpandExplicit = False;
4891
4892 Globals.name_cache_timeout = 660; /* In seconds */
4893
4894 Globals.bUseSpnego = True;
4895 Globals.bClientUseSpnego = True;
4896
4897 Globals.client_signing = Auto;
4898 Globals.server_signing = False;
4899
4900 Globals.bDeferSharingViolations = True;
4901 string_set(&Globals.smb_ports, SMB_PORTS);
4902
4903 Globals.bEnablePrivileges = True;
4904 Globals.bHostMSDfs = True;
4905 Globals.bASUSupport = False;
4906
4907 /* User defined shares. */
4908 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
4909 smb_panic("init_globals: ENOMEM");
4910 }
4911 string_set(&Globals.szUsersharePath, s);
4912 SAFE_FREE(s);
4913 string_set(&Globals.szUsershareTemplateShare, "");
4914 Globals.iUsershareMaxShares = 0;
4915 /* By default disallow sharing of directories not owned by the sharer. */
4916 Globals.bUsershareOwnerOnly = True;
4917 /* By default disallow guest access to usershares. */
4918 Globals.bUsershareAllowGuests = False;
4919
4920 Globals.iKeepalive = DEFAULT_KEEPALIVE;
4921
4922 /* By default no shares out of the registry */
4923 Globals.bRegistryShares = False;
4924
4925 Globals.iminreceivefile = 0;
4926}
4927
4928/*******************************************************************
4929 Convenience routine to grab string parameters into temporary memory
4930 and run standard_sub_basic on them. The buffers can be written to by
4931 callers without affecting the source string.
4932********************************************************************/
4933
4934static char *lp_string(const char *s)
4935{
4936 char *ret;
4937 TALLOC_CTX *ctx = talloc_tos();
4938
4939 /* The follow debug is useful for tracking down memory problems
4940 especially if you have an inner loop that is calling a lp_*()
4941 function that returns a string. Perhaps this debug should be
4942 present all the time? */
4943
4944#if 0
4945 DEBUG(10, ("lp_string(%s)\n", s));
4946#endif
4947
4948 ret = talloc_sub_basic(ctx,
4949 get_current_username(),
4950 current_user_info.domain,
4951 s);
4952 if (trim_char(ret, '\"', '\"')) {
4953 if (strchr(ret,'\"') != NULL) {
4954 TALLOC_FREE(ret);
4955 ret = talloc_sub_basic(ctx,
4956 get_current_username(),
4957 current_user_info.domain,
4958 s);
4959 }
4960 }
4961 return ret;
4962}
4963
4964/*
4965 In this section all the functions that are used to access the
4966 parameters from the rest of the program are defined
4967*/
4968
4969#define FN_GLOBAL_STRING(fn_name,ptr) \
4970 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
4971#define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
4972 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
4973#define FN_GLOBAL_LIST(fn_name,ptr) \
4974 const char **fn_name(void) {return(*(const char ***)(ptr));}
4975#define FN_GLOBAL_BOOL(fn_name,ptr) \
4976 bool fn_name(void) {return(*(bool *)(ptr));}
4977#define FN_GLOBAL_CHAR(fn_name,ptr) \
4978 char fn_name(void) {return(*(char *)(ptr));}
4979#define FN_GLOBAL_INTEGER(fn_name,ptr) \
4980 int fn_name(void) {return(*(int *)(ptr));}
4981
4982#define FN_LOCAL_STRING(fn_name,val) \
4983 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
4984#define FN_LOCAL_CONST_STRING(fn_name,val) \
4985 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
4986#define FN_LOCAL_LIST(fn_name,val) \
4987 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4988#define FN_LOCAL_BOOL(fn_name,val) \
4989 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4990#define FN_LOCAL_INTEGER(fn_name,val) \
4991 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
4992
4993#define FN_LOCAL_PARM_BOOL(fn_name,val) \
4994 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4995#define FN_LOCAL_PARM_INTEGER(fn_name,val) \
4996 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
4997#define FN_LOCAL_PARM_STRING(fn_name,val) \
4998 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));}
4999#define FN_LOCAL_CHAR(fn_name,val) \
5000 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5001
5002FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5003FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5004FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5005FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5006FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5007FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5008FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5009FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5010FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5011FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5012FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5013FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5014FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5015FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5016FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5017FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5018FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5019FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5020FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5021FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5022FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5023FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5024FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5025FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5026FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5027FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5028FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5029FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5030FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5031FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5032FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5033FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5034FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5035FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5036FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5037FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5038FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5039FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5040FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5041FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5042FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5043FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5044FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5045FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5046FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5047FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5048static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5049FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5050/* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5051 * lp_passdb_backend() should be replace by the this macro again after
5052 * some releases.
5053 * */
5054const char *lp_passdb_backend(void)
5055{
5056 char *delim, *quote;
5057
5058 delim = strchr( Globals.szPassdbBackend, ' ');
5059 /* no space at all */
5060 if (delim == NULL) {
5061 goto out;
5062 }
5063
5064 quote = strchr(Globals.szPassdbBackend, '"');
5065 /* no quote char or non in the first part */
5066 if (quote == NULL || quote > delim) {
5067 *delim = '\0';
5068 goto warn;
5069 }
5070
5071 quote = strchr(quote+1, '"');
5072 if (quote == NULL) {
5073 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5074 goto out;
5075 } else if (*(quote+1) == '\0') {
5076 /* space, fitting quote char, and one backend only */
5077 goto out;
5078 } else {
5079 /* terminate string after the fitting quote char */
5080 *(quote+1) = '\0';
5081 }
5082
5083warn:
5084 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5085 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5086 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5087 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5088
5089out:
5090 return Globals.szPassdbBackend;
5091}
5092FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5093FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5094FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5095FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5096FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5097
5098FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5099FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5100FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5101FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5102FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5103FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5104
5105FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5106
5107FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5108FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5109FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5110
5111FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5112
5113FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5114FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5115FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5116FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5117FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5118FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5119FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5120FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5121FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5122FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5123FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5124FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5125FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5126FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5127FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5128
5129FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5130FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5131FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5132FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5133FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5134FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5135
5136FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5137FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5138FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5139FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5140FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5141FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5142FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5143FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5144FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5145FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5146FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5147FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5148FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5149FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5150FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5151FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5152FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5153FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5154
5155FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5156
5157FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5158FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5159FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5160FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5161FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5162FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5163FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5164FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5165FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5166FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5167FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5168FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5169FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5170FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5171FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5172FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5173FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5174FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5175FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5176FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5177FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5178FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5179FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5180FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5181FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5182FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5183FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5184FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5185FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5186FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5187FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5188FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5189FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5190FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5191static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5192FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5193FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5194FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5195FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5196FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5197FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5198FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5199FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5200FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5201FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5202FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5203FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5204FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5205FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5206FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5207FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5208FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5209FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5210FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5211FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5212FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5213FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5214FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5215FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5216FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5217FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5218FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
5219FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5220FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5221FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5222FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5223FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5224FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5225FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5226FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5227FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5228FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5229FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5230FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5231FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5232FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5233FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5234FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5235FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5236FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5237FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5238FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5239FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5240FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5241FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5242FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5243FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5244FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5245static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5246FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5247FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5248FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5249FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5250FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5251FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5252FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5253FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5254FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5255
5256FN_LOCAL_STRING(lp_preexec, szPreExec)
5257FN_LOCAL_STRING(lp_postexec, szPostExec)
5258FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5259FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5260FN_LOCAL_STRING(lp_servicename, szService)
5261FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5262FN_LOCAL_STRING(lp_pathname, szPath)
5263FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5264FN_LOCAL_STRING(lp_username, szUsername)
5265FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5266FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5267FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5268FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5269FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5270FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5271FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5272FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5273FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5274FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5275FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5276FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5277FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5278FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5279FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5280FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5281FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5282FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5283static FN_LOCAL_STRING(_lp_printername, szPrintername)
5284FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5285FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5286FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5287FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5288FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5289FN_LOCAL_STRING(lp_comment, comment)
5290FN_LOCAL_STRING(lp_force_user, force_user)
5291FN_LOCAL_STRING(lp_force_group, force_group)
5292FN_LOCAL_LIST(lp_readlist, readlist)
5293FN_LOCAL_LIST(lp_writelist, writelist)
5294FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5295FN_LOCAL_STRING(lp_fstype, fstype)
5296FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5297FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5298static FN_LOCAL_STRING(lp_volume, volume)
5299FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5300FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5301FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5302FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5303FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5304FN_LOCAL_STRING(lp_dfree_command, szDfree)
5305FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5306FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5307FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5308FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5309FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5310FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5311FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5312FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5313FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5314FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5315FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5316FN_LOCAL_BOOL(lp_readonly, bRead_only)
5317FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5318FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5319FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5320FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5321FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5322FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5323FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5324FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5325FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5326FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5327FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5328FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5329FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5330FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5331FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5332FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5333FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5334FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5335FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5336FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5337FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5338FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5339FN_LOCAL_BOOL(lp_map_system, bMap_system)
5340FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5341FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5342FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5343FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5344FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5345FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5346FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5347FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5348FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5349FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5350FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5351FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5352FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5353FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5354FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5355FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5356FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5357FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5358FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5359FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5360FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5361FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5362FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5363FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5364FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5365FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5366FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5367FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5368FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5369FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5370FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5371FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5372FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5373FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5374FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5375FN_LOCAL_INTEGER(lp_printing, iPrinting)
5376FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5377FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5378FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5379FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5380FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5381FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5382FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5383FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5384FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5385FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5386FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5387FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5388FN_LOCAL_CHAR(lp_magicchar, magic_char)
5389FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5390FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5391FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5392FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5393FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5394FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5395FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5396FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5397
5398/* local prototypes */
5399
5400static int map_parameter(const char *pszParmName);
5401static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5402static bool set_boolean(bool *pb, const char *pszParmValue);
5403static const char *get_boolean(bool bool_value);
5404static int getservicebyname(const char *pszServiceName,
5405 struct service *pserviceDest);
5406static void copy_service(struct service *pserviceDest,
5407 struct service *pserviceSource,
5408 struct bitmap *pcopymapDest);
5409static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5410 void *userdata);
5411static bool do_section(const char *pszSectionName, void *userdata);
5412static void init_copymap(struct service *pservice);
5413static bool hash_a_service(const char *name, int number);
5414static void free_service_byindex(int iService);
5415static char * canonicalize_servicename(const char *name);
5416static void show_parameter(int parmIndex);
5417static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5418
5419/*
5420 * This is a helper function for parametrical options support. It returns a
5421 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5422 * parametrical functions are quite simple
5423 */
5424static struct param_opt_struct *get_parametrics(int snum, const char *type,
5425 const char *option)
5426{
5427 bool global_section = False;
5428 char* param_key;
5429 struct param_opt_struct *data;
5430
5431 if (snum >= iNumServices) return NULL;
5432
5433 if (snum < 0) {
5434 data = Globals.param_opt;
5435 global_section = True;
5436 } else {
5437 data = ServicePtrs[snum]->param_opt;
5438 }
5439
5440 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5441 DEBUG(0,("asprintf failed!\n"));
5442 return NULL;
5443 }
5444
5445 while (data) {
5446 if (strwicmp(data->key, param_key) == 0) {
5447 string_free(&param_key);
5448 return data;
5449 }
5450 data = data->next;
5451 }
5452
5453 if (!global_section) {
5454 /* Try to fetch the same option but from globals */
5455 /* but only if we are not already working with Globals */
5456 data = Globals.param_opt;
5457 while (data) {
5458 if (strwicmp(data->key, param_key) == 0) {
5459 string_free(&param_key);
5460 return data;
5461 }
5462 data = data->next;
5463 }
5464 }
5465
5466 string_free(&param_key);
5467
5468 return NULL;
5469}
5470
5471
5472#define MISSING_PARAMETER(name) \
5473 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5474
5475/*******************************************************************
5476convenience routine to return int parameters.
5477********************************************************************/
5478static int lp_int(const char *s)
5479{
5480
5481 if (!s || !*s) {
5482 MISSING_PARAMETER(lp_int);
5483 return (-1);
5484 }
5485
5486 return (int)strtol(s, NULL, 0);
5487}
5488
5489/*******************************************************************
5490convenience routine to return unsigned long parameters.
5491********************************************************************/
5492static unsigned long lp_ulong(const char *s)
5493{
5494
5495 if (!s || !*s) {
5496 MISSING_PARAMETER(lp_ulong);
5497 return (0);
5498 }
5499
5500 return strtoul(s, NULL, 0);
5501}
5502
5503/*******************************************************************
5504convenience routine to return boolean parameters.
5505********************************************************************/
5506static bool lp_bool(const char *s)
5507{
5508 bool ret = False;
5509
5510 if (!s || !*s) {
5511 MISSING_PARAMETER(lp_bool);
5512 return False;
5513 }
5514
5515 if (!set_boolean(&ret,s)) {
5516 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5517 return False;
5518 }
5519
5520 return ret;
5521}
5522
5523/*******************************************************************
5524convenience routine to return enum parameters.
5525********************************************************************/
5526static int lp_enum(const char *s,const struct enum_list *_enum)
5527{
5528 int i;
5529
5530 if (!s || !*s || !_enum) {
5531 MISSING_PARAMETER(lp_enum);
5532 return (-1);
5533 }
5534
5535 for (i=0; _enum[i].name; i++) {
5536 if (strequal(_enum[i].name,s))
5537 return _enum[i].value;
5538 }
5539
5540 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5541 return (-1);
5542}
5543
5544#undef MISSING_PARAMETER
5545
5546/* DO NOT USE lp_parm_string ANYMORE!!!!
5547 * use lp_parm_const_string or lp_parm_talloc_string
5548 *
5549 * lp_parm_string is only used to let old modules find this symbol
5550 */
5551#undef lp_parm_string
5552 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5553 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5554{
5555 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5556}
5557
5558/* Return parametric option from a given service. Type is a part of option before ':' */
5559/* Parametric option has following syntax: 'Type: option = value' */
5560/* the returned value is talloced on the talloc_tos() */
5561char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5562{
5563 struct param_opt_struct *data = get_parametrics(snum, type, option);
5564
5565 if (data == NULL||data->value==NULL) {
5566 if (def) {
5567 return lp_string(def);
5568 } else {
5569 return NULL;
5570 }
5571 }
5572
5573 return lp_string(data->value);
5574}
5575
5576/* Return parametric option from a given service. Type is a part of option before ':' */
5577/* Parametric option has following syntax: 'Type: option = value' */
5578const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5579{
5580 struct param_opt_struct *data = get_parametrics(snum, type, option);
5581
5582 if (data == NULL||data->value==NULL)
5583 return def;
5584
5585 return data->value;
5586}
5587
5588/* Return parametric option from a given service. Type is a part of option before ':' */
5589/* Parametric option has following syntax: 'Type: option = value' */
5590
5591const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5592{
5593 struct param_opt_struct *data = get_parametrics(snum, type, option);
5594
5595 if (data == NULL||data->value==NULL)
5596 return (const char **)def;
5597
5598 if (data->list==NULL) {
5599 data->list = str_list_make(talloc_autofree_context(), data->value, NULL);
5600 }
5601
5602 return (const char **)data->list;
5603}
5604
5605/* Return parametric option from a given service. Type is a part of option before ':' */
5606/* Parametric option has following syntax: 'Type: option = value' */
5607
5608int lp_parm_int(int snum, const char *type, const char *option, int def)
5609{
5610 struct param_opt_struct *data = get_parametrics(snum, type, option);
5611
5612 if (data && data->value && *data->value)
5613 return lp_int(data->value);
5614
5615 return def;
5616}
5617
5618/* Return parametric option from a given service. Type is a part of option before ':' */
5619/* Parametric option has following syntax: 'Type: option = value' */
5620
5621unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5622{
5623 struct param_opt_struct *data = get_parametrics(snum, type, option);
5624
5625 if (data && data->value && *data->value)
5626 return lp_ulong(data->value);
5627
5628 return def;
5629}
5630
5631/* Return parametric option from a given service. Type is a part of option before ':' */
5632/* Parametric option has following syntax: 'Type: option = value' */
5633
5634bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5635{
5636 struct param_opt_struct *data = get_parametrics(snum, type, option);
5637
5638 if (data && data->value && *data->value)
5639 return lp_bool(data->value);
5640
5641 return def;
5642}
5643
5644/* Return parametric option from a given service. Type is a part of option before ':' */
5645/* Parametric option has following syntax: 'Type: option = value' */
5646
5647int lp_parm_enum(int snum, const char *type, const char *option,
5648 const struct enum_list *_enum, int def)
5649{
5650 struct param_opt_struct *data = get_parametrics(snum, type, option);
5651
5652 if (data && data->value && *data->value && _enum)
5653 return lp_enum(data->value, _enum);
5654
5655 return def;
5656}
5657
5658
5659/***************************************************************************
5660 Initialise a service to the defaults.
5661***************************************************************************/
5662
5663static void init_service(struct service *pservice)
5664{
5665 memset((char *)pservice, '\0', sizeof(struct service));
5666 copy_service(pservice, &sDefault, NULL);
5667}
5668
5669/***************************************************************************
5670 Free the dynamically allocated parts of a service struct.
5671***************************************************************************/
5672
5673static void free_service(struct service *pservice)
5674{
5675 int i;
5676 struct param_opt_struct *data, *pdata;
5677 if (!pservice)
5678 return;
5679
5680 if (pservice->szService)
5681 DEBUG(5, ("free_service: Freeing service %s\n",
5682 pservice->szService));
5683
5684 string_free(&pservice->szService);
5685 bitmap_free(pservice->copymap);
5686
5687 for (i = 0; parm_table[i].label; i++) {
5688 if ((parm_table[i].type == P_STRING ||
5689 parm_table[i].type == P_USTRING) &&
5690 parm_table[i].p_class == P_LOCAL)
5691 string_free((char **)
5692 (((char *)pservice) +
5693 PTR_DIFF(parm_table[i].ptr, &sDefault)));
5694 else if (parm_table[i].type == P_LIST &&
5695 parm_table[i].p_class == P_LOCAL)
5696 TALLOC_FREE(*((char ***)
5697 (((char *)pservice) +
5698 PTR_DIFF(parm_table[i].ptr,
5699 &sDefault))));
5700 }
5701
5702 data = pservice->param_opt;
5703 if (data)
5704 DEBUG(5,("Freeing parametrics:\n"));
5705 while (data) {
5706 DEBUG(5,("[%s = %s]\n", data->key, data->value));
5707 string_free(&data->key);
5708 string_free(&data->value);
5709 TALLOC_FREE(data->list);
5710 pdata = data->next;
5711 SAFE_FREE(data);
5712 data = pdata;
5713 }
5714
5715 ZERO_STRUCTP(pservice);
5716}
5717
5718
5719/***************************************************************************
5720 remove a service indexed in the ServicePtrs array from the ServiceHash
5721 and free the dynamically allocated parts
5722***************************************************************************/
5723
5724static void free_service_byindex(int idx)
5725{
5726 if ( !LP_SNUM_OK(idx) )
5727 return;
5728
5729 ServicePtrs[idx]->valid = False;
5730 invalid_services[num_invalid_services++] = idx;
5731
5732 /* we have to cleanup the hash record */
5733
5734 if (ServicePtrs[idx]->szService) {
5735 char *canon_name = canonicalize_servicename(
5736 ServicePtrs[idx]->szService );
5737
5738 dbwrap_delete_bystring(ServiceHash, canon_name );
5739 TALLOC_FREE(canon_name);
5740 }
5741
5742 free_service(ServicePtrs[idx]);
5743}
5744
5745/***************************************************************************
5746 Add a new service to the services array initialising it with the given
5747 service.
5748***************************************************************************/
5749
5750static int add_a_service(const struct service *pservice, const char *name)
5751{
5752 int i;
5753 struct service tservice;
5754 int num_to_alloc = iNumServices + 1;
5755 struct param_opt_struct *data, *pdata;
5756
5757 tservice = *pservice;
5758
5759 /* it might already exist */
5760 if (name) {
5761 i = getservicebyname(name, NULL);
5762 if (i >= 0) {
5763 /* Clean all parametric options for service */
5764 /* They will be added during parsing again */
5765 data = ServicePtrs[i]->param_opt;
5766 while (data) {
5767 string_free(&data->key);
5768 string_free(&data->value);
5769 TALLOC_FREE(data->list);
5770 pdata = data->next;
5771 SAFE_FREE(data);
5772 data = pdata;
5773 }
5774 ServicePtrs[i]->param_opt = NULL;
5775 return (i);
5776 }
5777 }
5778
5779 /* find an invalid one */
5780 i = iNumServices;
5781 if (num_invalid_services > 0) {
5782 i = invalid_services[--num_invalid_services];
5783 }
5784
5785 /* if not, then create one */
5786 if (i == iNumServices) {
5787 struct service **tsp;
5788 int *tinvalid;
5789
5790 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
5791 if (tsp == NULL) {
5792 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
5793 return (-1);
5794 }
5795 ServicePtrs = tsp;
5796 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
5797 if (!ServicePtrs[iNumServices]) {
5798 DEBUG(0,("add_a_service: out of memory!\n"));
5799 return (-1);
5800 }
5801 iNumServices++;
5802
5803 /* enlarge invalid_services here for now... */
5804 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
5805 num_to_alloc);
5806 if (tinvalid == NULL) {
5807 DEBUG(0,("add_a_service: failed to enlarge "
5808 "invalid_services!\n"));
5809 return (-1);
5810 }
5811 invalid_services = tinvalid;
5812 } else {
5813 free_service_byindex(i);
5814 }
5815
5816 ServicePtrs[i]->valid = True;
5817
5818 init_service(ServicePtrs[i]);
5819 copy_service(ServicePtrs[i], &tservice, NULL);
5820 if (name)
5821 string_set(&ServicePtrs[i]->szService, name);
5822
5823 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
5824 i, ServicePtrs[i]->szService));
5825
5826 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
5827 return (-1);
5828 }
5829
5830 return (i);
5831}
5832
5833/***************************************************************************
5834 Convert a string to uppercase and remove whitespaces.
5835***************************************************************************/
5836
5837static char *canonicalize_servicename(const char *src)
5838{
5839 char *result;
5840
5841 if ( !src ) {
5842 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
5843 return NULL;
5844 }
5845
5846 result = talloc_strdup(talloc_tos(), src);
5847 SMB_ASSERT(result != NULL);
5848
5849 strlower_m(result);
5850 return result;
5851}
5852
5853/***************************************************************************
5854 Add a name/index pair for the services array to the hash table.
5855***************************************************************************/
5856
5857static bool hash_a_service(const char *name, int idx)
5858{
5859 char *canon_name;
5860
5861 if ( !ServiceHash ) {
5862 DEBUG(10,("hash_a_service: creating servicehash\n"));
5863 ServiceHash = db_open_rbt(NULL);
5864 if ( !ServiceHash ) {
5865 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
5866 return False;
5867 }
5868 }
5869
5870 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
5871 idx, name));
5872
5873 canon_name = canonicalize_servicename( name );
5874
5875 dbwrap_store_bystring(ServiceHash, canon_name,
5876 make_tdb_data((uint8 *)&idx, sizeof(idx)),
5877 TDB_REPLACE);
5878
5879 TALLOC_FREE(canon_name);
5880
5881 return True;
5882}
5883
5884/***************************************************************************
5885 Add a new home service, with the specified home directory, defaults coming
5886 from service ifrom.
5887***************************************************************************/
5888
5889bool lp_add_home(const char *pszHomename, int iDefaultService,
5890 const char *user, const char *pszHomedir)
5891{
5892 int i;
5893
5894 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
5895
5896 if (i < 0)
5897 return (False);
5898
5899 if (!(*(ServicePtrs[iDefaultService]->szPath))
5900 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
5901 string_set(&ServicePtrs[i]->szPath, pszHomedir);
5902 }
5903
5904 if (!(*(ServicePtrs[i]->comment))) {
5905 char *comment = NULL;
5906 if (asprintf(&comment, "Home directory of %s", user) < 0) {
5907 return false;
5908 }
5909 string_set(&ServicePtrs[i]->comment, comment);
5910 SAFE_FREE(comment);
5911 }
5912
5913 /* set the browseable flag from the global default */
5914
5915 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5916
5917 ServicePtrs[i]->autoloaded = True;
5918
5919 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
5920 user, ServicePtrs[i]->szPath ));
5921
5922 return (True);
5923}
5924
5925/***************************************************************************
5926 Add a new service, based on an old one.
5927***************************************************************************/
5928
5929int lp_add_service(const char *pszService, int iDefaultService)
5930{
5931 if (iDefaultService < 0) {
5932 return add_a_service(&sDefault, pszService);
5933 }
5934
5935 return (add_a_service(ServicePtrs[iDefaultService], pszService));
5936}
5937
5938/***************************************************************************
5939 Add the IPC service.
5940***************************************************************************/
5941
5942static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
5943{
5944 char *comment = NULL;
5945 int i = add_a_service(&sDefault, ipc_name);
5946
5947 if (i < 0)
5948 return (False);
5949
5950 if (asprintf(&comment, "IPC Service (%s)",
5951 Globals.szServerString) < 0) {
5952 return (False);
5953 }
5954
5955 string_set(&ServicePtrs[i]->szPath, tmpdir());
5956 string_set(&ServicePtrs[i]->szUsername, "");
5957 string_set(&ServicePtrs[i]->comment, comment);
5958 string_set(&ServicePtrs[i]->fstype, "IPC");
5959 ServicePtrs[i]->iMaxConnections = 0;
5960 ServicePtrs[i]->bAvailable = True;
5961 ServicePtrs[i]->bRead_only = True;
5962 ServicePtrs[i]->bGuest_only = False;
5963 ServicePtrs[i]->bAdministrative_share = True;
5964 ServicePtrs[i]->bGuest_ok = guest_ok;
5965 ServicePtrs[i]->bPrint_ok = False;
5966 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5967
5968 DEBUG(3, ("adding IPC service\n"));
5969
5970 SAFE_FREE(comment);
5971 return (True);
5972}
5973
5974/***************************************************************************
5975 Add a new printer service, with defaults coming from service iFrom.
5976***************************************************************************/
5977
5978bool lp_add_printer(const char *pszPrintername, int iDefaultService)
5979{
5980 const char *comment = "From Printcap";
5981 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
5982
5983 if (i < 0)
5984 return (False);
5985
5986 /* note that we do NOT default the availability flag to True - */
5987 /* we take it from the default service passed. This allows all */
5988 /* dynamic printers to be disabled by disabling the [printers] */
5989 /* entry (if/when the 'available' keyword is implemented!). */
5990
5991 /* the printer name is set to the service name. */
5992 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
5993 string_set(&ServicePtrs[i]->comment, comment);
5994
5995 /* set the browseable flag from the gloabl default */
5996 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
5997
5998 /* Printers cannot be read_only. */
5999 ServicePtrs[i]->bRead_only = False;
6000 /* No share modes on printer services. */
6001 ServicePtrs[i]->bShareModes = False;
6002 /* No oplocks on printer services. */
6003 ServicePtrs[i]->bOpLocks = False;
6004 /* Printer services must be printable. */
6005 ServicePtrs[i]->bPrint_ok = True;
6006
6007 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6008
6009 return (True);
6010}
6011
6012
6013/***************************************************************************
6014 Check whether the given parameter name is valid.
6015 Parametric options (names containing a colon) are considered valid.
6016***************************************************************************/
6017
6018bool lp_parameter_is_valid(const char *pszParmName)
6019{
6020 return ((map_parameter(pszParmName) != -1) ||
6021 (strchr(pszParmName, ':') != NULL));
6022}
6023
6024/***************************************************************************
6025 Check whether the given name is the name of a global parameter.
6026 Returns True for strings belonging to parameters of class
6027 P_GLOBAL, False for all other strings, also for parametric options
6028 and strings not belonging to any option.
6029***************************************************************************/
6030
6031bool lp_parameter_is_global(const char *pszParmName)
6032{
6033 int num = map_parameter(pszParmName);
6034
6035 if (num >= 0) {
6036 return (parm_table[num].p_class == P_GLOBAL);
6037 }
6038
6039 return False;
6040}
6041
6042/**************************************************************************
6043 Check whether the given name is the canonical name of a parameter.
6044 Returns False if it is not a valid parameter Name.
6045 For parametric options, True is returned.
6046**************************************************************************/
6047
6048bool lp_parameter_is_canonical(const char *parm_name)
6049{
6050 if (!lp_parameter_is_valid(parm_name)) {
6051 return False;
6052 }
6053
6054 return (map_parameter(parm_name) ==
6055 map_parameter_canonical(parm_name, NULL));
6056}
6057
6058/**************************************************************************
6059 Determine the canonical name for a parameter.
6060 Indicate when it is an inverse (boolean) synonym instead of a
6061 "usual" synonym.
6062**************************************************************************/
6063
6064bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6065 bool *inverse)
6066{
6067 int num;
6068
6069 if (!lp_parameter_is_valid(parm_name)) {
6070 *canon_parm = NULL;
6071 return False;
6072 }
6073
6074 num = map_parameter_canonical(parm_name, inverse);
6075 if (num < 0) {
6076 /* parametric option */
6077 *canon_parm = parm_name;
6078 } else {
6079 *canon_parm = parm_table[num].label;
6080 }
6081
6082 return True;
6083
6084}
6085
6086/**************************************************************************
6087 Determine the canonical name for a parameter.
6088 Turn the value given into the inverse boolean expression when
6089 the synonym is an invers boolean synonym.
6090
6091 Return True if parm_name is a valid parameter name and
6092 in case it is an invers boolean synonym, if the val string could
6093 successfully be converted to the reverse bool.
6094 Return false in all other cases.
6095**************************************************************************/
6096
6097bool lp_canonicalize_parameter_with_value(const char *parm_name,
6098 const char *val,
6099 const char **canon_parm,
6100 const char **canon_val)
6101{
6102 int num;
6103 bool inverse;
6104
6105 if (!lp_parameter_is_valid(parm_name)) {
6106 *canon_parm = NULL;
6107 *canon_val = NULL;
6108 return False;
6109 }
6110
6111 num = map_parameter_canonical(parm_name, &inverse);
6112 if (num < 0) {
6113 /* parametric option */
6114 *canon_parm = parm_name;
6115 *canon_val = val;
6116 } else {
6117 *canon_parm = parm_table[num].label;
6118 if (inverse) {
6119 if (!lp_invert_boolean(val, canon_val)) {
6120 *canon_val = NULL;
6121 return False;
6122 }
6123 } else {
6124 *canon_val = val;
6125 }
6126 }
6127
6128 return True;
6129}
6130
6131/***************************************************************************
6132 Map a parameter's string representation to something we can use.
6133 Returns False if the parameter string is not recognised, else TRUE.
6134***************************************************************************/
6135
6136static int map_parameter(const char *pszParmName)
6137{
6138 int iIndex;
6139
6140 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6141 return (-1);
6142
6143 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6144 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6145 return (iIndex);
6146
6147 /* Warn only if it isn't parametric option */
6148 if (strchr(pszParmName, ':') == NULL)
6149 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6150 /* We do return 'fail' for parametric options as well because they are
6151 stored in different storage
6152 */
6153 return (-1);
6154}
6155
6156/***************************************************************************
6157 Map a parameter's string representation to the index of the canonical
6158 form of the parameter (it might be a synonym).
6159 Returns -1 if the parameter string is not recognised.
6160***************************************************************************/
6161
6162static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6163{
6164 int parm_num, canon_num;
6165 bool loc_inverse = False;
6166
6167 parm_num = map_parameter(pszParmName);
6168 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6169 /* invalid, parametric or no canidate for synonyms ... */
6170 goto done;
6171 }
6172
6173 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6174 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6175 parm_num = canon_num;
6176 goto done;
6177 }
6178 }
6179
6180done:
6181 if (inverse != NULL) {
6182 *inverse = loc_inverse;
6183 }
6184 return parm_num;
6185}
6186
6187/***************************************************************************
6188 return true if parameter number parm1 is a synonym of parameter
6189 number parm2 (parm2 being the principal name).
6190 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6191 False otherwise.
6192***************************************************************************/
6193
6194static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6195{
6196 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6197 (parm_table[parm1].flags & FLAG_HIDE) &&
6198 !(parm_table[parm2].flags & FLAG_HIDE))
6199 {
6200 if (inverse != NULL) {
6201 if ((parm_table[parm1].type == P_BOOLREV) &&
6202 (parm_table[parm2].type == P_BOOL))
6203 {
6204 *inverse = True;
6205 } else {
6206 *inverse = False;
6207 }
6208 }
6209 return True;
6210 }
6211 return False;
6212}
6213
6214/***************************************************************************
6215 Show one parameter's name, type, [values,] and flags.
6216 (helper functions for show_parameter_list)
6217***************************************************************************/
6218
6219static void show_parameter(int parmIndex)
6220{
6221 int enumIndex, flagIndex;
6222 int parmIndex2;
6223 bool hadFlag;
6224 bool hadSyn;
6225 bool inverse;
6226 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6227 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6228 "P_ENUM", "P_SEP"};
6229 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6230 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6231 FLAG_HIDE, FLAG_DOS_STRING};
6232 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6233 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6234 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6235
6236 printf("%s=%s", parm_table[parmIndex].label,
6237 type[parm_table[parmIndex].type]);
6238 if (parm_table[parmIndex].type == P_ENUM) {
6239 printf(",");
6240 for (enumIndex=0;
6241 parm_table[parmIndex].enum_list[enumIndex].name;
6242 enumIndex++)
6243 {
6244 printf("%s%s",
6245 enumIndex ? "|" : "",
6246 parm_table[parmIndex].enum_list[enumIndex].name);
6247 }
6248 }
6249 printf(",");
6250 hadFlag = False;
6251 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6252 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6253 printf("%s%s",
6254 hadFlag ? "|" : "",
6255 flag_names[flagIndex]);
6256 hadFlag = True;
6257 }
6258 }
6259
6260 /* output synonyms */
6261 hadSyn = False;
6262 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6263 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6264 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6265 parm_table[parmIndex2].label);
6266 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6267 if (!hadSyn) {
6268 printf(" (synonyms: ");
6269 hadSyn = True;
6270 } else {
6271 printf(", ");
6272 }
6273 printf("%s%s", parm_table[parmIndex2].label,
6274 inverse ? "[i]" : "");
6275 }
6276 }
6277 if (hadSyn) {
6278 printf(")");
6279 }
6280
6281 printf("\n");
6282}
6283
6284/***************************************************************************
6285 Show all parameter's name, type, [values,] and flags.
6286***************************************************************************/
6287
6288void show_parameter_list(void)
6289{
6290 int classIndex, parmIndex;
6291 const char *section_names[] = { "local", "global", NULL};
6292
6293 for (classIndex=0; section_names[classIndex]; classIndex++) {
6294 printf("[%s]\n", section_names[classIndex]);
6295 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6296 if (parm_table[parmIndex].p_class == classIndex) {
6297 show_parameter(parmIndex);
6298 }
6299 }
6300 }
6301}
6302
6303/***************************************************************************
6304 Set a boolean variable from the text value stored in the passed string.
6305 Returns True in success, False if the passed string does not correctly
6306 represent a boolean.
6307***************************************************************************/
6308
6309static bool set_boolean(bool *pb, const char *pszParmValue)
6310{
6311 bool bRetval;
6312 bool value;
6313
6314 bRetval = True;
6315 value = False;
6316 if (strwicmp(pszParmValue, "yes") == 0 ||
6317 strwicmp(pszParmValue, "true") == 0 ||
6318 strwicmp(pszParmValue, "1") == 0)
6319 value = True;
6320 else if (strwicmp(pszParmValue, "no") == 0 ||
6321 strwicmp(pszParmValue, "False") == 0 ||
6322 strwicmp(pszParmValue, "0") == 0)
6323 value = False;
6324 else {
6325 DEBUG(2,
6326 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
6327 pszParmValue));
6328 bRetval = False;
6329 }
6330
6331 if ((pb != NULL) && (bRetval != False)) {
6332 *pb = value;
6333 }
6334
6335 return (bRetval);
6336}
6337
6338
6339/***************************************************************************
6340 Check if a given string correctly represents a boolean value.
6341***************************************************************************/
6342
6343bool lp_string_is_valid_boolean(const char *parm_value)
6344{
6345 return set_boolean(NULL, parm_value);
6346}
6347
6348/***************************************************************************
6349 Get the standard string representation of a boolean value ("yes" or "no")
6350***************************************************************************/
6351
6352static const char *get_boolean(bool bool_value)
6353{
6354 static const char *yes_str = "yes";
6355 static const char *no_str = "no";
6356
6357 return (bool_value ? yes_str : no_str);
6358}
6359
6360/***************************************************************************
6361 Provide the string of the negated boolean value associated to the boolean
6362 given as a string. Returns False if the passed string does not correctly
6363 represent a boolean.
6364***************************************************************************/
6365
6366bool lp_invert_boolean(const char *str, const char **inverse_str)
6367{
6368 bool val;
6369
6370 if (!set_boolean(&val, str)) {
6371 return False;
6372 }
6373
6374 *inverse_str = get_boolean(!val);
6375 return True;
6376}
6377
6378/***************************************************************************
6379 Provide the canonical string representation of a boolean value given
6380 as a string. Return True on success, False if the string given does
6381 not correctly represent a boolean.
6382***************************************************************************/
6383
6384bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6385{
6386 bool val;
6387
6388 if (!set_boolean(&val, str)) {
6389 return False;
6390 }
6391
6392 *canon_str = get_boolean(val);
6393 return True;
6394}
6395
6396/***************************************************************************
6397Find a service by name. Otherwise works like get_service.
6398***************************************************************************/
6399
6400static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6401{
6402 int iService = -1;
6403 char *canon_name;
6404 TDB_DATA data;
6405
6406 if (ServiceHash == NULL) {
6407 return -1;
6408 }
6409
6410 canon_name = canonicalize_servicename(pszServiceName);
6411
6412 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6413
6414 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6415 iService = *(int *)data.dptr;
6416 }
6417
6418 TALLOC_FREE(canon_name);
6419
6420 if ((iService != -1) && (LP_SNUM_OK(iService))
6421 && (pserviceDest != NULL)) {
6422 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6423 }
6424
6425 return (iService);
6426}
6427
6428/***************************************************************************
6429 Copy a service structure to another.
6430 If pcopymapDest is NULL then copy all fields
6431***************************************************************************/
6432
6433static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6434 struct bitmap *pcopymapDest)
6435{
6436 int i;
6437 bool bcopyall = (pcopymapDest == NULL);
6438 struct param_opt_struct *data, *pdata, *paramo;
6439 bool not_added;
6440
6441 for (i = 0; parm_table[i].label; i++)
6442 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6443 (bcopyall || bitmap_query(pcopymapDest,i))) {
6444 void *def_ptr = parm_table[i].ptr;
6445 void *src_ptr =
6446 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6447 &sDefault);
6448 void *dest_ptr =
6449 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6450 &sDefault);
6451
6452 switch (parm_table[i].type) {
6453 case P_BOOL:
6454 case P_BOOLREV:
6455 *(bool *)dest_ptr = *(bool *)src_ptr;
6456 break;
6457
6458 case P_INTEGER:
6459 case P_ENUM:
6460 case P_OCTAL:
6461 *(int *)dest_ptr = *(int *)src_ptr;
6462 break;
6463
6464 case P_CHAR:
6465 *(char *)dest_ptr = *(char *)src_ptr;
6466 break;
6467
6468 case P_STRING:
6469 string_set((char **)dest_ptr,
6470 *(char **)src_ptr);
6471 break;
6472
6473 case P_USTRING:
6474 string_set((char **)dest_ptr,
6475 *(char **)src_ptr);
6476 strupper_m(*(char **)dest_ptr);
6477 break;
6478 case P_LIST:
6479 TALLOC_FREE(*((char ***)dest_ptr));
6480 str_list_copy(NULL, (char ***)dest_ptr,
6481 *(const char ***)src_ptr);
6482 break;
6483 default:
6484 break;
6485 }
6486 }
6487
6488 if (bcopyall) {
6489 init_copymap(pserviceDest);
6490 if (pserviceSource->copymap)
6491 bitmap_copy(pserviceDest->copymap,
6492 pserviceSource->copymap);
6493 }
6494
6495 data = pserviceSource->param_opt;
6496 while (data) {
6497 not_added = True;
6498 pdata = pserviceDest->param_opt;
6499 /* Traverse destination */
6500 while (pdata) {
6501 /* If we already have same option, override it */
6502 if (strwicmp(pdata->key, data->key) == 0) {
6503 string_free(&pdata->value);
6504 TALLOC_FREE(data->list);
6505 pdata->value = SMB_STRDUP(data->value);
6506 not_added = False;
6507 break;
6508 }
6509 pdata = pdata->next;
6510 }
6511 if (not_added) {
6512 paramo = SMB_XMALLOC_P(struct param_opt_struct);
6513 paramo->key = SMB_STRDUP(data->key);
6514 paramo->value = SMB_STRDUP(data->value);
6515 paramo->list = NULL;
6516 DLIST_ADD(pserviceDest->param_opt, paramo);
6517 }
6518 data = data->next;
6519 }
6520}
6521
6522/***************************************************************************
6523Check a service for consistency. Return False if the service is in any way
6524incomplete or faulty, else True.
6525***************************************************************************/
6526
6527bool service_ok(int iService)
6528{
6529 bool bRetval;
6530
6531 bRetval = True;
6532 if (ServicePtrs[iService]->szService[0] == '\0') {
6533 DEBUG(0, ("The following message indicates an internal error:\n"));
6534 DEBUG(0, ("No service name in service entry.\n"));
6535 bRetval = False;
6536 }
6537
6538 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6539 /* I can't see why you'd want a non-printable printer service... */
6540 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6541 if (!ServicePtrs[iService]->bPrint_ok) {
6542 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6543 ServicePtrs[iService]->szService));
6544 ServicePtrs[iService]->bPrint_ok = True;
6545 }
6546 /* [printers] service must also be non-browsable. */
6547 if (ServicePtrs[iService]->bBrowseable)
6548 ServicePtrs[iService]->bBrowseable = False;
6549 }
6550
6551 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6552 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6553 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6554 ) {
6555 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6556 ServicePtrs[iService]->szService));
6557 ServicePtrs[iService]->bAvailable = False;
6558 }
6559
6560 /* If a service is flagged unavailable, log the fact at level 1. */
6561 if (!ServicePtrs[iService]->bAvailable)
6562 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6563 ServicePtrs[iService]->szService));
6564
6565 return (bRetval);
6566}
6567
6568static struct smbconf_ctx *lp_smbconf_ctx(void)
6569{
6570 WERROR werr;
6571 static struct smbconf_ctx *conf_ctx = NULL;
6572
6573 if (conf_ctx == NULL) {
6574 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6575 if (!W_ERROR_IS_OK(werr)) {
6576 DEBUG(1, ("error initializing registry configuration: "
6577 "%s\n", dos_errstr(werr)));
6578 conf_ctx = NULL;
6579 }
6580 }
6581
6582 return conf_ctx;
6583}
6584
6585static bool process_registry_service(struct smbconf_service *service)
6586{
6587 uint32_t count;
6588 bool ret;
6589
6590 if (service == NULL) {
6591 return false;
6592 }
6593
6594 ret = do_section(service->name, NULL);
6595 if (ret != true) {
6596 return false;
6597 }
6598 for (count = 0; count < service->num_params; count++) {
6599 ret = do_parameter(service->param_names[count],
6600 service->param_values[count],
6601 NULL);
6602 if (ret != true) {
6603 return false;
6604 }
6605 }
6606 return true;
6607}
6608
6609/*
6610 * process_registry_globals
6611 */
6612static bool process_registry_globals(void)
6613{
6614 WERROR werr;
6615 struct smbconf_service *service = NULL;
6616 TALLOC_CTX *mem_ctx = talloc_stackframe();
6617 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6618 bool ret = false;
6619
6620 if (conf_ctx == NULL) {
6621 goto done;
6622 }
6623
6624 ret = do_parameter("registry shares", "yes", NULL);
6625 if (!ret) {
6626 goto done;
6627 }
6628
6629 if (!smbconf_share_exists(conf_ctx, GLOBAL_NAME)) {
6630 /* nothing to read from the registry yet but make sure lp_load
6631 * doesn't return false */
6632 ret = true;
6633 goto done;
6634 }
6635
6636 werr = smbconf_get_share(conf_ctx, mem_ctx, GLOBAL_NAME, &service);
6637 if (!W_ERROR_IS_OK(werr)) {
6638 goto done;
6639 }
6640
6641 ret = process_registry_service(service);
6642 if (!ret) {
6643 goto done;
6644 }
6645
6646 /* store the csn */
6647 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6648
6649done:
6650 TALLOC_FREE(mem_ctx);
6651 return ret;
6652}
6653
6654static bool process_registry_shares(void)
6655{
6656 WERROR werr;
6657 uint32_t count;
6658 struct smbconf_service **service = NULL;
6659 uint32_t num_shares = 0;
6660 TALLOC_CTX *mem_ctx = talloc_stackframe();
6661 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6662 bool ret = false;
6663
6664 if (conf_ctx == NULL) {
6665 goto done;
6666 }
6667
6668 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6669 if (!W_ERROR_IS_OK(werr)) {
6670 goto done;
6671 }
6672
6673 ret = true;
6674
6675 for (count = 0; count < num_shares; count++) {
6676 if (strequal(service[count]->name, GLOBAL_NAME)) {
6677 continue;
6678 }
6679 ret = process_registry_service(service[count]);
6680 if (!ret) {
6681 goto done;
6682 }
6683 }
6684
6685 /* store the csn */
6686 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6687
6688done:
6689 TALLOC_FREE(mem_ctx);
6690 return ret;
6691}
6692
6693static struct file_lists {
6694 struct file_lists *next;
6695 char *name;
6696 char *subfname;
6697 time_t modtime;
6698} *file_lists = NULL;
6699
6700/*******************************************************************
6701 Keep a linked list of all config files so we know when one has changed
6702 it's date and needs to be reloaded.
6703********************************************************************/
6704
6705static void add_to_file_list(const char *fname, const char *subfname)
6706{
6707 struct file_lists *f = file_lists;
6708
6709 while (f) {
6710 if (f->name && !strcmp(f->name, fname))
6711 break;
6712 f = f->next;
6713 }
6714
6715 if (!f) {
6716 f = SMB_MALLOC_P(struct file_lists);
6717 if (!f)
6718 return;
6719 f->next = file_lists;
6720 f->name = SMB_STRDUP(fname);
6721 if (!f->name) {
6722 SAFE_FREE(f);
6723 return;
6724 }
6725 f->subfname = SMB_STRDUP(subfname);
6726 if (!f->subfname) {
6727 SAFE_FREE(f);
6728 return;
6729 }
6730 file_lists = f;
6731 f->modtime = file_modtime(subfname);
6732 } else {
6733 time_t t = file_modtime(subfname);
6734 if (t)
6735 f->modtime = t;
6736 }
6737}
6738
6739/**
6740 * Utility function for outsiders to check if we're running on registry.
6741 */
6742bool lp_config_backend_is_registry(void)
6743{
6744 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
6745}
6746
6747/**
6748 * Utility function to check if the config backend is FILE.
6749 */
6750bool lp_config_backend_is_file(void)
6751{
6752 return (lp_config_backend() == CONFIG_BACKEND_FILE);
6753}
6754
6755/*******************************************************************
6756 Check if a config file has changed date.
6757********************************************************************/
6758
6759bool lp_file_list_changed(void)
6760{
6761 struct file_lists *f = file_lists;
6762
6763 DEBUG(6, ("lp_file_list_changed()\n"));
6764
6765 if (lp_config_backend_is_registry()) {
6766 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6767
6768 if (conf_ctx == NULL) {
6769 return false;
6770 }
6771 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL)) {
6772 DEBUGADD(6, ("registry config changed\n"));
6773 return true;
6774 }
6775 }
6776
6777 while (f) {
6778 char *n2 = NULL;
6779 time_t mod_time;
6780
6781 n2 = alloc_sub_basic(get_current_username(),
6782 current_user_info.domain,
6783 f->name);
6784 if (!n2) {
6785 return false;
6786 }
6787 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
6788 f->name, n2, ctime(&f->modtime)));
6789
6790 mod_time = file_modtime(n2);
6791
6792 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
6793 DEBUGADD(6,
6794 ("file %s modified: %s\n", n2,
6795 ctime(&mod_time)));
6796 f->modtime = mod_time;
6797 SAFE_FREE(f->subfname);
6798 f->subfname = n2; /* Passing ownership of
6799 return from alloc_sub_basic
6800 above. */
6801 return true;
6802 }
6803 SAFE_FREE(n2);
6804 f = f->next;
6805 }
6806 return (False);
6807}
6808
6809
6810/***************************************************************************
6811 Run standard_sub_basic on netbios name... needed because global_myname
6812 is not accessed through any lp_ macro.
6813 Note: We must *NOT* use string_set() here as ptr points to global_myname.
6814***************************************************************************/
6815
6816static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
6817{
6818 bool ret;
6819 char *netbios_name = alloc_sub_basic(get_current_username(),
6820 current_user_info.domain,
6821 pszParmValue);
6822
6823 ret = set_global_myname(netbios_name);
6824 SAFE_FREE(netbios_name);
6825 string_set(&Globals.szNetbiosName,global_myname());
6826
6827 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
6828 global_myname()));
6829
6830 return ret;
6831}
6832
6833static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
6834{
6835 if (strcmp(*ptr, pszParmValue) != 0) {
6836 string_set(ptr, pszParmValue);
6837 init_iconv();
6838 }
6839 return True;
6840}
6841
6842
6843
6844static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
6845{
6846 bool ret;
6847
6848 ret = set_global_myworkgroup(pszParmValue);
6849 string_set(&Globals.szWorkgroup,lp_workgroup());
6850
6851 return ret;
6852}
6853
6854static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
6855{
6856 bool ret;
6857
6858 ret = set_global_scope(pszParmValue);
6859 string_set(&Globals.szNetbiosScope,global_scope());
6860
6861 return ret;
6862}
6863
6864static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
6865{
6866 TALLOC_FREE(Globals.szNetbiosAliases);
6867 Globals.szNetbiosAliases = str_list_make(talloc_autofree_context(), pszParmValue, NULL);
6868 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
6869}
6870
6871/***************************************************************************
6872 Handle the include operation.
6873***************************************************************************/
6874static bool bAllowIncludeRegistry = true;
6875
6876static bool handle_include(int snum, const char *pszParmValue, char **ptr)
6877{
6878 char *fname;
6879
6880 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
6881 if (!bAllowIncludeRegistry) {
6882 return true;
6883 }
6884 if (bInGlobalSection) {
6885 return process_registry_globals();
6886 } else {
6887 DEBUG(1, ("\"include = registry\" only effective "
6888 "in %s section\n", GLOBAL_NAME));
6889 return false;
6890 }
6891 }
6892
6893 fname = alloc_sub_basic(get_current_username(),
6894 current_user_info.domain,
6895 pszParmValue);
6896
6897 add_to_file_list(pszParmValue, fname);
6898
6899 string_set(ptr, fname);
6900
6901 if (file_exist(fname, NULL)) {
6902 bool ret = pm_process(fname, do_section, do_parameter, NULL);
6903 SAFE_FREE(fname);
6904 return ret;
6905 }
6906
6907 DEBUG(2, ("Can't find include file %s\n", fname));
6908 SAFE_FREE(fname);
6909 return true;
6910}
6911
6912/***************************************************************************
6913 Handle the interpretation of the copy parameter.
6914***************************************************************************/
6915
6916static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
6917{
6918 bool bRetval;
6919 int iTemp;
6920 struct service serviceTemp;
6921
6922 string_set(ptr, pszParmValue);
6923
6924 init_service(&serviceTemp);
6925
6926 bRetval = False;
6927
6928 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
6929
6930 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
6931 if (iTemp == iServiceIndex) {
6932 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
6933 } else {
6934 copy_service(ServicePtrs[iServiceIndex],
6935 &serviceTemp,
6936 ServicePtrs[iServiceIndex]->copymap);
6937 bRetval = True;
6938 }
6939 } else {
6940 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
6941 bRetval = False;
6942 }
6943
6944 free_service(&serviceTemp);
6945 return (bRetval);
6946}
6947
6948static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
6949{
6950 Globals.ldap_debug_level = lp_int(pszParmValue);
6951 init_ldap_debugging();
6952 return true;
6953}
6954
6955/***************************************************************************
6956 Handle idmap/non unix account uid and gid allocation parameters. The format of these
6957 parameters is:
6958
6959 [global]
6960
6961 idmap uid = 1000-1999
6962 idmap gid = 700-899
6963
6964 We only do simple parsing checks here. The strings are parsed into useful
6965 structures in the idmap daemon code.
6966
6967***************************************************************************/
6968
6969/* Some lp_ routines to return idmap [ug]id information */
6970
6971static uid_t idmap_uid_low, idmap_uid_high;
6972static gid_t idmap_gid_low, idmap_gid_high;
6973
6974bool lp_idmap_uid(uid_t *low, uid_t *high)
6975{
6976 if (idmap_uid_low == 0 || idmap_uid_high == 0)
6977 return False;
6978
6979 if (low)
6980 *low = idmap_uid_low;
6981
6982 if (high)
6983 *high = idmap_uid_high;
6984
6985 return True;
6986}
6987
6988bool lp_idmap_gid(gid_t *low, gid_t *high)
6989{
6990 if (idmap_gid_low == 0 || idmap_gid_high == 0)
6991 return False;
6992
6993 if (low)
6994 *low = idmap_gid_low;
6995
6996 if (high)
6997 *high = idmap_gid_high;
6998
6999 return True;
7000}
7001
7002/* Do some simple checks on "idmap [ug]id" parameter values */
7003
7004static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7005{
7006 uint32 low, high;
7007
7008 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7009 return False;
7010
7011 /* Parse OK */
7012
7013 string_set(ptr, pszParmValue);
7014
7015 idmap_uid_low = low;
7016 idmap_uid_high = high;
7017
7018 return True;
7019}
7020
7021static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7022{
7023 uint32 low, high;
7024
7025 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7026 return False;
7027
7028 /* Parse OK */
7029
7030 string_set(ptr, pszParmValue);
7031
7032 idmap_gid_low = low;
7033 idmap_gid_high = high;
7034
7035 return True;
7036}
7037
7038/***************************************************************************
7039 Handle the DEBUG level list.
7040***************************************************************************/
7041
7042static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7043{
7044 string_set(ptr, pszParmValueIn);
7045 return debug_parse_levels(pszParmValueIn);
7046}
7047
7048/***************************************************************************
7049 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7050***************************************************************************/
7051
7052static const char *append_ldap_suffix( const char *str )
7053{
7054 const char *suffix_string;
7055
7056
7057 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7058 Globals.szLdapSuffix );
7059 if ( !suffix_string ) {
7060 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7061 return "";
7062 }
7063
7064 return suffix_string;
7065}
7066
7067const char *lp_ldap_machine_suffix(void)
7068{
7069 if (Globals.szLdapMachineSuffix[0])
7070 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7071
7072 return lp_string(Globals.szLdapSuffix);
7073}
7074
7075const char *lp_ldap_user_suffix(void)
7076{
7077 if (Globals.szLdapUserSuffix[0])
7078 return append_ldap_suffix(Globals.szLdapUserSuffix);
7079
7080 return lp_string(Globals.szLdapSuffix);
7081}
7082
7083const char *lp_ldap_group_suffix(void)
7084{
7085 if (Globals.szLdapGroupSuffix[0])
7086 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7087
7088 return lp_string(Globals.szLdapSuffix);
7089}
7090
7091const char *lp_ldap_idmap_suffix(void)
7092{
7093 if (Globals.szLdapIdmapSuffix[0])
7094 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7095
7096 return lp_string(Globals.szLdapSuffix);
7097}
7098
7099/****************************************************************************
7100 set the value for a P_ENUM
7101 ***************************************************************************/
7102
7103static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7104 int *ptr )
7105{
7106 int i;
7107
7108 for (i = 0; parm->enum_list[i].name; i++) {
7109 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7110 *ptr = parm->enum_list[i].value;
7111 return;
7112 }
7113 }
7114 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7115 pszParmValue, parm->label));
7116}
7117
7118/***************************************************************************
7119***************************************************************************/
7120
7121static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7122{
7123 static int parm_num = -1;
7124 struct service *s;
7125
7126 if ( parm_num == -1 )
7127 parm_num = map_parameter( "printing" );
7128
7129 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7130
7131 if ( snum < 0 )
7132 s = &sDefault;
7133 else
7134 s = ServicePtrs[snum];
7135
7136 init_printer_values( s );
7137
7138 return True;
7139}
7140
7141
7142/***************************************************************************
7143 Initialise a copymap.
7144***************************************************************************/
7145
7146static void init_copymap(struct service *pservice)
7147{
7148 int i;
7149 if (pservice->copymap) {
7150 bitmap_free(pservice->copymap);
7151 }
7152 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7153 if (!pservice->copymap)
7154 DEBUG(0,
7155 ("Couldn't allocate copymap!! (size %d)\n",
7156 (int)NUMPARAMETERS));
7157 else
7158 for (i = 0; i < NUMPARAMETERS; i++)
7159 bitmap_set(pservice->copymap, i);
7160}
7161
7162/***************************************************************************
7163 Return the local pointer to a parameter given the service number and the
7164 pointer into the default structure.
7165***************************************************************************/
7166
7167void *lp_local_ptr(int snum, void *ptr)
7168{
7169 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
7170}
7171
7172/***************************************************************************
7173 Process a parameter for a particular service number. If snum < 0
7174 then assume we are in the globals.
7175***************************************************************************/
7176
7177bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7178{
7179 int parmnum, i;
7180 void *parm_ptr = NULL; /* where we are going to store the result */
7181 void *def_ptr = NULL;
7182 struct param_opt_struct *paramo, *data;
7183 bool not_added;
7184
7185 parmnum = map_parameter(pszParmName);
7186
7187 if (parmnum < 0) {
7188 TALLOC_CTX *frame;
7189
7190 if (strchr(pszParmName, ':') == NULL) {
7191 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7192 pszParmName));
7193 return (True);
7194 }
7195
7196 /*
7197 * We've got a parametric option
7198 */
7199
7200 frame = talloc_stackframe();
7201
7202 not_added = True;
7203 data = (snum < 0)
7204 ? Globals.param_opt : ServicePtrs[snum]->param_opt;
7205 /* Traverse destination */
7206 while (data) {
7207 /* If we already have same option, override it */
7208 if (strwicmp(data->key, pszParmName) == 0) {
7209 string_free(&data->value);
7210 TALLOC_FREE(data->list);
7211 data->value = SMB_STRDUP(pszParmValue);
7212 not_added = False;
7213 break;
7214 }
7215 data = data->next;
7216 }
7217 if (not_added) {
7218 paramo = SMB_XMALLOC_P(struct param_opt_struct);
7219 paramo->key = SMB_STRDUP(pszParmName);
7220 paramo->value = SMB_STRDUP(pszParmValue);
7221 paramo->list = NULL;
7222 if (snum < 0) {
7223 DLIST_ADD(Globals.param_opt, paramo);
7224 } else {
7225 DLIST_ADD(ServicePtrs[snum]->param_opt,
7226 paramo);
7227 }
7228 }
7229
7230 TALLOC_FREE(frame);
7231 return (True);
7232 }
7233
7234 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7235 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7236 pszParmName));
7237 }
7238
7239 def_ptr = parm_table[parmnum].ptr;
7240
7241 /* we might point at a service, the default service or a global */
7242 if (snum < 0) {
7243 parm_ptr = def_ptr;
7244 } else {
7245 if (parm_table[parmnum].p_class == P_GLOBAL) {
7246 DEBUG(0,
7247 ("Global parameter %s found in service section!\n",
7248 pszParmName));
7249 return (True);
7250 }
7251 parm_ptr =
7252 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
7253 &sDefault);
7254 }
7255
7256 if (snum >= 0) {
7257 if (!ServicePtrs[snum]->copymap)
7258 init_copymap(ServicePtrs[snum]);
7259
7260 /* this handles the aliases - set the copymap for other entries with
7261 the same data pointer */
7262 for (i = 0; parm_table[i].label; i++)
7263 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7264 bitmap_clear(ServicePtrs[snum]->copymap, i);
7265 }
7266
7267 /* if it is a special case then go ahead */
7268 if (parm_table[parmnum].special) {
7269 return parm_table[parmnum].special(snum, pszParmValue,
7270 (char **)parm_ptr);
7271 }
7272
7273 /* now switch on the type of variable it is */
7274 switch (parm_table[parmnum].type)
7275 {
7276 case P_BOOL:
7277 *(bool *)parm_ptr = lp_bool(pszParmValue);
7278 break;
7279
7280 case P_BOOLREV:
7281 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7282 break;
7283
7284 case P_INTEGER:
7285 *(int *)parm_ptr = lp_int(pszParmValue);
7286 break;
7287
7288 case P_CHAR:
7289 *(char *)parm_ptr = *pszParmValue;
7290 break;
7291
7292 case P_OCTAL:
7293 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7294 if ( i != 1 ) {
7295 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7296 }
7297 break;
7298
7299 case P_LIST:
7300 TALLOC_FREE(*((char ***)parm_ptr));
7301 *(char ***)parm_ptr = str_list_make(
7302 talloc_autofree_context(), pszParmValue, NULL);
7303 break;
7304
7305 case P_STRING:
7306 string_set((char **)parm_ptr, pszParmValue);
7307 break;
7308
7309 case P_USTRING:
7310 string_set((char **)parm_ptr, pszParmValue);
7311 strupper_m(*(char **)parm_ptr);
7312 break;
7313
7314 case P_ENUM:
7315 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7316 break;
7317 case P_SEP:
7318 break;
7319 }
7320
7321 return (True);
7322}
7323
7324/***************************************************************************
7325 Process a parameter.
7326***************************************************************************/
7327
7328static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7329 void *userdata)
7330{
7331 if (!bInGlobalSection && bGlobalOnly)
7332 return (True);
7333
7334 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7335
7336 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7337 pszParmName, pszParmValue));
7338}
7339
7340/***************************************************************************
7341 Print a parameter of the specified type.
7342***************************************************************************/
7343
7344static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7345{
7346 int i;
7347 switch (p->type)
7348 {
7349 case P_ENUM:
7350 for (i = 0; p->enum_list[i].name; i++) {
7351 if (*(int *)ptr == p->enum_list[i].value) {
7352 fprintf(f, "%s",
7353 p->enum_list[i].name);
7354 break;
7355 }
7356 }
7357 break;
7358
7359 case P_BOOL:
7360 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7361 break;
7362
7363 case P_BOOLREV:
7364 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7365 break;
7366
7367 case P_INTEGER:
7368 fprintf(f, "%d", *(int *)ptr);
7369 break;
7370
7371 case P_CHAR:
7372 fprintf(f, "%c", *(char *)ptr);
7373 break;
7374
7375 case P_OCTAL: {
7376 char *o = octal_string(*(int *)ptr);
7377 fprintf(f, "%s", o);
7378 TALLOC_FREE(o);
7379 break;
7380 }
7381
7382 case P_LIST:
7383 if ((char ***)ptr && *(char ***)ptr) {
7384 char **list = *(char ***)ptr;
7385 for (; *list; list++) {
7386 /* surround strings with whitespace in double quotes */
7387 if ( strchr_m( *list, ' ' ) )
7388 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7389 else
7390 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7391 }
7392 }
7393 break;
7394
7395 case P_STRING:
7396 case P_USTRING:
7397 if (*(char **)ptr) {
7398 fprintf(f, "%s", *(char **)ptr);
7399 }
7400 break;
7401 case P_SEP:
7402 break;
7403 }
7404}
7405
7406/***************************************************************************
7407 Check if two parameters are equal.
7408***************************************************************************/
7409
7410static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7411{
7412 switch (type) {
7413 case P_BOOL:
7414 case P_BOOLREV:
7415 return (*((bool *)ptr1) == *((bool *)ptr2));
7416
7417 case P_INTEGER:
7418 case P_ENUM:
7419 case P_OCTAL:
7420 return (*((int *)ptr1) == *((int *)ptr2));
7421
7422 case P_CHAR:
7423 return (*((char *)ptr1) == *((char *)ptr2));
7424
7425 case P_LIST:
7426 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
7427
7428 case P_STRING:
7429 case P_USTRING:
7430 {
7431 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7432 if (p1 && !*p1)
7433 p1 = NULL;
7434 if (p2 && !*p2)
7435 p2 = NULL;
7436 return (p1 == p2 || strequal(p1, p2));
7437 }
7438 case P_SEP:
7439 break;
7440 }
7441 return (False);
7442}
7443
7444/***************************************************************************
7445 Initialize any local varients in the sDefault table.
7446***************************************************************************/
7447
7448void init_locals(void)
7449{
7450 /* None as yet. */
7451}
7452
7453/***************************************************************************
7454 Process a new section (service). At this stage all sections are services.
7455 Later we'll have special sections that permit server parameters to be set.
7456 Returns True on success, False on failure.
7457***************************************************************************/
7458
7459static bool do_section(const char *pszSectionName, void *userdata)
7460{
7461 bool bRetval;
7462 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7463 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7464 bRetval = False;
7465
7466 /* if we were in a global section then do the local inits */
7467 if (bInGlobalSection && !isglobal)
7468 init_locals();
7469
7470 /* if we've just struck a global section, note the fact. */
7471 bInGlobalSection = isglobal;
7472
7473 /* check for multiple global sections */
7474 if (bInGlobalSection) {
7475 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7476 return (True);
7477 }
7478
7479 if (!bInGlobalSection && bGlobalOnly)
7480 return (True);
7481
7482 /* if we have a current service, tidy it up before moving on */
7483 bRetval = True;
7484
7485 if (iServiceIndex >= 0)
7486 bRetval = service_ok(iServiceIndex);
7487
7488 /* if all is still well, move to the next record in the services array */
7489 if (bRetval) {
7490 /* We put this here to avoid an odd message order if messages are */
7491 /* issued by the post-processing of a previous section. */
7492 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7493
7494 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7495 < 0) {
7496 DEBUG(0, ("Failed to add a new service\n"));
7497 return (False);
7498 }
7499 }
7500
7501 return (bRetval);
7502}
7503
7504
7505/***************************************************************************
7506 Determine if a partcular base parameter is currentl set to the default value.
7507***************************************************************************/
7508
7509static bool is_default(int i)
7510{
7511 if (!defaults_saved)
7512 return False;
7513 switch (parm_table[i].type) {
7514 case P_LIST:
7515 return str_list_compare (parm_table[i].def.lvalue,
7516 *(char ***)parm_table[i].ptr);
7517 case P_STRING:
7518 case P_USTRING:
7519 return strequal(parm_table[i].def.svalue,
7520 *(char **)parm_table[i].ptr);
7521 case P_BOOL:
7522 case P_BOOLREV:
7523 return parm_table[i].def.bvalue ==
7524 *(bool *)parm_table[i].ptr;
7525 case P_CHAR:
7526 return parm_table[i].def.cvalue ==
7527 *(char *)parm_table[i].ptr;
7528 case P_INTEGER:
7529 case P_OCTAL:
7530 case P_ENUM:
7531 return parm_table[i].def.ivalue ==
7532 *(int *)parm_table[i].ptr;
7533 case P_SEP:
7534 break;
7535 }
7536 return False;
7537}
7538
7539/***************************************************************************
7540Display the contents of the global structure.
7541***************************************************************************/
7542
7543static void dump_globals(FILE *f)
7544{
7545 int i;
7546 struct param_opt_struct *data;
7547
7548 fprintf(f, "[global]\n");
7549
7550 for (i = 0; parm_table[i].label; i++)
7551 if (parm_table[i].p_class == P_GLOBAL &&
7552 parm_table[i].ptr &&
7553 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7554 if (defaults_saved && is_default(i))
7555 continue;
7556 fprintf(f, "\t%s = ", parm_table[i].label);
7557 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7558 fprintf(f, "\n");
7559 }
7560 if (Globals.param_opt != NULL) {
7561 data = Globals.param_opt;
7562 while(data) {
7563 fprintf(f, "\t%s = %s\n", data->key, data->value);
7564 data = data->next;
7565 }
7566 }
7567
7568}
7569
7570/***************************************************************************
7571 Return True if a local parameter is currently set to the global default.
7572***************************************************************************/
7573
7574bool lp_is_default(int snum, struct parm_struct *parm)
7575{
7576 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7577
7578 return equal_parameter(parm->type,
7579 ((char *)ServicePtrs[snum]) + pdiff,
7580 ((char *)&sDefault) + pdiff);
7581}
7582
7583/***************************************************************************
7584 Display the contents of a single services record.
7585***************************************************************************/
7586
7587static void dump_a_service(struct service *pService, FILE * f)
7588{
7589 int i;
7590 struct param_opt_struct *data;
7591
7592 if (pService != &sDefault)
7593 fprintf(f, "[%s]\n", pService->szService);
7594
7595 for (i = 0; parm_table[i].label; i++) {
7596
7597 if (parm_table[i].p_class == P_LOCAL &&
7598 parm_table[i].ptr &&
7599 (*parm_table[i].label != '-') &&
7600 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7601 {
7602
7603 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7604
7605 if (pService == &sDefault) {
7606 if (defaults_saved && is_default(i))
7607 continue;
7608 } else {
7609 if (equal_parameter(parm_table[i].type,
7610 ((char *)pService) +
7611 pdiff,
7612 ((char *)&sDefault) +
7613 pdiff))
7614 continue;
7615 }
7616
7617 fprintf(f, "\t%s = ", parm_table[i].label);
7618 print_parameter(&parm_table[i],
7619 ((char *)pService) + pdiff, f);
7620 fprintf(f, "\n");
7621 }
7622 }
7623
7624 if (pService->param_opt != NULL) {
7625 data = pService->param_opt;
7626 while(data) {
7627 fprintf(f, "\t%s = %s\n", data->key, data->value);
7628 data = data->next;
7629 }
7630 }
7631}
7632
7633/***************************************************************************
7634 Display the contents of a parameter of a single services record.
7635***************************************************************************/
7636
7637bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7638{
7639 int i;
7640 bool result = False;
7641 parm_class p_class;
7642 unsigned flag = 0;
7643 fstring local_parm_name;
7644 char *parm_opt;
7645 const char *parm_opt_value;
7646
7647 /* check for parametrical option */
7648 fstrcpy( local_parm_name, parm_name);
7649 parm_opt = strchr( local_parm_name, ':');
7650
7651 if (parm_opt) {
7652 *parm_opt = '\0';
7653 parm_opt++;
7654 if (strlen(parm_opt)) {
7655 parm_opt_value = lp_parm_const_string( snum,
7656 local_parm_name, parm_opt, NULL);
7657 if (parm_opt_value) {
7658 printf( "%s\n", parm_opt_value);
7659 result = True;
7660 }
7661 }
7662 return result;
7663 }
7664
7665 /* check for a key and print the value */
7666 if (isGlobal) {
7667 p_class = P_GLOBAL;
7668 flag = FLAG_GLOBAL;
7669 } else
7670 p_class = P_LOCAL;
7671
7672 for (i = 0; parm_table[i].label; i++) {
7673 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7674 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7675 parm_table[i].ptr &&
7676 (*parm_table[i].label != '-') &&
7677 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7678 {
7679 void *ptr;
7680
7681 if (isGlobal) {
7682 ptr = parm_table[i].ptr;
7683 } else {
7684 struct service *pService = ServicePtrs[snum];
7685 ptr = ((char *)pService) +
7686 PTR_DIFF(parm_table[i].ptr, &sDefault);
7687 }
7688
7689 print_parameter(&parm_table[i],
7690 ptr, f);
7691 fprintf(f, "\n");
7692 result = True;
7693 break;
7694 }
7695 }
7696
7697 return result;
7698}
7699
7700/***************************************************************************
7701 Return info about the requested parameter (given as a string).
7702 Return NULL when the string is not a valid parameter name.
7703***************************************************************************/
7704
7705struct parm_struct *lp_get_parameter(const char *param_name)
7706{
7707 int num = map_parameter(param_name);
7708
7709 if (num < 0) {
7710 return NULL;
7711 }
7712
7713 return &parm_table[num];
7714}
7715
7716/***************************************************************************
7717 Return info about the next parameter in a service.
7718 snum==GLOBAL_SECTION_SNUM gives the globals.
7719 Return NULL when out of parameters.
7720***************************************************************************/
7721
7722struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7723{
7724 if (snum < 0) {
7725 /* do the globals */
7726 for (; parm_table[*i].label; (*i)++) {
7727 if (parm_table[*i].p_class == P_SEPARATOR)
7728 return &parm_table[(*i)++];
7729
7730 if (!parm_table[*i].ptr
7731 || (*parm_table[*i].label == '-'))
7732 continue;
7733
7734 if ((*i) > 0
7735 && (parm_table[*i].ptr ==
7736 parm_table[(*i) - 1].ptr))
7737 continue;
7738
7739 if (is_default(*i) && !allparameters)
7740 continue;
7741
7742 return &parm_table[(*i)++];
7743 }
7744 } else {
7745 struct service *pService = ServicePtrs[snum];
7746
7747 for (; parm_table[*i].label; (*i)++) {
7748 if (parm_table[*i].p_class == P_SEPARATOR)
7749 return &parm_table[(*i)++];
7750
7751 if (parm_table[*i].p_class == P_LOCAL &&
7752 parm_table[*i].ptr &&
7753 (*parm_table[*i].label != '-') &&
7754 ((*i) == 0 ||
7755 (parm_table[*i].ptr !=
7756 parm_table[(*i) - 1].ptr)))
7757 {
7758 int pdiff =
7759 PTR_DIFF(parm_table[*i].ptr,
7760 &sDefault);
7761
7762 if (allparameters ||
7763 !equal_parameter(parm_table[*i].type,
7764 ((char *)pService) +
7765 pdiff,
7766 ((char *)&sDefault) +
7767 pdiff))
7768 {
7769 return &parm_table[(*i)++];
7770 }
7771 }
7772 }
7773 }
7774
7775 return NULL;
7776}
7777
7778
7779#if 0
7780/***************************************************************************
7781 Display the contents of a single copy structure.
7782***************************************************************************/
7783static void dump_copy_map(bool *pcopymap)
7784{
7785 int i;
7786 if (!pcopymap)
7787 return;
7788
7789 printf("\n\tNon-Copied parameters:\n");
7790
7791 for (i = 0; parm_table[i].label; i++)
7792 if (parm_table[i].p_class == P_LOCAL &&
7793 parm_table[i].ptr && !pcopymap[i] &&
7794 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7795 {
7796 printf("\t\t%s\n", parm_table[i].label);
7797 }
7798}
7799#endif
7800
7801/***************************************************************************
7802 Return TRUE if the passed service number is within range.
7803***************************************************************************/
7804
7805bool lp_snum_ok(int iService)
7806{
7807 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
7808}
7809
7810/***************************************************************************
7811 Auto-load some home services.
7812***************************************************************************/
7813
7814static void lp_add_auto_services(char *str)
7815{
7816 char *s;
7817 char *p;
7818 int homes;
7819 char *saveptr;
7820
7821 if (!str)
7822 return;
7823
7824 s = SMB_STRDUP(str);
7825 if (!s)
7826 return;
7827
7828 homes = lp_servicenumber(HOMES_NAME);
7829
7830 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
7831 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
7832 char *home;
7833
7834 if (lp_servicenumber(p) >= 0)
7835 continue;
7836
7837 home = get_user_home_dir(talloc_tos(), p);
7838
7839 if (home && homes >= 0)
7840 lp_add_home(p, homes, p, home);
7841
7842 TALLOC_FREE(home);
7843 }
7844 SAFE_FREE(s);
7845}
7846
7847/***************************************************************************
7848 Auto-load one printer.
7849***************************************************************************/
7850
7851void lp_add_one_printer(const char *name, const char *comment, void *pdata)
7852{
7853 int printers = lp_servicenumber(PRINTERS_NAME);
7854 int i;
7855
7856 if (lp_servicenumber(name) < 0) {
7857 lp_add_printer(name, printers);
7858 if ((i = lp_servicenumber(name)) >= 0) {
7859 string_set(&ServicePtrs[i]->comment, comment);
7860 ServicePtrs[i]->autoloaded = True;
7861 }
7862 }
7863}
7864
7865/***************************************************************************
7866 Have we loaded a services file yet?
7867***************************************************************************/
7868
7869bool lp_loaded(void)
7870{
7871 return (bLoaded);
7872}
7873
7874/***************************************************************************
7875 Unload unused services.
7876***************************************************************************/
7877
7878void lp_killunused(bool (*snumused) (int))
7879{
7880 int i;
7881 for (i = 0; i < iNumServices; i++) {
7882 if (!VALID(i))
7883 continue;
7884
7885 /* don't kill autoloaded or usershare services */
7886 if ( ServicePtrs[i]->autoloaded ||
7887 ServicePtrs[i]->usershare == USERSHARE_VALID) {
7888 continue;
7889 }
7890
7891 if (!snumused || !snumused(i)) {
7892 free_service_byindex(i);
7893 }
7894 }
7895}
7896
7897/**
7898 * Kill all except autoloaded and usershare services - convenience wrapper
7899 */
7900void lp_kill_all_services(void)
7901{
7902 lp_killunused(NULL);
7903}
7904
7905/***************************************************************************
7906 Unload a service.
7907***************************************************************************/
7908
7909void lp_killservice(int iServiceIn)
7910{
7911 if (VALID(iServiceIn)) {
7912 free_service_byindex(iServiceIn);
7913 }
7914}
7915
7916/***************************************************************************
7917 Save the curent values of all global and sDefault parameters into the
7918 defaults union. This allows swat and testparm to show only the
7919 changed (ie. non-default) parameters.
7920***************************************************************************/
7921
7922static void lp_save_defaults(void)
7923{
7924 int i;
7925 for (i = 0; parm_table[i].label; i++) {
7926 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
7927 continue;
7928 switch (parm_table[i].type) {
7929 case P_LIST:
7930 str_list_copy(
7931 NULL, &(parm_table[i].def.lvalue),
7932 *(const char ***)parm_table[i].ptr);
7933 break;
7934 case P_STRING:
7935 case P_USTRING:
7936 if (parm_table[i].ptr) {
7937 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
7938 } else {
7939 parm_table[i].def.svalue = NULL;
7940 }
7941 break;
7942 case P_BOOL:
7943 case P_BOOLREV:
7944 parm_table[i].def.bvalue =
7945 *(bool *)parm_table[i].ptr;
7946 break;
7947 case P_CHAR:
7948 parm_table[i].def.cvalue =
7949 *(char *)parm_table[i].ptr;
7950 break;
7951 case P_INTEGER:
7952 case P_OCTAL:
7953 case P_ENUM:
7954 parm_table[i].def.ivalue =
7955 *(int *)parm_table[i].ptr;
7956 break;
7957 case P_SEP:
7958 break;
7959 }
7960 }
7961 defaults_saved = True;
7962}
7963
7964/*******************************************************************
7965 Set the server type we will announce as via nmbd.
7966********************************************************************/
7967
7968static const struct srv_role_tab {
7969 uint32 role;
7970 const char *role_str;
7971} srv_role_tab [] = {
7972 { ROLE_STANDALONE, "ROLE_STANDALONE" },
7973 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
7974 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
7975 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
7976 { 0, NULL }
7977};
7978
7979const char* server_role_str(uint32 role)
7980{
7981 int i = 0;
7982 for (i=0; srv_role_tab[i].role_str; i++) {
7983 if (role == srv_role_tab[i].role) {
7984 return srv_role_tab[i].role_str;
7985 }
7986 }
7987 return NULL;
7988}
7989
7990static void set_server_role(void)
7991{
7992 server_role = ROLE_STANDALONE;
7993
7994 switch (lp_security()) {
7995 case SEC_SHARE:
7996 if (lp_domain_logons())
7997 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
7998 break;
7999 case SEC_SERVER:
8000 if (lp_domain_logons())
8001 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8002 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8003 server_role = ROLE_STANDALONE;
8004 break;
8005 case SEC_DOMAIN:
8006 if (lp_domain_logons()) {
8007 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8008 server_role = ROLE_DOMAIN_BDC;
8009 break;
8010 }
8011 server_role = ROLE_DOMAIN_MEMBER;
8012 break;
8013 case SEC_ADS:
8014 if (lp_domain_logons()) {
8015 server_role = ROLE_DOMAIN_PDC;
8016 break;
8017 }
8018 server_role = ROLE_DOMAIN_MEMBER;
8019 break;
8020 case SEC_USER:
8021 if (lp_domain_logons()) {
8022
8023 if (Globals.iDomainMaster) /* auto or yes */
8024 server_role = ROLE_DOMAIN_PDC;
8025 else
8026 server_role = ROLE_DOMAIN_BDC;
8027 }
8028 break;
8029 default:
8030 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8031 break;
8032 }
8033
8034 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8035}
8036
8037/***********************************************************
8038 If we should send plaintext/LANMAN passwords in the clinet
8039************************************************************/
8040
8041static void set_allowed_client_auth(void)
8042{
8043 if (Globals.bClientNTLMv2Auth) {
8044 Globals.bClientLanManAuth = False;
8045 }
8046 if (!Globals.bClientLanManAuth) {
8047 Globals.bClientPlaintextAuth = False;
8048 }
8049}
8050
8051/***************************************************************************
8052 JRA.
8053 The following code allows smbd to read a user defined share file.
8054 Yes, this is my intent. Yes, I'm comfortable with that...
8055
8056 THE FOLLOWING IS SECURITY CRITICAL CODE.
8057
8058 It washes your clothes, it cleans your house, it guards you while you sleep...
8059 Do not f%^k with it....
8060***************************************************************************/
8061
8062#define MAX_USERSHARE_FILE_SIZE (10*1024)
8063
8064/***************************************************************************
8065 Check allowed stat state of a usershare file.
8066 Ensure we print out who is dicking with us so the admin can
8067 get their sorry ass fired.
8068***************************************************************************/
8069
8070static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8071{
8072 if (!S_ISREG(psbuf->st_mode)) {
8073 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8074 "not a regular file\n",
8075 fname, (unsigned int)psbuf->st_uid ));
8076 return False;
8077 }
8078
8079 /* Ensure this doesn't have the other write bit set. */
8080 if (psbuf->st_mode & S_IWOTH) {
8081 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8082 "public write. Refusing to allow as a usershare file.\n",
8083 fname, (unsigned int)psbuf->st_uid ));
8084 return False;
8085 }
8086
8087 /* Should be 10k or less. */
8088 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8089 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8090 "too large (%u) to be a user share file.\n",
8091 fname, (unsigned int)psbuf->st_uid,
8092 (unsigned int)psbuf->st_size ));
8093 return False;
8094 }
8095
8096 return True;
8097}
8098
8099/***************************************************************************
8100 Parse the contents of a usershare file.
8101***************************************************************************/
8102
8103enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8104 SMB_STRUCT_STAT *psbuf,
8105 const char *servicename,
8106 int snum,
8107 char **lines,
8108 int numlines,
8109 char **pp_sharepath,
8110 char **pp_comment,
8111 SEC_DESC **ppsd,
8112 bool *pallow_guest)
8113{
8114 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8115 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8116 int us_vers;
8117 SMB_STRUCT_DIR *dp;
8118 SMB_STRUCT_STAT sbuf;
8119 char *sharepath = NULL;
8120 char *comment = NULL;
8121
8122 *pp_sharepath = NULL;
8123 *pp_comment = NULL;
8124
8125 *pallow_guest = False;
8126
8127 if (numlines < 4) {
8128 return USERSHARE_MALFORMED_FILE;
8129 }
8130
8131 if (strcmp(lines[0], "#VERSION 1") == 0) {
8132 us_vers = 1;
8133 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8134 us_vers = 2;
8135 if (numlines < 5) {
8136 return USERSHARE_MALFORMED_FILE;
8137 }
8138 } else {
8139 return USERSHARE_BAD_VERSION;
8140 }
8141
8142 if (strncmp(lines[1], "path=", 5) != 0) {
8143 return USERSHARE_MALFORMED_PATH;
8144 }
8145
8146 sharepath = talloc_strdup(ctx, &lines[1][5]);
8147 if (!sharepath) {
8148 return USERSHARE_POSIX_ERR;
8149 }
8150 trim_string(sharepath, " ", " ");
8151
8152 if (strncmp(lines[2], "comment=", 8) != 0) {
8153 return USERSHARE_MALFORMED_COMMENT_DEF;
8154 }
8155
8156 comment = talloc_strdup(ctx, &lines[2][8]);
8157 if (!comment) {
8158 return USERSHARE_POSIX_ERR;
8159 }
8160 trim_string(comment, " ", " ");
8161 trim_char(comment, '"', '"');
8162
8163 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8164 return USERSHARE_MALFORMED_ACL_DEF;
8165 }
8166
8167 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8168 return USERSHARE_ACL_ERR;
8169 }
8170
8171 if (us_vers == 2) {
8172 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8173 return USERSHARE_MALFORMED_ACL_DEF;
8174 }
8175 if (lines[4][9] == 'y') {
8176 *pallow_guest = True;
8177 }
8178 }
8179
8180 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8181 /* Path didn't change, no checks needed. */
8182 *pp_sharepath = sharepath;
8183 *pp_comment = comment;
8184 return USERSHARE_OK;
8185 }
8186
8187 /* The path *must* be absolute. */
8188 if (sharepath[0] != '/') {
8189 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8190 servicename, sharepath));
8191 return USERSHARE_PATH_NOT_ABSOLUTE;
8192 }
8193
8194 /* If there is a usershare prefix deny list ensure one of these paths
8195 doesn't match the start of the user given path. */
8196 if (prefixdenylist) {
8197 int i;
8198 for ( i=0; prefixdenylist[i]; i++ ) {
8199 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8200 servicename, i, prefixdenylist[i], sharepath ));
8201 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8202 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8203 "usershare prefix deny list entries.\n",
8204 servicename, sharepath));
8205 return USERSHARE_PATH_IS_DENIED;
8206 }
8207 }
8208 }
8209
8210 /* If there is a usershare prefix allow list ensure one of these paths
8211 does match the start of the user given path. */
8212
8213 if (prefixallowlist) {
8214 int i;
8215 for ( i=0; prefixallowlist[i]; i++ ) {
8216 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8217 servicename, i, prefixallowlist[i], sharepath ));
8218 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8219 break;
8220 }
8221 }
8222 if (prefixallowlist[i] == NULL) {
8223 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8224 "usershare prefix allow list entries.\n",
8225 servicename, sharepath));
8226 return USERSHARE_PATH_NOT_ALLOWED;
8227 }
8228 }
8229
8230 /* Ensure this is pointing to a directory. */
8231 dp = sys_opendir(sharepath);
8232
8233 if (!dp) {
8234 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8235 servicename, sharepath));
8236 return USERSHARE_PATH_NOT_DIRECTORY;
8237 }
8238
8239 /* Ensure the owner of the usershare file has permission to share
8240 this directory. */
8241
8242 if (sys_stat(sharepath, &sbuf) == -1) {
8243 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8244 servicename, sharepath, strerror(errno) ));
8245 sys_closedir(dp);
8246 return USERSHARE_POSIX_ERR;
8247 }
8248
8249 sys_closedir(dp);
8250
8251 if (!S_ISDIR(sbuf.st_mode)) {
8252 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8253 servicename, sharepath ));
8254 return USERSHARE_PATH_NOT_DIRECTORY;
8255 }
8256
8257 /* Check if sharing is restricted to owner-only. */
8258 /* psbuf is the stat of the usershare definition file,
8259 sbuf is the stat of the target directory to be shared. */
8260
8261 if (lp_usershare_owner_only()) {
8262 /* root can share anything. */
8263 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8264 return USERSHARE_PATH_NOT_ALLOWED;
8265 }
8266 }
8267
8268 *pp_sharepath = sharepath;
8269 *pp_comment = comment;
8270 return USERSHARE_OK;
8271}
8272
8273/***************************************************************************
8274 Deal with a usershare file.
8275 Returns:
8276 >= 0 - snum
8277 -1 - Bad name, invalid contents.
8278 - service name already existed and not a usershare, problem
8279 with permissions to share directory etc.
8280***************************************************************************/
8281
8282static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8283{
8284 SMB_STRUCT_STAT sbuf;
8285 SMB_STRUCT_STAT lsbuf;
8286 char *fname = NULL;
8287 char *sharepath = NULL;
8288 char *comment = NULL;
8289 fstring service_name;
8290 char **lines = NULL;
8291 int numlines = 0;
8292 int fd = -1;
8293 int iService = -1;
8294 TALLOC_CTX *ctx = NULL;
8295 SEC_DESC *psd = NULL;
8296 bool guest_ok = False;
8297
8298 /* Ensure share name doesn't contain invalid characters. */
8299 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8300 DEBUG(0,("process_usershare_file: share name %s contains "
8301 "invalid characters (any of %s)\n",
8302 file_name, INVALID_SHARENAME_CHARS ));
8303 return -1;
8304 }
8305
8306 fstrcpy(service_name, file_name);
8307
8308 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8309 }
8310
8311 /* Minimize the race condition by doing an lstat before we
8312 open and fstat. Ensure this isn't a symlink link. */
8313
8314 if (sys_lstat(fname, &lsbuf) != 0) {
8315 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8316 fname, strerror(errno) ));
8317 SAFE_FREE(fname);
8318 return -1;
8319 }
8320
8321 /* This must be a regular file, not a symlink, directory or
8322 other strange filetype. */
8323 if (!check_usershare_stat(fname, &lsbuf)) {
8324 SAFE_FREE(fname);
8325 return -1;
8326 }
8327
8328 {
8329 char *canon_name = canonicalize_servicename(service_name);
8330 TDB_DATA data = dbwrap_fetch_bystring(
8331 ServiceHash, canon_name, canon_name);
8332
8333 iService = -1;
8334
8335 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8336 iService = *(int *)data.dptr;
8337 }
8338 TALLOC_FREE(canon_name);
8339 }
8340
8341 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8342 /* Nothing changed - Mark valid and return. */
8343 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8344 service_name ));
8345 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8346 SAFE_FREE(fname);
8347 return iService;
8348 }
8349
8350 /* Try and open the file read only - no symlinks allowed. */
8351#ifdef O_NOFOLLOW
8352 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8353#else
8354 fd = sys_open(fname, O_RDONLY, 0);
8355#endif
8356
8357 if (fd == -1) {
8358 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8359 fname, strerror(errno) ));
8360 SAFE_FREE(fname);
8361 return -1;
8362 }
8363
8364 /* Now fstat to be *SURE* it's a regular file. */
8365 if (sys_fstat(fd, &sbuf) != 0) {
8366 close(fd);
8367 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8368 fname, strerror(errno) ));
8369 SAFE_FREE(fname);
8370 return -1;
8371 }
8372
8373 /* Is it the same dev/inode as was lstated ? */
8374 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8375 close(fd);
8376 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8377 "Symlink spoofing going on ?\n", fname ));
8378 SAFE_FREE(fname);
8379 return -1;
8380 }
8381
8382 /* This must be a regular file, not a symlink, directory or
8383 other strange filetype. */
8384 if (!check_usershare_stat(fname, &sbuf)) {
8385 SAFE_FREE(fname);
8386 return -1;
8387 }
8388
8389 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
8390
8391 close(fd);
8392 if (lines == NULL) {
8393 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8394 fname, (unsigned int)sbuf.st_uid ));
8395 SAFE_FREE(fname);
8396 return -1;
8397 }
8398
8399 SAFE_FREE(fname);
8400
8401 /* Should we allow printers to be shared... ? */
8402 ctx = talloc_init("usershare_sd_xctx");
8403 if (!ctx) {
8404 file_lines_free(lines);
8405 return 1;
8406 }
8407
8408 if (parse_usershare_file(ctx, &sbuf, service_name,
8409 iService, lines, numlines, &sharepath,
8410 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8411 talloc_destroy(ctx);
8412 file_lines_free(lines);
8413 return -1;
8414 }
8415
8416 file_lines_free(lines);
8417
8418 /* Everything ok - add the service possibly using a template. */
8419 if (iService < 0) {
8420 const struct service *sp = &sDefault;
8421 if (snum_template != -1) {
8422 sp = ServicePtrs[snum_template];
8423 }
8424
8425 if ((iService = add_a_service(sp, service_name)) < 0) {
8426 DEBUG(0, ("process_usershare_file: Failed to add "
8427 "new service %s\n", service_name));
8428 talloc_destroy(ctx);
8429 return -1;
8430 }
8431
8432 /* Read only is controlled by usershare ACL below. */
8433 ServicePtrs[iService]->bRead_only = False;
8434 }
8435
8436 /* Write the ACL of the new/modified share. */
8437 if (!set_share_security(service_name, psd)) {
8438 DEBUG(0, ("process_usershare_file: Failed to set share "
8439 "security for user share %s\n",
8440 service_name ));
8441 lp_remove_service(iService);
8442 talloc_destroy(ctx);
8443 return -1;
8444 }
8445
8446 /* If from a template it may be marked invalid. */
8447 ServicePtrs[iService]->valid = True;
8448
8449 /* Set the service as a valid usershare. */
8450 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8451
8452 /* Set guest access. */
8453 if (lp_usershare_allow_guests()) {
8454 ServicePtrs[iService]->bGuest_ok = guest_ok;
8455 }
8456
8457 /* And note when it was loaded. */
8458 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8459 string_set(&ServicePtrs[iService]->szPath, sharepath);
8460 string_set(&ServicePtrs[iService]->comment, comment);
8461
8462 talloc_destroy(ctx);
8463
8464 return iService;
8465}
8466
8467/***************************************************************************
8468 Checks if a usershare entry has been modified since last load.
8469***************************************************************************/
8470
8471static bool usershare_exists(int iService, time_t *last_mod)
8472{
8473 SMB_STRUCT_STAT lsbuf;
8474 const char *usersharepath = Globals.szUsersharePath;
8475 char *fname;
8476
8477 if (asprintf(&fname, "%s/%s",
8478 usersharepath,
8479 ServicePtrs[iService]->szService) < 0) {
8480 return false;
8481 }
8482
8483 if (sys_lstat(fname, &lsbuf) != 0) {
8484 SAFE_FREE(fname);
8485 return false;
8486 }
8487
8488 if (!S_ISREG(lsbuf.st_mode)) {
8489 SAFE_FREE(fname);
8490 return false;
8491 }
8492
8493 SAFE_FREE(fname);
8494 *last_mod = lsbuf.st_mtime;
8495 return true;
8496}
8497
8498/***************************************************************************
8499 Load a usershare service by name. Returns a valid servicenumber or -1.
8500***************************************************************************/
8501
8502int load_usershare_service(const char *servicename)
8503{
8504 SMB_STRUCT_STAT sbuf;
8505 const char *usersharepath = Globals.szUsersharePath;
8506 int max_user_shares = Globals.iUsershareMaxShares;
8507 int snum_template = -1;
8508
8509 if (*usersharepath == 0 || max_user_shares == 0) {
8510 return -1;
8511 }
8512
8513 if (sys_stat(usersharepath, &sbuf) != 0) {
8514 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8515 usersharepath, strerror(errno) ));
8516 return -1;
8517 }
8518
8519 if (!S_ISDIR(sbuf.st_mode)) {
8520 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8521 usersharepath ));
8522 return -1;
8523 }
8524
8525 /*
8526 * This directory must be owned by root, and have the 't' bit set.
8527 * It also must not be writable by "other".
8528 */
8529
8530#ifdef S_ISVTX
8531 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8532#else
8533 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8534#endif
8535 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8536 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8537 usersharepath ));
8538 return -1;
8539 }
8540
8541 /* Ensure the template share exists if it's set. */
8542 if (Globals.szUsershareTemplateShare[0]) {
8543 /* We can't use lp_servicenumber here as we are recommending that
8544 template shares have -valid=False set. */
8545 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8546 if (ServicePtrs[snum_template]->szService &&
8547 strequal(ServicePtrs[snum_template]->szService,
8548 Globals.szUsershareTemplateShare)) {
8549 break;
8550 }
8551 }
8552
8553 if (snum_template == -1) {
8554 DEBUG(0,("load_usershare_service: usershare template share %s "
8555 "does not exist.\n",
8556 Globals.szUsershareTemplateShare ));
8557 return -1;
8558 }
8559 }
8560
8561 return process_usershare_file(usersharepath, servicename, snum_template);
8562}
8563
8564/***************************************************************************
8565 Load all user defined shares from the user share directory.
8566 We only do this if we're enumerating the share list.
8567 This is the function that can delete usershares that have
8568 been removed.
8569***************************************************************************/
8570
8571int load_usershare_shares(void)
8572{
8573 SMB_STRUCT_DIR *dp;
8574 SMB_STRUCT_STAT sbuf;
8575 SMB_STRUCT_DIRENT *de;
8576 int num_usershares = 0;
8577 int max_user_shares = Globals.iUsershareMaxShares;
8578 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8579 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8580 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8581 int iService;
8582 int snum_template = -1;
8583 const char *usersharepath = Globals.szUsersharePath;
8584 int ret = lp_numservices();
8585
8586 if (max_user_shares == 0 || *usersharepath == '\0') {
8587 return lp_numservices();
8588 }
8589
8590 if (sys_stat(usersharepath, &sbuf) != 0) {
8591 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8592 usersharepath, strerror(errno) ));
8593 return ret;
8594 }
8595
8596 /*
8597 * This directory must be owned by root, and have the 't' bit set.
8598 * It also must not be writable by "other".
8599 */
8600
8601#ifdef S_ISVTX
8602 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8603#else
8604 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8605#endif
8606 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8607 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8608 usersharepath ));
8609 return ret;
8610 }
8611
8612 /* Ensure the template share exists if it's set. */
8613 if (Globals.szUsershareTemplateShare[0]) {
8614 /* We can't use lp_servicenumber here as we are recommending that
8615 template shares have -valid=False set. */
8616 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8617 if (ServicePtrs[snum_template]->szService &&
8618 strequal(ServicePtrs[snum_template]->szService,
8619 Globals.szUsershareTemplateShare)) {
8620 break;
8621 }
8622 }
8623
8624 if (snum_template == -1) {
8625 DEBUG(0,("load_usershare_shares: usershare template share %s "
8626 "does not exist.\n",
8627 Globals.szUsershareTemplateShare ));
8628 return ret;
8629 }
8630 }
8631
8632 /* Mark all existing usershares as pending delete. */
8633 for (iService = iNumServices - 1; iService >= 0; iService--) {
8634 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8635 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8636 }
8637 }
8638
8639 dp = sys_opendir(usersharepath);
8640 if (!dp) {
8641 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8642 usersharepath, strerror(errno) ));
8643 return ret;
8644 }
8645
8646 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8647 (de = sys_readdir(dp));
8648 num_dir_entries++ ) {
8649 int r;
8650 const char *n = de->d_name;
8651
8652 /* Ignore . and .. */
8653 if (*n == '.') {
8654 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8655 continue;
8656 }
8657 }
8658
8659 if (n[0] == ':') {
8660 /* Temporary file used when creating a share. */
8661 num_tmp_dir_entries++;
8662 }
8663
8664 /* Allow 20% tmp entries. */
8665 if (num_tmp_dir_entries > allowed_tmp_entries) {
8666 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8667 "in directory %s\n",
8668 num_tmp_dir_entries, usersharepath));
8669 break;
8670 }
8671
8672 r = process_usershare_file(usersharepath, n, snum_template);
8673 if (r == 0) {
8674 /* Update the services count. */
8675 num_usershares++;
8676 if (num_usershares >= max_user_shares) {
8677 DEBUG(0,("load_usershare_shares: max user shares reached "
8678 "on file %s in directory %s\n",
8679 n, usersharepath ));
8680 break;
8681 }
8682 } else if (r == -1) {
8683 num_bad_dir_entries++;
8684 }
8685
8686 /* Allow 20% bad entries. */
8687 if (num_bad_dir_entries > allowed_bad_entries) {
8688 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8689 "in directory %s\n",
8690 num_bad_dir_entries, usersharepath));
8691 break;
8692 }
8693
8694 /* Allow 20% bad entries. */
8695 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8696 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8697 "in directory %s\n",
8698 num_dir_entries, usersharepath));
8699 break;
8700 }
8701 }
8702
8703 sys_closedir(dp);
8704
8705 /* Sweep through and delete any non-refreshed usershares that are
8706 not currently in use. */
8707 for (iService = iNumServices - 1; iService >= 0; iService--) {
8708 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8709 if (conn_snum_used(iService)) {
8710 continue;
8711 }
8712 /* Remove from the share ACL db. */
8713 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8714 lp_servicename(iService) ));
8715 delete_share_security(lp_servicename(iService));
8716 free_service_byindex(iService);
8717 }
8718 }
8719
8720 return lp_numservices();
8721}
8722
8723/********************************************************
8724 Destroy global resources allocated in this file
8725********************************************************/
8726
8727void gfree_loadparm(void)
8728{
8729 struct file_lists *f;
8730 struct file_lists *next;
8731 int i;
8732
8733 /* Free the file lists */
8734
8735 f = file_lists;
8736 while( f ) {
8737 next = f->next;
8738 SAFE_FREE( f->name );
8739 SAFE_FREE( f->subfname );
8740 SAFE_FREE( f );
8741 f = next;
8742 }
8743 file_lists = NULL;
8744
8745 /* Free resources allocated to services */
8746
8747 for ( i = 0; i < iNumServices; i++ ) {
8748 if ( VALID(i) ) {
8749 free_service_byindex(i);
8750 }
8751 }
8752
8753 SAFE_FREE( ServicePtrs );
8754 iNumServices = 0;
8755
8756 /* Now release all resources allocated to global
8757 parameters and the default service */
8758
8759 for (i = 0; parm_table[i].label; i++)
8760 {
8761 if ( parm_table[i].type == P_STRING
8762 || parm_table[i].type == P_USTRING )
8763 {
8764 string_free( (char**)parm_table[i].ptr );
8765 }
8766 else if (parm_table[i].type == P_LIST) {
8767 TALLOC_FREE( *((char***)parm_table[i].ptr) );
8768 }
8769 }
8770}
8771
8772
8773/***************************************************************************
8774 Allow client apps to specify that they are a client
8775***************************************************************************/
8776void lp_set_in_client(bool b)
8777{
8778 in_client = b;
8779}
8780
8781
8782/***************************************************************************
8783 Determine if we're running in a client app
8784***************************************************************************/
8785bool lp_is_in_client(void)
8786{
8787 return in_client;
8788}
8789
8790
8791
8792
8793/***************************************************************************
8794 Load the services array from the services file. Return True on success,
8795 False on failure.
8796***************************************************************************/
8797
8798bool lp_load_ex(const char *pszFname,
8799 bool global_only,
8800 bool save_defaults,
8801 bool add_ipc,
8802 bool initialize_globals,
8803 bool allow_include_registry,
8804 bool allow_registry_shares)
8805{
8806 char *n2 = NULL;
8807 bool bRetval;
8808 struct param_opt_struct *data, *pdata;
8809
8810 bRetval = False;
8811
8812 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
8813
8814 bInGlobalSection = True;
8815 bGlobalOnly = global_only;
8816 bAllowIncludeRegistry = allow_include_registry;
8817
8818 init_globals(! initialize_globals);
8819 debug_init();
8820
8821 if (save_defaults) {
8822 init_locals();
8823 lp_save_defaults();
8824 }
8825
8826 /* We get sections first, so have to start 'behind' to make up */
8827 iServiceIndex = -1;
8828
8829 if (Globals.param_opt != NULL) {
8830 data = Globals.param_opt;
8831 while (data) {
8832 string_free(&data->key);
8833 string_free(&data->value);
8834 TALLOC_FREE(data->list);
8835 pdata = data->next;
8836 SAFE_FREE(data);
8837 data = pdata;
8838 }
8839 Globals.param_opt = NULL;
8840 }
8841
8842 if (lp_config_backend_is_file()) {
8843 n2 = alloc_sub_basic(get_current_username(),
8844 current_user_info.domain,
8845 pszFname);
8846 if (!n2) {
8847 smb_panic("lp_load_ex: out of memory");
8848 }
8849
8850 add_to_file_list(pszFname, n2);
8851
8852 bRetval = pm_process(n2, do_section, do_parameter, NULL);
8853 SAFE_FREE(n2);
8854
8855 /* finish up the last section */
8856 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
8857 if (bRetval) {
8858 if (iServiceIndex >= 0) {
8859 bRetval = service_ok(iServiceIndex);
8860 }
8861 }
8862
8863 if (lp_config_backend_is_registry()) {
8864 /* config backend changed to registry in config file */
8865 /*
8866 * We need to use this extra global variable here to
8867 * survive restart: init_globals uses this as a default
8868 * for ConfigBackend. Otherwise, init_globals would
8869 * send us into an endless loop here.
8870 */
8871 config_backend = CONFIG_BACKEND_REGISTRY;
8872 /* start over */
8873 DEBUG(1, ("lp_load_ex: changing to config backend "
8874 "registry\n"));
8875 init_globals(false);
8876 lp_kill_all_services();
8877 return lp_load_ex(pszFname, global_only, save_defaults,
8878 add_ipc, initialize_globals,
8879 allow_include_registry,
8880 allow_registry_shares);
8881 }
8882 } else if (lp_config_backend_is_registry()) {
8883 bRetval = process_registry_globals();
8884 } else {
8885 DEBUG(0, ("Illegal config backend given: %d\n",
8886 lp_config_backend()));
8887 bRetval = false;
8888 }
8889
8890 if (bRetval && lp_registry_shares() && allow_registry_shares) {
8891 bRetval = process_registry_shares();
8892 }
8893
8894 lp_add_auto_services(lp_auto_services());
8895
8896 if (add_ipc) {
8897 /* When 'restrict anonymous = 2' guest connections to ipc$
8898 are denied */
8899 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
8900 if ( lp_enable_asu_support() ) {
8901 lp_add_ipc("ADMIN$", false);
8902 }
8903 }
8904
8905 set_server_role();
8906 set_default_server_announce_type();
8907 set_allowed_client_auth();
8908
8909 bLoaded = True;
8910
8911 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
8912 /* if bWINSsupport is true and we are in the client */
8913 if (lp_is_in_client() && Globals.bWINSsupport) {
8914 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
8915 }
8916
8917 init_iconv();
8918
8919 bAllowIncludeRegistry = true;
8920
8921 return (bRetval);
8922}
8923
8924bool lp_load(const char *pszFname,
8925 bool global_only,
8926 bool save_defaults,
8927 bool add_ipc,
8928 bool initialize_globals)
8929{
8930 return lp_load_ex(pszFname,
8931 global_only,
8932 save_defaults,
8933 add_ipc,
8934 initialize_globals,
8935 true, false);
8936}
8937
8938bool lp_load_initial_only(const char *pszFname)
8939{
8940 return lp_load_ex(pszFname,
8941 true,
8942 false,
8943 false,
8944 true,
8945 false,
8946 false);
8947}
8948
8949bool lp_load_with_registry_shares(const char *pszFname,
8950 bool global_only,
8951 bool save_defaults,
8952 bool add_ipc,
8953 bool initialize_globals)
8954{
8955 return lp_load_ex(pszFname,
8956 global_only,
8957 save_defaults,
8958 add_ipc,
8959 initialize_globals,
8960 true,
8961 true);
8962}
8963
8964/***************************************************************************
8965 Return the max number of services.
8966***************************************************************************/
8967
8968int lp_numservices(void)
8969{
8970 return (iNumServices);
8971}
8972
8973/***************************************************************************
8974Display the contents of the services array in human-readable form.
8975***************************************************************************/
8976
8977void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
8978{
8979 int iService;
8980
8981 if (show_defaults)
8982 defaults_saved = False;
8983
8984 dump_globals(f);
8985
8986 dump_a_service(&sDefault, f);
8987
8988 for (iService = 0; iService < maxtoprint; iService++) {
8989 fprintf(f,"\n");
8990 lp_dump_one(f, show_defaults, iService);
8991 }
8992}
8993
8994/***************************************************************************
8995Display the contents of one service in human-readable form.
8996***************************************************************************/
8997
8998void lp_dump_one(FILE * f, bool show_defaults, int snum)
8999{
9000 if (VALID(snum)) {
9001 if (ServicePtrs[snum]->szService[0] == '\0')
9002 return;
9003 dump_a_service(ServicePtrs[snum], f);
9004 }
9005}
9006
9007/***************************************************************************
9008Return the number of the service with the given name, or -1 if it doesn't
9009exist. Note that this is a DIFFERENT ANIMAL from the internal function
9010getservicebyname()! This works ONLY if all services have been loaded, and
9011does not copy the found service.
9012***************************************************************************/
9013
9014int lp_servicenumber(const char *pszServiceName)
9015{
9016 int iService;
9017 fstring serviceName;
9018
9019 if (!pszServiceName) {
9020 return GLOBAL_SECTION_SNUM;
9021 }
9022
9023 for (iService = iNumServices - 1; iService >= 0; iService--) {
9024 if (VALID(iService) && ServicePtrs[iService]->szService) {
9025 /*
9026 * The substitution here is used to support %U is
9027 * service names
9028 */
9029 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9030 standard_sub_basic(get_current_username(),
9031 current_user_info.domain,
9032 serviceName,sizeof(serviceName));
9033 if (strequal(serviceName, pszServiceName)) {
9034 break;
9035 }
9036 }
9037 }
9038
9039 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9040 time_t last_mod;
9041
9042 if (!usershare_exists(iService, &last_mod)) {
9043 /* Remove the share security tdb entry for it. */
9044 delete_share_security(lp_servicename(iService));
9045 /* Remove it from the array. */
9046 free_service_byindex(iService);
9047 /* Doesn't exist anymore. */
9048 return GLOBAL_SECTION_SNUM;
9049 }
9050
9051 /* Has it been modified ? If so delete and reload. */
9052 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9053 /* Remove it from the array. */
9054 free_service_byindex(iService);
9055 /* and now reload it. */
9056 iService = load_usershare_service(pszServiceName);
9057 }
9058 }
9059
9060 if (iService < 0) {
9061 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9062 return GLOBAL_SECTION_SNUM;
9063 }
9064
9065 return (iService);
9066}
9067
9068bool share_defined(const char *service_name)
9069{
9070 return (lp_servicenumber(service_name) != -1);
9071}
9072
9073struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9074 const char *sharename)
9075{
9076 struct share_params *result;
9077 char *sname;
9078 int snum;
9079
9080 if (!(sname = SMB_STRDUP(sharename))) {
9081 return NULL;
9082 }
9083
9084 snum = find_service(sname);
9085 SAFE_FREE(sname);
9086
9087 if (snum < 0) {
9088 return NULL;
9089 }
9090
9091 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9092 DEBUG(0, ("talloc failed\n"));
9093 return NULL;
9094 }
9095
9096 result->service = snum;
9097 return result;
9098}
9099
9100struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9101{
9102 struct share_iterator *result;
9103
9104 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9105 DEBUG(0, ("talloc failed\n"));
9106 return NULL;
9107 }
9108
9109 result->next_id = 0;
9110 return result;
9111}
9112
9113struct share_params *next_share(struct share_iterator *list)
9114{
9115 struct share_params *result;
9116
9117 while (!lp_snum_ok(list->next_id) &&
9118 (list->next_id < lp_numservices())) {
9119 list->next_id += 1;
9120 }
9121
9122 if (list->next_id >= lp_numservices()) {
9123 return NULL;
9124 }
9125
9126 if (!(result = TALLOC_P(list, struct share_params))) {
9127 DEBUG(0, ("talloc failed\n"));
9128 return NULL;
9129 }
9130
9131 result->service = list->next_id;
9132 list->next_id += 1;
9133 return result;
9134}
9135
9136struct share_params *next_printer(struct share_iterator *list)
9137{
9138 struct share_params *result;
9139
9140 while ((result = next_share(list)) != NULL) {
9141 if (lp_print_ok(result->service)) {
9142 break;
9143 }
9144 }
9145 return result;
9146}
9147
9148/*
9149 * This is a hack for a transition period until we transformed all code from
9150 * service numbers to struct share_params.
9151 */
9152
9153struct share_params *snum2params_static(int snum)
9154{
9155 static struct share_params result;
9156 result.service = snum;
9157 return &result;
9158}
9159
9160/*******************************************************************
9161 A useful volume label function.
9162********************************************************************/
9163
9164const char *volume_label(int snum)
9165{
9166 char *ret;
9167 const char *label = lp_volume(snum);
9168 if (!*label) {
9169 label = lp_servicename(snum);
9170 }
9171
9172 /* This returns a 33 byte guarenteed null terminated string. */
9173 ret = talloc_strndup(talloc_tos(), label, 32);
9174 if (!ret) {
9175 return "";
9176 }
9177 return ret;
9178}
9179
9180/*******************************************************************
9181 Set the server type we will announce as via nmbd.
9182********************************************************************/
9183
9184static void set_default_server_announce_type(void)
9185{
9186 default_server_announce = 0;
9187 default_server_announce |= SV_TYPE_WORKSTATION;
9188 default_server_announce |= SV_TYPE_SERVER;
9189 default_server_announce |= SV_TYPE_SERVER_UNIX;
9190
9191 /* note that the flag should be set only if we have a
9192 printer service but nmbd doesn't actually load the
9193 services so we can't tell --jerry */
9194
9195 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9196
9197 switch (lp_announce_as()) {
9198 case ANNOUNCE_AS_NT_SERVER:
9199 default_server_announce |= SV_TYPE_SERVER_NT;
9200 /* fall through... */
9201 case ANNOUNCE_AS_NT_WORKSTATION:
9202 default_server_announce |= SV_TYPE_NT;
9203 break;
9204 case ANNOUNCE_AS_WIN95:
9205 default_server_announce |= SV_TYPE_WIN95_PLUS;
9206 break;
9207 case ANNOUNCE_AS_WFW:
9208 default_server_announce |= SV_TYPE_WFW;
9209 break;
9210 default:
9211 break;
9212 }
9213
9214 switch (lp_server_role()) {
9215 case ROLE_DOMAIN_MEMBER:
9216 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9217 break;
9218 case ROLE_DOMAIN_PDC:
9219 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9220 break;
9221 case ROLE_DOMAIN_BDC:
9222 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9223 break;
9224 case ROLE_STANDALONE:
9225 default:
9226 break;
9227 }
9228 if (lp_time_server())
9229 default_server_announce |= SV_TYPE_TIME_SOURCE;
9230
9231 if (lp_host_msdfs())
9232 default_server_announce |= SV_TYPE_DFS_SERVER;
9233}
9234
9235/***********************************************************
9236 returns role of Samba server
9237************************************************************/
9238
9239int lp_server_role(void)
9240{
9241 return server_role;
9242}
9243
9244/***********************************************************
9245 If we are PDC then prefer us as DMB
9246************************************************************/
9247
9248bool lp_domain_master(void)
9249{
9250 if (Globals.iDomainMaster == Auto)
9251 return (lp_server_role() == ROLE_DOMAIN_PDC);
9252
9253 return (bool)Globals.iDomainMaster;
9254}
9255
9256/***********************************************************
9257 If we are DMB then prefer us as LMB
9258************************************************************/
9259
9260bool lp_preferred_master(void)
9261{
9262 if (Globals.iPreferredMaster == Auto)
9263 return (lp_local_master() && lp_domain_master());
9264
9265 return (bool)Globals.iPreferredMaster;
9266}
9267
9268/*******************************************************************
9269 Remove a service.
9270********************************************************************/
9271
9272void lp_remove_service(int snum)
9273{
9274 ServicePtrs[snum]->valid = False;
9275 invalid_services[num_invalid_services++] = snum;
9276}
9277
9278/*******************************************************************
9279 Copy a service.
9280********************************************************************/
9281
9282void lp_copy_service(int snum, const char *new_name)
9283{
9284 do_section(new_name, NULL);
9285 if (snum >= 0) {
9286 snum = lp_servicenumber(new_name);
9287 if (snum >= 0)
9288 lp_do_parameter(snum, "copy", lp_servicename(snum));
9289 }
9290}
9291
9292
9293/*******************************************************************
9294 Get the default server type we will announce as via nmbd.
9295********************************************************************/
9296
9297int lp_default_server_announce(void)
9298{
9299 return default_server_announce;
9300}
9301
9302/*******************************************************************
9303 Split the announce version into major and minor numbers.
9304********************************************************************/
9305
9306int lp_major_announce_version(void)
9307{
9308 static bool got_major = False;
9309 static int major_version = DEFAULT_MAJOR_VERSION;
9310 char *vers;
9311 char *p;
9312
9313 if (got_major)
9314 return major_version;
9315
9316 got_major = True;
9317 if ((vers = lp_announce_version()) == NULL)
9318 return major_version;
9319
9320 if ((p = strchr_m(vers, '.')) == 0)
9321 return major_version;
9322
9323 *p = '\0';
9324 major_version = atoi(vers);
9325 return major_version;
9326}
9327
9328int lp_minor_announce_version(void)
9329{
9330 static bool got_minor = False;
9331 static int minor_version = DEFAULT_MINOR_VERSION;
9332 char *vers;
9333 char *p;
9334
9335 if (got_minor)
9336 return minor_version;
9337
9338 got_minor = True;
9339 if ((vers = lp_announce_version()) == NULL)
9340 return minor_version;
9341
9342 if ((p = strchr_m(vers, '.')) == 0)
9343 return minor_version;
9344
9345 p++;
9346 minor_version = atoi(p);
9347 return minor_version;
9348}
9349
9350/***********************************************************
9351 Set the global name resolution order (used in smbclient).
9352************************************************************/
9353
9354void lp_set_name_resolve_order(const char *new_order)
9355{
9356 string_set(&Globals.szNameResolveOrder, new_order);
9357}
9358
9359const char *lp_printername(int snum)
9360{
9361 const char *ret = _lp_printername(snum);
9362 if (ret == NULL || (ret != NULL && *ret == '\0'))
9363 ret = lp_const_servicename(snum);
9364
9365 return ret;
9366}
9367
9368
9369/***********************************************************
9370 Allow daemons such as winbindd to fix their logfile name.
9371************************************************************/
9372
9373void lp_set_logfile(const char *name)
9374{
9375 string_set(&Globals.szLogFile, name);
9376 debug_set_logfile(name);
9377}
9378
9379/*******************************************************************
9380 Return the max print jobs per queue.
9381********************************************************************/
9382
9383int lp_maxprintjobs(int snum)
9384{
9385 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9386 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9387 maxjobs = PRINT_MAX_JOBID - 1;
9388
9389 return maxjobs;
9390}
9391
9392const char *lp_printcapname(void)
9393{
9394 if ((Globals.szPrintcapname != NULL) &&
9395 (Globals.szPrintcapname[0] != '\0'))
9396 return Globals.szPrintcapname;
9397
9398 if (sDefault.iPrinting == PRINT_CUPS) {
9399#ifdef HAVE_CUPS
9400 return "cups";
9401#else
9402 return "lpstat";
9403#endif
9404 }
9405
9406 if (sDefault.iPrinting == PRINT_BSD)
9407 return "/etc/printcap";
9408
9409 return PRINTCAP_NAME;
9410}
9411
9412/*******************************************************************
9413 Ensure we don't use sendfile if server smb signing is active.
9414********************************************************************/
9415
9416static uint32 spoolss_state;
9417
9418bool lp_disable_spoolss( void )
9419{
9420 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9421 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9422
9423 return spoolss_state == SVCCTL_STOPPED ? True : False;
9424}
9425
9426void lp_set_spoolss_state( uint32 state )
9427{
9428 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9429
9430 spoolss_state = state;
9431}
9432
9433uint32 lp_get_spoolss_state( void )
9434{
9435 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9436}
9437
9438/*******************************************************************
9439 Ensure we don't use sendfile if server smb signing is active.
9440********************************************************************/
9441
9442bool lp_use_sendfile(int snum)
9443{
9444 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9445 if (Protocol < PROTOCOL_NT1) {
9446 return False;
9447 }
9448 return (_lp_use_sendfile(snum) &&
9449 (get_remote_arch() != RA_WIN95) &&
9450 !srv_is_signing_active());
9451}
9452
9453/*******************************************************************
9454 Turn off sendfile if we find the underlying OS doesn't support it.
9455********************************************************************/
9456
9457void set_use_sendfile(int snum, bool val)
9458{
9459 if (LP_SNUM_OK(snum))
9460 ServicePtrs[snum]->bUseSendfile = val;
9461 else
9462 sDefault.bUseSendfile = val;
9463}
9464
9465/*******************************************************************
9466 Turn off storing DOS attributes if this share doesn't support it.
9467********************************************************************/
9468
9469void set_store_dos_attributes(int snum, bool val)
9470{
9471 if (!LP_SNUM_OK(snum))
9472 return;
9473 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9474}
9475
9476void lp_set_mangling_method(const char *new_method)
9477{
9478 string_set(&Globals.szManglingMethod, new_method);
9479}
9480
9481/*******************************************************************
9482 Global state for POSIX pathname processing.
9483********************************************************************/
9484
9485static bool posix_pathnames;
9486
9487bool lp_posix_pathnames(void)
9488{
9489 return posix_pathnames;
9490}
9491
9492/*******************************************************************
9493 Change everything needed to ensure POSIX pathname processing (currently
9494 not much).
9495********************************************************************/
9496
9497void lp_set_posix_pathnames(void)
9498{
9499 posix_pathnames = True;
9500}
9501
9502/*******************************************************************
9503 Global state for POSIX lock processing - CIFS unix extensions.
9504********************************************************************/
9505
9506bool posix_default_lock_was_set;
9507static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9508
9509enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9510{
9511 if (posix_default_lock_was_set) {
9512 return posix_cifsx_locktype;
9513 } else {
9514 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9515 }
9516}
9517
9518/*******************************************************************
9519********************************************************************/
9520
9521void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9522{
9523 posix_default_lock_was_set = True;
9524 posix_cifsx_locktype = val;
9525}
9526
9527int lp_min_receive_file_size(void)
9528{
9529 if (Globals.iminreceivefile < 0) {
9530 return 0;
9531 }
9532 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9533}
9534
9535/*******************************************************************
9536 If socket address is an empty character string, it is necessary to
9537 define it as "0.0.0.0".
9538********************************************************************/
9539
9540const char *lp_socket_address(void)
9541{
9542 char *sock_addr = Globals.szSocketAddress;
9543
9544 if (sock_addr[0] == '\0'){
9545 string_set(&Globals.szSocketAddress, "0.0.0.0");
9546 }
9547 return Globals.szSocketAddress;
9548}
Note: See TracBrowser for help on using the repository browser.