Fix bug 7104 - "wide links" and "unix extensions" are incompatible.
[Samba.git] / source3 / param / loadparm.c
blob6e5e0b2e069fd3f7ce115b9f474204d8fd45a0d3
1 /*
2 Unix SMB/CIFS implementation.
3 Parameter loading functions
4 Copyright (C) Karl Auer 1993-1998
6 Largely re-written by Andrew Tridgell, September 1994
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
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.
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.
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/>.
29 * Load parameters.
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.
35 * To add a parameter:
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
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!
54 #include "includes.h"
55 #include "printing.h"
57 #ifdef HAVE_SYS_SYSCTL_H
58 #include <sys/sysctl.h>
59 #endif
61 bool bLoaded = False;
63 extern enum protocol_types Protocol;
64 extern userdom_struct current_user_info;
66 #ifndef GLOBAL_NAME
67 #define GLOBAL_NAME "global"
68 #endif
70 #ifndef PRINTERS_NAME
71 #define PRINTERS_NAME "printers"
72 #endif
74 #ifndef HOMES_NAME
75 #define HOMES_NAME "homes"
76 #endif
78 /* the special value for the include parameter
79 * to be interpreted not as a file name but to
80 * trigger loading of the global smb.conf options
81 * from registry. */
82 #ifndef INCLUDE_REGISTRY_NAME
83 #define INCLUDE_REGISTRY_NAME "registry"
84 #endif
86 static bool in_client = False; /* Not in the client by default */
87 static struct smbconf_csn conf_last_csn;
89 #define CONFIG_BACKEND_FILE 0
90 #define CONFIG_BACKEND_REGISTRY 1
92 static int config_backend = CONFIG_BACKEND_FILE;
94 /* some helpful bits */
95 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
96 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
98 #define USERSHARE_VALID 1
99 #define USERSHARE_PENDING_DELETE 2
101 static bool defaults_saved = False;
103 struct param_opt_struct {
104 struct param_opt_struct *prev, *next;
105 char *key;
106 char *value;
107 char **list;
111 * This structure describes global (ie., server-wide) parameters.
113 struct global {
114 int ConfigBackend;
115 char *smb_ports;
116 char *dos_charset;
117 char *unix_charset;
118 char *display_charset;
119 char *szPrintcapname;
120 char *szAddPortCommand;
121 char *szEnumPortsCommand;
122 char *szAddPrinterCommand;
123 char *szDeletePrinterCommand;
124 char *szOs2DriverMap;
125 char *szLockDir;
126 char *szStateDir;
127 char *szCacheDir;
128 char *szPidDir;
129 char *szRootdir;
130 char *szDefaultService;
131 char *szGetQuota;
132 char *szSetQuota;
133 char *szMsgCommand;
134 char *szServerString;
135 char *szAutoServices;
136 char *szPasswdProgram;
137 char *szPasswdChat;
138 char *szLogFile;
139 char *szConfigFile;
140 char *szSMBPasswdFile;
141 char *szPrivateDir;
142 char *szPassdbBackend;
143 char **szPreloadModules;
144 char *szPasswordServer;
145 char *szSocketOptions;
146 char *szRealm;
147 char *szAfsUsernameMap;
148 int iAfsTokenLifetime;
149 char *szLogNtTokenCommand;
150 char *szUsernameMap;
151 char *szLogonScript;
152 char *szLogonPath;
153 char *szLogonDrive;
154 char *szLogonHome;
155 char **szWINSservers;
156 char **szInterfaces;
157 char *szRemoteAnnounce;
158 char *szRemoteBrowseSync;
159 char *szSocketAddress;
160 char *szNISHomeMapName;
161 char *szAnnounceVersion; /* This is initialised in init_globals */
162 char *szWorkgroup;
163 char *szNetbiosName;
164 char **szNetbiosAliases;
165 char *szNetbiosScope;
166 char *szNameResolveOrder;
167 char *szPanicAction;
168 char *szAddUserScript;
169 char *szRenameUserScript;
170 char *szDelUserScript;
171 char *szAddGroupScript;
172 char *szDelGroupScript;
173 char *szAddUserToGroupScript;
174 char *szDelUserFromGroupScript;
175 char *szSetPrimaryGroupScript;
176 char *szAddMachineScript;
177 char *szShutdownScript;
178 char *szAbortShutdownScript;
179 char *szUsernameMapScript;
180 char *szCheckPasswordScript;
181 char *szWINSHook;
182 char *szUtmpDir;
183 char *szWtmpDir;
184 bool bUtmp;
185 char *szIdmapUID;
186 char *szIdmapGID;
187 bool bPassdbExpandExplicit;
188 int AlgorithmicRidBase;
189 char *szTemplateHomedir;
190 char *szTemplateShell;
191 char *szWinbindSeparator;
192 bool bWinbindEnumUsers;
193 bool bWinbindEnumGroups;
194 bool bWinbindUseDefaultDomain;
195 bool bWinbindTrustedDomainsOnly;
196 bool bWinbindNestedGroups;
197 int winbind_expand_groups;
198 bool bWinbindRefreshTickets;
199 bool bWinbindOfflineLogon;
200 bool bWinbindNormalizeNames;
201 bool bWinbindRpcOnly;
202 char *szIdmapBackend;
203 char *szIdmapAllocBackend;
204 char *szAddShareCommand;
205 char *szChangeShareCommand;
206 char *szDeleteShareCommand;
207 char **szEventLogs;
208 char *szGuestaccount;
209 char *szManglingMethod;
210 char **szServicesList;
211 char *szUsersharePath;
212 char *szUsershareTemplateShare;
213 char **szUsersharePrefixAllowList;
214 char **szUsersharePrefixDenyList;
215 int mangle_prefix;
216 int max_log_size;
217 char *szLogLevel;
218 int max_xmit;
219 int max_mux;
220 int max_open_files;
221 int open_files_db_hash_size;
222 int pwordlevel;
223 int unamelevel;
224 int deadtime;
225 bool getwd_cache;
226 int maxprotocol;
227 int minprotocol;
228 int security;
229 char **AuthMethods;
230 bool paranoid_server_security;
231 int maxdisksize;
232 int lpqcachetime;
233 int iMaxSmbdProcesses;
234 bool bDisableSpoolss;
235 int syslog;
236 int os_level;
237 bool enhanced_browsing;
238 int max_ttl;
239 int max_wins_ttl;
240 int min_wins_ttl;
241 int lm_announce;
242 int lm_interval;
243 int announce_as; /* This is initialised in init_globals */
244 int machine_password_timeout;
245 int map_to_guest;
246 int oplock_break_wait_time;
247 int winbind_cache_time;
248 int winbind_reconnect_delay;
249 int winbind_max_idle_children;
250 char **szWinbindNssInfo;
251 int iLockSpinTime;
252 char *szLdapMachineSuffix;
253 char *szLdapUserSuffix;
254 char *szLdapIdmapSuffix;
255 char *szLdapGroupSuffix;
256 int ldap_ssl;
257 bool ldap_ssl_ads;
258 char *szLdapSuffix;
259 char *szLdapAdminDn;
260 int ldap_debug_level;
261 int ldap_debug_threshold;
262 int iAclCompat;
263 char *szCupsServer;
264 char *szIPrintServer;
265 char *ctdbdSocket;
266 char **szClusterAddresses;
267 bool clustering;
268 int ldap_passwd_sync;
269 int ldap_replication_sleep;
270 int ldap_timeout; /* This is initialised in init_globals */
271 int ldap_connection_timeout;
272 int ldap_page_size;
273 bool ldap_delete_dn;
274 bool bMsAddPrinterWizard;
275 bool bDNSproxy;
276 bool bWINSsupport;
277 bool bWINSproxy;
278 bool bLocalMaster;
279 int iPreferredMaster;
280 int iDomainMaster;
281 bool bDomainLogons;
282 char **szInitLogonDelayedHosts;
283 int InitLogonDelay;
284 bool bEncryptPasswords;
285 bool bUpdateEncrypt;
286 int clientSchannel;
287 int serverSchannel;
288 bool bNullPasswords;
289 bool bObeyPamRestrictions;
290 bool bLoadPrinters;
291 int PrintcapCacheTime;
292 bool bLargeReadwrite;
293 bool bReadRaw;
294 bool bWriteRaw;
295 bool bSyslogOnly;
296 bool bBrowseList;
297 bool bNISHomeMap;
298 bool bTimeServer;
299 bool bBindInterfacesOnly;
300 bool bPamPasswordChange;
301 bool bUnixPasswdSync;
302 bool bPasswdChatDebug;
303 int iPasswdChatTimeout;
304 bool bTimestampLogs;
305 bool bNTSmbSupport;
306 bool bNTPipeSupport;
307 bool bNTStatusSupport;
308 bool bStatCache;
309 int iMaxStatCacheSize;
310 bool bKernelOplocks;
311 bool bAllowTrustedDomains;
312 bool bLanmanAuth;
313 bool bNTLMAuth;
314 bool bUseSpnego;
315 bool bClientLanManAuth;
316 bool bClientNTLMv2Auth;
317 bool bClientPlaintextAuth;
318 bool bClientUseSpnego;
319 bool bDebugPrefixTimestamp;
320 bool bDebugHiresTimestamp;
321 bool bDebugPid;
322 bool bDebugUid;
323 bool bDebugClass;
324 bool bEnableCoreFiles;
325 bool bHostMSDfs;
326 bool bUseMmap;
327 bool bHostnameLookups;
328 bool bUnixExtensions;
329 bool bDisableNetbios;
330 char * szDedicatedKeytabFile;
331 int iKerberosMethod;
332 bool bDeferSharingViolations;
333 bool bEnablePrivileges;
334 bool bASUSupport;
335 bool bUsershareOwnerOnly;
336 bool bUsershareAllowGuests;
337 bool bRegistryShares;
338 int restrict_anonymous;
339 int name_cache_timeout;
340 int client_signing;
341 int server_signing;
342 int client_ldap_sasl_wrapping;
343 int iUsershareMaxShares;
344 int iIdmapCacheTime;
345 int iIdmapNegativeCacheTime;
346 bool bResetOnZeroVC;
347 int iKeepalive;
348 int iminreceivefile;
349 struct param_opt_struct *param_opt;
350 int cups_connection_timeout;
351 char *szSMBPerfcountModule;
352 bool bMapUntrustedToDomain;
355 static struct global Globals;
358 * This structure describes a single service.
360 struct service {
361 bool valid;
362 bool autoloaded;
363 int usershare;
364 time_t usershare_last_mod;
365 char *szService;
366 char *szPath;
367 char *szUsername;
368 char **szInvalidUsers;
369 char **szValidUsers;
370 char **szAdminUsers;
371 char *szCopy;
372 char *szInclude;
373 char *szPreExec;
374 char *szPostExec;
375 char *szRootPreExec;
376 char *szRootPostExec;
377 char *szCupsOptions;
378 char *szPrintcommand;
379 char *szLpqcommand;
380 char *szLprmcommand;
381 char *szLppausecommand;
382 char *szLpresumecommand;
383 char *szQueuepausecommand;
384 char *szQueueresumecommand;
385 char *szPrintername;
386 char *szPrintjobUsername;
387 char *szDontdescend;
388 char **szHostsallow;
389 char **szHostsdeny;
390 char *szMagicScript;
391 char *szMagicOutput;
392 char *szVetoFiles;
393 char *szHideFiles;
394 char *szVetoOplockFiles;
395 char *comment;
396 char *force_user;
397 char *force_group;
398 char **readlist;
399 char **writelist;
400 char **printer_admin;
401 char *volume;
402 char *fstype;
403 char **szVfsObjects;
404 char *szMSDfsProxy;
405 char *szAioWriteBehind;
406 char *szDfree;
407 int iMinPrintSpace;
408 int iMaxPrintJobs;
409 int iMaxReportedPrintJobs;
410 int iWriteCacheSize;
411 int iCreate_mask;
412 int iCreate_force_mode;
413 int iSecurity_mask;
414 int iSecurity_force_mode;
415 int iDir_mask;
416 int iDir_force_mode;
417 int iDir_Security_mask;
418 int iDir_Security_force_mode;
419 int iMaxConnections;
420 int iDefaultCase;
421 int iPrinting;
422 int iOplockContentionLimit;
423 int iCSCPolicy;
424 int iBlock_size;
425 int iDfreeCacheTime;
426 bool bPreexecClose;
427 bool bRootpreexecClose;
428 int iCaseSensitive;
429 bool bCasePreserve;
430 bool bShortCasePreserve;
431 bool bHideDotFiles;
432 bool bHideSpecialFiles;
433 bool bHideUnReadable;
434 bool bHideUnWriteableFiles;
435 bool bBrowseable;
436 bool bAccessBasedShareEnum;
437 bool bAvailable;
438 bool bRead_only;
439 bool bNo_set_dir;
440 bool bGuest_only;
441 bool bAdministrative_share;
442 bool bGuest_ok;
443 bool bPrint_ok;
444 bool bMap_system;
445 bool bMap_hidden;
446 bool bMap_archive;
447 bool bStoreDosAttributes;
448 bool bDmapiSupport;
449 bool bLocking;
450 int iStrictLocking;
451 bool bPosixLocking;
452 bool bShareModes;
453 bool bOpLocks;
454 bool bLevel2OpLocks;
455 bool bOnlyUser;
456 bool bMangledNames;
457 bool bWidelinks;
458 bool bSymlinks;
459 bool bSyncAlways;
460 bool bStrictAllocate;
461 bool bStrictSync;
462 char magic_char;
463 struct bitmap *copymap;
464 bool bDeleteReadonly;
465 bool bFakeOplocks;
466 bool bDeleteVetoFiles;
467 bool bDosFilemode;
468 bool bDosFiletimes;
469 bool bDosFiletimeResolution;
470 bool bFakeDirCreateTimes;
471 bool bBlockingLocks;
472 bool bInheritPerms;
473 bool bInheritACLS;
474 bool bInheritOwner;
475 bool bMSDfsRoot;
476 bool bUseClientDriver;
477 bool bDefaultDevmode;
478 bool bForcePrintername;
479 bool bNTAclSupport;
480 bool bForceUnknownAclUser;
481 bool bUseSendfile;
482 bool bProfileAcls;
483 bool bMap_acl_inherit;
484 bool bAfs_Share;
485 bool bEASupport;
486 bool bAclCheckPermissions;
487 bool bAclMapFullControl;
488 bool bAclGroupControl;
489 bool bChangeNotify;
490 bool bKernelChangeNotify;
491 int iallocation_roundup_size;
492 int iAioReadSize;
493 int iAioWriteSize;
494 int iMap_readonly;
495 int iDirectoryNameCacheSize;
496 int ismb_encrypt;
497 struct param_opt_struct *param_opt;
499 char dummy[3]; /* for alignment */
503 /* This is a default service used to prime a services structure */
504 static struct service sDefault = {
505 True, /* valid */
506 False, /* not autoloaded */
507 0, /* not a usershare */
508 (time_t)0, /* No last mod time */
509 NULL, /* szService */
510 NULL, /* szPath */
511 NULL, /* szUsername */
512 NULL, /* szInvalidUsers */
513 NULL, /* szValidUsers */
514 NULL, /* szAdminUsers */
515 NULL, /* szCopy */
516 NULL, /* szInclude */
517 NULL, /* szPreExec */
518 NULL, /* szPostExec */
519 NULL, /* szRootPreExec */
520 NULL, /* szRootPostExec */
521 NULL, /* szCupsOptions */
522 NULL, /* szPrintcommand */
523 NULL, /* szLpqcommand */
524 NULL, /* szLprmcommand */
525 NULL, /* szLppausecommand */
526 NULL, /* szLpresumecommand */
527 NULL, /* szQueuepausecommand */
528 NULL, /* szQueueresumecommand */
529 NULL, /* szPrintername */
530 NULL, /* szPrintjobUsername */
531 NULL, /* szDontdescend */
532 NULL, /* szHostsallow */
533 NULL, /* szHostsdeny */
534 NULL, /* szMagicScript */
535 NULL, /* szMagicOutput */
536 NULL, /* szVetoFiles */
537 NULL, /* szHideFiles */
538 NULL, /* szVetoOplockFiles */
539 NULL, /* comment */
540 NULL, /* force user */
541 NULL, /* force group */
542 NULL, /* readlist */
543 NULL, /* writelist */
544 NULL, /* printer admin */
545 NULL, /* volume */
546 NULL, /* fstype */
547 NULL, /* vfs objects */
548 NULL, /* szMSDfsProxy */
549 NULL, /* szAioWriteBehind */
550 NULL, /* szDfree */
551 0, /* iMinPrintSpace */
552 1000, /* iMaxPrintJobs */
553 0, /* iMaxReportedPrintJobs */
554 0, /* iWriteCacheSize */
555 0744, /* iCreate_mask */
556 0000, /* iCreate_force_mode */
557 0777, /* iSecurity_mask */
558 0, /* iSecurity_force_mode */
559 0755, /* iDir_mask */
560 0000, /* iDir_force_mode */
561 0777, /* iDir_Security_mask */
562 0, /* iDir_Security_force_mode */
563 0, /* iMaxConnections */
564 CASE_LOWER, /* iDefaultCase */
565 DEFAULT_PRINTING, /* iPrinting */
566 2, /* iOplockContentionLimit */
567 0, /* iCSCPolicy */
568 1024, /* iBlock_size */
569 0, /* iDfreeCacheTime */
570 False, /* bPreexecClose */
571 False, /* bRootpreexecClose */
572 Auto, /* case sensitive */
573 True, /* case preserve */
574 True, /* short case preserve */
575 True, /* bHideDotFiles */
576 False, /* bHideSpecialFiles */
577 False, /* bHideUnReadable */
578 False, /* bHideUnWriteableFiles */
579 True, /* bBrowseable */
580 False, /* bAccessBasedShareEnum */
581 True, /* bAvailable */
582 True, /* bRead_only */
583 True, /* bNo_set_dir */
584 False, /* bGuest_only */
585 False, /* bAdministrative_share */
586 False, /* bGuest_ok */
587 False, /* bPrint_ok */
588 False, /* bMap_system */
589 False, /* bMap_hidden */
590 True, /* bMap_archive */
591 False, /* bStoreDosAttributes */
592 False, /* bDmapiSupport */
593 True, /* bLocking */
594 Auto, /* iStrictLocking */
595 True, /* bPosixLocking */
596 True, /* bShareModes */
597 True, /* bOpLocks */
598 True, /* bLevel2OpLocks */
599 False, /* bOnlyUser */
600 True, /* bMangledNames */
601 false, /* bWidelinks */
602 True, /* bSymlinks */
603 False, /* bSyncAlways */
604 False, /* bStrictAllocate */
605 False, /* bStrictSync */
606 '~', /* magic char */
607 NULL, /* copymap */
608 False, /* bDeleteReadonly */
609 False, /* bFakeOplocks */
610 False, /* bDeleteVetoFiles */
611 False, /* bDosFilemode */
612 True, /* bDosFiletimes */
613 False, /* bDosFiletimeResolution */
614 False, /* bFakeDirCreateTimes */
615 True, /* bBlockingLocks */
616 False, /* bInheritPerms */
617 False, /* bInheritACLS */
618 False, /* bInheritOwner */
619 False, /* bMSDfsRoot */
620 False, /* bUseClientDriver */
621 True, /* bDefaultDevmode */
622 False, /* bForcePrintername */
623 True, /* bNTAclSupport */
624 False, /* bForceUnknownAclUser */
625 False, /* bUseSendfile */
626 False, /* bProfileAcls */
627 False, /* bMap_acl_inherit */
628 False, /* bAfs_Share */
629 False, /* bEASupport */
630 True, /* bAclCheckPermissions */
631 True, /* bAclMapFullControl */
632 False, /* bAclGroupControl */
633 True, /* bChangeNotify */
634 True, /* bKernelChangeNotify */
635 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
636 0, /* iAioReadSize */
637 0, /* iAioWriteSize */
638 MAP_READONLY_YES, /* iMap_readonly */
639 #ifdef BROKEN_DIRECTORY_HANDLING
640 0, /* iDirectoryNameCacheSize */
641 #else
642 100, /* iDirectoryNameCacheSize */
643 #endif
644 Auto, /* ismb_encrypt */
645 NULL, /* Parametric options */
647 "" /* dummy */
650 /* local variables */
651 static struct service **ServicePtrs = NULL;
652 static int iNumServices = 0;
653 static int iServiceIndex = 0;
654 static struct db_context *ServiceHash;
655 static int *invalid_services = NULL;
656 static int num_invalid_services = 0;
657 static bool bInGlobalSection = True;
658 static bool bGlobalOnly = False;
659 static int server_role;
660 static int default_server_announce;
662 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
664 /* prototypes for the special type handlers */
665 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
666 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
667 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
668 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
669 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
670 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
671 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
672 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
673 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
674 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
675 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
676 static bool handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
678 static void set_server_role(void);
679 static void set_default_server_announce_type(void);
680 static void set_allowed_client_auth(void);
682 static void *lp_local_ptr(struct service *service, void *ptr);
684 static void add_to_file_list(const char *fname, const char *subfname);
686 static const struct enum_list enum_protocol[] = {
687 {PROTOCOL_NT1, "NT1"},
688 {PROTOCOL_LANMAN2, "LANMAN2"},
689 {PROTOCOL_LANMAN1, "LANMAN1"},
690 {PROTOCOL_CORE, "CORE"},
691 {PROTOCOL_COREPLUS, "COREPLUS"},
692 {PROTOCOL_COREPLUS, "CORE+"},
693 {-1, NULL}
696 static const struct enum_list enum_security[] = {
697 {SEC_SHARE, "SHARE"},
698 {SEC_USER, "USER"},
699 {SEC_SERVER, "SERVER"},
700 {SEC_DOMAIN, "DOMAIN"},
701 #ifdef HAVE_ADS
702 {SEC_ADS, "ADS"},
703 #endif
704 {-1, NULL}
707 static const struct enum_list enum_printing[] = {
708 {PRINT_SYSV, "sysv"},
709 {PRINT_AIX, "aix"},
710 {PRINT_HPUX, "hpux"},
711 {PRINT_BSD, "bsd"},
712 {PRINT_QNX, "qnx"},
713 {PRINT_PLP, "plp"},
714 {PRINT_LPRNG, "lprng"},
715 {PRINT_CUPS, "cups"},
716 {PRINT_IPRINT, "iprint"},
717 {PRINT_LPRNT, "nt"},
718 {PRINT_LPROS2, "os2"},
719 #ifdef DEVELOPER
720 {PRINT_TEST, "test"},
721 {PRINT_VLP, "vlp"},
722 #endif /* DEVELOPER */
723 {-1, NULL}
726 static const struct enum_list enum_ldap_sasl_wrapping[] = {
727 {0, "plain"},
728 {ADS_AUTH_SASL_SIGN, "sign"},
729 {ADS_AUTH_SASL_SEAL, "seal"},
730 {-1, NULL}
733 static const struct enum_list enum_ldap_ssl[] = {
734 {LDAP_SSL_OFF, "no"},
735 {LDAP_SSL_OFF, "off"},
736 {LDAP_SSL_START_TLS, "start tls"},
737 {LDAP_SSL_START_TLS, "start_tls"},
738 {-1, NULL}
741 static const struct enum_list enum_ldap_passwd_sync[] = {
742 {LDAP_PASSWD_SYNC_OFF, "no"},
743 {LDAP_PASSWD_SYNC_OFF, "off"},
744 {LDAP_PASSWD_SYNC_ON, "yes"},
745 {LDAP_PASSWD_SYNC_ON, "on"},
746 {LDAP_PASSWD_SYNC_ONLY, "only"},
747 {-1, NULL}
750 /* Types of machine we can announce as. */
751 #define ANNOUNCE_AS_NT_SERVER 1
752 #define ANNOUNCE_AS_WIN95 2
753 #define ANNOUNCE_AS_WFW 3
754 #define ANNOUNCE_AS_NT_WORKSTATION 4
756 static const struct enum_list enum_announce_as[] = {
757 {ANNOUNCE_AS_NT_SERVER, "NT"},
758 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
759 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
760 {ANNOUNCE_AS_WIN95, "win95"},
761 {ANNOUNCE_AS_WFW, "WfW"},
762 {-1, NULL}
765 static const struct enum_list enum_map_readonly[] = {
766 {MAP_READONLY_NO, "no"},
767 {MAP_READONLY_NO, "false"},
768 {MAP_READONLY_NO, "0"},
769 {MAP_READONLY_YES, "yes"},
770 {MAP_READONLY_YES, "true"},
771 {MAP_READONLY_YES, "1"},
772 {MAP_READONLY_PERMISSIONS, "permissions"},
773 {MAP_READONLY_PERMISSIONS, "perms"},
774 {-1, NULL}
777 static const struct enum_list enum_case[] = {
778 {CASE_LOWER, "lower"},
779 {CASE_UPPER, "upper"},
780 {-1, NULL}
783 static const struct enum_list enum_bool_auto[] = {
784 {False, "No"},
785 {False, "False"},
786 {False, "0"},
787 {True, "Yes"},
788 {True, "True"},
789 {True, "1"},
790 {Auto, "Auto"},
791 {-1, NULL}
794 /* Client-side offline caching policy types */
795 #define CSC_POLICY_MANUAL 0
796 #define CSC_POLICY_DOCUMENTS 1
797 #define CSC_POLICY_PROGRAMS 2
798 #define CSC_POLICY_DISABLE 3
800 static const struct enum_list enum_csc_policy[] = {
801 {CSC_POLICY_MANUAL, "manual"},
802 {CSC_POLICY_DOCUMENTS, "documents"},
803 {CSC_POLICY_PROGRAMS, "programs"},
804 {CSC_POLICY_DISABLE, "disable"},
805 {-1, NULL}
808 /* SMB signing types. */
809 static const struct enum_list enum_smb_signing_vals[] = {
810 {False, "No"},
811 {False, "False"},
812 {False, "0"},
813 {False, "Off"},
814 {False, "disabled"},
815 {True, "Yes"},
816 {True, "True"},
817 {True, "1"},
818 {True, "On"},
819 {True, "enabled"},
820 {Auto, "auto"},
821 {Required, "required"},
822 {Required, "mandatory"},
823 {Required, "force"},
824 {Required, "forced"},
825 {Required, "enforced"},
826 {-1, NULL}
829 /* ACL compatibility options. */
830 static const struct enum_list enum_acl_compat_vals[] = {
831 { ACL_COMPAT_AUTO, "auto" },
832 { ACL_COMPAT_WINNT, "winnt" },
833 { ACL_COMPAT_WIN2K, "win2k" },
834 { -1, NULL}
838 Do you want session setups at user level security with a invalid
839 password to be rejected or allowed in as guest? WinNT rejects them
840 but it can be a pain as it means "net view" needs to use a password
842 You have 3 choices in the setting of map_to_guest:
844 "Never" means session setups with an invalid password
845 are rejected. This is the default.
847 "Bad User" means session setups with an invalid password
848 are rejected, unless the username does not exist, in which case it
849 is treated as a guest login
851 "Bad Password" means session setups with an invalid password
852 are treated as a guest login
854 Note that map_to_guest only has an effect in user or server
855 level security.
858 static const struct enum_list enum_map_to_guest[] = {
859 {NEVER_MAP_TO_GUEST, "Never"},
860 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
861 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
862 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
863 {-1, NULL}
866 /* Config backend options */
868 static const struct enum_list enum_config_backend[] = {
869 {CONFIG_BACKEND_FILE, "file"},
870 {CONFIG_BACKEND_REGISTRY, "registry"},
871 {-1, NULL}
874 /* ADS kerberos ticket verification options */
876 static const struct enum_list enum_kerberos_method[] = {
877 {KERBEROS_VERIFY_SECRETS, "default"},
878 {KERBEROS_VERIFY_SECRETS, "secrets only"},
879 {KERBEROS_VERIFY_SYSTEM_KEYTAB, "system keytab"},
880 {KERBEROS_VERIFY_DEDICATED_KEYTAB, "dedicated keytab"},
881 {KERBEROS_VERIFY_SECRETS_AND_KEYTAB, "secrets and keytab"},
882 {-1, NULL}
885 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
887 * The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
888 * screen in SWAT. This is used to exclude parameters as well as to squash all
889 * parameters that have been duplicated by pseudonyms.
891 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
892 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
893 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
894 * respective views.
896 * NOTE2: Handling of duplicated (synonym) parameters:
897 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
898 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
899 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
900 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
903 static struct parm_struct parm_table[] = {
904 {N_("Base Options"), P_SEP, P_SEPARATOR},
907 .label = "dos charset",
908 .type = P_STRING,
909 .p_class = P_GLOBAL,
910 .ptr = &Globals.dos_charset,
911 .special = handle_charset,
912 .enum_list = NULL,
913 .flags = FLAG_ADVANCED
916 .label = "unix charset",
917 .type = P_STRING,
918 .p_class = P_GLOBAL,
919 .ptr = &Globals.unix_charset,
920 .special = handle_charset,
921 .enum_list = NULL,
922 .flags = FLAG_ADVANCED
925 .label = "display charset",
926 .type = P_STRING,
927 .p_class = P_GLOBAL,
928 .ptr = &Globals.display_charset,
929 .special = handle_charset,
930 .enum_list = NULL,
931 .flags = FLAG_ADVANCED
934 .label = "comment",
935 .type = P_STRING,
936 .p_class = P_LOCAL,
937 .ptr = &sDefault.comment,
938 .special = NULL,
939 .enum_list = NULL,
940 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT
943 .label = "path",
944 .type = P_STRING,
945 .p_class = P_LOCAL,
946 .ptr = &sDefault.szPath,
947 .special = NULL,
948 .enum_list = NULL,
949 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
952 .label = "directory",
953 .type = P_STRING,
954 .p_class = P_LOCAL,
955 .ptr = &sDefault.szPath,
956 .special = NULL,
957 .enum_list = NULL,
958 .flags = FLAG_HIDE,
961 .label = "workgroup",
962 .type = P_USTRING,
963 .p_class = P_GLOBAL,
964 .ptr = &Globals.szWorkgroup,
965 .special = handle_workgroup,
966 .enum_list = NULL,
967 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
969 #ifdef WITH_ADS
971 .label = "realm",
972 .type = P_USTRING,
973 .p_class = P_GLOBAL,
974 .ptr = &Globals.szRealm,
975 .special = NULL,
976 .enum_list = NULL,
977 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
979 #endif
981 .label = "netbios name",
982 .type = P_USTRING,
983 .p_class = P_GLOBAL,
984 .ptr = &Globals.szNetbiosName,
985 .special = handle_netbios_name,
986 .enum_list = NULL,
987 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
990 .label = "netbios aliases",
991 .type = P_LIST,
992 .p_class = P_GLOBAL,
993 .ptr = &Globals.szNetbiosAliases,
994 .special = handle_netbios_aliases,
995 .enum_list = NULL,
996 .flags = FLAG_ADVANCED,
999 .label = "netbios scope",
1000 .type = P_USTRING,
1001 .p_class = P_GLOBAL,
1002 .ptr = &Globals.szNetbiosScope,
1003 .special = handle_netbios_scope,
1004 .enum_list = NULL,
1005 .flags = FLAG_ADVANCED,
1008 .label = "server string",
1009 .type = P_STRING,
1010 .p_class = P_GLOBAL,
1011 .ptr = &Globals.szServerString,
1012 .special = NULL,
1013 .enum_list = NULL,
1014 .flags = FLAG_BASIC | FLAG_ADVANCED,
1017 .label = "interfaces",
1018 .type = P_LIST,
1019 .p_class = P_GLOBAL,
1020 .ptr = &Globals.szInterfaces,
1021 .special = NULL,
1022 .enum_list = NULL,
1023 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1026 .label = "bind interfaces only",
1027 .type = P_BOOL,
1028 .p_class = P_GLOBAL,
1029 .ptr = &Globals.bBindInterfacesOnly,
1030 .special = NULL,
1031 .enum_list = NULL,
1032 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1035 .label = "config backend",
1036 .type = P_ENUM,
1037 .p_class = P_GLOBAL,
1038 .ptr = &Globals.ConfigBackend,
1039 .special = NULL,
1040 .enum_list = enum_config_backend,
1041 .flags = FLAG_HIDE|FLAG_ADVANCED|FLAG_META,
1044 {N_("Security Options"), P_SEP, P_SEPARATOR},
1047 .label = "security",
1048 .type = P_ENUM,
1049 .p_class = P_GLOBAL,
1050 .ptr = &Globals.security,
1051 .special = NULL,
1052 .enum_list = enum_security,
1053 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1056 .label = "auth methods",
1057 .type = P_LIST,
1058 .p_class = P_GLOBAL,
1059 .ptr = &Globals.AuthMethods,
1060 .special = NULL,
1061 .enum_list = NULL,
1062 .flags = FLAG_ADVANCED,
1065 .label = "encrypt passwords",
1066 .type = P_BOOL,
1067 .p_class = P_GLOBAL,
1068 .ptr = &Globals.bEncryptPasswords,
1069 .special = NULL,
1070 .enum_list = NULL,
1071 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
1074 .label = "update encrypted",
1075 .type = P_BOOL,
1076 .p_class = P_GLOBAL,
1077 .ptr = &Globals.bUpdateEncrypt,
1078 .special = NULL,
1079 .enum_list = NULL,
1080 .flags = FLAG_ADVANCED,
1083 .label = "client schannel",
1084 .type = P_ENUM,
1085 .p_class = P_GLOBAL,
1086 .ptr = &Globals.clientSchannel,
1087 .special = NULL,
1088 .enum_list = enum_bool_auto,
1089 .flags = FLAG_BASIC | FLAG_ADVANCED,
1092 .label = "server schannel",
1093 .type = P_ENUM,
1094 .p_class = P_GLOBAL,
1095 .ptr = &Globals.serverSchannel,
1096 .special = NULL,
1097 .enum_list = enum_bool_auto,
1098 .flags = FLAG_BASIC | FLAG_ADVANCED,
1101 .label = "allow trusted domains",
1102 .type = P_BOOL,
1103 .p_class = P_GLOBAL,
1104 .ptr = &Globals.bAllowTrustedDomains,
1105 .special = NULL,
1106 .enum_list = NULL,
1107 .flags = FLAG_ADVANCED,
1110 .label = "map to guest",
1111 .type = P_ENUM,
1112 .p_class = P_GLOBAL,
1113 .ptr = &Globals.map_to_guest,
1114 .special = NULL,
1115 .enum_list = enum_map_to_guest,
1116 .flags = FLAG_ADVANCED,
1119 .label = "null passwords",
1120 .type = P_BOOL,
1121 .p_class = P_GLOBAL,
1122 .ptr = &Globals.bNullPasswords,
1123 .special = NULL,
1124 .enum_list = NULL,
1125 .flags = FLAG_ADVANCED,
1128 .label = "obey pam restrictions",
1129 .type = P_BOOL,
1130 .p_class = P_GLOBAL,
1131 .ptr = &Globals.bObeyPamRestrictions,
1132 .special = NULL,
1133 .enum_list = NULL,
1134 .flags = FLAG_ADVANCED,
1137 .label = "password server",
1138 .type = P_STRING,
1139 .p_class = P_GLOBAL,
1140 .ptr = &Globals.szPasswordServer,
1141 .special = NULL,
1142 .enum_list = NULL,
1143 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1146 .label = "smb passwd file",
1147 .type = P_STRING,
1148 .p_class = P_GLOBAL,
1149 .ptr = &Globals.szSMBPasswdFile,
1150 .special = NULL,
1151 .enum_list = NULL,
1152 .flags = FLAG_ADVANCED,
1155 .label = "private dir",
1156 .type = P_STRING,
1157 .p_class = P_GLOBAL,
1158 .ptr = &Globals.szPrivateDir,
1159 .special = NULL,
1160 .enum_list = NULL,
1161 .flags = FLAG_ADVANCED,
1164 .label = "passdb backend",
1165 .type = P_STRING,
1166 .p_class = P_GLOBAL,
1167 .ptr = &Globals.szPassdbBackend,
1168 .special = NULL,
1169 .enum_list = NULL,
1170 .flags = FLAG_ADVANCED | FLAG_WIZARD,
1173 .label = "algorithmic rid base",
1174 .type = P_INTEGER,
1175 .p_class = P_GLOBAL,
1176 .ptr = &Globals.AlgorithmicRidBase,
1177 .special = NULL,
1178 .enum_list = NULL,
1179 .flags = FLAG_ADVANCED,
1182 .label = "root directory",
1183 .type = P_STRING,
1184 .p_class = P_GLOBAL,
1185 .ptr = &Globals.szRootdir,
1186 .special = NULL,
1187 .enum_list = NULL,
1188 .flags = FLAG_ADVANCED,
1191 .label = "root dir",
1192 .type = P_STRING,
1193 .p_class = P_GLOBAL,
1194 .ptr = &Globals.szRootdir,
1195 .special = NULL,
1196 .enum_list = NULL,
1197 .flags = FLAG_HIDE,
1200 .label = "root",
1201 .type = P_STRING,
1202 .p_class = P_GLOBAL,
1203 .ptr = &Globals.szRootdir,
1204 .special = NULL,
1205 .enum_list = NULL,
1206 .flags = FLAG_HIDE,
1209 .label = "guest account",
1210 .type = P_STRING,
1211 .p_class = P_GLOBAL,
1212 .ptr = &Globals.szGuestaccount,
1213 .special = NULL,
1214 .enum_list = NULL,
1215 .flags = FLAG_BASIC | FLAG_ADVANCED,
1218 .label = "enable privileges",
1219 .type = P_BOOL,
1220 .p_class = P_GLOBAL,
1221 .ptr = &Globals.bEnablePrivileges,
1222 .special = NULL,
1223 .enum_list = NULL,
1224 .flags = FLAG_ADVANCED,
1228 .label = "pam password change",
1229 .type = P_BOOL,
1230 .p_class = P_GLOBAL,
1231 .ptr = &Globals.bPamPasswordChange,
1232 .special = NULL,
1233 .enum_list = NULL,
1234 .flags = FLAG_ADVANCED,
1237 .label = "passwd program",
1238 .type = P_STRING,
1239 .p_class = P_GLOBAL,
1240 .ptr = &Globals.szPasswdProgram,
1241 .special = NULL,
1242 .enum_list = NULL,
1243 .flags = FLAG_ADVANCED,
1246 .label = "passwd chat",
1247 .type = P_STRING,
1248 .p_class = P_GLOBAL,
1249 .ptr = &Globals.szPasswdChat,
1250 .special = NULL,
1251 .enum_list = NULL,
1252 .flags = FLAG_ADVANCED,
1255 .label = "passwd chat debug",
1256 .type = P_BOOL,
1257 .p_class = P_GLOBAL,
1258 .ptr = &Globals.bPasswdChatDebug,
1259 .special = NULL,
1260 .enum_list = NULL,
1261 .flags = FLAG_ADVANCED,
1264 .label = "passwd chat timeout",
1265 .type = P_INTEGER,
1266 .p_class = P_GLOBAL,
1267 .ptr = &Globals.iPasswdChatTimeout,
1268 .special = NULL,
1269 .enum_list = NULL,
1270 .flags = FLAG_ADVANCED,
1273 .label = "check password script",
1274 .type = P_STRING,
1275 .p_class = P_GLOBAL,
1276 .ptr = &Globals.szCheckPasswordScript,
1277 .special = NULL,
1278 .enum_list = NULL,
1279 .flags = FLAG_ADVANCED,
1282 .label = "username map",
1283 .type = P_STRING,
1284 .p_class = P_GLOBAL,
1285 .ptr = &Globals.szUsernameMap,
1286 .special = NULL,
1287 .enum_list = NULL,
1288 .flags = FLAG_ADVANCED,
1291 .label = "password level",
1292 .type = P_INTEGER,
1293 .p_class = P_GLOBAL,
1294 .ptr = &Globals.pwordlevel,
1295 .special = NULL,
1296 .enum_list = NULL,
1297 .flags = FLAG_ADVANCED,
1300 .label = "username level",
1301 .type = P_INTEGER,
1302 .p_class = P_GLOBAL,
1303 .ptr = &Globals.unamelevel,
1304 .special = NULL,
1305 .enum_list = NULL,
1306 .flags = FLAG_ADVANCED,
1309 .label = "unix password sync",
1310 .type = P_BOOL,
1311 .p_class = P_GLOBAL,
1312 .ptr = &Globals.bUnixPasswdSync,
1313 .special = NULL,
1314 .enum_list = NULL,
1315 .flags = FLAG_ADVANCED,
1318 .label = "restrict anonymous",
1319 .type = P_INTEGER,
1320 .p_class = P_GLOBAL,
1321 .ptr = &Globals.restrict_anonymous,
1322 .special = NULL,
1323 .enum_list = NULL,
1324 .flags = FLAG_ADVANCED,
1327 .label = "lanman auth",
1328 .type = P_BOOL,
1329 .p_class = P_GLOBAL,
1330 .ptr = &Globals.bLanmanAuth,
1331 .special = NULL,
1332 .enum_list = NULL,
1333 .flags = FLAG_ADVANCED,
1336 .label = "ntlm auth",
1337 .type = P_BOOL,
1338 .p_class = P_GLOBAL,
1339 .ptr = &Globals.bNTLMAuth,
1340 .special = NULL,
1341 .enum_list = NULL,
1342 .flags = FLAG_ADVANCED,
1345 .label = "client NTLMv2 auth",
1346 .type = P_BOOL,
1347 .p_class = P_GLOBAL,
1348 .ptr = &Globals.bClientNTLMv2Auth,
1349 .special = NULL,
1350 .enum_list = NULL,
1351 .flags = FLAG_ADVANCED,
1354 .label = "client lanman auth",
1355 .type = P_BOOL,
1356 .p_class = P_GLOBAL,
1357 .ptr = &Globals.bClientLanManAuth,
1358 .special = NULL,
1359 .enum_list = NULL,
1360 .flags = FLAG_ADVANCED,
1363 .label = "client plaintext auth",
1364 .type = P_BOOL,
1365 .p_class = P_GLOBAL,
1366 .ptr = &Globals.bClientPlaintextAuth,
1367 .special = NULL,
1368 .enum_list = NULL,
1369 .flags = FLAG_ADVANCED,
1372 .label = "username",
1373 .type = P_STRING,
1374 .p_class = P_LOCAL,
1375 .ptr = &sDefault.szUsername,
1376 .special = NULL,
1377 .enum_list = NULL,
1378 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1381 .label = "user",
1382 .type = P_STRING,
1383 .p_class = P_LOCAL,
1384 .ptr = &sDefault.szUsername,
1385 .special = NULL,
1386 .enum_list = NULL,
1387 .flags = FLAG_HIDE,
1390 .label = "users",
1391 .type = P_STRING,
1392 .p_class = P_LOCAL,
1393 .ptr = &sDefault.szUsername,
1394 .special = NULL,
1395 .enum_list = NULL,
1396 .flags = FLAG_HIDE,
1399 .label = "invalid users",
1400 .type = P_LIST,
1401 .p_class = P_LOCAL,
1402 .ptr = &sDefault.szInvalidUsers,
1403 .special = NULL,
1404 .enum_list = NULL,
1405 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1408 .label = "valid users",
1409 .type = P_LIST,
1410 .p_class = P_LOCAL,
1411 .ptr = &sDefault.szValidUsers,
1412 .special = NULL,
1413 .enum_list = NULL,
1414 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1417 .label = "admin users",
1418 .type = P_LIST,
1419 .p_class = P_LOCAL,
1420 .ptr = &sDefault.szAdminUsers,
1421 .special = NULL,
1422 .enum_list = NULL,
1423 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1426 .label = "read list",
1427 .type = P_LIST,
1428 .p_class = P_LOCAL,
1429 .ptr = &sDefault.readlist,
1430 .special = NULL,
1431 .enum_list = NULL,
1432 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1435 .label = "write list",
1436 .type = P_LIST,
1437 .p_class = P_LOCAL,
1438 .ptr = &sDefault.writelist,
1439 .special = NULL,
1440 .enum_list = NULL,
1441 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1444 .label = "printer admin",
1445 .type = P_LIST,
1446 .p_class = P_LOCAL,
1447 .ptr = &sDefault.printer_admin,
1448 .special = NULL,
1449 .enum_list = NULL,
1450 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED,
1453 .label = "force user",
1454 .type = P_STRING,
1455 .p_class = P_LOCAL,
1456 .ptr = &sDefault.force_user,
1457 .special = NULL,
1458 .enum_list = NULL,
1459 .flags = FLAG_ADVANCED | FLAG_SHARE,
1462 .label = "force group",
1463 .type = P_STRING,
1464 .p_class = P_LOCAL,
1465 .ptr = &sDefault.force_group,
1466 .special = NULL,
1467 .enum_list = NULL,
1468 .flags = FLAG_ADVANCED | FLAG_SHARE,
1471 .label = "group",
1472 .type = P_STRING,
1473 .p_class = P_LOCAL,
1474 .ptr = &sDefault.force_group,
1475 .special = NULL,
1476 .enum_list = NULL,
1477 .flags = FLAG_ADVANCED,
1480 .label = "read only",
1481 .type = P_BOOL,
1482 .p_class = P_LOCAL,
1483 .ptr = &sDefault.bRead_only,
1484 .special = NULL,
1485 .enum_list = NULL,
1486 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE,
1489 .label = "write ok",
1490 .type = P_BOOLREV,
1491 .p_class = P_LOCAL,
1492 .ptr = &sDefault.bRead_only,
1493 .special = NULL,
1494 .enum_list = NULL,
1495 .flags = FLAG_HIDE,
1498 .label = "writeable",
1499 .type = P_BOOLREV,
1500 .p_class = P_LOCAL,
1501 .ptr = &sDefault.bRead_only,
1502 .special = NULL,
1503 .enum_list = NULL,
1504 .flags = FLAG_HIDE,
1507 .label = "writable",
1508 .type = P_BOOLREV,
1509 .p_class = P_LOCAL,
1510 .ptr = &sDefault.bRead_only,
1511 .special = NULL,
1512 .enum_list = NULL,
1513 .flags = FLAG_HIDE,
1516 .label = "acl check permissions",
1517 .type = P_BOOL,
1518 .p_class = P_LOCAL,
1519 .ptr = &sDefault.bAclCheckPermissions,
1520 .special = NULL,
1521 .enum_list = NULL,
1522 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1525 .label = "acl group control",
1526 .type = P_BOOL,
1527 .p_class = P_LOCAL,
1528 .ptr = &sDefault.bAclGroupControl,
1529 .special = NULL,
1530 .enum_list = NULL,
1531 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1534 .label = "acl map full control",
1535 .type = P_BOOL,
1536 .p_class = P_LOCAL,
1537 .ptr = &sDefault.bAclMapFullControl,
1538 .special = NULL,
1539 .enum_list = NULL,
1540 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1543 .label = "create mask",
1544 .type = P_OCTAL,
1545 .p_class = P_LOCAL,
1546 .ptr = &sDefault.iCreate_mask,
1547 .special = NULL,
1548 .enum_list = NULL,
1549 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1552 .label = "create mode",
1553 .type = P_OCTAL,
1554 .p_class = P_LOCAL,
1555 .ptr = &sDefault.iCreate_mask,
1556 .special = NULL,
1557 .enum_list = NULL,
1558 .flags = FLAG_HIDE,
1561 .label = "force create mode",
1562 .type = P_OCTAL,
1563 .p_class = P_LOCAL,
1564 .ptr = &sDefault.iCreate_force_mode,
1565 .special = NULL,
1566 .enum_list = NULL,
1567 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1570 .label = "security mask",
1571 .type = P_OCTAL,
1572 .p_class = P_LOCAL,
1573 .ptr = &sDefault.iSecurity_mask,
1574 .special = NULL,
1575 .enum_list = NULL,
1576 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1579 .label = "force security mode",
1580 .type = P_OCTAL,
1581 .p_class = P_LOCAL,
1582 .ptr = &sDefault.iSecurity_force_mode,
1583 .special = NULL,
1584 .enum_list = NULL,
1585 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1588 .label = "directory mask",
1589 .type = P_OCTAL,
1590 .p_class = P_LOCAL,
1591 .ptr = &sDefault.iDir_mask,
1592 .special = NULL,
1593 .enum_list = NULL,
1594 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1597 .label = "directory mode",
1598 .type = P_OCTAL,
1599 .p_class = P_LOCAL,
1600 .ptr = &sDefault.iDir_mask,
1601 .special = NULL,
1602 .enum_list = NULL,
1603 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1606 .label = "force directory mode",
1607 .type = P_OCTAL,
1608 .p_class = P_LOCAL,
1609 .ptr = &sDefault.iDir_force_mode,
1610 .special = NULL,
1611 .enum_list = NULL,
1612 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1615 .label = "directory security mask",
1616 .type = P_OCTAL,
1617 .p_class = P_LOCAL,
1618 .ptr = &sDefault.iDir_Security_mask,
1619 .special = NULL,
1620 .enum_list = NULL,
1621 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1624 .label = "force directory security mode",
1625 .type = P_OCTAL,
1626 .p_class = P_LOCAL,
1627 .ptr = &sDefault.iDir_Security_force_mode,
1628 .special = NULL,
1629 .enum_list = NULL,
1630 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1633 .label = "force unknown acl user",
1634 .type = P_BOOL,
1635 .p_class = P_LOCAL,
1636 .ptr = &sDefault.bForceUnknownAclUser,
1637 .special = NULL,
1638 .enum_list = NULL,
1639 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
1642 .label = "inherit permissions",
1643 .type = P_BOOL,
1644 .p_class = P_LOCAL,
1645 .ptr = &sDefault.bInheritPerms,
1646 .special = NULL,
1647 .enum_list = NULL,
1648 .flags = FLAG_ADVANCED | FLAG_SHARE,
1651 .label = "inherit acls",
1652 .type = P_BOOL,
1653 .p_class = P_LOCAL,
1654 .ptr = &sDefault.bInheritACLS,
1655 .special = NULL,
1656 .enum_list = NULL,
1657 .flags = FLAG_ADVANCED | FLAG_SHARE,
1660 .label = "inherit owner",
1661 .type = P_BOOL,
1662 .p_class = P_LOCAL,
1663 .ptr = &sDefault.bInheritOwner,
1664 .special = NULL,
1665 .enum_list = NULL,
1666 .flags = FLAG_ADVANCED | FLAG_SHARE,
1669 .label = "guest only",
1670 .type = P_BOOL,
1671 .p_class = P_LOCAL,
1672 .ptr = &sDefault.bGuest_only,
1673 .special = NULL,
1674 .enum_list = NULL,
1675 .flags = FLAG_ADVANCED | FLAG_SHARE,
1678 .label = "only guest",
1679 .type = P_BOOL,
1680 .p_class = P_LOCAL,
1681 .ptr = &sDefault.bGuest_only,
1682 .special = NULL,
1683 .enum_list = NULL,
1684 .flags = FLAG_HIDE,
1687 .label = "administrative share",
1688 .type = P_BOOL,
1689 .p_class = P_LOCAL,
1690 .ptr = &sDefault.bAdministrative_share,
1691 .special = NULL,
1692 .enum_list = NULL,
1693 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1697 .label = "guest ok",
1698 .type = P_BOOL,
1699 .p_class = P_LOCAL,
1700 .ptr = &sDefault.bGuest_ok,
1701 .special = NULL,
1702 .enum_list = NULL,
1703 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1706 .label = "public",
1707 .type = P_BOOL,
1708 .p_class = P_LOCAL,
1709 .ptr = &sDefault.bGuest_ok,
1710 .special = NULL,
1711 .enum_list = NULL,
1712 .flags = FLAG_HIDE,
1715 .label = "only user",
1716 .type = P_BOOL,
1717 .p_class = P_LOCAL,
1718 .ptr = &sDefault.bOnlyUser,
1719 .special = NULL,
1720 .enum_list = NULL,
1721 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
1724 .label = "hosts allow",
1725 .type = P_LIST,
1726 .p_class = P_LOCAL,
1727 .ptr = &sDefault.szHostsallow,
1728 .special = NULL,
1729 .enum_list = NULL,
1730 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1733 .label = "allow hosts",
1734 .type = P_LIST,
1735 .p_class = P_LOCAL,
1736 .ptr = &sDefault.szHostsallow,
1737 .special = NULL,
1738 .enum_list = NULL,
1739 .flags = FLAG_HIDE,
1742 .label = "hosts deny",
1743 .type = P_LIST,
1744 .p_class = P_LOCAL,
1745 .ptr = &sDefault.szHostsdeny,
1746 .special = NULL,
1747 .enum_list = NULL,
1748 .flags = FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
1751 .label = "deny hosts",
1752 .type = P_LIST,
1753 .p_class = P_LOCAL,
1754 .ptr = &sDefault.szHostsdeny,
1755 .special = NULL,
1756 .enum_list = NULL,
1757 .flags = FLAG_HIDE,
1760 .label = "preload modules",
1761 .type = P_LIST,
1762 .p_class = P_GLOBAL,
1763 .ptr = &Globals.szPreloadModules,
1764 .special = NULL,
1765 .enum_list = NULL,
1766 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1769 .label = "dedicated keytab file",
1770 .type = P_STRING,
1771 .p_class = P_GLOBAL,
1772 .ptr = &Globals.szDedicatedKeytabFile,
1773 .special = NULL,
1774 .enum_list = NULL,
1775 .flags = FLAG_ADVANCED,
1778 .label = "kerberos method",
1779 .type = P_ENUM,
1780 .p_class = P_GLOBAL,
1781 .ptr = &Globals.iKerberosMethod,
1782 .special = NULL,
1783 .enum_list = enum_kerberos_method,
1784 .flags = FLAG_ADVANCED,
1787 .label = "map untrusted to domain",
1788 .type = P_BOOL,
1789 .p_class = P_GLOBAL,
1790 .ptr = &Globals.bMapUntrustedToDomain,
1791 .special = NULL,
1792 .enum_list = NULL,
1793 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
1797 {N_("Logging Options"), P_SEP, P_SEPARATOR},
1800 .label = "log level",
1801 .type = P_STRING,
1802 .p_class = P_GLOBAL,
1803 .ptr = &Globals.szLogLevel,
1804 .special = handle_debug_list,
1805 .enum_list = NULL,
1806 .flags = FLAG_ADVANCED,
1809 .label = "debuglevel",
1810 .type = P_STRING,
1811 .p_class = P_GLOBAL,
1812 .ptr = &Globals.szLogLevel,
1813 .special = handle_debug_list,
1814 .enum_list = NULL,
1815 .flags = FLAG_HIDE,
1818 .label = "syslog",
1819 .type = P_INTEGER,
1820 .p_class = P_GLOBAL,
1821 .ptr = &Globals.syslog,
1822 .special = NULL,
1823 .enum_list = NULL,
1824 .flags = FLAG_ADVANCED,
1827 .label = "syslog only",
1828 .type = P_BOOL,
1829 .p_class = P_GLOBAL,
1830 .ptr = &Globals.bSyslogOnly,
1831 .special = NULL,
1832 .enum_list = NULL,
1833 .flags = FLAG_ADVANCED,
1836 .label = "log file",
1837 .type = P_STRING,
1838 .p_class = P_GLOBAL,
1839 .ptr = &Globals.szLogFile,
1840 .special = NULL,
1841 .enum_list = NULL,
1842 .flags = FLAG_ADVANCED,
1845 .label = "max log size",
1846 .type = P_INTEGER,
1847 .p_class = P_GLOBAL,
1848 .ptr = &Globals.max_log_size,
1849 .special = NULL,
1850 .enum_list = NULL,
1851 .flags = FLAG_ADVANCED,
1854 .label = "debug timestamp",
1855 .type = P_BOOL,
1856 .p_class = P_GLOBAL,
1857 .ptr = &Globals.bTimestampLogs,
1858 .special = NULL,
1859 .enum_list = NULL,
1860 .flags = FLAG_ADVANCED,
1863 .label = "timestamp logs",
1864 .type = P_BOOL,
1865 .p_class = P_GLOBAL,
1866 .ptr = &Globals.bTimestampLogs,
1867 .special = NULL,
1868 .enum_list = NULL,
1869 .flags = FLAG_ADVANCED,
1872 .label = "debug prefix timestamp",
1873 .type = P_BOOL,
1874 .p_class = P_GLOBAL,
1875 .ptr = &Globals.bDebugPrefixTimestamp,
1876 .special = NULL,
1877 .enum_list = NULL,
1878 .flags = FLAG_ADVANCED,
1881 .label = "debug hires timestamp",
1882 .type = P_BOOL,
1883 .p_class = P_GLOBAL,
1884 .ptr = &Globals.bDebugHiresTimestamp,
1885 .special = NULL,
1886 .enum_list = NULL,
1887 .flags = FLAG_ADVANCED,
1890 .label = "debug pid",
1891 .type = P_BOOL,
1892 .p_class = P_GLOBAL,
1893 .ptr = &Globals.bDebugPid,
1894 .special = NULL,
1895 .enum_list = NULL,
1896 .flags = FLAG_ADVANCED,
1899 .label = "debug uid",
1900 .type = P_BOOL,
1901 .p_class = P_GLOBAL,
1902 .ptr = &Globals.bDebugUid,
1903 .special = NULL,
1904 .enum_list = NULL,
1905 .flags = FLAG_ADVANCED,
1908 .label = "debug class",
1909 .type = P_BOOL,
1910 .p_class = P_GLOBAL,
1911 .ptr = &Globals.bDebugClass,
1912 .special = NULL,
1913 .enum_list = NULL,
1914 .flags = FLAG_ADVANCED,
1917 .label = "enable core files",
1918 .type = P_BOOL,
1919 .p_class = P_GLOBAL,
1920 .ptr = &Globals.bEnableCoreFiles,
1921 .special = NULL,
1922 .enum_list = NULL,
1923 .flags = FLAG_ADVANCED,
1926 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
1929 .label = "allocation roundup size",
1930 .type = P_INTEGER,
1931 .p_class = P_LOCAL,
1932 .ptr = &sDefault.iallocation_roundup_size,
1933 .special = NULL,
1934 .enum_list = NULL,
1935 .flags = FLAG_ADVANCED,
1938 .label = "aio read size",
1939 .type = P_INTEGER,
1940 .p_class = P_LOCAL,
1941 .ptr = &sDefault.iAioReadSize,
1942 .special = NULL,
1943 .enum_list = NULL,
1944 .flags = FLAG_ADVANCED,
1947 .label = "aio write size",
1948 .type = P_INTEGER,
1949 .p_class = P_LOCAL,
1950 .ptr = &sDefault.iAioWriteSize,
1951 .special = NULL,
1952 .enum_list = NULL,
1953 .flags = FLAG_ADVANCED,
1956 .label = "aio write behind",
1957 .type = P_STRING,
1958 .p_class = P_LOCAL,
1959 .ptr = &sDefault.szAioWriteBehind,
1960 .special = NULL,
1961 .enum_list = NULL,
1962 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
1965 .label = "smb ports",
1966 .type = P_STRING,
1967 .p_class = P_GLOBAL,
1968 .ptr = &Globals.smb_ports,
1969 .special = NULL,
1970 .enum_list = NULL,
1971 .flags = FLAG_ADVANCED,
1974 .label = "large readwrite",
1975 .type = P_BOOL,
1976 .p_class = P_GLOBAL,
1977 .ptr = &Globals.bLargeReadwrite,
1978 .special = NULL,
1979 .enum_list = NULL,
1980 .flags = FLAG_ADVANCED,
1983 .label = "max protocol",
1984 .type = P_ENUM,
1985 .p_class = P_GLOBAL,
1986 .ptr = &Globals.maxprotocol,
1987 .special = NULL,
1988 .enum_list = enum_protocol,
1989 .flags = FLAG_ADVANCED,
1992 .label = "protocol",
1993 .type = P_ENUM,
1994 .p_class = P_GLOBAL,
1995 .ptr = &Globals.maxprotocol,
1996 .special = NULL,
1997 .enum_list = enum_protocol,
1998 .flags = FLAG_ADVANCED,
2001 .label = "min protocol",
2002 .type = P_ENUM,
2003 .p_class = P_GLOBAL,
2004 .ptr = &Globals.minprotocol,
2005 .special = NULL,
2006 .enum_list = enum_protocol,
2007 .flags = FLAG_ADVANCED,
2010 .label = "min receivefile size",
2011 .type = P_INTEGER,
2012 .p_class = P_GLOBAL,
2013 .ptr = &Globals.iminreceivefile,
2014 .special = NULL,
2015 .enum_list = NULL,
2016 .flags = FLAG_ADVANCED,
2019 .label = "read raw",
2020 .type = P_BOOL,
2021 .p_class = P_GLOBAL,
2022 .ptr = &Globals.bReadRaw,
2023 .special = NULL,
2024 .enum_list = NULL,
2025 .flags = FLAG_ADVANCED,
2028 .label = "write raw",
2029 .type = P_BOOL,
2030 .p_class = P_GLOBAL,
2031 .ptr = &Globals.bWriteRaw,
2032 .special = NULL,
2033 .enum_list = NULL,
2034 .flags = FLAG_ADVANCED,
2037 .label = "disable netbios",
2038 .type = P_BOOL,
2039 .p_class = P_GLOBAL,
2040 .ptr = &Globals.bDisableNetbios,
2041 .special = NULL,
2042 .enum_list = NULL,
2043 .flags = FLAG_ADVANCED,
2046 .label = "reset on zero vc",
2047 .type = P_BOOL,
2048 .p_class = P_GLOBAL,
2049 .ptr = &Globals.bResetOnZeroVC,
2050 .special = NULL,
2051 .enum_list = NULL,
2052 .flags = FLAG_ADVANCED,
2055 .label = "acl compatibility",
2056 .type = P_ENUM,
2057 .p_class = P_GLOBAL,
2058 .ptr = &Globals.iAclCompat,
2059 .special = NULL,
2060 .enum_list = enum_acl_compat_vals,
2061 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2064 .label = "defer sharing violations",
2065 .type = P_BOOL,
2066 .p_class = P_GLOBAL,
2067 .ptr = &Globals.bDeferSharingViolations,
2068 .special = NULL,
2069 .enum_list = NULL,
2070 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2073 .label = "ea support",
2074 .type = P_BOOL,
2075 .p_class = P_LOCAL,
2076 .ptr = &sDefault.bEASupport,
2077 .special = NULL,
2078 .enum_list = NULL,
2079 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2082 .label = "nt acl support",
2083 .type = P_BOOL,
2084 .p_class = P_LOCAL,
2085 .ptr = &sDefault.bNTAclSupport,
2086 .special = NULL,
2087 .enum_list = NULL,
2088 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2091 .label = "nt pipe support",
2092 .type = P_BOOL,
2093 .p_class = P_GLOBAL,
2094 .ptr = &Globals.bNTPipeSupport,
2095 .special = NULL,
2096 .enum_list = NULL,
2097 .flags = FLAG_ADVANCED,
2100 .label = "nt status support",
2101 .type = P_BOOL,
2102 .p_class = P_GLOBAL,
2103 .ptr = &Globals.bNTStatusSupport,
2104 .special = NULL,
2105 .enum_list = NULL,
2106 .flags = FLAG_ADVANCED,
2109 .label = "profile acls",
2110 .type = P_BOOL,
2111 .p_class = P_LOCAL,
2112 .ptr = &sDefault.bProfileAcls,
2113 .special = NULL,
2114 .enum_list = NULL,
2115 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
2118 .label = "announce version",
2119 .type = P_STRING,
2120 .p_class = P_GLOBAL,
2121 .ptr = &Globals.szAnnounceVersion,
2122 .special = NULL,
2123 .enum_list = NULL,
2124 .flags = FLAG_ADVANCED,
2127 .label = "announce as",
2128 .type = P_ENUM,
2129 .p_class = P_GLOBAL,
2130 .ptr = &Globals.announce_as,
2131 .special = NULL,
2132 .enum_list = enum_announce_as,
2133 .flags = FLAG_ADVANCED,
2136 .label = "map acl inherit",
2137 .type = P_BOOL,
2138 .p_class = P_LOCAL,
2139 .ptr = &sDefault.bMap_acl_inherit,
2140 .special = NULL,
2141 .enum_list = NULL,
2142 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2145 .label = "afs share",
2146 .type = P_BOOL,
2147 .p_class = P_LOCAL,
2148 .ptr = &sDefault.bAfs_Share,
2149 .special = NULL,
2150 .enum_list = NULL,
2151 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2154 .label = "max mux",
2155 .type = P_INTEGER,
2156 .p_class = P_GLOBAL,
2157 .ptr = &Globals.max_mux,
2158 .special = NULL,
2159 .enum_list = NULL,
2160 .flags = FLAG_ADVANCED,
2163 .label = "max xmit",
2164 .type = P_INTEGER,
2165 .p_class = P_GLOBAL,
2166 .ptr = &Globals.max_xmit,
2167 .special = NULL,
2168 .enum_list = NULL,
2169 .flags = FLAG_ADVANCED,
2172 .label = "name resolve order",
2173 .type = P_STRING,
2174 .p_class = P_GLOBAL,
2175 .ptr = &Globals.szNameResolveOrder,
2176 .special = NULL,
2177 .enum_list = NULL,
2178 .flags = FLAG_ADVANCED | FLAG_WIZARD,
2181 .label = "max ttl",
2182 .type = P_INTEGER,
2183 .p_class = P_GLOBAL,
2184 .ptr = &Globals.max_ttl,
2185 .special = NULL,
2186 .enum_list = NULL,
2187 .flags = FLAG_ADVANCED,
2190 .label = "max wins ttl",
2191 .type = P_INTEGER,
2192 .p_class = P_GLOBAL,
2193 .ptr = &Globals.max_wins_ttl,
2194 .special = NULL,
2195 .enum_list = NULL,
2196 .flags = FLAG_ADVANCED,
2199 .label = "min wins ttl",
2200 .type = P_INTEGER,
2201 .p_class = P_GLOBAL,
2202 .ptr = &Globals.min_wins_ttl,
2203 .special = NULL,
2204 .enum_list = NULL,
2205 .flags = FLAG_ADVANCED,
2208 .label = "time server",
2209 .type = P_BOOL,
2210 .p_class = P_GLOBAL,
2211 .ptr = &Globals.bTimeServer,
2212 .special = NULL,
2213 .enum_list = NULL,
2214 .flags = FLAG_ADVANCED,
2217 .label = "unix extensions",
2218 .type = P_BOOL,
2219 .p_class = P_GLOBAL,
2220 .ptr = &Globals.bUnixExtensions,
2221 .special = NULL,
2222 .enum_list = NULL,
2223 .flags = FLAG_ADVANCED,
2226 .label = "use spnego",
2227 .type = P_BOOL,
2228 .p_class = P_GLOBAL,
2229 .ptr = &Globals.bUseSpnego,
2230 .special = NULL,
2231 .enum_list = NULL,
2232 .flags = FLAG_ADVANCED,
2235 .label = "client signing",
2236 .type = P_ENUM,
2237 .p_class = P_GLOBAL,
2238 .ptr = &Globals.client_signing,
2239 .special = NULL,
2240 .enum_list = enum_smb_signing_vals,
2241 .flags = FLAG_ADVANCED,
2244 .label = "server signing",
2245 .type = P_ENUM,
2246 .p_class = P_GLOBAL,
2247 .ptr = &Globals.server_signing,
2248 .special = NULL,
2249 .enum_list = enum_smb_signing_vals,
2250 .flags = FLAG_ADVANCED,
2253 .label = "smb encrypt",
2254 .type = P_ENUM,
2255 .p_class = P_LOCAL,
2256 .ptr = &sDefault.ismb_encrypt,
2257 .special = NULL,
2258 .enum_list = enum_smb_signing_vals,
2259 .flags = FLAG_ADVANCED,
2262 .label = "client use spnego",
2263 .type = P_BOOL,
2264 .p_class = P_GLOBAL,
2265 .ptr = &Globals.bClientUseSpnego,
2266 .special = NULL,
2267 .enum_list = NULL,
2268 .flags = FLAG_ADVANCED,
2271 .label = "client ldap sasl wrapping",
2272 .type = P_ENUM,
2273 .p_class = P_GLOBAL,
2274 .ptr = &Globals.client_ldap_sasl_wrapping,
2275 .special = NULL,
2276 .enum_list = enum_ldap_sasl_wrapping,
2277 .flags = FLAG_ADVANCED,
2280 .label = "enable asu support",
2281 .type = P_BOOL,
2282 .p_class = P_GLOBAL,
2283 .ptr = &Globals.bASUSupport,
2284 .special = NULL,
2285 .enum_list = NULL,
2286 .flags = FLAG_ADVANCED,
2289 .label = "svcctl list",
2290 .type = P_LIST,
2291 .p_class = P_GLOBAL,
2292 .ptr = &Globals.szServicesList,
2293 .special = NULL,
2294 .enum_list = NULL,
2295 .flags = FLAG_ADVANCED,
2298 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
2301 .label = "block size",
2302 .type = P_INTEGER,
2303 .p_class = P_LOCAL,
2304 .ptr = &sDefault.iBlock_size,
2305 .special = NULL,
2306 .enum_list = NULL,
2307 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2310 .label = "deadtime",
2311 .type = P_INTEGER,
2312 .p_class = P_GLOBAL,
2313 .ptr = &Globals.deadtime,
2314 .special = NULL,
2315 .enum_list = NULL,
2316 .flags = FLAG_ADVANCED,
2319 .label = "getwd cache",
2320 .type = P_BOOL,
2321 .p_class = P_GLOBAL,
2322 .ptr = &Globals.getwd_cache,
2323 .special = NULL,
2324 .enum_list = NULL,
2325 .flags = FLAG_ADVANCED,
2328 .label = "keepalive",
2329 .type = P_INTEGER,
2330 .p_class = P_GLOBAL,
2331 .ptr = &Globals.iKeepalive,
2332 .special = NULL,
2333 .enum_list = NULL,
2334 .flags = FLAG_ADVANCED,
2337 .label = "change notify",
2338 .type = P_BOOL,
2339 .p_class = P_LOCAL,
2340 .ptr = &sDefault.bChangeNotify,
2341 .special = NULL,
2342 .enum_list = NULL,
2343 .flags = FLAG_ADVANCED | FLAG_SHARE,
2346 .label = "directory name cache size",
2347 .type = P_INTEGER,
2348 .p_class = P_LOCAL,
2349 .ptr = &sDefault.iDirectoryNameCacheSize,
2350 .special = NULL,
2351 .enum_list = NULL,
2352 .flags = FLAG_ADVANCED | FLAG_SHARE,
2355 .label = "kernel change notify",
2356 .type = P_BOOL,
2357 .p_class = P_LOCAL,
2358 .ptr = &sDefault.bKernelChangeNotify,
2359 .special = NULL,
2360 .enum_list = NULL,
2361 .flags = FLAG_ADVANCED | FLAG_SHARE,
2364 .label = "lpq cache time",
2365 .type = P_INTEGER,
2366 .p_class = P_GLOBAL,
2367 .ptr = &Globals.lpqcachetime,
2368 .special = NULL,
2369 .enum_list = NULL,
2370 .flags = FLAG_ADVANCED,
2373 .label = "max smbd processes",
2374 .type = P_INTEGER,
2375 .p_class = P_GLOBAL,
2376 .ptr = &Globals.iMaxSmbdProcesses,
2377 .special = NULL,
2378 .enum_list = NULL,
2379 .flags = FLAG_ADVANCED,
2382 .label = "max connections",
2383 .type = P_INTEGER,
2384 .p_class = P_LOCAL,
2385 .ptr = &sDefault.iMaxConnections,
2386 .special = NULL,
2387 .enum_list = NULL,
2388 .flags = FLAG_ADVANCED | FLAG_SHARE,
2391 .label = "paranoid server security",
2392 .type = P_BOOL,
2393 .p_class = P_GLOBAL,
2394 .ptr = &Globals.paranoid_server_security,
2395 .special = NULL,
2396 .enum_list = NULL,
2397 .flags = FLAG_ADVANCED,
2400 .label = "max disk size",
2401 .type = P_INTEGER,
2402 .p_class = P_GLOBAL,
2403 .ptr = &Globals.maxdisksize,
2404 .special = NULL,
2405 .enum_list = NULL,
2406 .flags = FLAG_ADVANCED,
2409 .label = "max open files",
2410 .type = P_INTEGER,
2411 .p_class = P_GLOBAL,
2412 .ptr = &Globals.max_open_files,
2413 .special = NULL,
2414 .enum_list = NULL,
2415 .flags = FLAG_ADVANCED,
2418 .label = "min print space",
2419 .type = P_INTEGER,
2420 .p_class = P_LOCAL,
2421 .ptr = &sDefault.iMinPrintSpace,
2422 .special = NULL,
2423 .enum_list = NULL,
2424 .flags = FLAG_ADVANCED | FLAG_PRINT,
2427 .label = "socket options",
2428 .type = P_STRING,
2429 .p_class = P_GLOBAL,
2430 .ptr = &Globals.szSocketOptions,
2431 .special = NULL,
2432 .enum_list = NULL,
2433 .flags = FLAG_ADVANCED,
2436 .label = "strict allocate",
2437 .type = P_BOOL,
2438 .p_class = P_LOCAL,
2439 .ptr = &sDefault.bStrictAllocate,
2440 .special = NULL,
2441 .enum_list = NULL,
2442 .flags = FLAG_ADVANCED | FLAG_SHARE,
2445 .label = "strict sync",
2446 .type = P_BOOL,
2447 .p_class = P_LOCAL,
2448 .ptr = &sDefault.bStrictSync,
2449 .special = NULL,
2450 .enum_list = NULL,
2451 .flags = FLAG_ADVANCED | FLAG_SHARE,
2454 .label = "sync always",
2455 .type = P_BOOL,
2456 .p_class = P_LOCAL,
2457 .ptr = &sDefault.bSyncAlways,
2458 .special = NULL,
2459 .enum_list = NULL,
2460 .flags = FLAG_ADVANCED | FLAG_SHARE,
2463 .label = "use mmap",
2464 .type = P_BOOL,
2465 .p_class = P_GLOBAL,
2466 .ptr = &Globals.bUseMmap,
2467 .special = NULL,
2468 .enum_list = NULL,
2469 .flags = FLAG_ADVANCED,
2472 .label = "use sendfile",
2473 .type = P_BOOL,
2474 .p_class = P_LOCAL,
2475 .ptr = &sDefault.bUseSendfile,
2476 .special = NULL,
2477 .enum_list = NULL,
2478 .flags = FLAG_ADVANCED | FLAG_SHARE,
2481 .label = "hostname lookups",
2482 .type = P_BOOL,
2483 .p_class = P_GLOBAL,
2484 .ptr = &Globals.bHostnameLookups,
2485 .special = NULL,
2486 .enum_list = NULL,
2487 .flags = FLAG_ADVANCED,
2490 .label = "write cache size",
2491 .type = P_INTEGER,
2492 .p_class = P_LOCAL,
2493 .ptr = &sDefault.iWriteCacheSize,
2494 .special = NULL,
2495 .enum_list = NULL,
2496 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED,
2499 .label = "name cache timeout",
2500 .type = P_INTEGER,
2501 .p_class = P_GLOBAL,
2502 .ptr = &Globals.name_cache_timeout,
2503 .special = NULL,
2504 .enum_list = NULL,
2505 .flags = FLAG_ADVANCED,
2508 .label = "ctdbd socket",
2509 .type = P_STRING,
2510 .p_class = P_GLOBAL,
2511 .ptr = &Globals.ctdbdSocket,
2512 .special = NULL,
2513 .enum_list = NULL,
2514 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2517 .label = "cluster addresses",
2518 .type = P_LIST,
2519 .p_class = P_GLOBAL,
2520 .ptr = &Globals.szClusterAddresses,
2521 .special = NULL,
2522 .enum_list = NULL,
2523 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2526 .label = "clustering",
2527 .type = P_BOOL,
2528 .p_class = P_GLOBAL,
2529 .ptr = &Globals.clustering,
2530 .special = NULL,
2531 .enum_list = NULL,
2532 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
2535 {N_("Printing Options"), P_SEP, P_SEPARATOR},
2538 .label = "max reported print jobs",
2539 .type = P_INTEGER,
2540 .p_class = P_LOCAL,
2541 .ptr = &sDefault.iMaxReportedPrintJobs,
2542 .special = NULL,
2543 .enum_list = NULL,
2544 .flags = FLAG_ADVANCED | FLAG_PRINT,
2547 .label = "max print jobs",
2548 .type = P_INTEGER,
2549 .p_class = P_LOCAL,
2550 .ptr = &sDefault.iMaxPrintJobs,
2551 .special = NULL,
2552 .enum_list = NULL,
2553 .flags = FLAG_ADVANCED | FLAG_PRINT,
2556 .label = "load printers",
2557 .type = P_BOOL,
2558 .p_class = P_GLOBAL,
2559 .ptr = &Globals.bLoadPrinters,
2560 .special = NULL,
2561 .enum_list = NULL,
2562 .flags = FLAG_ADVANCED | FLAG_PRINT,
2565 .label = "printcap cache time",
2566 .type = P_INTEGER,
2567 .p_class = P_GLOBAL,
2568 .ptr = &Globals.PrintcapCacheTime,
2569 .special = NULL,
2570 .enum_list = NULL,
2571 .flags = FLAG_ADVANCED | FLAG_PRINT,
2574 .label = "printcap name",
2575 .type = P_STRING,
2576 .p_class = P_GLOBAL,
2577 .ptr = &Globals.szPrintcapname,
2578 .special = NULL,
2579 .enum_list = NULL,
2580 .flags = FLAG_ADVANCED | FLAG_PRINT,
2583 .label = "printcap",
2584 .type = P_STRING,
2585 .p_class = P_GLOBAL,
2586 .ptr = &Globals.szPrintcapname,
2587 .special = NULL,
2588 .enum_list = NULL,
2589 .flags = FLAG_HIDE,
2592 .label = "printable",
2593 .type = P_BOOL,
2594 .p_class = P_LOCAL,
2595 .ptr = &sDefault.bPrint_ok,
2596 .special = NULL,
2597 .enum_list = NULL,
2598 .flags = FLAG_ADVANCED | FLAG_PRINT,
2601 .label = "print ok",
2602 .type = P_BOOL,
2603 .p_class = P_LOCAL,
2604 .ptr = &sDefault.bPrint_ok,
2605 .special = NULL,
2606 .enum_list = NULL,
2607 .flags = FLAG_HIDE,
2610 .label = "printing",
2611 .type = P_ENUM,
2612 .p_class = P_LOCAL,
2613 .ptr = &sDefault.iPrinting,
2614 .special = handle_printing,
2615 .enum_list = enum_printing,
2616 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2619 .label = "cups options",
2620 .type = P_STRING,
2621 .p_class = P_LOCAL,
2622 .ptr = &sDefault.szCupsOptions,
2623 .special = NULL,
2624 .enum_list = NULL,
2625 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2628 .label = "cups server",
2629 .type = P_STRING,
2630 .p_class = P_GLOBAL,
2631 .ptr = &Globals.szCupsServer,
2632 .special = NULL,
2633 .enum_list = NULL,
2634 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2637 .label = "cups connection timeout",
2638 .type = P_INTEGER,
2639 .p_class = P_GLOBAL,
2640 .ptr = &Globals.cups_connection_timeout,
2641 .special = NULL,
2642 .enum_list = NULL,
2643 .flags = FLAG_ADVANCED,
2646 .label = "iprint server",
2647 .type = P_STRING,
2648 .p_class = P_GLOBAL,
2649 .ptr = &Globals.szIPrintServer,
2650 .special = NULL,
2651 .enum_list = NULL,
2652 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2655 .label = "print command",
2656 .type = P_STRING,
2657 .p_class = P_LOCAL,
2658 .ptr = &sDefault.szPrintcommand,
2659 .special = NULL,
2660 .enum_list = NULL,
2661 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2664 .label = "disable spoolss",
2665 .type = P_BOOL,
2666 .p_class = P_GLOBAL,
2667 .ptr = &Globals.bDisableSpoolss,
2668 .special = NULL,
2669 .enum_list = NULL,
2670 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2673 .label = "enable spoolss",
2674 .type = P_BOOLREV,
2675 .p_class = P_GLOBAL,
2676 .ptr = &Globals.bDisableSpoolss,
2677 .special = NULL,
2678 .enum_list = NULL,
2679 .flags = FLAG_HIDE,
2682 .label = "lpq command",
2683 .type = P_STRING,
2684 .p_class = P_LOCAL,
2685 .ptr = &sDefault.szLpqcommand,
2686 .special = NULL,
2687 .enum_list = NULL,
2688 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2691 .label = "lprm command",
2692 .type = P_STRING,
2693 .p_class = P_LOCAL,
2694 .ptr = &sDefault.szLprmcommand,
2695 .special = NULL,
2696 .enum_list = NULL,
2697 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2700 .label = "lppause command",
2701 .type = P_STRING,
2702 .p_class = P_LOCAL,
2703 .ptr = &sDefault.szLppausecommand,
2704 .special = NULL,
2705 .enum_list = NULL,
2706 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2709 .label = "lpresume command",
2710 .type = P_STRING,
2711 .p_class = P_LOCAL,
2712 .ptr = &sDefault.szLpresumecommand,
2713 .special = NULL,
2714 .enum_list = NULL,
2715 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2718 .label = "queuepause command",
2719 .type = P_STRING,
2720 .p_class = P_LOCAL,
2721 .ptr = &sDefault.szQueuepausecommand,
2722 .special = NULL,
2723 .enum_list = NULL,
2724 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2727 .label = "queueresume command",
2728 .type = P_STRING,
2729 .p_class = P_LOCAL,
2730 .ptr = &sDefault.szQueueresumecommand,
2731 .special = NULL,
2732 .enum_list = NULL,
2733 .flags = FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL,
2736 .label = "addport command",
2737 .type = P_STRING,
2738 .p_class = P_GLOBAL,
2739 .ptr = &Globals.szAddPortCommand,
2740 .special = NULL,
2741 .enum_list = NULL,
2742 .flags = FLAG_ADVANCED,
2745 .label = "enumports command",
2746 .type = P_STRING,
2747 .p_class = P_GLOBAL,
2748 .ptr = &Globals.szEnumPortsCommand,
2749 .special = NULL,
2750 .enum_list = NULL,
2751 .flags = FLAG_ADVANCED,
2754 .label = "addprinter command",
2755 .type = P_STRING,
2756 .p_class = P_GLOBAL,
2757 .ptr = &Globals.szAddPrinterCommand,
2758 .special = NULL,
2759 .enum_list = NULL,
2760 .flags = FLAG_ADVANCED,
2763 .label = "deleteprinter command",
2764 .type = P_STRING,
2765 .p_class = P_GLOBAL,
2766 .ptr = &Globals.szDeletePrinterCommand,
2767 .special = NULL,
2768 .enum_list = NULL,
2769 .flags = FLAG_ADVANCED,
2772 .label = "show add printer wizard",
2773 .type = P_BOOL,
2774 .p_class = P_GLOBAL,
2775 .ptr = &Globals.bMsAddPrinterWizard,
2776 .special = NULL,
2777 .enum_list = NULL,
2778 .flags = FLAG_ADVANCED,
2781 .label = "os2 driver map",
2782 .type = P_STRING,
2783 .p_class = P_GLOBAL,
2784 .ptr = &Globals.szOs2DriverMap,
2785 .special = NULL,
2786 .enum_list = NULL,
2787 .flags = FLAG_ADVANCED,
2791 .label = "printer name",
2792 .type = P_STRING,
2793 .p_class = P_LOCAL,
2794 .ptr = &sDefault.szPrintername,
2795 .special = NULL,
2796 .enum_list = NULL,
2797 .flags = FLAG_ADVANCED | FLAG_PRINT,
2800 .label = "printer",
2801 .type = P_STRING,
2802 .p_class = P_LOCAL,
2803 .ptr = &sDefault.szPrintername,
2804 .special = NULL,
2805 .enum_list = NULL,
2806 .flags = FLAG_HIDE,
2809 .label = "use client driver",
2810 .type = P_BOOL,
2811 .p_class = P_LOCAL,
2812 .ptr = &sDefault.bUseClientDriver,
2813 .special = NULL,
2814 .enum_list = NULL,
2815 .flags = FLAG_ADVANCED | FLAG_PRINT,
2818 .label = "default devmode",
2819 .type = P_BOOL,
2820 .p_class = P_LOCAL,
2821 .ptr = &sDefault.bDefaultDevmode,
2822 .special = NULL,
2823 .enum_list = NULL,
2824 .flags = FLAG_ADVANCED | FLAG_PRINT,
2827 .label = "force printername",
2828 .type = P_BOOL,
2829 .p_class = P_LOCAL,
2830 .ptr = &sDefault.bForcePrintername,
2831 .special = NULL,
2832 .enum_list = NULL,
2833 .flags = FLAG_ADVANCED | FLAG_PRINT,
2836 .label = "printjob username",
2837 .type = P_STRING,
2838 .p_class = P_LOCAL,
2839 .ptr = &sDefault.szPrintjobUsername,
2840 .special = NULL,
2841 .enum_list = NULL,
2842 .flags = FLAG_ADVANCED | FLAG_PRINT,
2845 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
2848 .label = "mangling method",
2849 .type = P_STRING,
2850 .p_class = P_GLOBAL,
2851 .ptr = &Globals.szManglingMethod,
2852 .special = NULL,
2853 .enum_list = NULL,
2854 .flags = FLAG_ADVANCED,
2857 .label = "mangle prefix",
2858 .type = P_INTEGER,
2859 .p_class = P_GLOBAL,
2860 .ptr = &Globals.mangle_prefix,
2861 .special = NULL,
2862 .enum_list = NULL,
2863 .flags = FLAG_ADVANCED,
2867 .label = "default case",
2868 .type = P_ENUM,
2869 .p_class = P_LOCAL,
2870 .ptr = &sDefault.iDefaultCase,
2871 .special = NULL,
2872 .enum_list = enum_case,
2873 .flags = FLAG_ADVANCED | FLAG_SHARE,
2876 .label = "case sensitive",
2877 .type = P_ENUM,
2878 .p_class = P_LOCAL,
2879 .ptr = &sDefault.iCaseSensitive,
2880 .special = NULL,
2881 .enum_list = enum_bool_auto,
2882 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2885 .label = "casesignames",
2886 .type = P_ENUM,
2887 .p_class = P_LOCAL,
2888 .ptr = &sDefault.iCaseSensitive,
2889 .special = NULL,
2890 .enum_list = enum_bool_auto,
2891 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE,
2894 .label = "preserve case",
2895 .type = P_BOOL,
2896 .p_class = P_LOCAL,
2897 .ptr = &sDefault.bCasePreserve,
2898 .special = NULL,
2899 .enum_list = NULL,
2900 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2903 .label = "short preserve case",
2904 .type = P_BOOL,
2905 .p_class = P_LOCAL,
2906 .ptr = &sDefault.bShortCasePreserve,
2907 .special = NULL,
2908 .enum_list = NULL,
2909 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2912 .label = "mangling char",
2913 .type = P_CHAR,
2914 .p_class = P_LOCAL,
2915 .ptr = &sDefault.magic_char,
2916 .special = NULL,
2917 .enum_list = NULL,
2918 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2921 .label = "hide dot files",
2922 .type = P_BOOL,
2923 .p_class = P_LOCAL,
2924 .ptr = &sDefault.bHideDotFiles,
2925 .special = NULL,
2926 .enum_list = NULL,
2927 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2930 .label = "hide special files",
2931 .type = P_BOOL,
2932 .p_class = P_LOCAL,
2933 .ptr = &sDefault.bHideSpecialFiles,
2934 .special = NULL,
2935 .enum_list = NULL,
2936 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2939 .label = "hide unreadable",
2940 .type = P_BOOL,
2941 .p_class = P_LOCAL,
2942 .ptr = &sDefault.bHideUnReadable,
2943 .special = NULL,
2944 .enum_list = NULL,
2945 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2948 .label = "hide unwriteable files",
2949 .type = P_BOOL,
2950 .p_class = P_LOCAL,
2951 .ptr = &sDefault.bHideUnWriteableFiles,
2952 .special = NULL,
2953 .enum_list = NULL,
2954 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2957 .label = "delete veto files",
2958 .type = P_BOOL,
2959 .p_class = P_LOCAL,
2960 .ptr = &sDefault.bDeleteVetoFiles,
2961 .special = NULL,
2962 .enum_list = NULL,
2963 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2966 .label = "veto files",
2967 .type = P_STRING,
2968 .p_class = P_LOCAL,
2969 .ptr = &sDefault.szVetoFiles,
2970 .special = NULL,
2971 .enum_list = NULL,
2972 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2975 .label = "hide files",
2976 .type = P_STRING,
2977 .p_class = P_LOCAL,
2978 .ptr = &sDefault.szHideFiles,
2979 .special = NULL,
2980 .enum_list = NULL,
2981 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2984 .label = "veto oplock files",
2985 .type = P_STRING,
2986 .p_class = P_LOCAL,
2987 .ptr = &sDefault.szVetoOplockFiles,
2988 .special = NULL,
2989 .enum_list = NULL,
2990 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
2993 .label = "map archive",
2994 .type = P_BOOL,
2995 .p_class = P_LOCAL,
2996 .ptr = &sDefault.bMap_archive,
2997 .special = NULL,
2998 .enum_list = NULL,
2999 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3002 .label = "map hidden",
3003 .type = P_BOOL,
3004 .p_class = P_LOCAL,
3005 .ptr = &sDefault.bMap_hidden,
3006 .special = NULL,
3007 .enum_list = NULL,
3008 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3011 .label = "map system",
3012 .type = P_BOOL,
3013 .p_class = P_LOCAL,
3014 .ptr = &sDefault.bMap_system,
3015 .special = NULL,
3016 .enum_list = NULL,
3017 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3020 .label = "map readonly",
3021 .type = P_ENUM,
3022 .p_class = P_LOCAL,
3023 .ptr = &sDefault.iMap_readonly,
3024 .special = NULL,
3025 .enum_list = enum_map_readonly,
3026 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3029 .label = "mangled names",
3030 .type = P_BOOL,
3031 .p_class = P_LOCAL,
3032 .ptr = &sDefault.bMangledNames,
3033 .special = NULL,
3034 .enum_list = NULL,
3035 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3038 .label = "max stat cache size",
3039 .type = P_INTEGER,
3040 .p_class = P_GLOBAL,
3041 .ptr = &Globals.iMaxStatCacheSize,
3042 .special = NULL,
3043 .enum_list = NULL,
3044 .flags = FLAG_ADVANCED,
3047 .label = "stat cache",
3048 .type = P_BOOL,
3049 .p_class = P_GLOBAL,
3050 .ptr = &Globals.bStatCache,
3051 .special = NULL,
3052 .enum_list = NULL,
3053 .flags = FLAG_ADVANCED,
3056 .label = "store dos attributes",
3057 .type = P_BOOL,
3058 .p_class = P_LOCAL,
3059 .ptr = &sDefault.bStoreDosAttributes,
3060 .special = NULL,
3061 .enum_list = NULL,
3062 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3065 .label = "dmapi support",
3066 .type = P_BOOL,
3067 .p_class = P_LOCAL,
3068 .ptr = &sDefault.bDmapiSupport,
3069 .special = NULL,
3070 .enum_list = NULL,
3071 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3075 {N_("Domain Options"), P_SEP, P_SEPARATOR},
3078 .label = "machine password timeout",
3079 .type = P_INTEGER,
3080 .p_class = P_GLOBAL,
3081 .ptr = &Globals.machine_password_timeout,
3082 .special = NULL,
3083 .enum_list = NULL,
3084 .flags = FLAG_ADVANCED | FLAG_WIZARD,
3087 {N_("Logon Options"), P_SEP, P_SEPARATOR},
3090 .label = "add user script",
3091 .type = P_STRING,
3092 .p_class = P_GLOBAL,
3093 .ptr = &Globals.szAddUserScript,
3094 .special = NULL,
3095 .enum_list = NULL,
3096 .flags = FLAG_ADVANCED,
3099 .label = "rename user script",
3100 .type = P_STRING,
3101 .p_class = P_GLOBAL,
3102 .ptr = &Globals.szRenameUserScript,
3103 .special = NULL,
3104 .enum_list = NULL,
3105 .flags = FLAG_ADVANCED,
3108 .label = "delete user script",
3109 .type = P_STRING,
3110 .p_class = P_GLOBAL,
3111 .ptr = &Globals.szDelUserScript,
3112 .special = NULL,
3113 .enum_list = NULL,
3114 .flags = FLAG_ADVANCED,
3117 .label = "add group script",
3118 .type = P_STRING,
3119 .p_class = P_GLOBAL,
3120 .ptr = &Globals.szAddGroupScript,
3121 .special = NULL,
3122 .enum_list = NULL,
3123 .flags = FLAG_ADVANCED,
3126 .label = "delete group script",
3127 .type = P_STRING,
3128 .p_class = P_GLOBAL,
3129 .ptr = &Globals.szDelGroupScript,
3130 .special = NULL,
3131 .enum_list = NULL,
3132 .flags = FLAG_ADVANCED,
3135 .label = "add user to group script",
3136 .type = P_STRING,
3137 .p_class = P_GLOBAL,
3138 .ptr = &Globals.szAddUserToGroupScript,
3139 .special = NULL,
3140 .enum_list = NULL,
3141 .flags = FLAG_ADVANCED,
3144 .label = "delete user from group script",
3145 .type = P_STRING,
3146 .p_class = P_GLOBAL,
3147 .ptr = &Globals.szDelUserFromGroupScript,
3148 .special = NULL,
3149 .enum_list = NULL,
3150 .flags = FLAG_ADVANCED,
3153 .label = "set primary group script",
3154 .type = P_STRING,
3155 .p_class = P_GLOBAL,
3156 .ptr = &Globals.szSetPrimaryGroupScript,
3157 .special = NULL,
3158 .enum_list = NULL,
3159 .flags = FLAG_ADVANCED,
3162 .label = "add machine script",
3163 .type = P_STRING,
3164 .p_class = P_GLOBAL,
3165 .ptr = &Globals.szAddMachineScript,
3166 .special = NULL,
3167 .enum_list = NULL,
3168 .flags = FLAG_ADVANCED,
3171 .label = "shutdown script",
3172 .type = P_STRING,
3173 .p_class = P_GLOBAL,
3174 .ptr = &Globals.szShutdownScript,
3175 .special = NULL,
3176 .enum_list = NULL,
3177 .flags = FLAG_ADVANCED,
3180 .label = "abort shutdown script",
3181 .type = P_STRING,
3182 .p_class = P_GLOBAL,
3183 .ptr = &Globals.szAbortShutdownScript,
3184 .special = NULL,
3185 .enum_list = NULL,
3186 .flags = FLAG_ADVANCED,
3189 .label = "username map script",
3190 .type = P_STRING,
3191 .p_class = P_GLOBAL,
3192 .ptr = &Globals.szUsernameMapScript,
3193 .special = NULL,
3194 .enum_list = NULL,
3195 .flags = FLAG_ADVANCED,
3198 .label = "logon script",
3199 .type = P_STRING,
3200 .p_class = P_GLOBAL,
3201 .ptr = &Globals.szLogonScript,
3202 .special = NULL,
3203 .enum_list = NULL,
3204 .flags = FLAG_ADVANCED,
3207 .label = "logon path",
3208 .type = P_STRING,
3209 .p_class = P_GLOBAL,
3210 .ptr = &Globals.szLogonPath,
3211 .special = NULL,
3212 .enum_list = NULL,
3213 .flags = FLAG_ADVANCED,
3216 .label = "logon drive",
3217 .type = P_STRING,
3218 .p_class = P_GLOBAL,
3219 .ptr = &Globals.szLogonDrive,
3220 .special = NULL,
3221 .enum_list = NULL,
3222 .flags = FLAG_ADVANCED,
3225 .label = "logon home",
3226 .type = P_STRING,
3227 .p_class = P_GLOBAL,
3228 .ptr = &Globals.szLogonHome,
3229 .special = NULL,
3230 .enum_list = NULL,
3231 .flags = FLAG_ADVANCED,
3234 .label = "domain logons",
3235 .type = P_BOOL,
3236 .p_class = P_GLOBAL,
3237 .ptr = &Globals.bDomainLogons,
3238 .special = NULL,
3239 .enum_list = NULL,
3240 .flags = FLAG_ADVANCED,
3244 .label = "init logon delayed hosts",
3245 .type = P_LIST,
3246 .p_class = P_GLOBAL,
3247 .ptr = &Globals.szInitLogonDelayedHosts,
3248 .special = NULL,
3249 .enum_list = NULL,
3250 .flags = FLAG_ADVANCED,
3254 .label = "init logon delay",
3255 .type = P_INTEGER,
3256 .p_class = P_GLOBAL,
3257 .ptr = &Globals.InitLogonDelay,
3258 .special = NULL,
3259 .enum_list = NULL,
3260 .flags = FLAG_ADVANCED,
3264 {N_("Browse Options"), P_SEP, P_SEPARATOR},
3267 .label = "os level",
3268 .type = P_INTEGER,
3269 .p_class = P_GLOBAL,
3270 .ptr = &Globals.os_level,
3271 .special = NULL,
3272 .enum_list = NULL,
3273 .flags = FLAG_BASIC | FLAG_ADVANCED,
3276 .label = "lm announce",
3277 .type = P_ENUM,
3278 .p_class = P_GLOBAL,
3279 .ptr = &Globals.lm_announce,
3280 .special = NULL,
3281 .enum_list = enum_bool_auto,
3282 .flags = FLAG_ADVANCED,
3285 .label = "lm interval",
3286 .type = P_INTEGER,
3287 .p_class = P_GLOBAL,
3288 .ptr = &Globals.lm_interval,
3289 .special = NULL,
3290 .enum_list = NULL,
3291 .flags = FLAG_ADVANCED,
3294 .label = "preferred master",
3295 .type = P_ENUM,
3296 .p_class = P_GLOBAL,
3297 .ptr = &Globals.iPreferredMaster,
3298 .special = NULL,
3299 .enum_list = enum_bool_auto,
3300 .flags = FLAG_BASIC | FLAG_ADVANCED,
3303 .label = "prefered master",
3304 .type = P_ENUM,
3305 .p_class = P_GLOBAL,
3306 .ptr = &Globals.iPreferredMaster,
3307 .special = NULL,
3308 .enum_list = enum_bool_auto,
3309 .flags = FLAG_HIDE,
3312 .label = "local master",
3313 .type = P_BOOL,
3314 .p_class = P_GLOBAL,
3315 .ptr = &Globals.bLocalMaster,
3316 .special = NULL,
3317 .enum_list = NULL,
3318 .flags = FLAG_BASIC | FLAG_ADVANCED,
3321 .label = "domain master",
3322 .type = P_ENUM,
3323 .p_class = P_GLOBAL,
3324 .ptr = &Globals.iDomainMaster,
3325 .special = NULL,
3326 .enum_list = enum_bool_auto,
3327 .flags = FLAG_BASIC | FLAG_ADVANCED,
3330 .label = "browse list",
3331 .type = P_BOOL,
3332 .p_class = P_GLOBAL,
3333 .ptr = &Globals.bBrowseList,
3334 .special = NULL,
3335 .enum_list = NULL,
3336 .flags = FLAG_ADVANCED,
3339 .label = "browseable",
3340 .type = P_BOOL,
3341 .p_class = P_LOCAL,
3342 .ptr = &sDefault.bBrowseable,
3343 .special = NULL,
3344 .enum_list = NULL,
3345 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
3348 .label = "access based share enum",
3349 .type = P_BOOL,
3350 .p_class = P_LOCAL,
3351 .ptr = &sDefault.bAccessBasedShareEnum,
3352 .special = NULL,
3353 .enum_list = NULL,
3354 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE
3357 .label = "browsable",
3358 .type = P_BOOL,
3359 .p_class = P_LOCAL,
3360 .ptr = &sDefault.bBrowseable,
3361 .special = NULL,
3362 .enum_list = NULL,
3363 .flags = FLAG_HIDE,
3366 .label = "enhanced browsing",
3367 .type = P_BOOL,
3368 .p_class = P_GLOBAL,
3369 .ptr = &Globals.enhanced_browsing,
3370 .special = NULL,
3371 .enum_list = NULL,
3372 .flags = FLAG_ADVANCED,
3375 {N_("WINS Options"), P_SEP, P_SEPARATOR},
3378 .label = "dns proxy",
3379 .type = P_BOOL,
3380 .p_class = P_GLOBAL,
3381 .ptr = &Globals.bDNSproxy,
3382 .special = NULL,
3383 .enum_list = NULL,
3384 .flags = FLAG_ADVANCED,
3387 .label = "wins proxy",
3388 .type = P_BOOL,
3389 .p_class = P_GLOBAL,
3390 .ptr = &Globals.bWINSproxy,
3391 .special = NULL,
3392 .enum_list = NULL,
3393 .flags = FLAG_ADVANCED,
3396 .label = "wins server",
3397 .type = P_LIST,
3398 .p_class = P_GLOBAL,
3399 .ptr = &Globals.szWINSservers,
3400 .special = NULL,
3401 .enum_list = NULL,
3402 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3405 .label = "wins support",
3406 .type = P_BOOL,
3407 .p_class = P_GLOBAL,
3408 .ptr = &Globals.bWINSsupport,
3409 .special = NULL,
3410 .enum_list = NULL,
3411 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD,
3414 .label = "wins hook",
3415 .type = P_STRING,
3416 .p_class = P_GLOBAL,
3417 .ptr = &Globals.szWINSHook,
3418 .special = NULL,
3419 .enum_list = NULL,
3420 .flags = FLAG_ADVANCED,
3423 {N_("Locking Options"), P_SEP, P_SEPARATOR},
3426 .label = "blocking locks",
3427 .type = P_BOOL,
3428 .p_class = P_LOCAL,
3429 .ptr = &sDefault.bBlockingLocks,
3430 .special = NULL,
3431 .enum_list = NULL,
3432 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3435 .label = "csc policy",
3436 .type = P_ENUM,
3437 .p_class = P_LOCAL,
3438 .ptr = &sDefault.iCSCPolicy,
3439 .special = NULL,
3440 .enum_list = enum_csc_policy,
3441 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3444 .label = "fake oplocks",
3445 .type = P_BOOL,
3446 .p_class = P_LOCAL,
3447 .ptr = &sDefault.bFakeOplocks,
3448 .special = NULL,
3449 .enum_list = NULL,
3450 .flags = FLAG_ADVANCED | FLAG_SHARE,
3453 .label = "kernel oplocks",
3454 .type = P_BOOL,
3455 .p_class = P_GLOBAL,
3456 .ptr = &Globals.bKernelOplocks,
3457 .special = NULL,
3458 .enum_list = NULL,
3459 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3462 .label = "locking",
3463 .type = P_BOOL,
3464 .p_class = P_LOCAL,
3465 .ptr = &sDefault.bLocking,
3466 .special = NULL,
3467 .enum_list = NULL,
3468 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3471 .label = "lock spin time",
3472 .type = P_INTEGER,
3473 .p_class = P_GLOBAL,
3474 .ptr = &Globals.iLockSpinTime,
3475 .special = NULL,
3476 .enum_list = NULL,
3477 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3480 .label = "oplocks",
3481 .type = P_BOOL,
3482 .p_class = P_LOCAL,
3483 .ptr = &sDefault.bOpLocks,
3484 .special = NULL,
3485 .enum_list = NULL,
3486 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3489 .label = "level2 oplocks",
3490 .type = P_BOOL,
3491 .p_class = P_LOCAL,
3492 .ptr = &sDefault.bLevel2OpLocks,
3493 .special = NULL,
3494 .enum_list = NULL,
3495 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3498 .label = "oplock break wait time",
3499 .type = P_INTEGER,
3500 .p_class = P_GLOBAL,
3501 .ptr = &Globals.oplock_break_wait_time,
3502 .special = NULL,
3503 .enum_list = NULL,
3504 .flags = FLAG_ADVANCED | FLAG_GLOBAL,
3507 .label = "oplock contention limit",
3508 .type = P_INTEGER,
3509 .p_class = P_LOCAL,
3510 .ptr = &sDefault.iOplockContentionLimit,
3511 .special = NULL,
3512 .enum_list = NULL,
3513 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3516 .label = "posix locking",
3517 .type = P_BOOL,
3518 .p_class = P_LOCAL,
3519 .ptr = &sDefault.bPosixLocking,
3520 .special = NULL,
3521 .enum_list = NULL,
3522 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3525 .label = "strict locking",
3526 .type = P_ENUM,
3527 .p_class = P_LOCAL,
3528 .ptr = &sDefault.iStrictLocking,
3529 .special = NULL,
3530 .enum_list = enum_bool_auto,
3531 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
3534 .label = "share modes",
3535 .type = P_BOOL,
3536 .p_class = P_LOCAL,
3537 .ptr = &sDefault.bShareModes,
3538 .special = NULL,
3539 .enum_list = NULL,
3540 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED,
3543 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
3546 .label = "ldap admin dn",
3547 .type = P_STRING,
3548 .p_class = P_GLOBAL,
3549 .ptr = &Globals.szLdapAdminDn,
3550 .special = NULL,
3551 .enum_list = NULL,
3552 .flags = FLAG_ADVANCED,
3555 .label = "ldap delete dn",
3556 .type = P_BOOL,
3557 .p_class = P_GLOBAL,
3558 .ptr = &Globals.ldap_delete_dn,
3559 .special = NULL,
3560 .enum_list = NULL,
3561 .flags = FLAG_ADVANCED,
3564 .label = "ldap group suffix",
3565 .type = P_STRING,
3566 .p_class = P_GLOBAL,
3567 .ptr = &Globals.szLdapGroupSuffix,
3568 .special = NULL,
3569 .enum_list = NULL,
3570 .flags = FLAG_ADVANCED,
3573 .label = "ldap idmap suffix",
3574 .type = P_STRING,
3575 .p_class = P_GLOBAL,
3576 .ptr = &Globals.szLdapIdmapSuffix,
3577 .special = NULL,
3578 .enum_list = NULL,
3579 .flags = FLAG_ADVANCED,
3582 .label = "ldap machine suffix",
3583 .type = P_STRING,
3584 .p_class = P_GLOBAL,
3585 .ptr = &Globals.szLdapMachineSuffix,
3586 .special = NULL,
3587 .enum_list = NULL,
3588 .flags = FLAG_ADVANCED,
3591 .label = "ldap passwd sync",
3592 .type = P_ENUM,
3593 .p_class = P_GLOBAL,
3594 .ptr = &Globals.ldap_passwd_sync,
3595 .special = NULL,
3596 .enum_list = enum_ldap_passwd_sync,
3597 .flags = FLAG_ADVANCED,
3600 .label = "ldap password sync",
3601 .type = P_ENUM,
3602 .p_class = P_GLOBAL,
3603 .ptr = &Globals.ldap_passwd_sync,
3604 .special = NULL,
3605 .enum_list = enum_ldap_passwd_sync,
3606 .flags = FLAG_HIDE,
3609 .label = "ldap replication sleep",
3610 .type = P_INTEGER,
3611 .p_class = P_GLOBAL,
3612 .ptr = &Globals.ldap_replication_sleep,
3613 .special = NULL,
3614 .enum_list = NULL,
3615 .flags = FLAG_ADVANCED,
3618 .label = "ldap suffix",
3619 .type = P_STRING,
3620 .p_class = P_GLOBAL,
3621 .ptr = &Globals.szLdapSuffix,
3622 .special = NULL,
3623 .enum_list = NULL,
3624 .flags = FLAG_ADVANCED,
3627 .label = "ldap ssl",
3628 .type = P_ENUM,
3629 .p_class = P_GLOBAL,
3630 .ptr = &Globals.ldap_ssl,
3631 .special = NULL,
3632 .enum_list = enum_ldap_ssl,
3633 .flags = FLAG_ADVANCED,
3636 .label = "ldap ssl ads",
3637 .type = P_BOOL,
3638 .p_class = P_GLOBAL,
3639 .ptr = &Globals.ldap_ssl_ads,
3640 .special = NULL,
3641 .enum_list = NULL,
3642 .flags = FLAG_ADVANCED,
3645 .label = "ldap timeout",
3646 .type = P_INTEGER,
3647 .p_class = P_GLOBAL,
3648 .ptr = &Globals.ldap_timeout,
3649 .special = NULL,
3650 .enum_list = NULL,
3651 .flags = FLAG_ADVANCED,
3654 .label = "ldap connection timeout",
3655 .type = P_INTEGER,
3656 .p_class = P_GLOBAL,
3657 .ptr = &Globals.ldap_connection_timeout,
3658 .special = NULL,
3659 .enum_list = NULL,
3660 .flags = FLAG_ADVANCED,
3663 .label = "ldap page size",
3664 .type = P_INTEGER,
3665 .p_class = P_GLOBAL,
3666 .ptr = &Globals.ldap_page_size,
3667 .special = NULL,
3668 .enum_list = NULL,
3669 .flags = FLAG_ADVANCED,
3672 .label = "ldap user suffix",
3673 .type = P_STRING,
3674 .p_class = P_GLOBAL,
3675 .ptr = &Globals.szLdapUserSuffix,
3676 .special = NULL,
3677 .enum_list = NULL,
3678 .flags = FLAG_ADVANCED,
3681 .label = "ldap debug level",
3682 .type = P_INTEGER,
3683 .p_class = P_GLOBAL,
3684 .ptr = &Globals.ldap_debug_level,
3685 .special = handle_ldap_debug_level,
3686 .enum_list = NULL,
3687 .flags = FLAG_ADVANCED,
3690 .label = "ldap debug threshold",
3691 .type = P_INTEGER,
3692 .p_class = P_GLOBAL,
3693 .ptr = &Globals.ldap_debug_threshold,
3694 .special = NULL,
3695 .enum_list = NULL,
3696 .flags = FLAG_ADVANCED,
3699 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
3702 .label = "eventlog list",
3703 .type = P_LIST,
3704 .p_class = P_GLOBAL,
3705 .ptr = &Globals.szEventLogs,
3706 .special = NULL,
3707 .enum_list = NULL,
3708 .flags = FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE,
3711 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
3714 .label = "add share command",
3715 .type = P_STRING,
3716 .p_class = P_GLOBAL,
3717 .ptr = &Globals.szAddShareCommand,
3718 .special = NULL,
3719 .enum_list = NULL,
3720 .flags = FLAG_ADVANCED,
3723 .label = "change share command",
3724 .type = P_STRING,
3725 .p_class = P_GLOBAL,
3726 .ptr = &Globals.szChangeShareCommand,
3727 .special = NULL,
3728 .enum_list = NULL,
3729 .flags = FLAG_ADVANCED,
3732 .label = "delete share command",
3733 .type = P_STRING,
3734 .p_class = P_GLOBAL,
3735 .ptr = &Globals.szDeleteShareCommand,
3736 .special = NULL,
3737 .enum_list = NULL,
3738 .flags = FLAG_ADVANCED,
3741 .label = "config file",
3742 .type = P_STRING,
3743 .p_class = P_GLOBAL,
3744 .ptr = &Globals.szConfigFile,
3745 .special = NULL,
3746 .enum_list = NULL,
3747 .flags = FLAG_HIDE|FLAG_META,
3750 .label = "preload",
3751 .type = P_STRING,
3752 .p_class = P_GLOBAL,
3753 .ptr = &Globals.szAutoServices,
3754 .special = NULL,
3755 .enum_list = NULL,
3756 .flags = FLAG_ADVANCED,
3759 .label = "auto services",
3760 .type = P_STRING,
3761 .p_class = P_GLOBAL,
3762 .ptr = &Globals.szAutoServices,
3763 .special = NULL,
3764 .enum_list = NULL,
3765 .flags = FLAG_ADVANCED,
3768 .label = "lock directory",
3769 .type = P_STRING,
3770 .p_class = P_GLOBAL,
3771 .ptr = &Globals.szLockDir,
3772 .special = NULL,
3773 .enum_list = NULL,
3774 .flags = FLAG_ADVANCED,
3777 .label = "lock dir",
3778 .type = P_STRING,
3779 .p_class = P_GLOBAL,
3780 .ptr = &Globals.szLockDir,
3781 .special = NULL,
3782 .enum_list = NULL,
3783 .flags = FLAG_HIDE,
3786 .label = "state directory",
3787 .type = P_STRING,
3788 .p_class = P_GLOBAL,
3789 .ptr = &Globals.szStateDir,
3790 .special = NULL,
3791 .enum_list = NULL,
3792 .flags = FLAG_ADVANCED,
3795 .label = "cache directory",
3796 .type = P_STRING,
3797 .p_class = P_GLOBAL,
3798 .ptr = &Globals.szCacheDir,
3799 .special = NULL,
3800 .enum_list = NULL,
3801 .flags = FLAG_ADVANCED,
3804 .label = "pid directory",
3805 .type = P_STRING,
3806 .p_class = P_GLOBAL,
3807 .ptr = &Globals.szPidDir,
3808 .special = NULL,
3809 .enum_list = NULL,
3810 .flags = FLAG_ADVANCED,
3812 #ifdef WITH_UTMP
3814 .label = "utmp directory",
3815 .type = P_STRING,
3816 .p_class = P_GLOBAL,
3817 .ptr = &Globals.szUtmpDir,
3818 .special = NULL,
3819 .enum_list = NULL,
3820 .flags = FLAG_ADVANCED,
3823 .label = "wtmp directory",
3824 .type = P_STRING,
3825 .p_class = P_GLOBAL,
3826 .ptr = &Globals.szWtmpDir,
3827 .special = NULL,
3828 .enum_list = NULL,
3829 .flags = FLAG_ADVANCED,
3832 .label = "utmp",
3833 .type = P_BOOL,
3834 .p_class = P_GLOBAL,
3835 .ptr = &Globals.bUtmp,
3836 .special = NULL,
3837 .enum_list = NULL,
3838 .flags = FLAG_ADVANCED,
3840 #endif
3842 .label = "default service",
3843 .type = P_STRING,
3844 .p_class = P_GLOBAL,
3845 .ptr = &Globals.szDefaultService,
3846 .special = NULL,
3847 .enum_list = NULL,
3848 .flags = FLAG_ADVANCED,
3851 .label = "default",
3852 .type = P_STRING,
3853 .p_class = P_GLOBAL,
3854 .ptr = &Globals.szDefaultService,
3855 .special = NULL,
3856 .enum_list = NULL,
3857 .flags = FLAG_ADVANCED,
3860 .label = "message command",
3861 .type = P_STRING,
3862 .p_class = P_GLOBAL,
3863 .ptr = &Globals.szMsgCommand,
3864 .special = NULL,
3865 .enum_list = NULL,
3866 .flags = FLAG_ADVANCED,
3869 .label = "dfree cache time",
3870 .type = P_INTEGER,
3871 .p_class = P_LOCAL,
3872 .ptr = &sDefault.iDfreeCacheTime,
3873 .special = NULL,
3874 .enum_list = NULL,
3875 .flags = FLAG_ADVANCED,
3878 .label = "dfree command",
3879 .type = P_STRING,
3880 .p_class = P_LOCAL,
3881 .ptr = &sDefault.szDfree,
3882 .special = NULL,
3883 .enum_list = NULL,
3884 .flags = FLAG_ADVANCED,
3887 .label = "get quota command",
3888 .type = P_STRING,
3889 .p_class = P_GLOBAL,
3890 .ptr = &Globals.szGetQuota,
3891 .special = NULL,
3892 .enum_list = NULL,
3893 .flags = FLAG_ADVANCED,
3896 .label = "set quota command",
3897 .type = P_STRING,
3898 .p_class = P_GLOBAL,
3899 .ptr = &Globals.szSetQuota,
3900 .special = NULL,
3901 .enum_list = NULL,
3902 .flags = FLAG_ADVANCED,
3905 .label = "remote announce",
3906 .type = P_STRING,
3907 .p_class = P_GLOBAL,
3908 .ptr = &Globals.szRemoteAnnounce,
3909 .special = NULL,
3910 .enum_list = NULL,
3911 .flags = FLAG_ADVANCED,
3914 .label = "remote browse sync",
3915 .type = P_STRING,
3916 .p_class = P_GLOBAL,
3917 .ptr = &Globals.szRemoteBrowseSync,
3918 .special = NULL,
3919 .enum_list = NULL,
3920 .flags = FLAG_ADVANCED,
3923 .label = "socket address",
3924 .type = P_STRING,
3925 .p_class = P_GLOBAL,
3926 .ptr = &Globals.szSocketAddress,
3927 .special = NULL,
3928 .enum_list = NULL,
3929 .flags = FLAG_ADVANCED,
3932 .label = "homedir map",
3933 .type = P_STRING,
3934 .p_class = P_GLOBAL,
3935 .ptr = &Globals.szNISHomeMapName,
3936 .special = NULL,
3937 .enum_list = NULL,
3938 .flags = FLAG_ADVANCED,
3941 .label = "afs username map",
3942 .type = P_STRING,
3943 .p_class = P_GLOBAL,
3944 .ptr = &Globals.szAfsUsernameMap,
3945 .special = NULL,
3946 .enum_list = NULL,
3947 .flags = FLAG_ADVANCED,
3950 .label = "afs token lifetime",
3951 .type = P_INTEGER,
3952 .p_class = P_GLOBAL,
3953 .ptr = &Globals.iAfsTokenLifetime,
3954 .special = NULL,
3955 .enum_list = NULL,
3956 .flags = FLAG_ADVANCED,
3959 .label = "log nt token command",
3960 .type = P_STRING,
3961 .p_class = P_GLOBAL,
3962 .ptr = &Globals.szLogNtTokenCommand,
3963 .special = NULL,
3964 .enum_list = NULL,
3965 .flags = FLAG_ADVANCED,
3968 .label = "time offset",
3969 .type = P_INTEGER,
3970 .p_class = P_GLOBAL,
3971 .ptr = &extra_time_offset,
3972 .special = NULL,
3973 .enum_list = NULL,
3974 .flags = FLAG_ADVANCED,
3977 .label = "NIS homedir",
3978 .type = P_BOOL,
3979 .p_class = P_GLOBAL,
3980 .ptr = &Globals.bNISHomeMap,
3981 .special = NULL,
3982 .enum_list = NULL,
3983 .flags = FLAG_ADVANCED,
3986 .label = "-valid",
3987 .type = P_BOOL,
3988 .p_class = P_LOCAL,
3989 .ptr = &sDefault.valid,
3990 .special = NULL,
3991 .enum_list = NULL,
3992 .flags = FLAG_HIDE,
3995 .label = "copy",
3996 .type = P_STRING,
3997 .p_class = P_LOCAL,
3998 .ptr = &sDefault.szCopy,
3999 .special = handle_copy,
4000 .enum_list = NULL,
4001 .flags = FLAG_HIDE,
4004 .label = "include",
4005 .type = P_STRING,
4006 .p_class = P_LOCAL,
4007 .ptr = &sDefault.szInclude,
4008 .special = handle_include,
4009 .enum_list = NULL,
4010 .flags = FLAG_HIDE|FLAG_META,
4013 .label = "preexec",
4014 .type = P_STRING,
4015 .p_class = P_LOCAL,
4016 .ptr = &sDefault.szPreExec,
4017 .special = NULL,
4018 .enum_list = NULL,
4019 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4022 .label = "exec",
4023 .type = P_STRING,
4024 .p_class = P_LOCAL,
4025 .ptr = &sDefault.szPreExec,
4026 .special = NULL,
4027 .enum_list = NULL,
4028 .flags = FLAG_ADVANCED,
4031 .label = "preexec close",
4032 .type = P_BOOL,
4033 .p_class = P_LOCAL,
4034 .ptr = &sDefault.bPreexecClose,
4035 .special = NULL,
4036 .enum_list = NULL,
4037 .flags = FLAG_ADVANCED | FLAG_SHARE,
4040 .label = "postexec",
4041 .type = P_STRING,
4042 .p_class = P_LOCAL,
4043 .ptr = &sDefault.szPostExec,
4044 .special = NULL,
4045 .enum_list = NULL,
4046 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4049 .label = "root preexec",
4050 .type = P_STRING,
4051 .p_class = P_LOCAL,
4052 .ptr = &sDefault.szRootPreExec,
4053 .special = NULL,
4054 .enum_list = NULL,
4055 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4058 .label = "root preexec close",
4059 .type = P_BOOL,
4060 .p_class = P_LOCAL,
4061 .ptr = &sDefault.bRootpreexecClose,
4062 .special = NULL,
4063 .enum_list = NULL,
4064 .flags = FLAG_ADVANCED | FLAG_SHARE,
4067 .label = "root postexec",
4068 .type = P_STRING,
4069 .p_class = P_LOCAL,
4070 .ptr = &sDefault.szRootPostExec,
4071 .special = NULL,
4072 .enum_list = NULL,
4073 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4076 .label = "available",
4077 .type = P_BOOL,
4078 .p_class = P_LOCAL,
4079 .ptr = &sDefault.bAvailable,
4080 .special = NULL,
4081 .enum_list = NULL,
4082 .flags = FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT,
4085 .label = "registry shares",
4086 .type = P_BOOL,
4087 .p_class = P_GLOBAL,
4088 .ptr = &Globals.bRegistryShares,
4089 .special = NULL,
4090 .enum_list = NULL,
4091 .flags = FLAG_ADVANCED,
4094 .label = "usershare allow guests",
4095 .type = P_BOOL,
4096 .p_class = P_GLOBAL,
4097 .ptr = &Globals.bUsershareAllowGuests,
4098 .special = NULL,
4099 .enum_list = NULL,
4100 .flags = FLAG_ADVANCED,
4103 .label = "usershare max shares",
4104 .type = P_INTEGER,
4105 .p_class = P_GLOBAL,
4106 .ptr = &Globals.iUsershareMaxShares,
4107 .special = NULL,
4108 .enum_list = NULL,
4109 .flags = FLAG_ADVANCED,
4112 .label = "usershare owner only",
4113 .type = P_BOOL,
4114 .p_class = P_GLOBAL,
4115 .ptr = &Globals.bUsershareOwnerOnly,
4116 .special = NULL,
4117 .enum_list = NULL,
4118 .flags = FLAG_ADVANCED,
4121 .label = "usershare path",
4122 .type = P_STRING,
4123 .p_class = P_GLOBAL,
4124 .ptr = &Globals.szUsersharePath,
4125 .special = NULL,
4126 .enum_list = NULL,
4127 .flags = FLAG_ADVANCED,
4130 .label = "usershare prefix allow list",
4131 .type = P_LIST,
4132 .p_class = P_GLOBAL,
4133 .ptr = &Globals.szUsersharePrefixAllowList,
4134 .special = NULL,
4135 .enum_list = NULL,
4136 .flags = FLAG_ADVANCED,
4139 .label = "usershare prefix deny list",
4140 .type = P_LIST,
4141 .p_class = P_GLOBAL,
4142 .ptr = &Globals.szUsersharePrefixDenyList,
4143 .special = NULL,
4144 .enum_list = NULL,
4145 .flags = FLAG_ADVANCED,
4148 .label = "usershare template share",
4149 .type = P_STRING,
4150 .p_class = P_GLOBAL,
4151 .ptr = &Globals.szUsershareTemplateShare,
4152 .special = NULL,
4153 .enum_list = NULL,
4154 .flags = FLAG_ADVANCED,
4157 .label = "volume",
4158 .type = P_STRING,
4159 .p_class = P_LOCAL,
4160 .ptr = &sDefault.volume,
4161 .special = NULL,
4162 .enum_list = NULL,
4163 .flags = FLAG_ADVANCED | FLAG_SHARE,
4166 .label = "fstype",
4167 .type = P_STRING,
4168 .p_class = P_LOCAL,
4169 .ptr = &sDefault.fstype,
4170 .special = NULL,
4171 .enum_list = NULL,
4172 .flags = FLAG_ADVANCED | FLAG_SHARE,
4175 .label = "set directory",
4176 .type = P_BOOLREV,
4177 .p_class = P_LOCAL,
4178 .ptr = &sDefault.bNo_set_dir,
4179 .special = NULL,
4180 .enum_list = NULL,
4181 .flags = FLAG_ADVANCED | FLAG_SHARE,
4184 .label = "wide links",
4185 .type = P_BOOL,
4186 .p_class = P_LOCAL,
4187 .ptr = &sDefault.bWidelinks,
4188 .special = NULL,
4189 .enum_list = NULL,
4190 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4193 .label = "follow symlinks",
4194 .type = P_BOOL,
4195 .p_class = P_LOCAL,
4196 .ptr = &sDefault.bSymlinks,
4197 .special = NULL,
4198 .enum_list = NULL,
4199 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4202 .label = "dont descend",
4203 .type = P_STRING,
4204 .p_class = P_LOCAL,
4205 .ptr = &sDefault.szDontdescend,
4206 .special = NULL,
4207 .enum_list = NULL,
4208 .flags = FLAG_ADVANCED | FLAG_SHARE,
4211 .label = "magic script",
4212 .type = P_STRING,
4213 .p_class = P_LOCAL,
4214 .ptr = &sDefault.szMagicScript,
4215 .special = NULL,
4216 .enum_list = NULL,
4217 .flags = FLAG_ADVANCED | FLAG_SHARE,
4220 .label = "magic output",
4221 .type = P_STRING,
4222 .p_class = P_LOCAL,
4223 .ptr = &sDefault.szMagicOutput,
4224 .special = NULL,
4225 .enum_list = NULL,
4226 .flags = FLAG_ADVANCED | FLAG_SHARE,
4229 .label = "delete readonly",
4230 .type = P_BOOL,
4231 .p_class = P_LOCAL,
4232 .ptr = &sDefault.bDeleteReadonly,
4233 .special = NULL,
4234 .enum_list = NULL,
4235 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4238 .label = "dos filemode",
4239 .type = P_BOOL,
4240 .p_class = P_LOCAL,
4241 .ptr = &sDefault.bDosFilemode,
4242 .special = NULL,
4243 .enum_list = NULL,
4244 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4247 .label = "dos filetimes",
4248 .type = P_BOOL,
4249 .p_class = P_LOCAL,
4250 .ptr = &sDefault.bDosFiletimes,
4251 .special = NULL,
4252 .enum_list = NULL,
4253 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4256 .label = "dos filetime resolution",
4257 .type = P_BOOL,
4258 .p_class = P_LOCAL,
4259 .ptr = &sDefault.bDosFiletimeResolution,
4260 .special = NULL,
4261 .enum_list = NULL,
4262 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4265 .label = "fake directory create times",
4266 .type = P_BOOL,
4267 .p_class = P_LOCAL,
4268 .ptr = &sDefault.bFakeDirCreateTimes,
4269 .special = NULL,
4270 .enum_list = NULL,
4271 .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL,
4274 .label = "panic action",
4275 .type = P_STRING,
4276 .p_class = P_GLOBAL,
4277 .ptr = &Globals.szPanicAction,
4278 .special = NULL,
4279 .enum_list = NULL,
4280 .flags = FLAG_ADVANCED,
4283 .label = "perfcount module",
4284 .type = P_STRING,
4285 .p_class = P_GLOBAL,
4286 .ptr = &Globals.szSMBPerfcountModule,
4287 .special = NULL,
4288 .enum_list = NULL,
4289 .flags = FLAG_ADVANCED,
4292 {N_("VFS module options"), P_SEP, P_SEPARATOR},
4295 .label = "vfs objects",
4296 .type = P_LIST,
4297 .p_class = P_LOCAL,
4298 .ptr = &sDefault.szVfsObjects,
4299 .special = NULL,
4300 .enum_list = NULL,
4301 .flags = FLAG_ADVANCED | FLAG_SHARE,
4304 .label = "vfs object",
4305 .type = P_LIST,
4306 .p_class = P_LOCAL,
4307 .ptr = &sDefault.szVfsObjects,
4308 .special = NULL,
4309 .enum_list = NULL,
4310 .flags = FLAG_HIDE,
4314 {N_("MSDFS options"), P_SEP, P_SEPARATOR},
4317 .label = "msdfs root",
4318 .type = P_BOOL,
4319 .p_class = P_LOCAL,
4320 .ptr = &sDefault.bMSDfsRoot,
4321 .special = NULL,
4322 .enum_list = NULL,
4323 .flags = FLAG_ADVANCED | FLAG_SHARE,
4326 .label = "msdfs proxy",
4327 .type = P_STRING,
4328 .p_class = P_LOCAL,
4329 .ptr = &sDefault.szMSDfsProxy,
4330 .special = NULL,
4331 .enum_list = NULL,
4332 .flags = FLAG_ADVANCED | FLAG_SHARE,
4335 .label = "host msdfs",
4336 .type = P_BOOL,
4337 .p_class = P_GLOBAL,
4338 .ptr = &Globals.bHostMSDfs,
4339 .special = NULL,
4340 .enum_list = NULL,
4341 .flags = FLAG_ADVANCED,
4344 {N_("Winbind options"), P_SEP, P_SEPARATOR},
4347 .label = "passdb expand explicit",
4348 .type = P_BOOL,
4349 .p_class = P_GLOBAL,
4350 .ptr = &Globals.bPassdbExpandExplicit,
4351 .special = NULL,
4352 .enum_list = NULL,
4353 .flags = FLAG_ADVANCED,
4356 .label = "idmap backend",
4357 .type = P_STRING,
4358 .p_class = P_GLOBAL,
4359 .ptr = &Globals.szIdmapBackend,
4360 .special = NULL,
4361 .enum_list = NULL,
4362 .flags = FLAG_ADVANCED,
4365 .label = "idmap alloc backend",
4366 .type = P_STRING,
4367 .p_class = P_GLOBAL,
4368 .ptr = &Globals.szIdmapAllocBackend,
4369 .special = NULL,
4370 .enum_list = NULL,
4371 .flags = FLAG_ADVANCED,
4374 .label = "idmap cache time",
4375 .type = P_INTEGER,
4376 .p_class = P_GLOBAL,
4377 .ptr = &Globals.iIdmapCacheTime,
4378 .special = NULL,
4379 .enum_list = NULL,
4380 .flags = FLAG_ADVANCED,
4383 .label = "idmap negative cache time",
4384 .type = P_INTEGER,
4385 .p_class = P_GLOBAL,
4386 .ptr = &Globals.iIdmapNegativeCacheTime,
4387 .special = NULL,
4388 .enum_list = NULL,
4389 .flags = FLAG_ADVANCED,
4392 .label = "idmap uid",
4393 .type = P_STRING,
4394 .p_class = P_GLOBAL,
4395 .ptr = &Globals.szIdmapUID,
4396 .special = handle_idmap_uid,
4397 .enum_list = NULL,
4398 .flags = FLAG_ADVANCED,
4401 .label = "winbind uid",
4402 .type = P_STRING,
4403 .p_class = P_GLOBAL,
4404 .ptr = &Globals.szIdmapUID,
4405 .special = handle_idmap_uid,
4406 .enum_list = NULL,
4407 .flags = FLAG_HIDE,
4410 .label = "idmap gid",
4411 .type = P_STRING,
4412 .p_class = P_GLOBAL,
4413 .ptr = &Globals.szIdmapGID,
4414 .special = handle_idmap_gid,
4415 .enum_list = NULL,
4416 .flags = FLAG_ADVANCED,
4419 .label = "winbind gid",
4420 .type = P_STRING,
4421 .p_class = P_GLOBAL,
4422 .ptr = &Globals.szIdmapGID,
4423 .special = handle_idmap_gid,
4424 .enum_list = NULL,
4425 .flags = FLAG_HIDE,
4428 .label = "template homedir",
4429 .type = P_STRING,
4430 .p_class = P_GLOBAL,
4431 .ptr = &Globals.szTemplateHomedir,
4432 .special = NULL,
4433 .enum_list = NULL,
4434 .flags = FLAG_ADVANCED,
4437 .label = "template shell",
4438 .type = P_STRING,
4439 .p_class = P_GLOBAL,
4440 .ptr = &Globals.szTemplateShell,
4441 .special = NULL,
4442 .enum_list = NULL,
4443 .flags = FLAG_ADVANCED,
4446 .label = "winbind separator",
4447 .type = P_STRING,
4448 .p_class = P_GLOBAL,
4449 .ptr = &Globals.szWinbindSeparator,
4450 .special = NULL,
4451 .enum_list = NULL,
4452 .flags = FLAG_ADVANCED,
4455 .label = "winbind cache time",
4456 .type = P_INTEGER,
4457 .p_class = P_GLOBAL,
4458 .ptr = &Globals.winbind_cache_time,
4459 .special = NULL,
4460 .enum_list = NULL,
4461 .flags = FLAG_ADVANCED,
4464 .label = "winbind reconnect delay",
4465 .type = P_INTEGER,
4466 .p_class = P_GLOBAL,
4467 .ptr = &Globals.winbind_reconnect_delay,
4468 .special = NULL,
4469 .enum_list = NULL,
4470 .flags = FLAG_ADVANCED,
4473 .label = "winbind enum users",
4474 .type = P_BOOL,
4475 .p_class = P_GLOBAL,
4476 .ptr = &Globals.bWinbindEnumUsers,
4477 .special = NULL,
4478 .enum_list = NULL,
4479 .flags = FLAG_ADVANCED,
4482 .label = "winbind enum groups",
4483 .type = P_BOOL,
4484 .p_class = P_GLOBAL,
4485 .ptr = &Globals.bWinbindEnumGroups,
4486 .special = NULL,
4487 .enum_list = NULL,
4488 .flags = FLAG_ADVANCED,
4491 .label = "winbind use default domain",
4492 .type = P_BOOL,
4493 .p_class = P_GLOBAL,
4494 .ptr = &Globals.bWinbindUseDefaultDomain,
4495 .special = NULL,
4496 .enum_list = NULL,
4497 .flags = FLAG_ADVANCED,
4500 .label = "winbind trusted domains only",
4501 .type = P_BOOL,
4502 .p_class = P_GLOBAL,
4503 .ptr = &Globals.bWinbindTrustedDomainsOnly,
4504 .special = NULL,
4505 .enum_list = NULL,
4506 .flags = FLAG_ADVANCED,
4509 .label = "winbind nested groups",
4510 .type = P_BOOL,
4511 .p_class = P_GLOBAL,
4512 .ptr = &Globals.bWinbindNestedGroups,
4513 .special = NULL,
4514 .enum_list = NULL,
4515 .flags = FLAG_ADVANCED,
4518 .label = "winbind expand groups",
4519 .type = P_INTEGER,
4520 .p_class = P_GLOBAL,
4521 .ptr = &Globals.winbind_expand_groups,
4522 .special = NULL,
4523 .enum_list = NULL,
4524 .flags = FLAG_ADVANCED,
4527 .label = "winbind nss info",
4528 .type = P_LIST,
4529 .p_class = P_GLOBAL,
4530 .ptr = &Globals.szWinbindNssInfo,
4531 .special = NULL,
4532 .enum_list = NULL,
4533 .flags = FLAG_ADVANCED,
4536 .label = "winbind refresh tickets",
4537 .type = P_BOOL,
4538 .p_class = P_GLOBAL,
4539 .ptr = &Globals.bWinbindRefreshTickets,
4540 .special = NULL,
4541 .enum_list = NULL,
4542 .flags = FLAG_ADVANCED,
4545 .label = "winbind offline logon",
4546 .type = P_BOOL,
4547 .p_class = P_GLOBAL,
4548 .ptr = &Globals.bWinbindOfflineLogon,
4549 .special = NULL,
4550 .enum_list = NULL,
4551 .flags = FLAG_ADVANCED,
4554 .label = "winbind normalize names",
4555 .type = P_BOOL,
4556 .p_class = P_GLOBAL,
4557 .ptr = &Globals.bWinbindNormalizeNames,
4558 .special = NULL,
4559 .enum_list = NULL,
4560 .flags = FLAG_ADVANCED,
4563 .label = "winbind rpc only",
4564 .type = P_BOOL,
4565 .p_class = P_GLOBAL,
4566 .ptr = &Globals.bWinbindRpcOnly,
4567 .special = NULL,
4568 .enum_list = NULL,
4569 .flags = FLAG_ADVANCED,
4572 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
4575 /***************************************************************************
4576 Initialise the sDefault parameter structure for the printer values.
4577 ***************************************************************************/
4579 static void init_printer_values(struct service *pService)
4581 /* choose defaults depending on the type of printing */
4582 switch (pService->iPrinting) {
4583 case PRINT_BSD:
4584 case PRINT_AIX:
4585 case PRINT_LPRNT:
4586 case PRINT_LPROS2:
4587 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4588 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4589 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4590 break;
4592 case PRINT_LPRNG:
4593 case PRINT_PLP:
4594 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4595 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4596 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
4597 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
4598 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
4599 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
4600 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
4601 break;
4603 case PRINT_CUPS:
4604 case PRINT_IPRINT:
4605 #ifdef HAVE_CUPS
4606 /* set the lpq command to contain the destination printer
4607 name only. This is used by cups_queue_get() */
4608 string_set(&pService->szLpqcommand, "%p");
4609 string_set(&pService->szLprmcommand, "");
4610 string_set(&pService->szPrintcommand, "");
4611 string_set(&pService->szLppausecommand, "");
4612 string_set(&pService->szLpresumecommand, "");
4613 string_set(&pService->szQueuepausecommand, "");
4614 string_set(&pService->szQueueresumecommand, "");
4615 #else
4616 string_set(&pService->szLpqcommand, "lpq -P'%p'");
4617 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
4618 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
4619 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
4620 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
4621 string_set(&pService->szQueuepausecommand, "disable '%p'");
4622 string_set(&pService->szQueueresumecommand, "enable '%p'");
4623 #endif /* HAVE_CUPS */
4624 break;
4626 case PRINT_SYSV:
4627 case PRINT_HPUX:
4628 string_set(&pService->szLpqcommand, "lpstat -o%p");
4629 string_set(&pService->szLprmcommand, "cancel %p-%j");
4630 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
4631 string_set(&pService->szQueuepausecommand, "disable %p");
4632 string_set(&pService->szQueueresumecommand, "enable %p");
4633 #ifndef HPUX
4634 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
4635 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
4636 #endif /* HPUX */
4637 break;
4639 case PRINT_QNX:
4640 string_set(&pService->szLpqcommand, "lpq -P%p");
4641 string_set(&pService->szLprmcommand, "lprm -P%p %j");
4642 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
4643 break;
4645 #ifdef DEVELOPER
4646 case PRINT_TEST:
4647 case PRINT_VLP:
4648 string_set(&pService->szPrintcommand, "vlp print %p %s");
4649 string_set(&pService->szLpqcommand, "vlp lpq %p");
4650 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
4651 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
4652 string_set(&pService->szLpresumecommand, "vlp lpresume %p %j");
4653 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
4654 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
4655 break;
4656 #endif /* DEVELOPER */
4661 * Function to return the default value for the maximum number of open
4662 * file descriptors permitted. This function tries to consult the
4663 * kernel-level (sysctl) and ulimit (getrlimit()) values and goes
4664 * the smaller of those.
4666 static int max_open_files(void)
4668 int sysctl_max = MAX_OPEN_FILES;
4669 int rlimit_max = MAX_OPEN_FILES;
4671 #ifdef HAVE_SYSCTLBYNAME
4673 size_t size = sizeof(sysctl_max);
4674 sysctlbyname("kern.maxfilesperproc", &sysctl_max, &size, NULL,
4677 #endif
4679 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
4681 struct rlimit rl;
4683 ZERO_STRUCT(rl);
4685 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
4686 rlimit_max = rl.rlim_cur;
4688 #if defined(RLIM_INFINITY)
4689 if(rl.rlim_cur == RLIM_INFINITY)
4690 rlimit_max = MAX_OPEN_FILES;
4692 #endif
4693 #endif
4695 if (sysctl_max < MIN_OPEN_FILES_WINDOWS) {
4696 DEBUG(2,("max_open_files: sysctl_max (%d) below "
4697 "minimum Windows limit (%d)\n",
4698 sysctl_max,
4699 MIN_OPEN_FILES_WINDOWS));
4700 sysctl_max = MIN_OPEN_FILES_WINDOWS;
4703 if (rlimit_max < MIN_OPEN_FILES_WINDOWS) {
4704 DEBUG(2,("rlimit_max: rlimit_max (%d) below "
4705 "minimum Windows limit (%d)\n",
4706 rlimit_max,
4707 MIN_OPEN_FILES_WINDOWS));
4708 rlimit_max = MIN_OPEN_FILES_WINDOWS;
4711 return MIN(sysctl_max, rlimit_max);
4715 * Common part of freeing allocated data for one parameter.
4717 static void free_one_parameter_common(void *parm_ptr,
4718 struct parm_struct parm)
4720 if ((parm.type == P_STRING) ||
4721 (parm.type == P_USTRING))
4723 string_free((char**)parm_ptr);
4724 } else if (parm.type == P_LIST) {
4725 TALLOC_FREE(*((char***)parm_ptr));
4730 * Free the allocated data for one parameter for a share
4731 * given as a service struct.
4733 static void free_one_parameter(struct service *service,
4734 struct parm_struct parm)
4736 void *parm_ptr;
4738 if (parm.p_class != P_LOCAL) {
4739 return;
4742 parm_ptr = lp_local_ptr(service, parm.ptr);
4744 free_one_parameter_common(parm_ptr, parm);
4748 * Free the allocated parameter data of a share given
4749 * as a service struct.
4751 static void free_parameters(struct service *service)
4753 uint32_t i;
4755 for (i=0; parm_table[i].label; i++) {
4756 free_one_parameter(service, parm_table[i]);
4761 * Free the allocated data for one parameter for a given share
4762 * specified by an snum.
4764 static void free_one_parameter_by_snum(int snum, struct parm_struct parm)
4766 void *parm_ptr;
4768 if (parm.ptr == NULL) {
4769 return;
4772 if (snum < 0) {
4773 parm_ptr = parm.ptr;
4774 } else if (parm.p_class != P_LOCAL) {
4775 return;
4776 } else {
4777 parm_ptr = lp_local_ptr_by_snum(snum, parm.ptr);
4780 free_one_parameter_common(parm_ptr, parm);
4784 * Free the allocated parameter data for a share specified
4785 * by an snum.
4787 static void free_parameters_by_snum(int snum)
4789 uint32_t i;
4791 for (i=0; parm_table[i].label; i++) {
4792 free_one_parameter_by_snum(snum, parm_table[i]);
4797 * Free the allocated global parameters.
4799 static void free_global_parameters(void)
4801 free_parameters_by_snum(GLOBAL_SECTION_SNUM);
4804 /***************************************************************************
4805 Initialise the global parameter structure.
4806 ***************************************************************************/
4808 static void init_globals(bool first_time_only)
4810 static bool done_init = False;
4811 char *s = NULL;
4812 int i;
4814 /* If requested to initialize only once and we've already done it... */
4815 if (first_time_only && done_init) {
4816 /* ... then we have nothing more to do */
4817 return;
4820 if (!done_init) {
4821 /* The logfile can be set before this is invoked. Free it if so. */
4822 if (Globals.szLogFile != NULL) {
4823 string_free(&Globals.szLogFile);
4824 Globals.szLogFile = NULL;
4826 done_init = True;
4827 } else {
4828 free_global_parameters();
4831 memset((void *)&Globals, '\0', sizeof(Globals));
4833 for (i = 0; parm_table[i].label; i++) {
4834 if ((parm_table[i].type == P_STRING ||
4835 parm_table[i].type == P_USTRING) &&
4836 parm_table[i].ptr)
4838 string_set((char **)parm_table[i].ptr, "");
4842 string_set(&sDefault.fstype, FSTYPE_STRING);
4843 string_set(&sDefault.szPrintjobUsername, "%U");
4845 init_printer_values(&sDefault);
4848 DEBUG(3, ("Initialising global parameters\n"));
4850 string_set(&Globals.szSMBPasswdFile, get_dyn_SMB_PASSWD_FILE());
4851 string_set(&Globals.szPrivateDir, get_dyn_PRIVATE_DIR());
4853 /* use the new 'hash2' method by default, with a prefix of 1 */
4854 string_set(&Globals.szManglingMethod, "hash2");
4855 Globals.mangle_prefix = 1;
4857 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
4859 /* using UTF8 by default allows us to support all chars */
4860 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
4862 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
4863 /* If the system supports nl_langinfo(), try to grab the value
4864 from the user's locale */
4865 string_set(&Globals.display_charset, "LOCALE");
4866 #else
4867 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
4868 #endif
4870 /* Use codepage 850 as a default for the dos character set */
4871 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
4874 * Allow the default PASSWD_CHAT to be overridden in local.h.
4876 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
4878 set_global_myname(myhostname());
4879 string_set(&Globals.szNetbiosName,global_myname());
4881 set_global_myworkgroup(WORKGROUP);
4882 string_set(&Globals.szWorkgroup, lp_workgroup());
4884 string_set(&Globals.szPasswdProgram, "");
4885 string_set(&Globals.szLockDir, get_dyn_LOCKDIR());
4886 string_set(&Globals.szStateDir, get_dyn_STATEDIR());
4887 string_set(&Globals.szCacheDir, get_dyn_CACHEDIR());
4888 string_set(&Globals.szPidDir, get_dyn_PIDDIR());
4889 string_set(&Globals.szSocketAddress, "0.0.0.0");
4891 if (asprintf(&s, "Samba %s", samba_version_string()) < 0) {
4892 smb_panic("init_globals: ENOMEM");
4894 string_set(&Globals.szServerString, s);
4895 SAFE_FREE(s);
4896 if (asprintf(&s, "%d.%d", DEFAULT_MAJOR_VERSION,
4897 DEFAULT_MINOR_VERSION) < 0) {
4898 smb_panic("init_globals: ENOMEM");
4900 string_set(&Globals.szAnnounceVersion, s);
4901 SAFE_FREE(s);
4902 #ifdef DEVELOPER
4903 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
4904 #endif
4906 string_set(&Globals.szSocketOptions, DEFAULT_SOCKET_OPTIONS);
4908 string_set(&Globals.szLogonDrive, "");
4909 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
4910 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
4911 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
4913 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
4914 string_set(&Globals.szPasswordServer, "*");
4916 Globals.AlgorithmicRidBase = BASE_RID;
4918 Globals.bLoadPrinters = True;
4919 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
4921 Globals.ConfigBackend = config_backend;
4923 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
4924 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
4925 Globals.max_xmit = 0x4104;
4926 Globals.max_mux = 50; /* This is *needed* for profile support. */
4927 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
4928 Globals.bDisableSpoolss = False;
4929 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
4930 Globals.pwordlevel = 0;
4931 Globals.unamelevel = 0;
4932 Globals.deadtime = 0;
4933 Globals.getwd_cache = true;
4934 Globals.bLargeReadwrite = True;
4935 Globals.max_log_size = 5000;
4936 Globals.max_open_files = max_open_files();
4937 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
4938 Globals.maxprotocol = PROTOCOL_NT1;
4939 Globals.minprotocol = PROTOCOL_CORE;
4940 Globals.security = SEC_USER;
4941 Globals.paranoid_server_security = True;
4942 Globals.bEncryptPasswords = True;
4943 Globals.bUpdateEncrypt = False;
4944 Globals.clientSchannel = Auto;
4945 Globals.serverSchannel = Auto;
4946 Globals.bReadRaw = True;
4947 Globals.bWriteRaw = True;
4948 Globals.bNullPasswords = False;
4949 Globals.bObeyPamRestrictions = False;
4950 Globals.syslog = 1;
4951 Globals.bSyslogOnly = False;
4952 Globals.bTimestampLogs = True;
4953 string_set(&Globals.szLogLevel, "0");
4954 Globals.bDebugPrefixTimestamp = False;
4955 Globals.bDebugHiresTimestamp = False;
4956 Globals.bDebugPid = False;
4957 Globals.bDebugUid = False;
4958 Globals.bDebugClass = False;
4959 Globals.bEnableCoreFiles = True;
4960 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
4961 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
4962 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
4963 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
4964 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
4965 Globals.lm_interval = 60;
4966 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
4967 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
4968 Globals.bNISHomeMap = False;
4969 #ifdef WITH_NISPLUS_HOME
4970 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
4971 #else
4972 string_set(&Globals.szNISHomeMapName, "auto.home");
4973 #endif
4974 #endif
4975 Globals.bTimeServer = False;
4976 Globals.bBindInterfacesOnly = False;
4977 Globals.bUnixPasswdSync = False;
4978 Globals.bPamPasswordChange = False;
4979 Globals.bPasswdChatDebug = False;
4980 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
4981 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
4982 Globals.bNTStatusSupport = True; /* Use NT status by default. */
4983 Globals.bStatCache = True; /* use stat cache by default */
4984 Globals.iMaxStatCacheSize = 256; /* 256k by default */
4985 Globals.restrict_anonymous = 0;
4986 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
4987 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
4988 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
4989 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
4990 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
4991 /* Note, that we will use NTLM2 session security (which is different), if it is available */
4993 Globals.map_to_guest = 0; /* By Default, "Never" */
4994 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
4995 Globals.enhanced_browsing = true;
4996 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
4997 #ifdef MMAP_BLACKLIST
4998 Globals.bUseMmap = False;
4999 #else
5000 Globals.bUseMmap = True;
5001 #endif
5002 Globals.bUnixExtensions = True;
5003 Globals.bResetOnZeroVC = False;
5005 /* hostname lookups can be very expensive and are broken on
5006 a large number of sites (tridge) */
5007 Globals.bHostnameLookups = False;
5009 string_set(&Globals.szPassdbBackend, "tdbsam");
5010 string_set(&Globals.szLdapSuffix, "");
5011 string_set(&Globals.szLdapMachineSuffix, "");
5012 string_set(&Globals.szLdapUserSuffix, "");
5013 string_set(&Globals.szLdapGroupSuffix, "");
5014 string_set(&Globals.szLdapIdmapSuffix, "");
5016 string_set(&Globals.szLdapAdminDn, "");
5017 Globals.ldap_ssl = LDAP_SSL_START_TLS;
5018 Globals.ldap_ssl_ads = False;
5019 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
5020 Globals.ldap_delete_dn = False;
5021 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
5022 Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
5023 Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
5024 Globals.ldap_page_size = LDAP_PAGE_SIZE;
5026 Globals.ldap_debug_level = 0;
5027 Globals.ldap_debug_threshold = 10;
5029 /* This is what we tell the afs client. in reality we set the token
5030 * to never expire, though, when this runs out the afs client will
5031 * forget the token. Set to 0 to get NEVERDATE.*/
5032 Globals.iAfsTokenLifetime = 604800;
5033 Globals.cups_connection_timeout = CUPS_DEFAULT_CONNECTION_TIMEOUT;
5035 /* these parameters are set to defaults that are more appropriate
5036 for the increasing samba install base:
5038 as a member of the workgroup, that will possibly become a
5039 _local_ master browser (lm = True). this is opposed to a forced
5040 local master browser startup (pm = True).
5042 doesn't provide WINS server service by default (wsupp = False),
5043 and doesn't provide domain master browser services by default, either.
5047 Globals.bMsAddPrinterWizard = True;
5048 Globals.os_level = 20;
5049 Globals.bLocalMaster = True;
5050 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
5051 Globals.bDomainLogons = False;
5052 Globals.bBrowseList = True;
5053 Globals.bWINSsupport = False;
5054 Globals.bWINSproxy = False;
5056 TALLOC_FREE(Globals.szInitLogonDelayedHosts);
5057 Globals.InitLogonDelay = 100; /* 100 ms default delay */
5059 Globals.bDNSproxy = True;
5061 /* this just means to use them if they exist */
5062 Globals.bKernelOplocks = True;
5064 Globals.bAllowTrustedDomains = True;
5065 string_set(&Globals.szIdmapBackend, "tdb");
5067 string_set(&Globals.szTemplateShell, "/bin/false");
5068 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
5069 string_set(&Globals.szWinbindSeparator, "\\");
5071 string_set(&Globals.szCupsServer, "");
5072 string_set(&Globals.szIPrintServer, "");
5074 string_set(&Globals.ctdbdSocket, "");
5075 Globals.szClusterAddresses = NULL;
5076 Globals.clustering = False;
5078 Globals.winbind_cache_time = 300; /* 5 minutes */
5079 Globals.winbind_reconnect_delay = 30; /* 30 seconds */
5080 Globals.bWinbindEnumUsers = False;
5081 Globals.bWinbindEnumGroups = False;
5082 Globals.bWinbindUseDefaultDomain = False;
5083 Globals.bWinbindTrustedDomainsOnly = False;
5084 Globals.bWinbindNestedGroups = True;
5085 Globals.winbind_expand_groups = 1;
5086 Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL);
5087 Globals.bWinbindRefreshTickets = False;
5088 Globals.bWinbindOfflineLogon = False;
5090 Globals.iIdmapCacheTime = 86400 * 7; /* a week by default */
5091 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
5093 Globals.bPassdbExpandExplicit = False;
5095 Globals.name_cache_timeout = 660; /* In seconds */
5097 Globals.bUseSpnego = True;
5098 Globals.bClientUseSpnego = True;
5100 Globals.client_signing = Auto;
5101 Globals.server_signing = False;
5103 Globals.bDeferSharingViolations = True;
5104 string_set(&Globals.smb_ports, SMB_PORTS);
5106 Globals.bEnablePrivileges = True;
5107 Globals.bHostMSDfs = True;
5108 Globals.bASUSupport = False;
5110 /* User defined shares. */
5111 if (asprintf(&s, "%s/usershares", get_dyn_STATEDIR()) < 0) {
5112 smb_panic("init_globals: ENOMEM");
5114 string_set(&Globals.szUsersharePath, s);
5115 SAFE_FREE(s);
5116 string_set(&Globals.szUsershareTemplateShare, "");
5117 Globals.iUsershareMaxShares = 0;
5118 /* By default disallow sharing of directories not owned by the sharer. */
5119 Globals.bUsershareOwnerOnly = True;
5120 /* By default disallow guest access to usershares. */
5121 Globals.bUsershareAllowGuests = False;
5123 Globals.iKeepalive = DEFAULT_KEEPALIVE;
5125 /* By default no shares out of the registry */
5126 Globals.bRegistryShares = False;
5128 Globals.iminreceivefile = 0;
5130 Globals.bMapUntrustedToDomain = false;
5133 /*******************************************************************
5134 Convenience routine to grab string parameters into temporary memory
5135 and run standard_sub_basic on them. The buffers can be written to by
5136 callers without affecting the source string.
5137 ********************************************************************/
5139 static char *lp_string(const char *s)
5141 char *ret;
5142 TALLOC_CTX *ctx = talloc_tos();
5144 /* The follow debug is useful for tracking down memory problems
5145 especially if you have an inner loop that is calling a lp_*()
5146 function that returns a string. Perhaps this debug should be
5147 present all the time? */
5149 #if 0
5150 DEBUG(10, ("lp_string(%s)\n", s));
5151 #endif
5153 ret = talloc_sub_basic(ctx,
5154 get_current_username(),
5155 current_user_info.domain,
5157 if (trim_char(ret, '\"', '\"')) {
5158 if (strchr(ret,'\"') != NULL) {
5159 TALLOC_FREE(ret);
5160 ret = talloc_sub_basic(ctx,
5161 get_current_username(),
5162 current_user_info.domain,
5166 return ret;
5170 In this section all the functions that are used to access the
5171 parameters from the rest of the program are defined
5174 #define FN_GLOBAL_STRING(fn_name,ptr) \
5175 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
5176 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
5177 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
5178 #define FN_GLOBAL_LIST(fn_name,ptr) \
5179 const char **fn_name(void) {return(*(const char ***)(ptr));}
5180 #define FN_GLOBAL_BOOL(fn_name,ptr) \
5181 bool fn_name(void) {return(*(bool *)(ptr));}
5182 #define FN_GLOBAL_CHAR(fn_name,ptr) \
5183 char fn_name(void) {return(*(char *)(ptr));}
5184 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
5185 int fn_name(void) {return(*(int *)(ptr));}
5187 #define FN_LOCAL_STRING(fn_name,val) \
5188 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
5189 #define FN_LOCAL_CONST_STRING(fn_name,val) \
5190 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
5191 #define FN_LOCAL_LIST(fn_name,val) \
5192 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5193 #define FN_LOCAL_BOOL(fn_name,val) \
5194 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5195 #define FN_LOCAL_INTEGER(fn_name,val) \
5196 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
5198 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
5199 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5200 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
5201 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5202 #define FN_LOCAL_PARM_STRING(fn_name,val) \
5203 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));}
5204 #define FN_LOCAL_CHAR(fn_name,val) \
5205 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
5207 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
5208 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
5209 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
5210 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
5211 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
5212 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
5213 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
5214 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
5215 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
5216 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
5217 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
5218 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
5219 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
5220 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
5221 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
5222 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
5223 /* If lp_statedir() and lp_cachedir() are explicitely set during the
5224 * build process or in smb.conf, we use that value. Otherwise they
5225 * default to the value of lp_lockdir(). */
5226 char *lp_statedir(void) {
5227 if ((strcmp(get_dyn_STATEDIR(), get_dyn_LOCKDIR()) != 0) ||
5228 (strcmp(get_dyn_STATEDIR(), Globals.szStateDir) != 0))
5229 return(lp_string(*(char **)(&Globals.szStateDir) ?
5230 *(char **)(&Globals.szStateDir) : ""));
5231 else
5232 return(lp_string(*(char **)(&Globals.szLockDir) ?
5233 *(char **)(&Globals.szLockDir) : ""));
5235 char *lp_cachedir(void) {
5236 if ((strcmp(get_dyn_CACHEDIR(), get_dyn_LOCKDIR()) != 0) ||
5237 (strcmp(get_dyn_CACHEDIR(), Globals.szCacheDir) != 0))
5238 return(lp_string(*(char **)(&Globals.szCacheDir) ?
5239 *(char **)(&Globals.szCacheDir) : ""));
5240 else
5241 return(lp_string(*(char **)(&Globals.szLockDir) ?
5242 *(char **)(&Globals.szLockDir) : ""));
5244 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
5245 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
5246 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
5247 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
5248 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
5249 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
5250 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
5251 FN_GLOBAL_STRING(lp_perfcount_module, &Globals.szSMBPerfcountModule)
5252 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
5253 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
5254 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
5255 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
5256 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
5257 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
5258 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
5259 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
5260 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
5261 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
5262 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
5263 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
5264 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
5265 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
5266 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
5267 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
5268 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
5269 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
5270 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
5271 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
5272 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
5273 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
5274 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
5275 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
5276 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
5277 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
5278 * lp_passdb_backend() should be replace by the this macro again after
5279 * some releases.
5280 * */
5281 const char *lp_passdb_backend(void)
5283 char *delim, *quote;
5285 delim = strchr( Globals.szPassdbBackend, ' ');
5286 /* no space at all */
5287 if (delim == NULL) {
5288 goto out;
5291 quote = strchr(Globals.szPassdbBackend, '"');
5292 /* no quote char or non in the first part */
5293 if (quote == NULL || quote > delim) {
5294 *delim = '\0';
5295 goto warn;
5298 quote = strchr(quote+1, '"');
5299 if (quote == NULL) {
5300 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
5301 goto out;
5302 } else if (*(quote+1) == '\0') {
5303 /* space, fitting quote char, and one backend only */
5304 goto out;
5305 } else {
5306 /* terminate string after the fitting quote char */
5307 *(quote+1) = '\0';
5310 warn:
5311 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
5312 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
5313 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
5314 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
5316 out:
5317 return Globals.szPassdbBackend;
5319 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
5320 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
5321 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
5322 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
5323 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
5325 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
5326 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
5327 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
5328 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
5329 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
5330 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
5332 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
5334 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
5335 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
5336 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
5338 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
5340 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
5341 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
5342 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
5343 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
5344 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
5345 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
5346 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
5347 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
5348 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
5349 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
5350 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
5351 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
5352 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
5353 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
5354 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
5356 FN_GLOBAL_CONST_STRING(lp_idmap_backend, &Globals.szIdmapBackend)
5357 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
5358 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
5359 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
5360 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
5361 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
5363 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
5364 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
5365 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
5366 FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
5367 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
5368 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
5369 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
5370 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
5371 FN_GLOBAL_INTEGER(lp_ldap_connection_timeout, &Globals.ldap_connection_timeout)
5372 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
5373 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
5374 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
5375 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
5376 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
5377 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
5378 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
5379 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
5380 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
5382 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
5384 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
5385 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
5386 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
5387 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
5388 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
5389 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
5390 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
5391 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
5392 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
5393 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
5394 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
5395 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
5396 FN_GLOBAL_LIST(lp_init_logon_delayed_hosts, &Globals.szInitLogonDelayedHosts)
5397 FN_GLOBAL_INTEGER(lp_init_logon_delay, &Globals.InitLogonDelay)
5398 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
5399 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
5400 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
5401 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
5402 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
5403 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
5404 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
5405 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
5406 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
5407 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
5408 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
5409 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
5410 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
5411 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
5412 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
5413 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
5414 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
5415 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
5416 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
5417 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
5418 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
5419 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
5420 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
5421 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
5422 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
5423 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
5424 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
5425 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
5426 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
5427 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
5428 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
5429 FN_GLOBAL_BOOL(lp_map_untrusted_to_domain, &Globals.bMapUntrustedToDomain)
5430 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
5431 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
5432 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
5433 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
5434 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
5435 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
5436 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
5437 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
5438 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
5439 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
5440 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
5441 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
5442 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
5443 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
5444 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
5445 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
5446 FN_GLOBAL_STRING(lp_dedicated_keytab_file, &Globals.szDedicatedKeytabFile)
5447 FN_GLOBAL_INTEGER(lp_kerberos_method, &Globals.iKerberosMethod)
5448 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
5449 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
5450 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
5451 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
5452 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
5453 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
5454 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
5455 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
5456 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
5457 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
5458 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
5459 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
5460 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
5461 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
5462 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
5463 FN_GLOBAL_BOOL(lp_getwd_cache, &Globals.getwd_cache)
5464 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
5465 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
5466 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
5467 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
5468 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
5469 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
5470 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
5471 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
5472 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
5473 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
5474 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
5475 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
5476 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
5477 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
5478 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
5479 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
5480 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
5481 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
5482 FN_GLOBAL_CONST_STRING(lp_socket_options, &Globals.szSocketOptions)
5483 FN_GLOBAL_INTEGER(lp_config_backend, &Globals.ConfigBackend)
5485 FN_LOCAL_STRING(lp_preexec, szPreExec)
5486 FN_LOCAL_STRING(lp_postexec, szPostExec)
5487 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
5488 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
5489 FN_LOCAL_STRING(lp_servicename, szService)
5490 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
5491 FN_LOCAL_STRING(lp_pathname, szPath)
5492 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
5493 FN_LOCAL_STRING(lp_username, szUsername)
5494 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
5495 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
5496 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
5497 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
5498 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
5499 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
5500 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
5501 FN_GLOBAL_INTEGER(lp_cups_connection_timeout, &Globals.cups_connection_timeout)
5502 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
5503 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
5504 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering)
5505 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
5506 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
5507 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
5508 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
5509 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
5510 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
5511 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
5512 static FN_LOCAL_STRING(_lp_printername, szPrintername)
5513 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
5514 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
5515 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
5516 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
5517 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
5518 FN_LOCAL_STRING(lp_comment, comment)
5519 FN_LOCAL_STRING(lp_force_user, force_user)
5520 FN_LOCAL_STRING(lp_force_group, force_group)
5521 FN_LOCAL_LIST(lp_readlist, readlist)
5522 FN_LOCAL_LIST(lp_writelist, writelist)
5523 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
5524 FN_LOCAL_STRING(lp_fstype, fstype)
5525 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
5526 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
5527 static FN_LOCAL_STRING(lp_volume, volume)
5528 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
5529 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
5530 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
5531 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
5532 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
5533 FN_LOCAL_STRING(lp_dfree_command, szDfree)
5534 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
5535 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
5536 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
5537 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
5538 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
5539 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
5540 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
5541 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
5542 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
5543 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
5544 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
5545 FN_LOCAL_BOOL(lp_access_based_share_enum, bAccessBasedShareEnum)
5546 FN_LOCAL_BOOL(lp_readonly, bRead_only)
5547 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
5548 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
5549 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
5550 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
5551 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
5552 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
5553 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
5554 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
5555 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
5556 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
5557 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
5558 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
5559 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
5560 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
5561 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
5562 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
5563 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
5564 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
5565 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
5566 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
5567 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
5568 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
5569 FN_LOCAL_BOOL(lp_map_system, bMap_system)
5570 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
5571 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
5572 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
5573 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
5574 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
5575 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
5576 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
5577 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
5578 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
5579 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
5580 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
5581 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
5582 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
5583 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
5584 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
5585 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
5586 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
5587 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
5588 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
5589 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
5590 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
5591 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
5592 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
5593 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
5594 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
5595 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
5596 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
5597 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
5598 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
5599 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
5600 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
5601 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
5602 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
5603 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
5604 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
5605 FN_LOCAL_INTEGER(lp_printing, iPrinting)
5606 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
5607 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
5608 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
5609 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
5610 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
5611 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
5612 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
5613 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
5614 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
5615 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
5616 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
5617 FN_LOCAL_INTEGER(lp_smb_encrypt, ismb_encrypt)
5618 FN_LOCAL_CHAR(lp_magicchar, magic_char)
5619 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
5620 FN_GLOBAL_INTEGER(lp_winbind_reconnect_delay, &Globals.winbind_reconnect_delay)
5621 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
5622 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
5623 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
5624 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
5625 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
5626 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
5628 /* local prototypes */
5630 static int map_parameter(const char *pszParmName);
5631 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
5632 static const char *get_boolean(bool bool_value);
5633 static int getservicebyname(const char *pszServiceName,
5634 struct service *pserviceDest);
5635 static void copy_service(struct service *pserviceDest,
5636 struct service *pserviceSource,
5637 struct bitmap *pcopymapDest);
5638 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
5639 void *userdata);
5640 static bool do_section(const char *pszSectionName, void *userdata);
5641 static void init_copymap(struct service *pservice);
5642 static bool hash_a_service(const char *name, int number);
5643 static void free_service_byindex(int iService);
5644 static void free_param_opts(struct param_opt_struct **popts);
5645 static char * canonicalize_servicename(const char *name);
5646 static void show_parameter(int parmIndex);
5647 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
5650 * This is a helper function for parametrical options support. It returns a
5651 * pointer to parametrical option value if it exists or NULL otherwise. Actual
5652 * parametrical functions are quite simple
5654 static struct param_opt_struct *get_parametrics(int snum, const char *type,
5655 const char *option)
5657 bool global_section = False;
5658 char* param_key;
5659 struct param_opt_struct *data;
5661 if (snum >= iNumServices) return NULL;
5663 if (snum < 0) {
5664 data = Globals.param_opt;
5665 global_section = True;
5666 } else {
5667 data = ServicePtrs[snum]->param_opt;
5670 if (asprintf(&param_key, "%s:%s", type, option) == -1) {
5671 DEBUG(0,("asprintf failed!\n"));
5672 return NULL;
5675 while (data) {
5676 if (strwicmp(data->key, param_key) == 0) {
5677 string_free(&param_key);
5678 return data;
5680 data = data->next;
5683 if (!global_section) {
5684 /* Try to fetch the same option but from globals */
5685 /* but only if we are not already working with Globals */
5686 data = Globals.param_opt;
5687 while (data) {
5688 if (strwicmp(data->key, param_key) == 0) {
5689 string_free(&param_key);
5690 return data;
5692 data = data->next;
5696 string_free(&param_key);
5698 return NULL;
5702 #define MISSING_PARAMETER(name) \
5703 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
5705 /*******************************************************************
5706 convenience routine to return int parameters.
5707 ********************************************************************/
5708 static int lp_int(const char *s)
5711 if (!s || !*s) {
5712 MISSING_PARAMETER(lp_int);
5713 return (-1);
5716 return (int)strtol(s, NULL, 0);
5719 /*******************************************************************
5720 convenience routine to return unsigned long parameters.
5721 ********************************************************************/
5722 static unsigned long lp_ulong(const char *s)
5725 if (!s || !*s) {
5726 MISSING_PARAMETER(lp_ulong);
5727 return (0);
5730 return strtoul(s, NULL, 0);
5733 /*******************************************************************
5734 convenience routine to return boolean parameters.
5735 ********************************************************************/
5736 static bool lp_bool(const char *s)
5738 bool ret = False;
5740 if (!s || !*s) {
5741 MISSING_PARAMETER(lp_bool);
5742 return False;
5745 if (!set_boolean(s, &ret)) {
5746 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
5747 return False;
5750 return ret;
5753 /*******************************************************************
5754 convenience routine to return enum parameters.
5755 ********************************************************************/
5756 static int lp_enum(const char *s,const struct enum_list *_enum)
5758 int i;
5760 if (!s || !*s || !_enum) {
5761 MISSING_PARAMETER(lp_enum);
5762 return (-1);
5765 for (i=0; _enum[i].name; i++) {
5766 if (strequal(_enum[i].name,s))
5767 return _enum[i].value;
5770 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
5771 return (-1);
5774 #undef MISSING_PARAMETER
5776 /* DO NOT USE lp_parm_string ANYMORE!!!!
5777 * use lp_parm_const_string or lp_parm_talloc_string
5779 * lp_parm_string is only used to let old modules find this symbol
5781 #undef lp_parm_string
5782 char *lp_parm_string(const char *servicename, const char *type, const char *option);
5783 char *lp_parm_string(const char *servicename, const char *type, const char *option)
5785 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
5788 /* Return parametric option from a given service. Type is a part of option before ':' */
5789 /* Parametric option has following syntax: 'Type: option = value' */
5790 /* the returned value is talloced on the talloc_tos() */
5791 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
5793 struct param_opt_struct *data = get_parametrics(snum, type, option);
5795 if (data == NULL||data->value==NULL) {
5796 if (def) {
5797 return lp_string(def);
5798 } else {
5799 return NULL;
5803 return lp_string(data->value);
5806 /* Return parametric option from a given service. Type is a part of option before ':' */
5807 /* Parametric option has following syntax: 'Type: option = value' */
5808 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
5810 struct param_opt_struct *data = get_parametrics(snum, type, option);
5812 if (data == NULL||data->value==NULL)
5813 return def;
5815 return data->value;
5818 /* Return parametric option from a given service. Type is a part of option before ':' */
5819 /* Parametric option has following syntax: 'Type: option = value' */
5821 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
5823 struct param_opt_struct *data = get_parametrics(snum, type, option);
5825 if (data == NULL||data->value==NULL)
5826 return (const char **)def;
5828 if (data->list==NULL) {
5829 data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL);
5832 return (const char **)data->list;
5835 /* Return parametric option from a given service. Type is a part of option before ':' */
5836 /* Parametric option has following syntax: 'Type: option = value' */
5838 int lp_parm_int(int snum, const char *type, const char *option, int def)
5840 struct param_opt_struct *data = get_parametrics(snum, type, option);
5842 if (data && data->value && *data->value)
5843 return lp_int(data->value);
5845 return def;
5848 /* Return parametric option from a given service. Type is a part of option before ':' */
5849 /* Parametric option has following syntax: 'Type: option = value' */
5851 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
5853 struct param_opt_struct *data = get_parametrics(snum, type, option);
5855 if (data && data->value && *data->value)
5856 return lp_ulong(data->value);
5858 return def;
5861 /* Return parametric option from a given service. Type is a part of option before ':' */
5862 /* Parametric option has following syntax: 'Type: option = value' */
5864 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
5866 struct param_opt_struct *data = get_parametrics(snum, type, option);
5868 if (data && data->value && *data->value)
5869 return lp_bool(data->value);
5871 return def;
5874 /* Return parametric option from a given service. Type is a part of option before ':' */
5875 /* Parametric option has following syntax: 'Type: option = value' */
5877 int lp_parm_enum(int snum, const char *type, const char *option,
5878 const struct enum_list *_enum, int def)
5880 struct param_opt_struct *data = get_parametrics(snum, type, option);
5882 if (data && data->value && *data->value && _enum)
5883 return lp_enum(data->value, _enum);
5885 return def;
5889 /***************************************************************************
5890 Initialise a service to the defaults.
5891 ***************************************************************************/
5893 static void init_service(struct service *pservice)
5895 memset((char *)pservice, '\0', sizeof(struct service));
5896 copy_service(pservice, &sDefault, NULL);
5901 * free a param_opts structure.
5902 * param_opts handling should be moved to talloc;
5903 * then this whole functions reduces to a TALLOC_FREE().
5906 static void free_param_opts(struct param_opt_struct **popts)
5908 struct param_opt_struct *opt, *next_opt;
5910 if (popts == NULL) {
5911 return;
5914 if (*popts != NULL) {
5915 DEBUG(5, ("Freeing parametrics:\n"));
5917 opt = *popts;
5918 while (opt != NULL) {
5919 string_free(&opt->key);
5920 string_free(&opt->value);
5921 TALLOC_FREE(opt->list);
5922 next_opt = opt->next;
5923 SAFE_FREE(opt);
5924 opt = next_opt;
5926 *popts = NULL;
5929 /***************************************************************************
5930 Free the dynamically allocated parts of a service struct.
5931 ***************************************************************************/
5933 static void free_service(struct service *pservice)
5935 if (!pservice)
5936 return;
5938 if (pservice->szService)
5939 DEBUG(5, ("free_service: Freeing service %s\n",
5940 pservice->szService));
5942 free_parameters(pservice);
5944 string_free(&pservice->szService);
5945 bitmap_free(pservice->copymap);
5947 free_param_opts(&pservice->param_opt);
5949 ZERO_STRUCTP(pservice);
5953 /***************************************************************************
5954 remove a service indexed in the ServicePtrs array from the ServiceHash
5955 and free the dynamically allocated parts
5956 ***************************************************************************/
5958 static void free_service_byindex(int idx)
5960 if ( !LP_SNUM_OK(idx) )
5961 return;
5963 ServicePtrs[idx]->valid = False;
5964 invalid_services[num_invalid_services++] = idx;
5966 /* we have to cleanup the hash record */
5968 if (ServicePtrs[idx]->szService) {
5969 char *canon_name = canonicalize_servicename(
5970 ServicePtrs[idx]->szService );
5972 dbwrap_delete_bystring(ServiceHash, canon_name );
5973 TALLOC_FREE(canon_name);
5976 free_service(ServicePtrs[idx]);
5979 /***************************************************************************
5980 Add a new service to the services array initialising it with the given
5981 service.
5982 ***************************************************************************/
5984 static int add_a_service(const struct service *pservice, const char *name)
5986 int i;
5987 struct service tservice;
5988 int num_to_alloc = iNumServices + 1;
5990 tservice = *pservice;
5992 /* it might already exist */
5993 if (name) {
5994 i = getservicebyname(name, NULL);
5995 if (i >= 0) {
5996 /* Clean all parametric options for service */
5997 /* They will be added during parsing again */
5998 free_param_opts(&ServicePtrs[i]->param_opt);
5999 return (i);
6003 /* find an invalid one */
6004 i = iNumServices;
6005 if (num_invalid_services > 0) {
6006 i = invalid_services[--num_invalid_services];
6009 /* if not, then create one */
6010 if (i == iNumServices) {
6011 struct service **tsp;
6012 int *tinvalid;
6014 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, struct service *, num_to_alloc);
6015 if (tsp == NULL) {
6016 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
6017 return (-1);
6019 ServicePtrs = tsp;
6020 ServicePtrs[iNumServices] = SMB_MALLOC_P(struct service);
6021 if (!ServicePtrs[iNumServices]) {
6022 DEBUG(0,("add_a_service: out of memory!\n"));
6023 return (-1);
6025 iNumServices++;
6027 /* enlarge invalid_services here for now... */
6028 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
6029 num_to_alloc);
6030 if (tinvalid == NULL) {
6031 DEBUG(0,("add_a_service: failed to enlarge "
6032 "invalid_services!\n"));
6033 return (-1);
6035 invalid_services = tinvalid;
6036 } else {
6037 free_service_byindex(i);
6040 ServicePtrs[i]->valid = True;
6042 init_service(ServicePtrs[i]);
6043 copy_service(ServicePtrs[i], &tservice, NULL);
6044 if (name)
6045 string_set(&ServicePtrs[i]->szService, name);
6047 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
6048 i, ServicePtrs[i]->szService));
6050 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
6051 return (-1);
6054 return (i);
6057 /***************************************************************************
6058 Convert a string to uppercase and remove whitespaces.
6059 ***************************************************************************/
6061 static char *canonicalize_servicename(const char *src)
6063 char *result;
6065 if ( !src ) {
6066 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
6067 return NULL;
6070 result = talloc_strdup(talloc_tos(), src);
6071 SMB_ASSERT(result != NULL);
6073 strlower_m(result);
6074 return result;
6077 /***************************************************************************
6078 Add a name/index pair for the services array to the hash table.
6079 ***************************************************************************/
6081 static bool hash_a_service(const char *name, int idx)
6083 char *canon_name;
6085 if ( !ServiceHash ) {
6086 DEBUG(10,("hash_a_service: creating servicehash\n"));
6087 ServiceHash = db_open_rbt(NULL);
6088 if ( !ServiceHash ) {
6089 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
6090 return False;
6094 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
6095 idx, name));
6097 canon_name = canonicalize_servicename( name );
6099 dbwrap_store_bystring(ServiceHash, canon_name,
6100 make_tdb_data((uint8 *)&idx, sizeof(idx)),
6101 TDB_REPLACE);
6103 TALLOC_FREE(canon_name);
6105 return True;
6108 /***************************************************************************
6109 Add a new home service, with the specified home directory, defaults coming
6110 from service ifrom.
6111 ***************************************************************************/
6113 bool lp_add_home(const char *pszHomename, int iDefaultService,
6114 const char *user, const char *pszHomedir)
6116 int i;
6118 if (pszHomename == NULL || user == NULL || pszHomedir == NULL ||
6119 pszHomedir[0] == '\0') {
6120 return false;
6123 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
6125 if (i < 0)
6126 return (False);
6128 if (!(*(ServicePtrs[iDefaultService]->szPath))
6129 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
6130 string_set(&ServicePtrs[i]->szPath, pszHomedir);
6133 if (!(*(ServicePtrs[i]->comment))) {
6134 char *comment = NULL;
6135 if (asprintf(&comment, "Home directory of %s", user) < 0) {
6136 return false;
6138 string_set(&ServicePtrs[i]->comment, comment);
6139 SAFE_FREE(comment);
6142 /* set the browseable flag from the global default */
6144 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6145 ServicePtrs[i]->bAccessBasedShareEnum = sDefault.bAccessBasedShareEnum;
6147 ServicePtrs[i]->autoloaded = True;
6149 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
6150 user, ServicePtrs[i]->szPath ));
6152 return (True);
6155 /***************************************************************************
6156 Add a new service, based on an old one.
6157 ***************************************************************************/
6159 int lp_add_service(const char *pszService, int iDefaultService)
6161 if (iDefaultService < 0) {
6162 return add_a_service(&sDefault, pszService);
6165 return (add_a_service(ServicePtrs[iDefaultService], pszService));
6168 /***************************************************************************
6169 Add the IPC service.
6170 ***************************************************************************/
6172 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
6174 char *comment = NULL;
6175 int i = add_a_service(&sDefault, ipc_name);
6177 if (i < 0)
6178 return (False);
6180 if (asprintf(&comment, "IPC Service (%s)",
6181 Globals.szServerString) < 0) {
6182 return (False);
6185 string_set(&ServicePtrs[i]->szPath, tmpdir());
6186 string_set(&ServicePtrs[i]->szUsername, "");
6187 string_set(&ServicePtrs[i]->comment, comment);
6188 string_set(&ServicePtrs[i]->fstype, "IPC");
6189 ServicePtrs[i]->iMaxConnections = 0;
6190 ServicePtrs[i]->bAvailable = True;
6191 ServicePtrs[i]->bRead_only = True;
6192 ServicePtrs[i]->bGuest_only = False;
6193 ServicePtrs[i]->bAdministrative_share = True;
6194 ServicePtrs[i]->bGuest_ok = guest_ok;
6195 ServicePtrs[i]->bPrint_ok = False;
6196 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6198 DEBUG(3, ("adding IPC service\n"));
6200 SAFE_FREE(comment);
6201 return (True);
6204 /***************************************************************************
6205 Add a new printer service, with defaults coming from service iFrom.
6206 ***************************************************************************/
6208 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
6210 const char *comment = "From Printcap";
6211 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
6213 if (i < 0)
6214 return (False);
6216 /* note that we do NOT default the availability flag to True - */
6217 /* we take it from the default service passed. This allows all */
6218 /* dynamic printers to be disabled by disabling the [printers] */
6219 /* entry (if/when the 'available' keyword is implemented!). */
6221 /* the printer name is set to the service name. */
6222 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
6223 string_set(&ServicePtrs[i]->comment, comment);
6225 /* set the browseable flag from the gloabl default */
6226 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
6228 /* Printers cannot be read_only. */
6229 ServicePtrs[i]->bRead_only = False;
6230 /* No share modes on printer services. */
6231 ServicePtrs[i]->bShareModes = False;
6232 /* No oplocks on printer services. */
6233 ServicePtrs[i]->bOpLocks = False;
6234 /* Printer services must be printable. */
6235 ServicePtrs[i]->bPrint_ok = True;
6237 DEBUG(3, ("adding printer service %s\n", pszPrintername));
6239 return (True);
6243 /***************************************************************************
6244 Check whether the given parameter name is valid.
6245 Parametric options (names containing a colon) are considered valid.
6246 ***************************************************************************/
6248 bool lp_parameter_is_valid(const char *pszParmName)
6250 return ((map_parameter(pszParmName) != -1) ||
6251 (strchr(pszParmName, ':') != NULL));
6254 /***************************************************************************
6255 Check whether the given name is the name of a global parameter.
6256 Returns True for strings belonging to parameters of class
6257 P_GLOBAL, False for all other strings, also for parametric options
6258 and strings not belonging to any option.
6259 ***************************************************************************/
6261 bool lp_parameter_is_global(const char *pszParmName)
6263 int num = map_parameter(pszParmName);
6265 if (num >= 0) {
6266 return (parm_table[num].p_class == P_GLOBAL);
6269 return False;
6272 /**************************************************************************
6273 Check whether the given name is the canonical name of a parameter.
6274 Returns False if it is not a valid parameter Name.
6275 For parametric options, True is returned.
6276 **************************************************************************/
6278 bool lp_parameter_is_canonical(const char *parm_name)
6280 if (!lp_parameter_is_valid(parm_name)) {
6281 return False;
6284 return (map_parameter(parm_name) ==
6285 map_parameter_canonical(parm_name, NULL));
6288 /**************************************************************************
6289 Determine the canonical name for a parameter.
6290 Indicate when it is an inverse (boolean) synonym instead of a
6291 "usual" synonym.
6292 **************************************************************************/
6294 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
6295 bool *inverse)
6297 int num;
6299 if (!lp_parameter_is_valid(parm_name)) {
6300 *canon_parm = NULL;
6301 return False;
6304 num = map_parameter_canonical(parm_name, inverse);
6305 if (num < 0) {
6306 /* parametric option */
6307 *canon_parm = parm_name;
6308 } else {
6309 *canon_parm = parm_table[num].label;
6312 return True;
6316 /**************************************************************************
6317 Determine the canonical name for a parameter.
6318 Turn the value given into the inverse boolean expression when
6319 the synonym is an invers boolean synonym.
6321 Return True if parm_name is a valid parameter name and
6322 in case it is an invers boolean synonym, if the val string could
6323 successfully be converted to the reverse bool.
6324 Return false in all other cases.
6325 **************************************************************************/
6327 bool lp_canonicalize_parameter_with_value(const char *parm_name,
6328 const char *val,
6329 const char **canon_parm,
6330 const char **canon_val)
6332 int num;
6333 bool inverse;
6335 if (!lp_parameter_is_valid(parm_name)) {
6336 *canon_parm = NULL;
6337 *canon_val = NULL;
6338 return False;
6341 num = map_parameter_canonical(parm_name, &inverse);
6342 if (num < 0) {
6343 /* parametric option */
6344 *canon_parm = parm_name;
6345 *canon_val = val;
6346 } else {
6347 *canon_parm = parm_table[num].label;
6348 if (inverse) {
6349 if (!lp_invert_boolean(val, canon_val)) {
6350 *canon_val = NULL;
6351 return False;
6353 } else {
6354 *canon_val = val;
6358 return True;
6361 /***************************************************************************
6362 Map a parameter's string representation to something we can use.
6363 Returns False if the parameter string is not recognised, else TRUE.
6364 ***************************************************************************/
6366 static int map_parameter(const char *pszParmName)
6368 int iIndex;
6370 if (*pszParmName == '-' && !strequal(pszParmName, "-valid"))
6371 return (-1);
6373 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
6374 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
6375 return (iIndex);
6377 /* Warn only if it isn't parametric option */
6378 if (strchr(pszParmName, ':') == NULL)
6379 DEBUG(1, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
6380 /* We do return 'fail' for parametric options as well because they are
6381 stored in different storage
6383 return (-1);
6386 /***************************************************************************
6387 Map a parameter's string representation to the index of the canonical
6388 form of the parameter (it might be a synonym).
6389 Returns -1 if the parameter string is not recognised.
6390 ***************************************************************************/
6392 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
6394 int parm_num, canon_num;
6395 bool loc_inverse = False;
6397 parm_num = map_parameter(pszParmName);
6398 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
6399 /* invalid, parametric or no canidate for synonyms ... */
6400 goto done;
6403 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
6404 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
6405 parm_num = canon_num;
6406 goto done;
6410 done:
6411 if (inverse != NULL) {
6412 *inverse = loc_inverse;
6414 return parm_num;
6417 /***************************************************************************
6418 return true if parameter number parm1 is a synonym of parameter
6419 number parm2 (parm2 being the principal name).
6420 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
6421 False otherwise.
6422 ***************************************************************************/
6424 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
6426 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
6427 (parm_table[parm1].flags & FLAG_HIDE) &&
6428 !(parm_table[parm2].flags & FLAG_HIDE))
6430 if (inverse != NULL) {
6431 if ((parm_table[parm1].type == P_BOOLREV) &&
6432 (parm_table[parm2].type == P_BOOL))
6434 *inverse = True;
6435 } else {
6436 *inverse = False;
6439 return True;
6441 return False;
6444 /***************************************************************************
6445 Show one parameter's name, type, [values,] and flags.
6446 (helper functions for show_parameter_list)
6447 ***************************************************************************/
6449 static void show_parameter(int parmIndex)
6451 int enumIndex, flagIndex;
6452 int parmIndex2;
6453 bool hadFlag;
6454 bool hadSyn;
6455 bool inverse;
6456 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
6457 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING",
6458 "P_ENUM", "P_SEP"};
6459 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
6460 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
6461 FLAG_HIDE, FLAG_DOS_STRING};
6462 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
6463 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
6464 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
6466 printf("%s=%s", parm_table[parmIndex].label,
6467 type[parm_table[parmIndex].type]);
6468 if (parm_table[parmIndex].type == P_ENUM) {
6469 printf(",");
6470 for (enumIndex=0;
6471 parm_table[parmIndex].enum_list[enumIndex].name;
6472 enumIndex++)
6474 printf("%s%s",
6475 enumIndex ? "|" : "",
6476 parm_table[parmIndex].enum_list[enumIndex].name);
6479 printf(",");
6480 hadFlag = False;
6481 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
6482 if (parm_table[parmIndex].flags & flags[flagIndex]) {
6483 printf("%s%s",
6484 hadFlag ? "|" : "",
6485 flag_names[flagIndex]);
6486 hadFlag = True;
6490 /* output synonyms */
6491 hadSyn = False;
6492 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
6493 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
6494 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
6495 parm_table[parmIndex2].label);
6496 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
6497 if (!hadSyn) {
6498 printf(" (synonyms: ");
6499 hadSyn = True;
6500 } else {
6501 printf(", ");
6503 printf("%s%s", parm_table[parmIndex2].label,
6504 inverse ? "[i]" : "");
6507 if (hadSyn) {
6508 printf(")");
6511 printf("\n");
6514 /***************************************************************************
6515 Show all parameter's name, type, [values,] and flags.
6516 ***************************************************************************/
6518 void show_parameter_list(void)
6520 int classIndex, parmIndex;
6521 const char *section_names[] = { "local", "global", NULL};
6523 for (classIndex=0; section_names[classIndex]; classIndex++) {
6524 printf("[%s]\n", section_names[classIndex]);
6525 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
6526 if (parm_table[parmIndex].p_class == classIndex) {
6527 show_parameter(parmIndex);
6533 /***************************************************************************
6534 Check if a given string correctly represents a boolean value.
6535 ***************************************************************************/
6537 bool lp_string_is_valid_boolean(const char *parm_value)
6539 return set_boolean(parm_value, NULL);
6542 /***************************************************************************
6543 Get the standard string representation of a boolean value ("yes" or "no")
6544 ***************************************************************************/
6546 static const char *get_boolean(bool bool_value)
6548 static const char *yes_str = "yes";
6549 static const char *no_str = "no";
6551 return (bool_value ? yes_str : no_str);
6554 /***************************************************************************
6555 Provide the string of the negated boolean value associated to the boolean
6556 given as a string. Returns False if the passed string does not correctly
6557 represent a boolean.
6558 ***************************************************************************/
6560 bool lp_invert_boolean(const char *str, const char **inverse_str)
6562 bool val;
6564 if (!set_boolean(str, &val)) {
6565 return False;
6568 *inverse_str = get_boolean(!val);
6569 return True;
6572 /***************************************************************************
6573 Provide the canonical string representation of a boolean value given
6574 as a string. Return True on success, False if the string given does
6575 not correctly represent a boolean.
6576 ***************************************************************************/
6578 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
6580 bool val;
6582 if (!set_boolean(str, &val)) {
6583 return False;
6586 *canon_str = get_boolean(val);
6587 return True;
6590 /***************************************************************************
6591 Find a service by name. Otherwise works like get_service.
6592 ***************************************************************************/
6594 static int getservicebyname(const char *pszServiceName, struct service *pserviceDest)
6596 int iService = -1;
6597 char *canon_name;
6598 TDB_DATA data;
6600 if (ServiceHash == NULL) {
6601 return -1;
6604 canon_name = canonicalize_servicename(pszServiceName);
6606 data = dbwrap_fetch_bystring(ServiceHash, canon_name, canon_name);
6608 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
6609 iService = *(int *)data.dptr;
6612 TALLOC_FREE(canon_name);
6614 if ((iService != -1) && (LP_SNUM_OK(iService))
6615 && (pserviceDest != NULL)) {
6616 copy_service(pserviceDest, ServicePtrs[iService], NULL);
6619 return (iService);
6622 /***************************************************************************
6623 Copy a service structure to another.
6624 If pcopymapDest is NULL then copy all fields
6625 ***************************************************************************/
6628 * Add a parametric option to a param_opt_struct,
6629 * replacing old value, if already present.
6631 static void set_param_opt(struct param_opt_struct **opt_list,
6632 const char *opt_name,
6633 const char *opt_value)
6635 struct param_opt_struct *new_opt, *opt;
6636 bool not_added;
6638 if (opt_list == NULL) {
6639 return;
6642 opt = *opt_list;
6643 not_added = true;
6645 /* Traverse destination */
6646 while (opt) {
6647 /* If we already have same option, override it */
6648 if (strwicmp(opt->key, opt_name) == 0) {
6649 string_free(&opt->value);
6650 TALLOC_FREE(opt->list);
6651 opt->value = SMB_STRDUP(opt_value);
6652 not_added = false;
6653 break;
6655 opt = opt->next;
6657 if (not_added) {
6658 new_opt = SMB_XMALLOC_P(struct param_opt_struct);
6659 new_opt->key = SMB_STRDUP(opt_name);
6660 new_opt->value = SMB_STRDUP(opt_value);
6661 new_opt->list = NULL;
6662 DLIST_ADD(*opt_list, new_opt);
6666 static void copy_service(struct service *pserviceDest, struct service *pserviceSource,
6667 struct bitmap *pcopymapDest)
6669 int i;
6670 bool bcopyall = (pcopymapDest == NULL);
6671 struct param_opt_struct *data;
6673 for (i = 0; parm_table[i].label; i++)
6674 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
6675 (bcopyall || bitmap_query(pcopymapDest,i))) {
6676 void *def_ptr = parm_table[i].ptr;
6677 void *src_ptr =
6678 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
6679 &sDefault);
6680 void *dest_ptr =
6681 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
6682 &sDefault);
6684 switch (parm_table[i].type) {
6685 case P_BOOL:
6686 case P_BOOLREV:
6687 *(bool *)dest_ptr = *(bool *)src_ptr;
6688 break;
6690 case P_INTEGER:
6691 case P_ENUM:
6692 case P_OCTAL:
6693 *(int *)dest_ptr = *(int *)src_ptr;
6694 break;
6696 case P_CHAR:
6697 *(char *)dest_ptr = *(char *)src_ptr;
6698 break;
6700 case P_STRING:
6701 string_set((char **)dest_ptr,
6702 *(char **)src_ptr);
6703 break;
6705 case P_USTRING:
6706 string_set((char **)dest_ptr,
6707 *(char **)src_ptr);
6708 strupper_m(*(char **)dest_ptr);
6709 break;
6710 case P_LIST:
6711 TALLOC_FREE(*((char ***)dest_ptr));
6712 *((char ***)dest_ptr) = str_list_copy(NULL,
6713 *(const char ***)src_ptr);
6714 break;
6715 default:
6716 break;
6720 if (bcopyall) {
6721 init_copymap(pserviceDest);
6722 if (pserviceSource->copymap)
6723 bitmap_copy(pserviceDest->copymap,
6724 pserviceSource->copymap);
6727 data = pserviceSource->param_opt;
6728 while (data) {
6729 set_param_opt(&pserviceDest->param_opt, data->key, data->value);
6730 data = data->next;
6734 /***************************************************************************
6735 Check a service for consistency. Return False if the service is in any way
6736 incomplete or faulty, else True.
6737 ***************************************************************************/
6739 bool service_ok(int iService)
6741 bool bRetval;
6743 bRetval = True;
6744 if (ServicePtrs[iService]->szService[0] == '\0') {
6745 DEBUG(0, ("The following message indicates an internal error:\n"));
6746 DEBUG(0, ("No service name in service entry.\n"));
6747 bRetval = False;
6750 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
6751 /* I can't see why you'd want a non-printable printer service... */
6752 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
6753 if (!ServicePtrs[iService]->bPrint_ok) {
6754 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
6755 ServicePtrs[iService]->szService));
6756 ServicePtrs[iService]->bPrint_ok = True;
6758 /* [printers] service must also be non-browsable. */
6759 if (ServicePtrs[iService]->bBrowseable)
6760 ServicePtrs[iService]->bBrowseable = False;
6763 if (ServicePtrs[iService]->szPath[0] == '\0' &&
6764 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
6765 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
6767 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
6768 ServicePtrs[iService]->szService));
6769 ServicePtrs[iService]->bAvailable = False;
6772 /* If a service is flagged unavailable, log the fact at level 1. */
6773 if (!ServicePtrs[iService]->bAvailable)
6774 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
6775 ServicePtrs[iService]->szService));
6777 return (bRetval);
6780 static struct smbconf_ctx *lp_smbconf_ctx(void)
6782 WERROR werr;
6783 static struct smbconf_ctx *conf_ctx = NULL;
6785 if (conf_ctx == NULL) {
6786 werr = smbconf_init(NULL, &conf_ctx, "registry:");
6787 if (!W_ERROR_IS_OK(werr)) {
6788 DEBUG(1, ("error initializing registry configuration: "
6789 "%s\n", win_errstr(werr)));
6790 conf_ctx = NULL;
6794 return conf_ctx;
6797 static bool process_smbconf_service(struct smbconf_service *service)
6799 uint32_t count;
6800 bool ret;
6802 if (service == NULL) {
6803 return false;
6806 ret = do_section(service->name, NULL);
6807 if (ret != true) {
6808 return false;
6810 for (count = 0; count < service->num_params; count++) {
6811 ret = do_parameter(service->param_names[count],
6812 service->param_values[count],
6813 NULL);
6814 if (ret != true) {
6815 return false;
6818 if (iServiceIndex >= 0) {
6819 return service_ok(iServiceIndex);
6821 return true;
6825 * load a service from registry and activate it
6827 bool process_registry_service(const char *service_name)
6829 WERROR werr;
6830 struct smbconf_service *service = NULL;
6831 TALLOC_CTX *mem_ctx = talloc_stackframe();
6832 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6833 bool ret = false;
6835 if (conf_ctx == NULL) {
6836 goto done;
6839 DEBUG(5, ("process_registry_service: service name %s\n", service_name));
6841 if (!smbconf_share_exists(conf_ctx, service_name)) {
6843 * Registry does not contain data for this service (yet),
6844 * but make sure lp_load doesn't return false.
6846 ret = true;
6847 goto done;
6850 werr = smbconf_get_share(conf_ctx, mem_ctx, service_name, &service);
6851 if (!W_ERROR_IS_OK(werr)) {
6852 goto done;
6855 ret = process_smbconf_service(service);
6856 if (!ret) {
6857 goto done;
6860 /* store the csn */
6861 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6863 done:
6864 TALLOC_FREE(mem_ctx);
6865 return ret;
6869 * process_registry_globals
6871 static bool process_registry_globals(void)
6873 bool ret;
6875 add_to_file_list(INCLUDE_REGISTRY_NAME, INCLUDE_REGISTRY_NAME);
6877 ret = do_parameter("registry shares", "yes", NULL);
6878 if (!ret) {
6879 return ret;
6882 return process_registry_service(GLOBAL_NAME);
6885 bool process_registry_shares(void)
6887 WERROR werr;
6888 uint32_t count;
6889 struct smbconf_service **service = NULL;
6890 uint32_t num_shares = 0;
6891 TALLOC_CTX *mem_ctx = talloc_stackframe();
6892 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
6893 bool ret = false;
6895 if (conf_ctx == NULL) {
6896 goto done;
6899 werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &service);
6900 if (!W_ERROR_IS_OK(werr)) {
6901 goto done;
6904 ret = true;
6906 for (count = 0; count < num_shares; count++) {
6907 if (strequal(service[count]->name, GLOBAL_NAME)) {
6908 continue;
6910 ret = process_smbconf_service(service[count]);
6911 if (!ret) {
6912 goto done;
6916 /* store the csn */
6917 smbconf_changed(conf_ctx, &conf_last_csn, NULL, NULL);
6919 done:
6920 TALLOC_FREE(mem_ctx);
6921 return ret;
6924 #define MAX_INCLUDE_DEPTH 100
6926 static uint8_t include_depth;
6928 static struct file_lists {
6929 struct file_lists *next;
6930 char *name;
6931 char *subfname;
6932 time_t modtime;
6933 } *file_lists = NULL;
6935 /*******************************************************************
6936 Keep a linked list of all config files so we know when one has changed
6937 it's date and needs to be reloaded.
6938 ********************************************************************/
6940 static void add_to_file_list(const char *fname, const char *subfname)
6942 struct file_lists *f = file_lists;
6944 while (f) {
6945 if (f->name && !strcmp(f->name, fname))
6946 break;
6947 f = f->next;
6950 if (!f) {
6951 f = SMB_MALLOC_P(struct file_lists);
6952 if (!f)
6953 return;
6954 f->next = file_lists;
6955 f->name = SMB_STRDUP(fname);
6956 if (!f->name) {
6957 SAFE_FREE(f);
6958 return;
6960 f->subfname = SMB_STRDUP(subfname);
6961 if (!f->subfname) {
6962 SAFE_FREE(f);
6963 return;
6965 file_lists = f;
6966 f->modtime = file_modtime(subfname);
6967 } else {
6968 time_t t = file_modtime(subfname);
6969 if (t)
6970 f->modtime = t;
6975 * Free the file lists
6977 static void free_file_list(void)
6979 struct file_lists *f;
6980 struct file_lists *next;
6982 f = file_lists;
6983 while( f ) {
6984 next = f->next;
6985 SAFE_FREE( f->name );
6986 SAFE_FREE( f->subfname );
6987 SAFE_FREE( f );
6988 f = next;
6990 file_lists = NULL;
6995 * Utility function for outsiders to check if we're running on registry.
6997 bool lp_config_backend_is_registry(void)
6999 return (lp_config_backend() == CONFIG_BACKEND_REGISTRY);
7003 * Utility function to check if the config backend is FILE.
7005 bool lp_config_backend_is_file(void)
7007 return (lp_config_backend() == CONFIG_BACKEND_FILE);
7010 /*******************************************************************
7011 Check if a config file has changed date.
7012 ********************************************************************/
7014 bool lp_file_list_changed(void)
7016 struct file_lists *f = file_lists;
7018 DEBUG(6, ("lp_file_list_changed()\n"));
7020 while (f) {
7021 char *n2 = NULL;
7022 time_t mod_time;
7024 if (strequal(f->name, INCLUDE_REGISTRY_NAME)) {
7025 struct smbconf_ctx *conf_ctx = lp_smbconf_ctx();
7027 if (conf_ctx == NULL) {
7028 return false;
7030 if (smbconf_changed(conf_ctx, &conf_last_csn, NULL,
7031 NULL))
7033 DEBUGADD(6, ("registry config changed\n"));
7034 return true;
7036 } else {
7037 n2 = alloc_sub_basic(get_current_username(),
7038 current_user_info.domain,
7039 f->name);
7040 if (!n2) {
7041 return false;
7043 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
7044 f->name, n2, ctime(&f->modtime)));
7046 mod_time = file_modtime(n2);
7048 if (mod_time &&
7049 ((f->modtime != mod_time) ||
7050 (f->subfname == NULL) ||
7051 (strcmp(n2, f->subfname) != 0)))
7053 DEBUGADD(6,
7054 ("file %s modified: %s\n", n2,
7055 ctime(&mod_time)));
7056 f->modtime = mod_time;
7057 SAFE_FREE(f->subfname);
7058 f->subfname = n2; /* Passing ownership of
7059 return from alloc_sub_basic
7060 above. */
7061 return true;
7063 SAFE_FREE(n2);
7065 f = f->next;
7067 return (False);
7071 /***************************************************************************
7072 Run standard_sub_basic on netbios name... needed because global_myname
7073 is not accessed through any lp_ macro.
7074 Note: We must *NOT* use string_set() here as ptr points to global_myname.
7075 ***************************************************************************/
7077 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
7079 bool ret;
7080 char *netbios_name = alloc_sub_basic(get_current_username(),
7081 current_user_info.domain,
7082 pszParmValue);
7084 ret = set_global_myname(netbios_name);
7085 SAFE_FREE(netbios_name);
7086 string_set(&Globals.szNetbiosName,global_myname());
7088 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
7089 global_myname()));
7091 return ret;
7094 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
7096 if (strcmp(*ptr, pszParmValue) != 0) {
7097 string_set(ptr, pszParmValue);
7098 init_iconv();
7100 return True;
7105 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
7107 bool ret;
7109 ret = set_global_myworkgroup(pszParmValue);
7110 string_set(&Globals.szWorkgroup,lp_workgroup());
7112 return ret;
7115 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
7117 bool ret;
7119 ret = set_global_scope(pszParmValue);
7120 string_set(&Globals.szNetbiosScope,global_scope());
7122 return ret;
7125 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
7127 TALLOC_FREE(Globals.szNetbiosAliases);
7128 Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL);
7129 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
7132 /***************************************************************************
7133 Handle the include operation.
7134 ***************************************************************************/
7135 static bool bAllowIncludeRegistry = true;
7137 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
7139 char *fname;
7141 if (include_depth >= MAX_INCLUDE_DEPTH) {
7142 DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
7143 include_depth));
7144 return false;
7147 if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
7148 if (!bAllowIncludeRegistry) {
7149 return true;
7151 if (bInGlobalSection) {
7152 bool ret;
7153 include_depth++;
7154 ret = process_registry_globals();
7155 include_depth--;
7156 return ret;
7157 } else {
7158 DEBUG(1, ("\"include = registry\" only effective "
7159 "in %s section\n", GLOBAL_NAME));
7160 return false;
7164 fname = alloc_sub_basic(get_current_username(),
7165 current_user_info.domain,
7166 pszParmValue);
7168 add_to_file_list(pszParmValue, fname);
7170 string_set(ptr, fname);
7172 if (file_exist(fname)) {
7173 bool ret;
7174 include_depth++;
7175 ret = pm_process(fname, do_section, do_parameter, NULL);
7176 include_depth--;
7177 SAFE_FREE(fname);
7178 return ret;
7181 DEBUG(2, ("Can't find include file %s\n", fname));
7182 SAFE_FREE(fname);
7183 return true;
7186 /***************************************************************************
7187 Handle the interpretation of the copy parameter.
7188 ***************************************************************************/
7190 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
7192 bool bRetval;
7193 int iTemp;
7194 struct service serviceTemp;
7196 string_set(ptr, pszParmValue);
7198 init_service(&serviceTemp);
7200 bRetval = False;
7202 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
7204 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
7205 if (iTemp == iServiceIndex) {
7206 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
7207 } else {
7208 copy_service(ServicePtrs[iServiceIndex],
7209 &serviceTemp,
7210 ServicePtrs[iServiceIndex]->copymap);
7211 bRetval = True;
7213 } else {
7214 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
7215 bRetval = False;
7218 free_service(&serviceTemp);
7219 return (bRetval);
7222 static bool handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
7224 Globals.ldap_debug_level = lp_int(pszParmValue);
7225 init_ldap_debugging();
7226 return true;
7229 /***************************************************************************
7230 Handle idmap/non unix account uid and gid allocation parameters. The format of these
7231 parameters is:
7233 [global]
7235 idmap uid = 1000-1999
7236 idmap gid = 700-899
7238 We only do simple parsing checks here. The strings are parsed into useful
7239 structures in the idmap daemon code.
7241 ***************************************************************************/
7243 /* Some lp_ routines to return idmap [ug]id information */
7245 static uid_t idmap_uid_low, idmap_uid_high;
7246 static gid_t idmap_gid_low, idmap_gid_high;
7248 bool lp_idmap_uid(uid_t *low, uid_t *high)
7250 if (idmap_uid_low == 0 || idmap_uid_high == 0)
7251 return False;
7253 if (low)
7254 *low = idmap_uid_low;
7256 if (high)
7257 *high = idmap_uid_high;
7259 return True;
7262 bool lp_idmap_gid(gid_t *low, gid_t *high)
7264 if (idmap_gid_low == 0 || idmap_gid_high == 0)
7265 return False;
7267 if (low)
7268 *low = idmap_gid_low;
7270 if (high)
7271 *high = idmap_gid_high;
7273 return True;
7276 /* Do some simple checks on "idmap [ug]id" parameter values */
7278 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
7280 uint32 low, high;
7282 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7283 return False;
7285 /* Parse OK */
7287 string_set(ptr, pszParmValue);
7289 idmap_uid_low = low;
7290 idmap_uid_high = high;
7292 return True;
7295 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
7297 uint32 low, high;
7299 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
7300 return False;
7302 /* Parse OK */
7304 string_set(ptr, pszParmValue);
7306 idmap_gid_low = low;
7307 idmap_gid_high = high;
7309 return True;
7312 /***************************************************************************
7313 Handle the DEBUG level list.
7314 ***************************************************************************/
7316 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
7318 string_set(ptr, pszParmValueIn);
7319 return debug_parse_levels(pszParmValueIn);
7322 /***************************************************************************
7323 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
7324 ***************************************************************************/
7326 static const char *append_ldap_suffix( const char *str )
7328 const char *suffix_string;
7331 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
7332 Globals.szLdapSuffix );
7333 if ( !suffix_string ) {
7334 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
7335 return "";
7338 return suffix_string;
7341 const char *lp_ldap_machine_suffix(void)
7343 if (Globals.szLdapMachineSuffix[0])
7344 return append_ldap_suffix(Globals.szLdapMachineSuffix);
7346 return lp_string(Globals.szLdapSuffix);
7349 const char *lp_ldap_user_suffix(void)
7351 if (Globals.szLdapUserSuffix[0])
7352 return append_ldap_suffix(Globals.szLdapUserSuffix);
7354 return lp_string(Globals.szLdapSuffix);
7357 const char *lp_ldap_group_suffix(void)
7359 if (Globals.szLdapGroupSuffix[0])
7360 return append_ldap_suffix(Globals.szLdapGroupSuffix);
7362 return lp_string(Globals.szLdapSuffix);
7365 const char *lp_ldap_idmap_suffix(void)
7367 if (Globals.szLdapIdmapSuffix[0])
7368 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
7370 return lp_string(Globals.szLdapSuffix);
7373 /****************************************************************************
7374 set the value for a P_ENUM
7375 ***************************************************************************/
7377 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
7378 int *ptr )
7380 int i;
7382 for (i = 0; parm->enum_list[i].name; i++) {
7383 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
7384 *ptr = parm->enum_list[i].value;
7385 return;
7388 DEBUG(0, ("WARNING: Ignoring invalid value '%s' for parameter '%s'\n",
7389 pszParmValue, parm->label));
7392 /***************************************************************************
7393 ***************************************************************************/
7395 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
7397 static int parm_num = -1;
7398 struct service *s;
7400 if ( parm_num == -1 )
7401 parm_num = map_parameter( "printing" );
7403 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
7405 if ( snum < 0 )
7406 s = &sDefault;
7407 else
7408 s = ServicePtrs[snum];
7410 init_printer_values( s );
7412 return True;
7416 /***************************************************************************
7417 Initialise a copymap.
7418 ***************************************************************************/
7420 static void init_copymap(struct service *pservice)
7422 int i;
7423 if (pservice->copymap) {
7424 bitmap_free(pservice->copymap);
7426 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
7427 if (!pservice->copymap)
7428 DEBUG(0,
7429 ("Couldn't allocate copymap!! (size %d)\n",
7430 (int)NUMPARAMETERS));
7431 else
7432 for (i = 0; i < NUMPARAMETERS; i++)
7433 bitmap_set(pservice->copymap, i);
7436 /***************************************************************************
7437 Return the local pointer to a parameter given a service struct and the
7438 pointer into the default structure.
7439 ***************************************************************************/
7441 static void *lp_local_ptr(struct service *service, void *ptr)
7443 return (void *)(((char *)service) + PTR_DIFF(ptr, &sDefault));
7446 /***************************************************************************
7447 Return the local pointer to a parameter given the service number and the
7448 pointer into the default structure.
7449 ***************************************************************************/
7451 void *lp_local_ptr_by_snum(int snum, void *ptr)
7453 return lp_local_ptr(ServicePtrs[snum], ptr);
7456 /***************************************************************************
7457 Process a parameter for a particular service number. If snum < 0
7458 then assume we are in the globals.
7459 ***************************************************************************/
7461 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
7463 int parmnum, i;
7464 void *parm_ptr = NULL; /* where we are going to store the result */
7465 void *def_ptr = NULL;
7466 struct param_opt_struct **opt_list;
7468 parmnum = map_parameter(pszParmName);
7470 if (parmnum < 0) {
7471 if (strchr(pszParmName, ':') == NULL) {
7472 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n",
7473 pszParmName));
7474 return (True);
7478 * We've got a parametric option
7481 opt_list = (snum < 0)
7482 ? &Globals.param_opt : &ServicePtrs[snum]->param_opt;
7483 set_param_opt(opt_list, pszParmName, pszParmValue);
7485 return (True);
7488 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
7489 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
7490 pszParmName));
7493 def_ptr = parm_table[parmnum].ptr;
7495 /* we might point at a service, the default service or a global */
7496 if (snum < 0) {
7497 parm_ptr = def_ptr;
7498 } else {
7499 if (parm_table[parmnum].p_class == P_GLOBAL) {
7500 DEBUG(0,
7501 ("Global parameter %s found in service section!\n",
7502 pszParmName));
7503 return (True);
7505 parm_ptr = lp_local_ptr_by_snum(snum, def_ptr);
7508 if (snum >= 0) {
7509 if (!ServicePtrs[snum]->copymap)
7510 init_copymap(ServicePtrs[snum]);
7512 /* this handles the aliases - set the copymap for other entries with
7513 the same data pointer */
7514 for (i = 0; parm_table[i].label; i++)
7515 if (parm_table[i].ptr == parm_table[parmnum].ptr)
7516 bitmap_clear(ServicePtrs[snum]->copymap, i);
7519 /* if it is a special case then go ahead */
7520 if (parm_table[parmnum].special) {
7521 return parm_table[parmnum].special(snum, pszParmValue,
7522 (char **)parm_ptr);
7525 /* now switch on the type of variable it is */
7526 switch (parm_table[parmnum].type)
7528 case P_BOOL:
7529 *(bool *)parm_ptr = lp_bool(pszParmValue);
7530 break;
7532 case P_BOOLREV:
7533 *(bool *)parm_ptr = !lp_bool(pszParmValue);
7534 break;
7536 case P_INTEGER:
7537 *(int *)parm_ptr = lp_int(pszParmValue);
7538 break;
7540 case P_CHAR:
7541 *(char *)parm_ptr = *pszParmValue;
7542 break;
7544 case P_OCTAL:
7545 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
7546 if ( i != 1 ) {
7547 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
7549 break;
7551 case P_LIST:
7552 TALLOC_FREE(*((char ***)parm_ptr));
7553 *(char ***)parm_ptr = str_list_make_v3(
7554 talloc_autofree_context(), pszParmValue, NULL);
7555 break;
7557 case P_STRING:
7558 string_set((char **)parm_ptr, pszParmValue);
7559 break;
7561 case P_USTRING:
7562 string_set((char **)parm_ptr, pszParmValue);
7563 strupper_m(*(char **)parm_ptr);
7564 break;
7566 case P_ENUM:
7567 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
7568 break;
7569 case P_SEP:
7570 break;
7573 return (True);
7576 /***************************************************************************
7577 Process a parameter.
7578 ***************************************************************************/
7580 static bool do_parameter(const char *pszParmName, const char *pszParmValue,
7581 void *userdata)
7583 if (!bInGlobalSection && bGlobalOnly)
7584 return (True);
7586 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
7588 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
7589 pszParmName, pszParmValue));
7592 /***************************************************************************
7593 Print a parameter of the specified type.
7594 ***************************************************************************/
7596 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
7598 int i;
7599 switch (p->type)
7601 case P_ENUM:
7602 for (i = 0; p->enum_list[i].name; i++) {
7603 if (*(int *)ptr == p->enum_list[i].value) {
7604 fprintf(f, "%s",
7605 p->enum_list[i].name);
7606 break;
7609 break;
7611 case P_BOOL:
7612 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
7613 break;
7615 case P_BOOLREV:
7616 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
7617 break;
7619 case P_INTEGER:
7620 fprintf(f, "%d", *(int *)ptr);
7621 break;
7623 case P_CHAR:
7624 fprintf(f, "%c", *(char *)ptr);
7625 break;
7627 case P_OCTAL: {
7628 char *o = octal_string(*(int *)ptr);
7629 fprintf(f, "%s", o);
7630 TALLOC_FREE(o);
7631 break;
7634 case P_LIST:
7635 if ((char ***)ptr && *(char ***)ptr) {
7636 char **list = *(char ***)ptr;
7637 for (; *list; list++) {
7638 /* surround strings with whitespace in double quotes */
7639 if ( strchr_m( *list, ' ' ) )
7640 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
7641 else
7642 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
7645 break;
7647 case P_STRING:
7648 case P_USTRING:
7649 if (*(char **)ptr) {
7650 fprintf(f, "%s", *(char **)ptr);
7652 break;
7653 case P_SEP:
7654 break;
7658 /***************************************************************************
7659 Check if two parameters are equal.
7660 ***************************************************************************/
7662 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
7664 switch (type) {
7665 case P_BOOL:
7666 case P_BOOLREV:
7667 return (*((bool *)ptr1) == *((bool *)ptr2));
7669 case P_INTEGER:
7670 case P_ENUM:
7671 case P_OCTAL:
7672 return (*((int *)ptr1) == *((int *)ptr2));
7674 case P_CHAR:
7675 return (*((char *)ptr1) == *((char *)ptr2));
7677 case P_LIST:
7678 return str_list_equal(*(const char ***)ptr1, *(const char ***)ptr2);
7680 case P_STRING:
7681 case P_USTRING:
7683 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
7684 if (p1 && !*p1)
7685 p1 = NULL;
7686 if (p2 && !*p2)
7687 p2 = NULL;
7688 return (p1 == p2 || strequal(p1, p2));
7690 case P_SEP:
7691 break;
7693 return (False);
7696 /***************************************************************************
7697 Initialize any local varients in the sDefault table.
7698 ***************************************************************************/
7700 void init_locals(void)
7702 /* None as yet. */
7705 /***************************************************************************
7706 Process a new section (service). At this stage all sections are services.
7707 Later we'll have special sections that permit server parameters to be set.
7708 Returns True on success, False on failure.
7709 ***************************************************************************/
7711 static bool do_section(const char *pszSectionName, void *userdata)
7713 bool bRetval;
7714 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
7715 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
7716 bRetval = False;
7718 /* if we were in a global section then do the local inits */
7719 if (bInGlobalSection && !isglobal)
7720 init_locals();
7722 /* if we've just struck a global section, note the fact. */
7723 bInGlobalSection = isglobal;
7725 /* check for multiple global sections */
7726 if (bInGlobalSection) {
7727 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
7728 return (True);
7731 if (!bInGlobalSection && bGlobalOnly)
7732 return (True);
7734 /* if we have a current service, tidy it up before moving on */
7735 bRetval = True;
7737 if (iServiceIndex >= 0)
7738 bRetval = service_ok(iServiceIndex);
7740 /* if all is still well, move to the next record in the services array */
7741 if (bRetval) {
7742 /* We put this here to avoid an odd message order if messages are */
7743 /* issued by the post-processing of a previous section. */
7744 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
7746 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
7747 < 0) {
7748 DEBUG(0, ("Failed to add a new service\n"));
7749 return (False);
7753 return (bRetval);
7757 /***************************************************************************
7758 Determine if a partcular base parameter is currentl set to the default value.
7759 ***************************************************************************/
7761 static bool is_default(int i)
7763 if (!defaults_saved)
7764 return False;
7765 switch (parm_table[i].type) {
7766 case P_LIST:
7767 return str_list_equal((const char **)parm_table[i].def.lvalue,
7768 *(const char ***)parm_table[i].ptr);
7769 case P_STRING:
7770 case P_USTRING:
7771 return strequal(parm_table[i].def.svalue,
7772 *(char **)parm_table[i].ptr);
7773 case P_BOOL:
7774 case P_BOOLREV:
7775 return parm_table[i].def.bvalue ==
7776 *(bool *)parm_table[i].ptr;
7777 case P_CHAR:
7778 return parm_table[i].def.cvalue ==
7779 *(char *)parm_table[i].ptr;
7780 case P_INTEGER:
7781 case P_OCTAL:
7782 case P_ENUM:
7783 return parm_table[i].def.ivalue ==
7784 *(int *)parm_table[i].ptr;
7785 case P_SEP:
7786 break;
7788 return False;
7791 /***************************************************************************
7792 Display the contents of the global structure.
7793 ***************************************************************************/
7795 static void dump_globals(FILE *f)
7797 int i;
7798 struct param_opt_struct *data;
7800 fprintf(f, "[global]\n");
7802 for (i = 0; parm_table[i].label; i++)
7803 if (parm_table[i].p_class == P_GLOBAL &&
7804 !(parm_table[i].flags & FLAG_META) &&
7805 parm_table[i].ptr &&
7806 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
7807 if (defaults_saved && is_default(i))
7808 continue;
7809 fprintf(f, "\t%s = ", parm_table[i].label);
7810 print_parameter(&parm_table[i], parm_table[i].ptr, f);
7811 fprintf(f, "\n");
7813 if (Globals.param_opt != NULL) {
7814 data = Globals.param_opt;
7815 while(data) {
7816 fprintf(f, "\t%s = %s\n", data->key, data->value);
7817 data = data->next;
7823 /***************************************************************************
7824 Return True if a local parameter is currently set to the global default.
7825 ***************************************************************************/
7827 bool lp_is_default(int snum, struct parm_struct *parm)
7829 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
7831 return equal_parameter(parm->type,
7832 ((char *)ServicePtrs[snum]) + pdiff,
7833 ((char *)&sDefault) + pdiff);
7836 /***************************************************************************
7837 Display the contents of a single services record.
7838 ***************************************************************************/
7840 static void dump_a_service(struct service *pService, FILE * f)
7842 int i;
7843 struct param_opt_struct *data;
7845 if (pService != &sDefault)
7846 fprintf(f, "[%s]\n", pService->szService);
7848 for (i = 0; parm_table[i].label; i++) {
7850 if (parm_table[i].p_class == P_LOCAL &&
7851 !(parm_table[i].flags & FLAG_META) &&
7852 parm_table[i].ptr &&
7853 (*parm_table[i].label != '-') &&
7854 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7857 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
7859 if (pService == &sDefault) {
7860 if (defaults_saved && is_default(i))
7861 continue;
7862 } else {
7863 if (equal_parameter(parm_table[i].type,
7864 ((char *)pService) +
7865 pdiff,
7866 ((char *)&sDefault) +
7867 pdiff))
7868 continue;
7871 fprintf(f, "\t%s = ", parm_table[i].label);
7872 print_parameter(&parm_table[i],
7873 ((char *)pService) + pdiff, f);
7874 fprintf(f, "\n");
7878 if (pService->param_opt != NULL) {
7879 data = pService->param_opt;
7880 while(data) {
7881 fprintf(f, "\t%s = %s\n", data->key, data->value);
7882 data = data->next;
7887 /***************************************************************************
7888 Display the contents of a parameter of a single services record.
7889 ***************************************************************************/
7891 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
7893 int i;
7894 bool result = False;
7895 parm_class p_class;
7896 unsigned flag = 0;
7897 fstring local_parm_name;
7898 char *parm_opt;
7899 const char *parm_opt_value;
7901 /* check for parametrical option */
7902 fstrcpy( local_parm_name, parm_name);
7903 parm_opt = strchr( local_parm_name, ':');
7905 if (parm_opt) {
7906 *parm_opt = '\0';
7907 parm_opt++;
7908 if (strlen(parm_opt)) {
7909 parm_opt_value = lp_parm_const_string( snum,
7910 local_parm_name, parm_opt, NULL);
7911 if (parm_opt_value) {
7912 printf( "%s\n", parm_opt_value);
7913 result = True;
7916 return result;
7919 /* check for a key and print the value */
7920 if (isGlobal) {
7921 p_class = P_GLOBAL;
7922 flag = FLAG_GLOBAL;
7923 } else
7924 p_class = P_LOCAL;
7926 for (i = 0; parm_table[i].label; i++) {
7927 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
7928 !(parm_table[i].flags & FLAG_META) &&
7929 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
7930 parm_table[i].ptr &&
7931 (*parm_table[i].label != '-') &&
7932 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
7934 void *ptr;
7936 if (isGlobal) {
7937 ptr = parm_table[i].ptr;
7938 } else {
7939 struct service *pService = ServicePtrs[snum];
7940 ptr = ((char *)pService) +
7941 PTR_DIFF(parm_table[i].ptr, &sDefault);
7944 print_parameter(&parm_table[i],
7945 ptr, f);
7946 fprintf(f, "\n");
7947 result = True;
7948 break;
7952 return result;
7955 /***************************************************************************
7956 Return info about the requested parameter (given as a string).
7957 Return NULL when the string is not a valid parameter name.
7958 ***************************************************************************/
7960 struct parm_struct *lp_get_parameter(const char *param_name)
7962 int num = map_parameter(param_name);
7964 if (num < 0) {
7965 return NULL;
7968 return &parm_table[num];
7971 /***************************************************************************
7972 Return info about the next parameter in a service.
7973 snum==GLOBAL_SECTION_SNUM gives the globals.
7974 Return NULL when out of parameters.
7975 ***************************************************************************/
7977 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
7979 if (snum < 0) {
7980 /* do the globals */
7981 for (; parm_table[*i].label; (*i)++) {
7982 if (parm_table[*i].p_class == P_SEPARATOR)
7983 return &parm_table[(*i)++];
7985 if (!parm_table[*i].ptr
7986 || (*parm_table[*i].label == '-'))
7987 continue;
7989 if ((*i) > 0
7990 && (parm_table[*i].ptr ==
7991 parm_table[(*i) - 1].ptr))
7992 continue;
7994 if (is_default(*i) && !allparameters)
7995 continue;
7997 return &parm_table[(*i)++];
7999 } else {
8000 struct service *pService = ServicePtrs[snum];
8002 for (; parm_table[*i].label; (*i)++) {
8003 if (parm_table[*i].p_class == P_SEPARATOR)
8004 return &parm_table[(*i)++];
8006 if (parm_table[*i].p_class == P_LOCAL &&
8007 parm_table[*i].ptr &&
8008 (*parm_table[*i].label != '-') &&
8009 ((*i) == 0 ||
8010 (parm_table[*i].ptr !=
8011 parm_table[(*i) - 1].ptr)))
8013 int pdiff =
8014 PTR_DIFF(parm_table[*i].ptr,
8015 &sDefault);
8017 if (allparameters ||
8018 !equal_parameter(parm_table[*i].type,
8019 ((char *)pService) +
8020 pdiff,
8021 ((char *)&sDefault) +
8022 pdiff))
8024 return &parm_table[(*i)++];
8030 return NULL;
8034 #if 0
8035 /***************************************************************************
8036 Display the contents of a single copy structure.
8037 ***************************************************************************/
8038 static void dump_copy_map(bool *pcopymap)
8040 int i;
8041 if (!pcopymap)
8042 return;
8044 printf("\n\tNon-Copied parameters:\n");
8046 for (i = 0; parm_table[i].label; i++)
8047 if (parm_table[i].p_class == P_LOCAL &&
8048 parm_table[i].ptr && !pcopymap[i] &&
8049 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
8051 printf("\t\t%s\n", parm_table[i].label);
8054 #endif
8056 /***************************************************************************
8057 Return TRUE if the passed service number is within range.
8058 ***************************************************************************/
8060 bool lp_snum_ok(int iService)
8062 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
8065 /***************************************************************************
8066 Auto-load some home services.
8067 ***************************************************************************/
8069 static void lp_add_auto_services(char *str)
8071 char *s;
8072 char *p;
8073 int homes;
8074 char *saveptr;
8076 if (!str)
8077 return;
8079 s = SMB_STRDUP(str);
8080 if (!s)
8081 return;
8083 homes = lp_servicenumber(HOMES_NAME);
8085 for (p = strtok_r(s, LIST_SEP, &saveptr); p;
8086 p = strtok_r(NULL, LIST_SEP, &saveptr)) {
8087 char *home;
8089 if (lp_servicenumber(p) >= 0)
8090 continue;
8092 home = get_user_home_dir(talloc_tos(), p);
8094 if (home && home[0] && homes >= 0)
8095 lp_add_home(p, homes, p, home);
8097 TALLOC_FREE(home);
8099 SAFE_FREE(s);
8102 /***************************************************************************
8103 Auto-load one printer.
8104 ***************************************************************************/
8106 void lp_add_one_printer(const char *name, const char *comment, void *pdata)
8108 int printers = lp_servicenumber(PRINTERS_NAME);
8109 int i;
8111 if (lp_servicenumber(name) < 0) {
8112 lp_add_printer(name, printers);
8113 if ((i = lp_servicenumber(name)) >= 0) {
8114 string_set(&ServicePtrs[i]->comment, comment);
8115 ServicePtrs[i]->autoloaded = True;
8120 /***************************************************************************
8121 Have we loaded a services file yet?
8122 ***************************************************************************/
8124 bool lp_loaded(void)
8126 return (bLoaded);
8129 /***************************************************************************
8130 Unload unused services.
8131 ***************************************************************************/
8133 void lp_killunused(bool (*snumused) (int))
8135 int i;
8136 for (i = 0; i < iNumServices; i++) {
8137 if (!VALID(i))
8138 continue;
8140 /* don't kill autoloaded or usershare services */
8141 if ( ServicePtrs[i]->autoloaded ||
8142 ServicePtrs[i]->usershare == USERSHARE_VALID) {
8143 continue;
8146 if (!snumused || !snumused(i)) {
8147 free_service_byindex(i);
8153 * Kill all except autoloaded and usershare services - convenience wrapper
8155 void lp_kill_all_services(void)
8157 lp_killunused(NULL);
8160 /***************************************************************************
8161 Unload a service.
8162 ***************************************************************************/
8164 void lp_killservice(int iServiceIn)
8166 if (VALID(iServiceIn)) {
8167 free_service_byindex(iServiceIn);
8171 /***************************************************************************
8172 Save the curent values of all global and sDefault parameters into the
8173 defaults union. This allows swat and testparm to show only the
8174 changed (ie. non-default) parameters.
8175 ***************************************************************************/
8177 static void lp_save_defaults(void)
8179 int i;
8180 for (i = 0; parm_table[i].label; i++) {
8181 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
8182 continue;
8183 switch (parm_table[i].type) {
8184 case P_LIST:
8185 parm_table[i].def.lvalue = str_list_copy(
8186 NULL, *(const char ***)parm_table[i].ptr);
8187 break;
8188 case P_STRING:
8189 case P_USTRING:
8190 if (parm_table[i].ptr) {
8191 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
8192 } else {
8193 parm_table[i].def.svalue = NULL;
8195 break;
8196 case P_BOOL:
8197 case P_BOOLREV:
8198 parm_table[i].def.bvalue =
8199 *(bool *)parm_table[i].ptr;
8200 break;
8201 case P_CHAR:
8202 parm_table[i].def.cvalue =
8203 *(char *)parm_table[i].ptr;
8204 break;
8205 case P_INTEGER:
8206 case P_OCTAL:
8207 case P_ENUM:
8208 parm_table[i].def.ivalue =
8209 *(int *)parm_table[i].ptr;
8210 break;
8211 case P_SEP:
8212 break;
8215 defaults_saved = True;
8218 /*******************************************************************
8219 Set the server type we will announce as via nmbd.
8220 ********************************************************************/
8222 static const struct srv_role_tab {
8223 uint32 role;
8224 const char *role_str;
8225 } srv_role_tab [] = {
8226 { ROLE_STANDALONE, "ROLE_STANDALONE" },
8227 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
8228 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
8229 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
8230 { 0, NULL }
8233 const char* server_role_str(uint32 role)
8235 int i = 0;
8236 for (i=0; srv_role_tab[i].role_str; i++) {
8237 if (role == srv_role_tab[i].role) {
8238 return srv_role_tab[i].role_str;
8241 return NULL;
8244 static void set_server_role(void)
8246 server_role = ROLE_STANDALONE;
8248 switch (lp_security()) {
8249 case SEC_SHARE:
8250 if (lp_domain_logons())
8251 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
8252 break;
8253 case SEC_SERVER:
8254 if (lp_domain_logons())
8255 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
8256 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
8257 server_role = ROLE_STANDALONE;
8258 break;
8259 case SEC_DOMAIN:
8260 if (lp_domain_logons()) {
8261 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
8262 server_role = ROLE_DOMAIN_BDC;
8263 break;
8265 server_role = ROLE_DOMAIN_MEMBER;
8266 break;
8267 case SEC_ADS:
8268 if (lp_domain_logons()) {
8269 server_role = ROLE_DOMAIN_PDC;
8270 break;
8272 server_role = ROLE_DOMAIN_MEMBER;
8273 break;
8274 case SEC_USER:
8275 if (lp_domain_logons()) {
8277 if (Globals.iDomainMaster) /* auto or yes */
8278 server_role = ROLE_DOMAIN_PDC;
8279 else
8280 server_role = ROLE_DOMAIN_BDC;
8282 break;
8283 default:
8284 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
8285 break;
8288 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
8291 /***********************************************************
8292 If we should send plaintext/LANMAN passwords in the clinet
8293 ************************************************************/
8295 static void set_allowed_client_auth(void)
8297 if (Globals.bClientNTLMv2Auth) {
8298 Globals.bClientLanManAuth = False;
8300 if (!Globals.bClientLanManAuth) {
8301 Globals.bClientPlaintextAuth = False;
8305 /***************************************************************************
8306 JRA.
8307 The following code allows smbd to read a user defined share file.
8308 Yes, this is my intent. Yes, I'm comfortable with that...
8310 THE FOLLOWING IS SECURITY CRITICAL CODE.
8312 It washes your clothes, it cleans your house, it guards you while you sleep...
8313 Do not f%^k with it....
8314 ***************************************************************************/
8316 #define MAX_USERSHARE_FILE_SIZE (10*1024)
8318 /***************************************************************************
8319 Check allowed stat state of a usershare file.
8320 Ensure we print out who is dicking with us so the admin can
8321 get their sorry ass fired.
8322 ***************************************************************************/
8324 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
8326 if (!S_ISREG(psbuf->st_mode)) {
8327 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8328 "not a regular file\n",
8329 fname, (unsigned int)psbuf->st_uid ));
8330 return False;
8333 /* Ensure this doesn't have the other write bit set. */
8334 if (psbuf->st_mode & S_IWOTH) {
8335 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
8336 "public write. Refusing to allow as a usershare file.\n",
8337 fname, (unsigned int)psbuf->st_uid ));
8338 return False;
8341 /* Should be 10k or less. */
8342 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
8343 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
8344 "too large (%u) to be a user share file.\n",
8345 fname, (unsigned int)psbuf->st_uid,
8346 (unsigned int)psbuf->st_size ));
8347 return False;
8350 return True;
8353 /***************************************************************************
8354 Parse the contents of a usershare file.
8355 ***************************************************************************/
8357 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
8358 SMB_STRUCT_STAT *psbuf,
8359 const char *servicename,
8360 int snum,
8361 char **lines,
8362 int numlines,
8363 char **pp_sharepath,
8364 char **pp_comment,
8365 SEC_DESC **ppsd,
8366 bool *pallow_guest)
8368 const char **prefixallowlist = lp_usershare_prefix_allow_list();
8369 const char **prefixdenylist = lp_usershare_prefix_deny_list();
8370 int us_vers;
8371 SMB_STRUCT_DIR *dp;
8372 SMB_STRUCT_STAT sbuf;
8373 char *sharepath = NULL;
8374 char *comment = NULL;
8376 *pp_sharepath = NULL;
8377 *pp_comment = NULL;
8379 *pallow_guest = False;
8381 if (numlines < 4) {
8382 return USERSHARE_MALFORMED_FILE;
8385 if (strcmp(lines[0], "#VERSION 1") == 0) {
8386 us_vers = 1;
8387 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
8388 us_vers = 2;
8389 if (numlines < 5) {
8390 return USERSHARE_MALFORMED_FILE;
8392 } else {
8393 return USERSHARE_BAD_VERSION;
8396 if (strncmp(lines[1], "path=", 5) != 0) {
8397 return USERSHARE_MALFORMED_PATH;
8400 sharepath = talloc_strdup(ctx, &lines[1][5]);
8401 if (!sharepath) {
8402 return USERSHARE_POSIX_ERR;
8404 trim_string(sharepath, " ", " ");
8406 if (strncmp(lines[2], "comment=", 8) != 0) {
8407 return USERSHARE_MALFORMED_COMMENT_DEF;
8410 comment = talloc_strdup(ctx, &lines[2][8]);
8411 if (!comment) {
8412 return USERSHARE_POSIX_ERR;
8414 trim_string(comment, " ", " ");
8415 trim_char(comment, '"', '"');
8417 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
8418 return USERSHARE_MALFORMED_ACL_DEF;
8421 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
8422 return USERSHARE_ACL_ERR;
8425 if (us_vers == 2) {
8426 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
8427 return USERSHARE_MALFORMED_ACL_DEF;
8429 if (lines[4][9] == 'y') {
8430 *pallow_guest = True;
8434 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
8435 /* Path didn't change, no checks needed. */
8436 *pp_sharepath = sharepath;
8437 *pp_comment = comment;
8438 return USERSHARE_OK;
8441 /* The path *must* be absolute. */
8442 if (sharepath[0] != '/') {
8443 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
8444 servicename, sharepath));
8445 return USERSHARE_PATH_NOT_ABSOLUTE;
8448 /* If there is a usershare prefix deny list ensure one of these paths
8449 doesn't match the start of the user given path. */
8450 if (prefixdenylist) {
8451 int i;
8452 for ( i=0; prefixdenylist[i]; i++ ) {
8453 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
8454 servicename, i, prefixdenylist[i], sharepath ));
8455 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
8456 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
8457 "usershare prefix deny list entries.\n",
8458 servicename, sharepath));
8459 return USERSHARE_PATH_IS_DENIED;
8464 /* If there is a usershare prefix allow list ensure one of these paths
8465 does match the start of the user given path. */
8467 if (prefixallowlist) {
8468 int i;
8469 for ( i=0; prefixallowlist[i]; i++ ) {
8470 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
8471 servicename, i, prefixallowlist[i], sharepath ));
8472 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
8473 break;
8476 if (prefixallowlist[i] == NULL) {
8477 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
8478 "usershare prefix allow list entries.\n",
8479 servicename, sharepath));
8480 return USERSHARE_PATH_NOT_ALLOWED;
8484 /* Ensure this is pointing to a directory. */
8485 dp = sys_opendir(sharepath);
8487 if (!dp) {
8488 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8489 servicename, sharepath));
8490 return USERSHARE_PATH_NOT_DIRECTORY;
8493 /* Ensure the owner of the usershare file has permission to share
8494 this directory. */
8496 if (sys_stat(sharepath, &sbuf) == -1) {
8497 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
8498 servicename, sharepath, strerror(errno) ));
8499 sys_closedir(dp);
8500 return USERSHARE_POSIX_ERR;
8503 sys_closedir(dp);
8505 if (!S_ISDIR(sbuf.st_mode)) {
8506 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
8507 servicename, sharepath ));
8508 return USERSHARE_PATH_NOT_DIRECTORY;
8511 /* Check if sharing is restricted to owner-only. */
8512 /* psbuf is the stat of the usershare definition file,
8513 sbuf is the stat of the target directory to be shared. */
8515 if (lp_usershare_owner_only()) {
8516 /* root can share anything. */
8517 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
8518 return USERSHARE_PATH_NOT_ALLOWED;
8522 *pp_sharepath = sharepath;
8523 *pp_comment = comment;
8524 return USERSHARE_OK;
8527 /***************************************************************************
8528 Deal with a usershare file.
8529 Returns:
8530 >= 0 - snum
8531 -1 - Bad name, invalid contents.
8532 - service name already existed and not a usershare, problem
8533 with permissions to share directory etc.
8534 ***************************************************************************/
8536 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
8538 SMB_STRUCT_STAT sbuf;
8539 SMB_STRUCT_STAT lsbuf;
8540 char *fname = NULL;
8541 char *sharepath = NULL;
8542 char *comment = NULL;
8543 fstring service_name;
8544 char **lines = NULL;
8545 int numlines = 0;
8546 int fd = -1;
8547 int iService = -1;
8548 TALLOC_CTX *ctx = NULL;
8549 SEC_DESC *psd = NULL;
8550 bool guest_ok = False;
8552 /* Ensure share name doesn't contain invalid characters. */
8553 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
8554 DEBUG(0,("process_usershare_file: share name %s contains "
8555 "invalid characters (any of %s)\n",
8556 file_name, INVALID_SHARENAME_CHARS ));
8557 return -1;
8560 fstrcpy(service_name, file_name);
8562 if (asprintf(&fname, "%s/%s", dir_name, file_name) < 0) {
8565 /* Minimize the race condition by doing an lstat before we
8566 open and fstat. Ensure this isn't a symlink link. */
8568 if (sys_lstat(fname, &lsbuf) != 0) {
8569 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
8570 fname, strerror(errno) ));
8571 SAFE_FREE(fname);
8572 return -1;
8575 /* This must be a regular file, not a symlink, directory or
8576 other strange filetype. */
8577 if (!check_usershare_stat(fname, &lsbuf)) {
8578 SAFE_FREE(fname);
8579 return -1;
8583 char *canon_name = canonicalize_servicename(service_name);
8584 TDB_DATA data = dbwrap_fetch_bystring(
8585 ServiceHash, canon_name, canon_name);
8587 iService = -1;
8589 if ((data.dptr != NULL) && (data.dsize == sizeof(iService))) {
8590 iService = *(int *)data.dptr;
8592 TALLOC_FREE(canon_name);
8595 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
8596 /* Nothing changed - Mark valid and return. */
8597 DEBUG(10,("process_usershare_file: service %s not changed.\n",
8598 service_name ));
8599 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8600 SAFE_FREE(fname);
8601 return iService;
8604 /* Try and open the file read only - no symlinks allowed. */
8605 #ifdef O_NOFOLLOW
8606 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
8607 #else
8608 fd = sys_open(fname, O_RDONLY, 0);
8609 #endif
8611 if (fd == -1) {
8612 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
8613 fname, strerror(errno) ));
8614 SAFE_FREE(fname);
8615 return -1;
8618 /* Now fstat to be *SURE* it's a regular file. */
8619 if (sys_fstat(fd, &sbuf) != 0) {
8620 close(fd);
8621 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
8622 fname, strerror(errno) ));
8623 SAFE_FREE(fname);
8624 return -1;
8627 /* Is it the same dev/inode as was lstated ? */
8628 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
8629 close(fd);
8630 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
8631 "Symlink spoofing going on ?\n", fname ));
8632 SAFE_FREE(fname);
8633 return -1;
8636 /* This must be a regular file, not a symlink, directory or
8637 other strange filetype. */
8638 if (!check_usershare_stat(fname, &sbuf)) {
8639 SAFE_FREE(fname);
8640 return -1;
8643 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE, NULL);
8645 close(fd);
8646 if (lines == NULL) {
8647 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
8648 fname, (unsigned int)sbuf.st_uid ));
8649 SAFE_FREE(fname);
8650 return -1;
8653 SAFE_FREE(fname);
8655 /* Should we allow printers to be shared... ? */
8656 ctx = talloc_init("usershare_sd_xctx");
8657 if (!ctx) {
8658 TALLOC_FREE(lines);
8659 return 1;
8662 if (parse_usershare_file(ctx, &sbuf, service_name,
8663 iService, lines, numlines, &sharepath,
8664 &comment, &psd, &guest_ok) != USERSHARE_OK) {
8665 talloc_destroy(ctx);
8666 TALLOC_FREE(lines);
8667 return -1;
8670 TALLOC_FREE(lines);
8672 /* Everything ok - add the service possibly using a template. */
8673 if (iService < 0) {
8674 const struct service *sp = &sDefault;
8675 if (snum_template != -1) {
8676 sp = ServicePtrs[snum_template];
8679 if ((iService = add_a_service(sp, service_name)) < 0) {
8680 DEBUG(0, ("process_usershare_file: Failed to add "
8681 "new service %s\n", service_name));
8682 talloc_destroy(ctx);
8683 return -1;
8686 /* Read only is controlled by usershare ACL below. */
8687 ServicePtrs[iService]->bRead_only = False;
8690 /* Write the ACL of the new/modified share. */
8691 if (!set_share_security(service_name, psd)) {
8692 DEBUG(0, ("process_usershare_file: Failed to set share "
8693 "security for user share %s\n",
8694 service_name ));
8695 lp_remove_service(iService);
8696 talloc_destroy(ctx);
8697 return -1;
8700 /* If from a template it may be marked invalid. */
8701 ServicePtrs[iService]->valid = True;
8703 /* Set the service as a valid usershare. */
8704 ServicePtrs[iService]->usershare = USERSHARE_VALID;
8706 /* Set guest access. */
8707 if (lp_usershare_allow_guests()) {
8708 ServicePtrs[iService]->bGuest_ok = guest_ok;
8711 /* And note when it was loaded. */
8712 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
8713 string_set(&ServicePtrs[iService]->szPath, sharepath);
8714 string_set(&ServicePtrs[iService]->comment, comment);
8716 talloc_destroy(ctx);
8718 return iService;
8721 /***************************************************************************
8722 Checks if a usershare entry has been modified since last load.
8723 ***************************************************************************/
8725 static bool usershare_exists(int iService, time_t *last_mod)
8727 SMB_STRUCT_STAT lsbuf;
8728 const char *usersharepath = Globals.szUsersharePath;
8729 char *fname;
8731 if (asprintf(&fname, "%s/%s",
8732 usersharepath,
8733 ServicePtrs[iService]->szService) < 0) {
8734 return false;
8737 if (sys_lstat(fname, &lsbuf) != 0) {
8738 SAFE_FREE(fname);
8739 return false;
8742 if (!S_ISREG(lsbuf.st_mode)) {
8743 SAFE_FREE(fname);
8744 return false;
8747 SAFE_FREE(fname);
8748 *last_mod = lsbuf.st_mtime;
8749 return true;
8752 /***************************************************************************
8753 Load a usershare service by name. Returns a valid servicenumber or -1.
8754 ***************************************************************************/
8756 int load_usershare_service(const char *servicename)
8758 SMB_STRUCT_STAT sbuf;
8759 const char *usersharepath = Globals.szUsersharePath;
8760 int max_user_shares = Globals.iUsershareMaxShares;
8761 int snum_template = -1;
8763 if (*usersharepath == 0 || max_user_shares == 0) {
8764 return -1;
8767 if (sys_stat(usersharepath, &sbuf) != 0) {
8768 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
8769 usersharepath, strerror(errno) ));
8770 return -1;
8773 if (!S_ISDIR(sbuf.st_mode)) {
8774 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
8775 usersharepath ));
8776 return -1;
8780 * This directory must be owned by root, and have the 't' bit set.
8781 * It also must not be writable by "other".
8784 #ifdef S_ISVTX
8785 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8786 #else
8787 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8788 #endif
8789 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
8790 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8791 usersharepath ));
8792 return -1;
8795 /* Ensure the template share exists if it's set. */
8796 if (Globals.szUsershareTemplateShare[0]) {
8797 /* We can't use lp_servicenumber here as we are recommending that
8798 template shares have -valid=False set. */
8799 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8800 if (ServicePtrs[snum_template]->szService &&
8801 strequal(ServicePtrs[snum_template]->szService,
8802 Globals.szUsershareTemplateShare)) {
8803 break;
8807 if (snum_template == -1) {
8808 DEBUG(0,("load_usershare_service: usershare template share %s "
8809 "does not exist.\n",
8810 Globals.szUsershareTemplateShare ));
8811 return -1;
8815 return process_usershare_file(usersharepath, servicename, snum_template);
8818 /***************************************************************************
8819 Load all user defined shares from the user share directory.
8820 We only do this if we're enumerating the share list.
8821 This is the function that can delete usershares that have
8822 been removed.
8823 ***************************************************************************/
8825 int load_usershare_shares(void)
8827 SMB_STRUCT_DIR *dp;
8828 SMB_STRUCT_STAT sbuf;
8829 SMB_STRUCT_DIRENT *de;
8830 int num_usershares = 0;
8831 int max_user_shares = Globals.iUsershareMaxShares;
8832 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
8833 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
8834 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
8835 int iService;
8836 int snum_template = -1;
8837 const char *usersharepath = Globals.szUsersharePath;
8838 int ret = lp_numservices();
8840 if (max_user_shares == 0 || *usersharepath == '\0') {
8841 return lp_numservices();
8844 if (sys_stat(usersharepath, &sbuf) != 0) {
8845 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
8846 usersharepath, strerror(errno) ));
8847 return ret;
8851 * This directory must be owned by root, and have the 't' bit set.
8852 * It also must not be writable by "other".
8855 #ifdef S_ISVTX
8856 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
8857 #else
8858 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
8859 #endif
8860 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
8861 "or does not have the sticky bit 't' set or is writable by anyone.\n",
8862 usersharepath ));
8863 return ret;
8866 /* Ensure the template share exists if it's set. */
8867 if (Globals.szUsershareTemplateShare[0]) {
8868 /* We can't use lp_servicenumber here as we are recommending that
8869 template shares have -valid=False set. */
8870 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
8871 if (ServicePtrs[snum_template]->szService &&
8872 strequal(ServicePtrs[snum_template]->szService,
8873 Globals.szUsershareTemplateShare)) {
8874 break;
8878 if (snum_template == -1) {
8879 DEBUG(0,("load_usershare_shares: usershare template share %s "
8880 "does not exist.\n",
8881 Globals.szUsershareTemplateShare ));
8882 return ret;
8886 /* Mark all existing usershares as pending delete. */
8887 for (iService = iNumServices - 1; iService >= 0; iService--) {
8888 if (VALID(iService) && ServicePtrs[iService]->usershare) {
8889 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
8893 dp = sys_opendir(usersharepath);
8894 if (!dp) {
8895 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
8896 usersharepath, strerror(errno) ));
8897 return ret;
8900 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
8901 (de = sys_readdir(dp));
8902 num_dir_entries++ ) {
8903 int r;
8904 const char *n = de->d_name;
8906 /* Ignore . and .. */
8907 if (*n == '.') {
8908 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
8909 continue;
8913 if (n[0] == ':') {
8914 /* Temporary file used when creating a share. */
8915 num_tmp_dir_entries++;
8918 /* Allow 20% tmp entries. */
8919 if (num_tmp_dir_entries > allowed_tmp_entries) {
8920 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
8921 "in directory %s\n",
8922 num_tmp_dir_entries, usersharepath));
8923 break;
8926 r = process_usershare_file(usersharepath, n, snum_template);
8927 if (r == 0) {
8928 /* Update the services count. */
8929 num_usershares++;
8930 if (num_usershares >= max_user_shares) {
8931 DEBUG(0,("load_usershare_shares: max user shares reached "
8932 "on file %s in directory %s\n",
8933 n, usersharepath ));
8934 break;
8936 } else if (r == -1) {
8937 num_bad_dir_entries++;
8940 /* Allow 20% bad entries. */
8941 if (num_bad_dir_entries > allowed_bad_entries) {
8942 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
8943 "in directory %s\n",
8944 num_bad_dir_entries, usersharepath));
8945 break;
8948 /* Allow 20% bad entries. */
8949 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
8950 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
8951 "in directory %s\n",
8952 num_dir_entries, usersharepath));
8953 break;
8957 sys_closedir(dp);
8959 /* Sweep through and delete any non-refreshed usershares that are
8960 not currently in use. */
8961 for (iService = iNumServices - 1; iService >= 0; iService--) {
8962 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
8963 if (conn_snum_used(iService)) {
8964 continue;
8966 /* Remove from the share ACL db. */
8967 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
8968 lp_servicename(iService) ));
8969 delete_share_security(lp_servicename(iService));
8970 free_service_byindex(iService);
8974 return lp_numservices();
8977 /********************************************************
8978 Destroy global resources allocated in this file
8979 ********************************************************/
8981 void gfree_loadparm(void)
8983 int i;
8985 free_file_list();
8987 /* Free resources allocated to services */
8989 for ( i = 0; i < iNumServices; i++ ) {
8990 if ( VALID(i) ) {
8991 free_service_byindex(i);
8995 SAFE_FREE( ServicePtrs );
8996 iNumServices = 0;
8998 /* Now release all resources allocated to global
8999 parameters and the default service */
9001 free_global_parameters();
9005 /***************************************************************************
9006 Allow client apps to specify that they are a client
9007 ***************************************************************************/
9008 void lp_set_in_client(bool b)
9010 in_client = b;
9014 /***************************************************************************
9015 Determine if we're running in a client app
9016 ***************************************************************************/
9017 bool lp_is_in_client(void)
9019 return in_client;
9022 /***************************************************************************
9023 Load the services array from the services file. Return True on success,
9024 False on failure.
9025 ***************************************************************************/
9027 bool lp_load_ex(const char *pszFname,
9028 bool global_only,
9029 bool save_defaults,
9030 bool add_ipc,
9031 bool initialize_globals,
9032 bool allow_include_registry,
9033 bool allow_registry_shares)
9035 char *n2 = NULL;
9036 bool bRetval;
9038 bRetval = False;
9040 DEBUG(3, ("lp_load_ex: refreshing parameters\n"));
9042 bInGlobalSection = True;
9043 bGlobalOnly = global_only;
9044 bAllowIncludeRegistry = allow_include_registry;
9046 init_globals(! initialize_globals);
9047 debug_init();
9049 free_file_list();
9051 if (save_defaults) {
9052 init_locals();
9053 lp_save_defaults();
9056 free_param_opts(&Globals.param_opt);
9058 /* We get sections first, so have to start 'behind' to make up */
9059 iServiceIndex = -1;
9061 if (lp_config_backend_is_file()) {
9062 n2 = alloc_sub_basic(get_current_username(),
9063 current_user_info.domain,
9064 pszFname);
9065 if (!n2) {
9066 smb_panic("lp_load_ex: out of memory");
9069 add_to_file_list(pszFname, n2);
9071 bRetval = pm_process(n2, do_section, do_parameter, NULL);
9072 SAFE_FREE(n2);
9074 /* finish up the last section */
9075 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
9076 if (bRetval) {
9077 if (iServiceIndex >= 0) {
9078 bRetval = service_ok(iServiceIndex);
9082 if (lp_config_backend_is_registry()) {
9083 /* config backend changed to registry in config file */
9085 * We need to use this extra global variable here to
9086 * survive restart: init_globals uses this as a default
9087 * for ConfigBackend. Otherwise, init_globals would
9088 * send us into an endless loop here.
9090 config_backend = CONFIG_BACKEND_REGISTRY;
9091 /* start over */
9092 DEBUG(1, ("lp_load_ex: changing to config backend "
9093 "registry\n"));
9094 init_globals(false);
9095 lp_kill_all_services();
9096 return lp_load_ex(pszFname, global_only, save_defaults,
9097 add_ipc, initialize_globals,
9098 allow_include_registry,
9099 allow_registry_shares);
9101 } else if (lp_config_backend_is_registry()) {
9102 bRetval = process_registry_globals();
9103 } else {
9104 DEBUG(0, ("Illegal config backend given: %d\n",
9105 lp_config_backend()));
9106 bRetval = false;
9109 if (bRetval && lp_registry_shares() && allow_registry_shares) {
9110 bRetval = process_registry_shares();
9113 lp_add_auto_services(lp_auto_services());
9115 if (add_ipc) {
9116 /* When 'restrict anonymous = 2' guest connections to ipc$
9117 are denied */
9118 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
9119 if ( lp_enable_asu_support() ) {
9120 lp_add_ipc("ADMIN$", false);
9124 set_server_role();
9125 set_default_server_announce_type();
9126 set_allowed_client_auth();
9128 bLoaded = True;
9130 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
9131 /* if bWINSsupport is true and we are in the client */
9132 if (lp_is_in_client() && Globals.bWINSsupport) {
9133 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
9136 init_iconv();
9138 bAllowIncludeRegistry = true;
9140 return (bRetval);
9143 bool lp_load(const char *pszFname,
9144 bool global_only,
9145 bool save_defaults,
9146 bool add_ipc,
9147 bool initialize_globals)
9149 return lp_load_ex(pszFname,
9150 global_only,
9151 save_defaults,
9152 add_ipc,
9153 initialize_globals,
9154 true, false);
9157 bool lp_load_initial_only(const char *pszFname)
9159 return lp_load_ex(pszFname,
9160 true,
9161 false,
9162 false,
9163 true,
9164 false,
9165 false);
9168 bool lp_load_with_registry_shares(const char *pszFname,
9169 bool global_only,
9170 bool save_defaults,
9171 bool add_ipc,
9172 bool initialize_globals)
9174 return lp_load_ex(pszFname,
9175 global_only,
9176 save_defaults,
9177 add_ipc,
9178 initialize_globals,
9179 true,
9180 true);
9183 /***************************************************************************
9184 Return the max number of services.
9185 ***************************************************************************/
9187 int lp_numservices(void)
9189 return (iNumServices);
9192 /***************************************************************************
9193 Display the contents of the services array in human-readable form.
9194 ***************************************************************************/
9196 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
9198 int iService;
9200 if (show_defaults)
9201 defaults_saved = False;
9203 dump_globals(f);
9205 dump_a_service(&sDefault, f);
9207 for (iService = 0; iService < maxtoprint; iService++) {
9208 fprintf(f,"\n");
9209 lp_dump_one(f, show_defaults, iService);
9213 /***************************************************************************
9214 Display the contents of one service in human-readable form.
9215 ***************************************************************************/
9217 void lp_dump_one(FILE * f, bool show_defaults, int snum)
9219 if (VALID(snum)) {
9220 if (ServicePtrs[snum]->szService[0] == '\0')
9221 return;
9222 dump_a_service(ServicePtrs[snum], f);
9226 /***************************************************************************
9227 Return the number of the service with the given name, or -1 if it doesn't
9228 exist. Note that this is a DIFFERENT ANIMAL from the internal function
9229 getservicebyname()! This works ONLY if all services have been loaded, and
9230 does not copy the found service.
9231 ***************************************************************************/
9233 int lp_servicenumber(const char *pszServiceName)
9235 int iService;
9236 fstring serviceName;
9238 if (!pszServiceName) {
9239 return GLOBAL_SECTION_SNUM;
9242 for (iService = iNumServices - 1; iService >= 0; iService--) {
9243 if (VALID(iService) && ServicePtrs[iService]->szService) {
9245 * The substitution here is used to support %U is
9246 * service names
9248 fstrcpy(serviceName, ServicePtrs[iService]->szService);
9249 standard_sub_basic(get_current_username(),
9250 current_user_info.domain,
9251 serviceName,sizeof(serviceName));
9252 if (strequal(serviceName, pszServiceName)) {
9253 break;
9258 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
9259 time_t last_mod;
9261 if (!usershare_exists(iService, &last_mod)) {
9262 /* Remove the share security tdb entry for it. */
9263 delete_share_security(lp_servicename(iService));
9264 /* Remove it from the array. */
9265 free_service_byindex(iService);
9266 /* Doesn't exist anymore. */
9267 return GLOBAL_SECTION_SNUM;
9270 /* Has it been modified ? If so delete and reload. */
9271 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
9272 /* Remove it from the array. */
9273 free_service_byindex(iService);
9274 /* and now reload it. */
9275 iService = load_usershare_service(pszServiceName);
9279 if (iService < 0) {
9280 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
9281 return GLOBAL_SECTION_SNUM;
9284 return (iService);
9287 bool share_defined(const char *service_name)
9289 return (lp_servicenumber(service_name) != -1);
9292 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
9293 const char *sharename)
9295 struct share_params *result;
9296 char *sname;
9297 int snum;
9299 if (!(sname = SMB_STRDUP(sharename))) {
9300 return NULL;
9303 snum = find_service(sname);
9304 SAFE_FREE(sname);
9306 if (snum < 0) {
9307 return NULL;
9310 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
9311 DEBUG(0, ("talloc failed\n"));
9312 return NULL;
9315 result->service = snum;
9316 return result;
9319 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
9321 struct share_iterator *result;
9323 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
9324 DEBUG(0, ("talloc failed\n"));
9325 return NULL;
9328 result->next_id = 0;
9329 return result;
9332 struct share_params *next_share(struct share_iterator *list)
9334 struct share_params *result;
9336 while (!lp_snum_ok(list->next_id) &&
9337 (list->next_id < lp_numservices())) {
9338 list->next_id += 1;
9341 if (list->next_id >= lp_numservices()) {
9342 return NULL;
9345 if (!(result = TALLOC_P(list, struct share_params))) {
9346 DEBUG(0, ("talloc failed\n"));
9347 return NULL;
9350 result->service = list->next_id;
9351 list->next_id += 1;
9352 return result;
9355 struct share_params *next_printer(struct share_iterator *list)
9357 struct share_params *result;
9359 while ((result = next_share(list)) != NULL) {
9360 if (lp_print_ok(result->service)) {
9361 break;
9364 return result;
9368 * This is a hack for a transition period until we transformed all code from
9369 * service numbers to struct share_params.
9372 struct share_params *snum2params_static(int snum)
9374 static struct share_params result;
9375 result.service = snum;
9376 return &result;
9379 /*******************************************************************
9380 A useful volume label function.
9381 ********************************************************************/
9383 const char *volume_label(int snum)
9385 char *ret;
9386 const char *label = lp_volume(snum);
9387 if (!*label) {
9388 label = lp_servicename(snum);
9391 /* This returns a 33 byte guarenteed null terminated string. */
9392 ret = talloc_strndup(talloc_tos(), label, 32);
9393 if (!ret) {
9394 return "";
9396 return ret;
9399 /*******************************************************************
9400 Set the server type we will announce as via nmbd.
9401 ********************************************************************/
9403 static void set_default_server_announce_type(void)
9405 default_server_announce = 0;
9406 default_server_announce |= SV_TYPE_WORKSTATION;
9407 default_server_announce |= SV_TYPE_SERVER;
9408 default_server_announce |= SV_TYPE_SERVER_UNIX;
9410 /* note that the flag should be set only if we have a
9411 printer service but nmbd doesn't actually load the
9412 services so we can't tell --jerry */
9414 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
9416 switch (lp_announce_as()) {
9417 case ANNOUNCE_AS_NT_SERVER:
9418 default_server_announce |= SV_TYPE_SERVER_NT;
9419 /* fall through... */
9420 case ANNOUNCE_AS_NT_WORKSTATION:
9421 default_server_announce |= SV_TYPE_NT;
9422 break;
9423 case ANNOUNCE_AS_WIN95:
9424 default_server_announce |= SV_TYPE_WIN95_PLUS;
9425 break;
9426 case ANNOUNCE_AS_WFW:
9427 default_server_announce |= SV_TYPE_WFW;
9428 break;
9429 default:
9430 break;
9433 switch (lp_server_role()) {
9434 case ROLE_DOMAIN_MEMBER:
9435 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
9436 break;
9437 case ROLE_DOMAIN_PDC:
9438 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
9439 break;
9440 case ROLE_DOMAIN_BDC:
9441 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
9442 break;
9443 case ROLE_STANDALONE:
9444 default:
9445 break;
9447 if (lp_time_server())
9448 default_server_announce |= SV_TYPE_TIME_SOURCE;
9450 if (lp_host_msdfs())
9451 default_server_announce |= SV_TYPE_DFS_SERVER;
9454 /***********************************************************
9455 returns role of Samba server
9456 ************************************************************/
9458 int lp_server_role(void)
9460 return server_role;
9463 /***********************************************************
9464 If we are PDC then prefer us as DMB
9465 ************************************************************/
9467 bool lp_domain_master(void)
9469 if (Globals.iDomainMaster == Auto)
9470 return (lp_server_role() == ROLE_DOMAIN_PDC);
9472 return (bool)Globals.iDomainMaster;
9475 /***********************************************************
9476 If we are DMB then prefer us as LMB
9477 ************************************************************/
9479 bool lp_preferred_master(void)
9481 if (Globals.iPreferredMaster == Auto)
9482 return (lp_local_master() && lp_domain_master());
9484 return (bool)Globals.iPreferredMaster;
9487 /*******************************************************************
9488 Remove a service.
9489 ********************************************************************/
9491 void lp_remove_service(int snum)
9493 ServicePtrs[snum]->valid = False;
9494 invalid_services[num_invalid_services++] = snum;
9497 /*******************************************************************
9498 Copy a service.
9499 ********************************************************************/
9501 void lp_copy_service(int snum, const char *new_name)
9503 do_section(new_name, NULL);
9504 if (snum >= 0) {
9505 snum = lp_servicenumber(new_name);
9506 if (snum >= 0)
9507 lp_do_parameter(snum, "copy", lp_servicename(snum));
9512 /*******************************************************************
9513 Get the default server type we will announce as via nmbd.
9514 ********************************************************************/
9516 int lp_default_server_announce(void)
9518 return default_server_announce;
9521 /*******************************************************************
9522 Split the announce version into major and minor numbers.
9523 ********************************************************************/
9525 int lp_major_announce_version(void)
9527 static bool got_major = False;
9528 static int major_version = DEFAULT_MAJOR_VERSION;
9529 char *vers;
9530 char *p;
9532 if (got_major)
9533 return major_version;
9535 got_major = True;
9536 if ((vers = lp_announce_version()) == NULL)
9537 return major_version;
9539 if ((p = strchr_m(vers, '.')) == 0)
9540 return major_version;
9542 *p = '\0';
9543 major_version = atoi(vers);
9544 return major_version;
9547 int lp_minor_announce_version(void)
9549 static bool got_minor = False;
9550 static int minor_version = DEFAULT_MINOR_VERSION;
9551 char *vers;
9552 char *p;
9554 if (got_minor)
9555 return minor_version;
9557 got_minor = True;
9558 if ((vers = lp_announce_version()) == NULL)
9559 return minor_version;
9561 if ((p = strchr_m(vers, '.')) == 0)
9562 return minor_version;
9564 p++;
9565 minor_version = atoi(p);
9566 return minor_version;
9569 /***********************************************************
9570 Set the global name resolution order (used in smbclient).
9571 ************************************************************/
9573 void lp_set_name_resolve_order(const char *new_order)
9575 string_set(&Globals.szNameResolveOrder, new_order);
9578 const char *lp_printername(int snum)
9580 const char *ret = _lp_printername(snum);
9581 if (ret == NULL || (ret != NULL && *ret == '\0'))
9582 ret = lp_const_servicename(snum);
9584 return ret;
9588 /***********************************************************
9589 Allow daemons such as winbindd to fix their logfile name.
9590 ************************************************************/
9592 void lp_set_logfile(const char *name)
9594 string_set(&Globals.szLogFile, name);
9595 debug_set_logfile(name);
9598 /*******************************************************************
9599 Return the max print jobs per queue.
9600 ********************************************************************/
9602 int lp_maxprintjobs(int snum)
9604 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
9605 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
9606 maxjobs = PRINT_MAX_JOBID - 1;
9608 return maxjobs;
9611 const char *lp_printcapname(void)
9613 if ((Globals.szPrintcapname != NULL) &&
9614 (Globals.szPrintcapname[0] != '\0'))
9615 return Globals.szPrintcapname;
9617 if (sDefault.iPrinting == PRINT_CUPS) {
9618 #ifdef HAVE_CUPS
9619 return "cups";
9620 #else
9621 return "lpstat";
9622 #endif
9625 if (sDefault.iPrinting == PRINT_BSD)
9626 return "/etc/printcap";
9628 return PRINTCAP_NAME;
9631 /*******************************************************************
9632 Ensure we don't use sendfile if server smb signing is active.
9633 ********************************************************************/
9635 static uint32 spoolss_state;
9637 bool lp_disable_spoolss( void )
9639 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
9640 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9642 return spoolss_state == SVCCTL_STOPPED ? True : False;
9645 void lp_set_spoolss_state( uint32 state )
9647 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
9649 spoolss_state = state;
9652 uint32 lp_get_spoolss_state( void )
9654 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
9657 /*******************************************************************
9658 Ensure we don't use sendfile if server smb signing is active.
9659 ********************************************************************/
9661 bool lp_use_sendfile(int snum)
9663 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
9664 if (Protocol < PROTOCOL_NT1) {
9665 return False;
9667 return (_lp_use_sendfile(snum) &&
9668 (get_remote_arch() != RA_WIN95) &&
9669 !srv_is_signing_active());
9672 /*******************************************************************
9673 Turn off sendfile if we find the underlying OS doesn't support it.
9674 ********************************************************************/
9676 void set_use_sendfile(int snum, bool val)
9678 if (LP_SNUM_OK(snum))
9679 ServicePtrs[snum]->bUseSendfile = val;
9680 else
9681 sDefault.bUseSendfile = val;
9684 /*******************************************************************
9685 Turn off storing DOS attributes if this share doesn't support it.
9686 ********************************************************************/
9688 void set_store_dos_attributes(int snum, bool val)
9690 if (!LP_SNUM_OK(snum))
9691 return;
9692 ServicePtrs[(snum)]->bStoreDosAttributes = val;
9695 void lp_set_mangling_method(const char *new_method)
9697 string_set(&Globals.szManglingMethod, new_method);
9700 /*******************************************************************
9701 Global state for POSIX pathname processing.
9702 ********************************************************************/
9704 static bool posix_pathnames;
9706 bool lp_posix_pathnames(void)
9708 return posix_pathnames;
9711 /*******************************************************************
9712 Change everything needed to ensure POSIX pathname processing (currently
9713 not much).
9714 ********************************************************************/
9716 void lp_set_posix_pathnames(void)
9718 posix_pathnames = True;
9721 /*******************************************************************
9722 Global state for POSIX lock processing - CIFS unix extensions.
9723 ********************************************************************/
9725 bool posix_default_lock_was_set;
9726 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
9728 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
9730 if (posix_default_lock_was_set) {
9731 return posix_cifsx_locktype;
9732 } else {
9733 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
9737 /*******************************************************************
9738 ********************************************************************/
9740 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
9742 posix_default_lock_was_set = True;
9743 posix_cifsx_locktype = val;
9746 int lp_min_receive_file_size(void)
9748 if (Globals.iminreceivefile < 0) {
9749 return 0;
9751 return MIN(Globals.iminreceivefile, BUFFER_SIZE);
9754 /*******************************************************************
9755 If socket address is an empty character string, it is necessary to
9756 define it as "0.0.0.0".
9757 ********************************************************************/
9759 const char *lp_socket_address(void)
9761 char *sock_addr = Globals.szSocketAddress;
9763 if (sock_addr[0] == '\0'){
9764 string_set(&Globals.szSocketAddress, "0.0.0.0");
9766 return Globals.szSocketAddress;
9769 void lp_set_passdb_backend(const char *backend)
9771 string_set(&Globals.szPassdbBackend, backend);