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

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

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

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