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

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

Update 3.3 branch to 3.3.5

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