Merge branch 'v3-2-test' of git://git.samba.org/samba into v3-2-test
[Samba/gebeck_regimport.git] / source3 / param / loadparm.c
blob19af6aa3cf728063db96b1fa2a321f0a76e783ef
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
13 This program is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 3 of the License, or
16 (at your option) any later version.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 * Load parameters.
30 * This module provides suitable callback functions for the params
31 * module. It builds the internal table of service details which is
32 * then used by the rest of the server.
34 * To add a parameter:
36 * 1) add it to the global or service structure definition
37 * 2) add it to the parm_table
38 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
39 * 4) If it's a global then initialise it in init_globals. If a local
40 * (ie. service) parameter then initialise it in the sDefault structure
43 * Notes:
44 * The configuration file is processed sequentially for speed. It is NOT
45 * accessed randomly as happens in 'real' Windows. For this reason, there
46 * is a fair bit of sequence-dependent code here - ie., code which assumes
47 * that certain things happen before others. In particular, the code which
48 * happens at the boundary between sections is delicately poised, so be
49 * careful!
53 #include "includes.h"
55 bool in_client = False; /* Not in the client by default */
56 bool bLoaded = False;
58 extern pstring user_socket_options;
59 extern enum protocol_types Protocol;
60 extern userdom_struct current_user_info;
62 #ifndef GLOBAL_NAME
63 #define GLOBAL_NAME "global"
64 #endif
66 #ifndef PRINTERS_NAME
67 #define PRINTERS_NAME "printers"
68 #endif
70 #ifndef HOMES_NAME
71 #define HOMES_NAME "homes"
72 #endif
74 /* the special value for the include parameter
75 * to be interpreted not as a file name but to
76 * trigger loading of the global smb.conf options
77 * from registry. */
78 #ifndef INCLUDE_REGISTRY_NAME
79 #define INCLUDE_REGISTRY_NAME "registry"
80 #endif
82 static int regdb_last_seqnum = 0;
83 static bool include_registry_globals = False;
85 /* some helpful bits */
86 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
87 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
89 #define USERSHARE_VALID 1
90 #define USERSHARE_PENDING_DELETE 2
92 bool use_getwd_cache = True;
94 extern int extra_time_offset;
96 static bool defaults_saved = False;
98 typedef struct _param_opt_struct param_opt_struct;
99 struct _param_opt_struct {
100 param_opt_struct *prev, *next;
101 char *key;
102 char *value;
103 char **list;
107 * This structure describes global (ie., server-wide) parameters.
109 typedef struct {
110 char *smb_ports;
111 char *dos_charset;
112 char *unix_charset;
113 char *display_charset;
114 char *szPrintcapname;
115 char *szAddPortCommand;
116 char *szEnumPortsCommand;
117 char *szAddPrinterCommand;
118 char *szDeletePrinterCommand;
119 char *szOs2DriverMap;
120 char *szLockDir;
121 char *szPidDir;
122 char *szRootdir;
123 char *szDefaultService;
124 char *szGetQuota;
125 char *szSetQuota;
126 char *szMsgCommand;
127 char *szServerString;
128 char *szAutoServices;
129 char *szPasswdProgram;
130 char *szPasswdChat;
131 char *szLogFile;
132 char *szConfigFile;
133 char *szSMBPasswdFile;
134 char *szPrivateDir;
135 char *szPassdbBackend;
136 char **szPreloadModules;
137 char *szPasswordServer;
138 char *szSocketOptions;
139 char *szRealm;
140 char *szAfsUsernameMap;
141 int iAfsTokenLifetime;
142 char *szLogNtTokenCommand;
143 char *szUsernameMap;
144 char *szLogonScript;
145 char *szLogonPath;
146 char *szLogonDrive;
147 char *szLogonHome;
148 char **szWINSservers;
149 char **szInterfaces;
150 char *szRemoteAnnounce;
151 char *szRemoteBrowseSync;
152 char *szSocketAddress;
153 char *szNISHomeMapName;
154 char *szAnnounceVersion; /* This is initialised in init_globals */
155 char *szWorkgroup;
156 char *szNetbiosName;
157 char **szNetbiosAliases;
158 char *szNetbiosScope;
159 char *szNameResolveOrder;
160 char *szPanicAction;
161 char *szAddUserScript;
162 char *szRenameUserScript;
163 char *szDelUserScript;
164 char *szAddGroupScript;
165 char *szDelGroupScript;
166 char *szAddUserToGroupScript;
167 char *szDelUserFromGroupScript;
168 char *szSetPrimaryGroupScript;
169 char *szAddMachineScript;
170 char *szShutdownScript;
171 char *szAbortShutdownScript;
172 char *szUsernameMapScript;
173 char *szCheckPasswordScript;
174 char *szWINSHook;
175 char *szUtmpDir;
176 char *szWtmpDir;
177 bool bUtmp;
178 char *szIdmapUID;
179 char *szIdmapGID;
180 bool bPassdbExpandExplicit;
181 int AlgorithmicRidBase;
182 char *szTemplateHomedir;
183 char *szTemplateShell;
184 char *szWinbindSeparator;
185 bool bWinbindEnumUsers;
186 bool bWinbindEnumGroups;
187 bool bWinbindUseDefaultDomain;
188 bool bWinbindTrustedDomainsOnly;
189 bool bWinbindNestedGroups;
190 int winbind_expand_groups;
191 bool bWinbindRefreshTickets;
192 bool bWinbindOfflineLogon;
193 bool bWinbindNormalizeNames;
194 bool bWinbindRpcOnly;
195 char **szIdmapDomains;
196 char **szIdmapBackend; /* deprecated */
197 char *szIdmapAllocBackend;
198 char *szAddShareCommand;
199 char *szChangeShareCommand;
200 char *szDeleteShareCommand;
201 char **szEventLogs;
202 char *szGuestaccount;
203 char *szManglingMethod;
204 char **szServicesList;
205 char *szUsersharePath;
206 char *szUsershareTemplateShare;
207 char **szUsersharePrefixAllowList;
208 char **szUsersharePrefixDenyList;
209 int mangle_prefix;
210 int max_log_size;
211 char *szLogLevel;
212 int max_xmit;
213 int max_mux;
214 int max_open_files;
215 int open_files_db_hash_size;
216 int pwordlevel;
217 int unamelevel;
218 int deadtime;
219 int maxprotocol;
220 int minprotocol;
221 int security;
222 char **AuthMethods;
223 bool paranoid_server_security;
224 int maxdisksize;
225 int lpqcachetime;
226 int iMaxSmbdProcesses;
227 bool bDisableSpoolss;
228 int syslog;
229 int os_level;
230 bool enhanced_browsing;
231 int max_ttl;
232 int max_wins_ttl;
233 int min_wins_ttl;
234 int lm_announce;
235 int lm_interval;
236 int announce_as; /* This is initialised in init_globals */
237 int machine_password_timeout;
238 int map_to_guest;
239 int oplock_break_wait_time;
240 int winbind_cache_time;
241 int winbind_max_idle_children;
242 char **szWinbindNssInfo;
243 int iLockSpinTime;
244 char *szLdapMachineSuffix;
245 char *szLdapUserSuffix;
246 char *szLdapIdmapSuffix;
247 char *szLdapGroupSuffix;
248 int ldap_ssl;
249 char *szLdapSuffix;
250 char *szLdapAdminDn;
251 int iAclCompat;
252 char *szCupsServer;
253 char *szIPrintServer;
254 char *ctdbdSocket;
255 char **szClusterAddresses;
256 bool clustering;
257 int ldap_passwd_sync;
258 int ldap_replication_sleep;
259 int ldap_timeout; /* This is initialised in init_globals */
260 int ldap_page_size;
261 bool ldap_delete_dn;
262 bool bMsAddPrinterWizard;
263 bool bDNSproxy;
264 bool bWINSsupport;
265 bool bWINSproxy;
266 bool bLocalMaster;
267 int iPreferredMaster;
268 int iDomainMaster;
269 bool bDomainLogons;
270 bool bEncryptPasswords;
271 bool bUpdateEncrypt;
272 int clientSchannel;
273 int serverSchannel;
274 bool bNullPasswords;
275 bool bObeyPamRestrictions;
276 bool bLoadPrinters;
277 int PrintcapCacheTime;
278 bool bLargeReadwrite;
279 bool bReadRaw;
280 bool bWriteRaw;
281 bool bSyslogOnly;
282 bool bBrowseList;
283 bool bNISHomeMap;
284 bool bTimeServer;
285 bool bBindInterfacesOnly;
286 bool bPamPasswordChange;
287 bool bUnixPasswdSync;
288 bool bPasswdChatDebug;
289 int iPasswdChatTimeout;
290 bool bTimestampLogs;
291 bool bNTSmbSupport;
292 bool bNTPipeSupport;
293 bool bNTStatusSupport;
294 bool bStatCache;
295 int iMaxStatCacheSize;
296 bool bKernelOplocks;
297 bool bAllowTrustedDomains;
298 bool bLanmanAuth;
299 bool bNTLMAuth;
300 bool bUseSpnego;
301 bool bClientLanManAuth;
302 bool bClientNTLMv2Auth;
303 bool bClientPlaintextAuth;
304 bool bClientUseSpnego;
305 bool bDebugPrefixTimestamp;
306 bool bDebugHiresTimestamp;
307 bool bDebugPid;
308 bool bDebugUid;
309 bool bDebugClass;
310 bool bEnableCoreFiles;
311 bool bHostMSDfs;
312 bool bUseMmap;
313 bool bHostnameLookups;
314 bool bUnixExtensions;
315 bool bDisableNetbios;
316 bool bUseKerberosKeytab;
317 bool bDeferSharingViolations;
318 bool bEnablePrivileges;
319 bool bASUSupport;
320 bool bUsershareOwnerOnly;
321 bool bUsershareAllowGuests;
322 bool bRegistryShares;
323 int restrict_anonymous;
324 int name_cache_timeout;
325 int client_signing;
326 int server_signing;
327 int client_ldap_sasl_wrapping;
328 int iUsershareMaxShares;
329 int iIdmapCacheTime;
330 int iIdmapNegativeCacheTime;
332 bool bResetOnZeroVC;
333 int iKeepalive;
334 int iminreceivefile;
335 param_opt_struct *param_opt;
336 } global;
338 static global Globals;
341 * This structure describes a single service.
343 typedef struct {
344 bool valid;
345 bool autoloaded;
346 int usershare;
347 time_t usershare_last_mod;
348 char *szService;
349 char *szPath;
350 char *szUsername;
351 char **szInvalidUsers;
352 char **szValidUsers;
353 char **szAdminUsers;
354 char *szCopy;
355 char *szInclude;
356 char *szPreExec;
357 char *szPostExec;
358 char *szRootPreExec;
359 char *szRootPostExec;
360 char *szCupsOptions;
361 char *szPrintcommand;
362 char *szLpqcommand;
363 char *szLprmcommand;
364 char *szLppausecommand;
365 char *szLpresumecommand;
366 char *szQueuepausecommand;
367 char *szQueueresumecommand;
368 char *szPrintername;
369 char *szPrintjobUsername;
370 char *szDontdescend;
371 char **szHostsallow;
372 char **szHostsdeny;
373 char *szMagicScript;
374 char *szMagicOutput;
375 char *szVetoFiles;
376 char *szHideFiles;
377 char *szVetoOplockFiles;
378 char *comment;
379 char *force_user;
380 char *force_group;
381 char **readlist;
382 char **writelist;
383 char **printer_admin;
384 char *volume;
385 char *fstype;
386 char **szVfsObjects;
387 char *szMSDfsProxy;
388 char *szAioWriteBehind;
389 char *szDfree;
390 int iMinPrintSpace;
391 int iMaxPrintJobs;
392 int iMaxReportedPrintJobs;
393 int iWriteCacheSize;
394 int iCreate_mask;
395 int iCreate_force_mode;
396 int iSecurity_mask;
397 int iSecurity_force_mode;
398 int iDir_mask;
399 int iDir_force_mode;
400 int iDir_Security_mask;
401 int iDir_Security_force_mode;
402 int iMaxConnections;
403 int iDefaultCase;
404 int iPrinting;
405 int iOplockContentionLimit;
406 int iCSCPolicy;
407 int iBlock_size;
408 int iDfreeCacheTime;
409 bool bPreexecClose;
410 bool bRootpreexecClose;
411 int iCaseSensitive;
412 bool bCasePreserve;
413 bool bShortCasePreserve;
414 bool bHideDotFiles;
415 bool bHideSpecialFiles;
416 bool bHideUnReadable;
417 bool bHideUnWriteableFiles;
418 bool bBrowseable;
419 bool bAvailable;
420 bool bRead_only;
421 bool bNo_set_dir;
422 bool bGuest_only;
423 bool bGuest_ok;
424 bool bPrint_ok;
425 bool bMap_system;
426 bool bMap_hidden;
427 bool bMap_archive;
428 bool bStoreDosAttributes;
429 bool bDmapiSupport;
430 bool bLocking;
431 int iStrictLocking;
432 bool bPosixLocking;
433 bool bShareModes;
434 bool bOpLocks;
435 bool bLevel2OpLocks;
436 bool bOnlyUser;
437 bool bMangledNames;
438 bool bWidelinks;
439 bool bSymlinks;
440 bool bSyncAlways;
441 bool bStrictAllocate;
442 bool bStrictSync;
443 char magic_char;
444 struct bitmap *copymap;
445 bool bDeleteReadonly;
446 bool bFakeOplocks;
447 bool bDeleteVetoFiles;
448 bool bDosFilemode;
449 bool bDosFiletimes;
450 bool bDosFiletimeResolution;
451 bool bFakeDirCreateTimes;
452 bool bBlockingLocks;
453 bool bInheritPerms;
454 bool bInheritACLS;
455 bool bInheritOwner;
456 bool bMSDfsRoot;
457 bool bUseClientDriver;
458 bool bDefaultDevmode;
459 bool bForcePrintername;
460 bool bNTAclSupport;
461 bool bForceUnknownAclUser;
462 bool bUseSendfile;
463 bool bProfileAcls;
464 bool bMap_acl_inherit;
465 bool bAfs_Share;
466 bool bEASupport;
467 bool bAclCheckPermissions;
468 bool bAclMapFullControl;
469 bool bAclGroupControl;
470 bool bChangeNotify;
471 bool bKernelChangeNotify;
472 int iallocation_roundup_size;
473 int iAioReadSize;
474 int iAioWriteSize;
475 int iMap_readonly;
476 int iDirectoryNameCacheSize;
477 param_opt_struct *param_opt;
479 char dummy[3]; /* for alignment */
480 } service;
483 /* This is a default service used to prime a services structure */
484 static service sDefault = {
485 True, /* valid */
486 False, /* not autoloaded */
487 0, /* not a usershare */
488 (time_t)0, /* No last mod time */
489 NULL, /* szService */
490 NULL, /* szPath */
491 NULL, /* szUsername */
492 NULL, /* szInvalidUsers */
493 NULL, /* szValidUsers */
494 NULL, /* szAdminUsers */
495 NULL, /* szCopy */
496 NULL, /* szInclude */
497 NULL, /* szPreExec */
498 NULL, /* szPostExec */
499 NULL, /* szRootPreExec */
500 NULL, /* szRootPostExec */
501 NULL, /* szCupsOptions */
502 NULL, /* szPrintcommand */
503 NULL, /* szLpqcommand */
504 NULL, /* szLprmcommand */
505 NULL, /* szLppausecommand */
506 NULL, /* szLpresumecommand */
507 NULL, /* szQueuepausecommand */
508 NULL, /* szQueueresumecommand */
509 NULL, /* szPrintername */
510 NULL, /* szPrintjobUsername */
511 NULL, /* szDontdescend */
512 NULL, /* szHostsallow */
513 NULL, /* szHostsdeny */
514 NULL, /* szMagicScript */
515 NULL, /* szMagicOutput */
516 NULL, /* szVetoFiles */
517 NULL, /* szHideFiles */
518 NULL, /* szVetoOplockFiles */
519 NULL, /* comment */
520 NULL, /* force user */
521 NULL, /* force group */
522 NULL, /* readlist */
523 NULL, /* writelist */
524 NULL, /* printer admin */
525 NULL, /* volume */
526 NULL, /* fstype */
527 NULL, /* vfs objects */
528 NULL, /* szMSDfsProxy */
529 NULL, /* szAioWriteBehind */
530 NULL, /* szDfree */
531 0, /* iMinPrintSpace */
532 1000, /* iMaxPrintJobs */
533 0, /* iMaxReportedPrintJobs */
534 0, /* iWriteCacheSize */
535 0744, /* iCreate_mask */
536 0000, /* iCreate_force_mode */
537 0777, /* iSecurity_mask */
538 0, /* iSecurity_force_mode */
539 0755, /* iDir_mask */
540 0000, /* iDir_force_mode */
541 0777, /* iDir_Security_mask */
542 0, /* iDir_Security_force_mode */
543 0, /* iMaxConnections */
544 CASE_LOWER, /* iDefaultCase */
545 DEFAULT_PRINTING, /* iPrinting */
546 2, /* iOplockContentionLimit */
547 0, /* iCSCPolicy */
548 1024, /* iBlock_size */
549 0, /* iDfreeCacheTime */
550 False, /* bPreexecClose */
551 False, /* bRootpreexecClose */
552 Auto, /* case sensitive */
553 True, /* case preserve */
554 True, /* short case preserve */
555 True, /* bHideDotFiles */
556 False, /* bHideSpecialFiles */
557 False, /* bHideUnReadable */
558 False, /* bHideUnWriteableFiles */
559 True, /* bBrowseable */
560 True, /* bAvailable */
561 True, /* bRead_only */
562 True, /* bNo_set_dir */
563 False, /* bGuest_only */
564 False, /* bGuest_ok */
565 False, /* bPrint_ok */
566 False, /* bMap_system */
567 False, /* bMap_hidden */
568 True, /* bMap_archive */
569 False, /* bStoreDosAttributes */
570 False, /* bDmapiSupport */
571 True, /* bLocking */
572 Auto, /* iStrictLocking */
573 True, /* bPosixLocking */
574 True, /* bShareModes */
575 True, /* bOpLocks */
576 True, /* bLevel2OpLocks */
577 False, /* bOnlyUser */
578 True, /* bMangledNames */
579 True, /* bWidelinks */
580 True, /* bSymlinks */
581 False, /* bSyncAlways */
582 False, /* bStrictAllocate */
583 False, /* bStrictSync */
584 '~', /* magic char */
585 NULL, /* copymap */
586 False, /* bDeleteReadonly */
587 False, /* bFakeOplocks */
588 False, /* bDeleteVetoFiles */
589 False, /* bDosFilemode */
590 True, /* bDosFiletimes */
591 False, /* bDosFiletimeResolution */
592 False, /* bFakeDirCreateTimes */
593 True, /* bBlockingLocks */
594 False, /* bInheritPerms */
595 False, /* bInheritACLS */
596 False, /* bInheritOwner */
597 False, /* bMSDfsRoot */
598 False, /* bUseClientDriver */
599 True, /* bDefaultDevmode */
600 False, /* bForcePrintername */
601 True, /* bNTAclSupport */
602 False, /* bForceUnknownAclUser */
603 False, /* bUseSendfile */
604 False, /* bProfileAcls */
605 False, /* bMap_acl_inherit */
606 False, /* bAfs_Share */
607 False, /* bEASupport */
608 True, /* bAclCheckPermissions */
609 True, /* bAclMapFullControl */
610 False, /* bAclGroupControl */
611 True, /* bChangeNotify */
612 True, /* bKernelChangeNotify */
613 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
614 0, /* iAioReadSize */
615 0, /* iAioWriteSize */
616 MAP_READONLY_YES, /* iMap_readonly */
617 #ifdef BROKEN_DIRECTORY_HANDLING
618 0, /* iDirectoryNameCacheSize */
619 #else
620 100, /* iDirectoryNameCacheSize */
621 #endif
622 NULL, /* Parametric options */
624 "" /* dummy */
627 /* local variables */
628 static service **ServicePtrs = NULL;
629 static int iNumServices = 0;
630 static int iServiceIndex = 0;
631 static TDB_CONTEXT *ServiceHash;
632 static int *invalid_services = NULL;
633 static int num_invalid_services = 0;
634 static bool bInGlobalSection = True;
635 static bool bGlobalOnly = False;
636 static int server_role;
637 static int default_server_announce;
639 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
641 /* prototypes for the special type handlers */
642 static bool handle_include( int snum, const char *pszParmValue, char **ptr);
643 static bool handle_copy( int snum, const char *pszParmValue, char **ptr);
644 static bool handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
645 static bool handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
646 static bool handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
647 static bool handle_debug_list( int snum, const char *pszParmValue, char **ptr );
648 static bool handle_workgroup( int snum, const char *pszParmValue, char **ptr );
649 static bool handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
650 static bool handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
651 static bool handle_charset( int snum, const char *pszParmValue, char **ptr );
652 static bool handle_printing( int snum, const char *pszParmValue, char **ptr);
654 static void set_server_role(void);
655 static void set_default_server_announce_type(void);
656 static void set_allowed_client_auth(void);
658 static const struct enum_list enum_protocol[] = {
659 {PROTOCOL_NT1, "NT1"},
660 {PROTOCOL_LANMAN2, "LANMAN2"},
661 {PROTOCOL_LANMAN1, "LANMAN1"},
662 {PROTOCOL_CORE, "CORE"},
663 {PROTOCOL_COREPLUS, "COREPLUS"},
664 {PROTOCOL_COREPLUS, "CORE+"},
665 {-1, NULL}
668 static const struct enum_list enum_security[] = {
669 {SEC_SHARE, "SHARE"},
670 {SEC_USER, "USER"},
671 {SEC_SERVER, "SERVER"},
672 {SEC_DOMAIN, "DOMAIN"},
673 #ifdef HAVE_ADS
674 {SEC_ADS, "ADS"},
675 #endif
676 {-1, NULL}
679 static const struct enum_list enum_printing[] = {
680 {PRINT_SYSV, "sysv"},
681 {PRINT_AIX, "aix"},
682 {PRINT_HPUX, "hpux"},
683 {PRINT_BSD, "bsd"},
684 {PRINT_QNX, "qnx"},
685 {PRINT_PLP, "plp"},
686 {PRINT_LPRNG, "lprng"},
687 {PRINT_CUPS, "cups"},
688 {PRINT_IPRINT, "iprint"},
689 {PRINT_LPRNT, "nt"},
690 {PRINT_LPROS2, "os2"},
691 #ifdef DEVELOPER
692 {PRINT_TEST, "test"},
693 {PRINT_VLP, "vlp"},
694 #endif /* DEVELOPER */
695 {-1, NULL}
698 static const struct enum_list enum_ldap_sasl_wrapping[] = {
699 {0, "plain"},
700 {ADS_AUTH_SASL_SIGN, "sign"},
701 {ADS_AUTH_SASL_SEAL, "seal"},
702 {-1, NULL}
705 static const struct enum_list enum_ldap_ssl[] = {
706 {LDAP_SSL_OFF, "no"},
707 {LDAP_SSL_OFF, "No"},
708 {LDAP_SSL_OFF, "off"},
709 {LDAP_SSL_OFF, "Off"},
710 {LDAP_SSL_START_TLS, "start tls"},
711 {LDAP_SSL_START_TLS, "Start_tls"},
712 {-1, NULL}
715 static const struct enum_list enum_ldap_passwd_sync[] = {
716 {LDAP_PASSWD_SYNC_OFF, "no"},
717 {LDAP_PASSWD_SYNC_OFF, "No"},
718 {LDAP_PASSWD_SYNC_OFF, "off"},
719 {LDAP_PASSWD_SYNC_OFF, "Off"},
720 {LDAP_PASSWD_SYNC_ON, "Yes"},
721 {LDAP_PASSWD_SYNC_ON, "yes"},
722 {LDAP_PASSWD_SYNC_ON, "on"},
723 {LDAP_PASSWD_SYNC_ON, "On"},
724 {LDAP_PASSWD_SYNC_ONLY, "Only"},
725 {LDAP_PASSWD_SYNC_ONLY, "only"},
726 {-1, NULL}
729 /* Types of machine we can announce as. */
730 #define ANNOUNCE_AS_NT_SERVER 1
731 #define ANNOUNCE_AS_WIN95 2
732 #define ANNOUNCE_AS_WFW 3
733 #define ANNOUNCE_AS_NT_WORKSTATION 4
735 static const struct enum_list enum_announce_as[] = {
736 {ANNOUNCE_AS_NT_SERVER, "NT"},
737 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
738 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
739 {ANNOUNCE_AS_WIN95, "win95"},
740 {ANNOUNCE_AS_WFW, "WfW"},
741 {-1, NULL}
744 static const struct enum_list enum_map_readonly[] = {
745 {MAP_READONLY_NO, "no"},
746 {MAP_READONLY_NO, "false"},
747 {MAP_READONLY_NO, "0"},
748 {MAP_READONLY_YES, "yes"},
749 {MAP_READONLY_YES, "true"},
750 {MAP_READONLY_YES, "1"},
751 {MAP_READONLY_PERMISSIONS, "permissions"},
752 {MAP_READONLY_PERMISSIONS, "perms"},
753 {-1, NULL}
756 static const struct enum_list enum_case[] = {
757 {CASE_LOWER, "lower"},
758 {CASE_UPPER, "upper"},
759 {-1, NULL}
762 static const struct enum_list enum_bool_auto[] = {
763 {False, "No"},
764 {False, "False"},
765 {False, "0"},
766 {True, "Yes"},
767 {True, "True"},
768 {True, "1"},
769 {Auto, "Auto"},
770 {-1, NULL}
773 /* Client-side offline caching policy types */
774 #define CSC_POLICY_MANUAL 0
775 #define CSC_POLICY_DOCUMENTS 1
776 #define CSC_POLICY_PROGRAMS 2
777 #define CSC_POLICY_DISABLE 3
779 static const struct enum_list enum_csc_policy[] = {
780 {CSC_POLICY_MANUAL, "manual"},
781 {CSC_POLICY_DOCUMENTS, "documents"},
782 {CSC_POLICY_PROGRAMS, "programs"},
783 {CSC_POLICY_DISABLE, "disable"},
784 {-1, NULL}
787 /* SMB signing types. */
788 static const struct enum_list enum_smb_signing_vals[] = {
789 {False, "No"},
790 {False, "False"},
791 {False, "0"},
792 {False, "Off"},
793 {False, "disabled"},
794 {True, "Yes"},
795 {True, "True"},
796 {True, "1"},
797 {True, "On"},
798 {True, "enabled"},
799 {Auto, "auto"},
800 {Required, "required"},
801 {Required, "mandatory"},
802 {Required, "force"},
803 {Required, "forced"},
804 {Required, "enforced"},
805 {-1, NULL}
808 /* ACL compatibility options. */
809 static const struct enum_list enum_acl_compat_vals[] = {
810 { ACL_COMPAT_AUTO, "auto" },
811 { ACL_COMPAT_WINNT, "winnt" },
812 { ACL_COMPAT_WIN2K, "win2k" },
813 { -1, NULL}
817 Do you want session setups at user level security with a invalid
818 password to be rejected or allowed in as guest? WinNT rejects them
819 but it can be a pain as it means "net view" needs to use a password
821 You have 3 choices in the setting of map_to_guest:
823 "Never" means session setups with an invalid password
824 are rejected. This is the default.
826 "Bad User" means session setups with an invalid password
827 are rejected, unless the username does not exist, in which case it
828 is treated as a guest login
830 "Bad Password" means session setups with an invalid password
831 are treated as a guest login
833 Note that map_to_guest only has an effect in user or server
834 level security.
837 static const struct enum_list enum_map_to_guest[] = {
838 {NEVER_MAP_TO_GUEST, "Never"},
839 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
840 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
841 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
842 {-1, NULL}
845 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
847 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
848 * screen in SWAT. This is used to exclude parameters as well as to squash all
849 * parameters that have been duplicated by pseudonyms.
851 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
852 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
853 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
854 * respective views.
856 * NOTE2: Handling of duplicated (synonym) paramters:
857 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
858 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
859 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
860 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
863 static struct parm_struct parm_table[] = {
864 {N_("Base Options"), P_SEP, P_SEPARATOR},
866 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
867 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
868 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
869 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
870 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
871 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
872 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
873 #ifdef WITH_ADS
874 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
875 #endif
876 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
877 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
878 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
879 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
880 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
881 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
883 {N_("Security Options"), P_SEP, P_SEPARATOR},
885 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
886 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
887 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
888 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
889 {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
890 {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
891 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
892 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
893 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
894 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
895 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
896 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
897 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
898 {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
899 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
900 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
901 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
902 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
903 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
904 {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
906 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
907 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
908 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
909 {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
910 {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
911 {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
912 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
913 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
914 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
915 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
916 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
917 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
918 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
919 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
920 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
921 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
923 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
924 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
925 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
927 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
928 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
929 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
930 {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
931 {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
932 {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED },
933 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
934 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
935 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
937 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
938 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
939 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
940 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
942 {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
943 {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
944 {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
945 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
946 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
947 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
948 {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
949 {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
950 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
951 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
952 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
953 {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
954 {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
955 {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
956 {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
957 {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
958 {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
959 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
960 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
962 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
963 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
965 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
966 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
967 {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
968 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
969 {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
970 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
971 {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED},
973 {N_("Logging Options"), P_SEP, P_SEPARATOR},
975 {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
976 {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
977 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
978 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
979 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
981 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
982 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
983 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
984 {"debug prefix timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugPrefixTimestamp, NULL, NULL, FLAG_ADVANCED},
985 {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
986 {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
987 {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
988 {"debug class", P_BOOL, P_GLOBAL, &Globals.bDebugClass, NULL, NULL, FLAG_ADVANCED},
989 {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
991 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
993 {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
994 {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED},
995 {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED},
996 {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
997 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
998 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
999 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
1000 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
1001 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
1002 {"min receivefile size", P_INTEGER, P_GLOBAL, &Globals.iminreceivefile, NULL, NULL, FLAG_ADVANCED},
1003 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
1004 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
1005 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
1006 {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED},
1008 {"acl compatibility", P_ENUM, P_GLOBAL, &Globals.iAclCompat, NULL, enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1009 {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1010 {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1011 {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1012 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
1013 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
1014 {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1016 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
1017 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
1018 {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1019 {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1020 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
1021 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
1023 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1024 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
1025 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
1026 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
1027 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
1028 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
1029 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
1030 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1031 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1032 {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
1033 {"client ldap sasl wrapping", P_ENUM, P_GLOBAL, &Globals.client_ldap_sasl_wrapping, NULL, enum_ldap_sasl_wrapping, FLAG_ADVANCED},
1034 {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
1035 {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
1037 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1039 {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1040 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
1041 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
1042 {"keepalive", P_INTEGER, P_GLOBAL, &Globals.iKeepalive, NULL, NULL, FLAG_ADVANCED},
1043 {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1044 {"directory name cache size", P_INTEGER, P_LOCAL, &sDefault.iDirectoryNameCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1045 {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1047 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
1048 {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
1049 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1050 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
1051 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
1052 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
1053 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1055 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
1056 {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1057 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1058 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1059 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
1060 {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1061 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
1062 {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
1064 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
1065 {"ctdbd socket", P_STRING, P_GLOBAL, &Globals.ctdbdSocket, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1066 {"cluster addresses", P_LIST, P_GLOBAL, &Globals.szClusterAddresses, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1067 {"clustering", P_BOOL, P_GLOBAL, &Globals.clustering, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1069 {N_("Printing Options"), P_SEP, P_SEPARATOR},
1071 {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1072 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1073 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1074 {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1075 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1076 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
1077 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1078 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
1079 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1080 {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1081 {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1082 {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1083 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1084 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1085 {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE},
1086 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1087 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1088 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1089 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1090 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1091 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1093 {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED},
1094 {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
1095 {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
1096 {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
1097 {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
1098 {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
1100 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1101 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
1102 {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1103 {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1104 {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1105 {"printjob username", P_STRING, P_LOCAL, &sDefault.szPrintjobUsername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1107 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
1108 {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
1109 {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
1111 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
1112 {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1113 {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},
1114 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1115 {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1116 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1117 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1118 {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1119 {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1120 {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1121 {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1122 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1123 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1124 {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1125 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1126 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1127 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1128 {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1129 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1130 {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
1131 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
1132 {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1133 {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1136 {N_("Domain Options"), P_SEP, P_SEPARATOR},
1138 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1140 {N_("Logon Options"), P_SEP, P_SEPARATOR},
1142 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
1143 {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1144 {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
1145 {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
1146 {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
1147 {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
1148 {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
1149 {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
1150 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
1151 {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
1152 {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
1153 {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED},
1155 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
1156 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
1157 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
1158 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
1159 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
1161 {N_("Browse Options"), P_SEP, P_SEPARATOR},
1163 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1164 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
1165 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
1166 {"preferred master", P_ENUM, P_GLOBAL, &Globals.iPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1167 {"prefered master", P_ENUM, P_GLOBAL, &Globals.iPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1168 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1169 {"domain master", P_ENUM, P_GLOBAL, &Globals.iDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1170 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
1171 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1172 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1173 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
1175 {N_("WINS Options"), P_SEP, P_SEPARATOR},
1177 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
1178 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
1180 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1181 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1182 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
1184 {N_("Locking Options"), P_SEP, P_SEPARATOR},
1186 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1187 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1188 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1189 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1190 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1191 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1193 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1194 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1195 {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1196 {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1197 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1198 {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1199 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1201 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
1203 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
1204 {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
1205 {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
1206 {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
1207 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
1208 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
1209 {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
1210 {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1211 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
1212 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
1213 {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1214 {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1215 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
1217 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
1218 {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
1219 {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
1220 {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
1222 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
1223 {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1225 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1226 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1227 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1228 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
1229 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
1230 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
1231 #ifdef WITH_UTMP
1232 {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
1233 {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
1234 {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
1235 #endif
1237 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1238 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1239 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
1240 {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED},
1241 {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED},
1242 {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
1243 {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
1244 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
1245 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
1246 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
1247 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
1248 {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
1249 {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1250 {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1251 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
1252 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
1253 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1255 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1256 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1257 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1258 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
1260 {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1261 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1262 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1263 {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1264 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1265 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1266 {"registry shares", P_BOOL, P_GLOBAL, &Globals.bRegistryShares, NULL, NULL, FLAG_ADVANCED},
1267 {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
1268 {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1269 {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED},
1270 {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1271 {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED},
1272 {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED},
1273 {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1274 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1275 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1276 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1277 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1278 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1279 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1280 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1281 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1282 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1283 {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1284 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1285 {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1287 {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1288 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
1290 {N_("VFS module options"), P_SEP, P_SEPARATOR},
1292 {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1293 {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
1296 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1297 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1298 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
1300 {N_("Winbind options"), P_SEP, P_SEPARATOR},
1302 {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1303 {"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED},
1304 {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED },
1305 {"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED},
1306 {"idmap cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapCacheTime, NULL, NULL, FLAG_ADVANCED},
1307 {"idmap negative cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeCacheTime, NULL, NULL, FLAG_ADVANCED},
1308 {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED },
1309 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE },
1310 {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED },
1311 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE },
1312 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
1313 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
1314 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
1315 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
1316 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
1317 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
1318 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
1319 {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
1320 {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
1321 {"winbind expand groups", P_INTEGER, P_GLOBAL, &Globals.winbind_expand_groups, NULL, NULL, FLAG_ADVANCED},
1322 {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
1323 {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
1324 {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1325 {"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
1326 {"winbind rpc only", P_BOOL, P_GLOBAL, &Globals.bWinbindRpcOnly, NULL, NULL, FLAG_ADVANCED},
1328 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1331 /***************************************************************************
1332 Initialise the sDefault parameter structure for the printer values.
1333 ***************************************************************************/
1335 static void init_printer_values(service *pService)
1337 /* choose defaults depending on the type of printing */
1338 switch (pService->iPrinting) {
1339 case PRINT_BSD:
1340 case PRINT_AIX:
1341 case PRINT_LPRNT:
1342 case PRINT_LPROS2:
1343 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1344 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1345 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1346 break;
1348 case PRINT_LPRNG:
1349 case PRINT_PLP:
1350 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1351 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1352 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1353 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1354 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1355 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1356 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1357 break;
1359 case PRINT_CUPS:
1360 case PRINT_IPRINT:
1361 #ifdef HAVE_CUPS
1362 /* set the lpq command to contain the destination printer
1363 name only. This is used by cups_queue_get() */
1364 string_set(&pService->szLpqcommand, "%p");
1365 string_set(&pService->szLprmcommand, "");
1366 string_set(&pService->szPrintcommand, "");
1367 string_set(&pService->szLppausecommand, "");
1368 string_set(&pService->szLpresumecommand, "");
1369 string_set(&pService->szQueuepausecommand, "");
1370 string_set(&pService->szQueueresumecommand, "");
1371 #else
1372 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1373 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1374 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1375 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1376 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1377 string_set(&pService->szQueuepausecommand, "disable '%p'");
1378 string_set(&pService->szQueueresumecommand, "enable '%p'");
1379 #endif /* HAVE_CUPS */
1380 break;
1382 case PRINT_SYSV:
1383 case PRINT_HPUX:
1384 string_set(&pService->szLpqcommand, "lpstat -o%p");
1385 string_set(&pService->szLprmcommand, "cancel %p-%j");
1386 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1387 string_set(&pService->szQueuepausecommand, "disable %p");
1388 string_set(&pService->szQueueresumecommand, "enable %p");
1389 #ifndef HPUX
1390 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1391 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1392 #endif /* HPUX */
1393 break;
1395 case PRINT_QNX:
1396 string_set(&pService->szLpqcommand, "lpq -P%p");
1397 string_set(&pService->szLprmcommand, "lprm -P%p %j");
1398 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1399 break;
1401 #ifdef DEVELOPER
1402 case PRINT_TEST:
1403 case PRINT_VLP:
1404 string_set(&pService->szPrintcommand, "vlp print %p %s");
1405 string_set(&pService->szLpqcommand, "vlp lpq %p");
1406 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1407 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1408 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1409 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1410 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1411 break;
1412 #endif /* DEVELOPER */
1417 /***************************************************************************
1418 Initialise the global parameter structure.
1419 ***************************************************************************/
1421 static void init_globals(bool first_time_only)
1423 static bool done_init = False;
1424 pstring s;
1426 /* If requested to initialize only once and we've already done it... */
1427 if (first_time_only && done_init) {
1428 /* ... then we have nothing more to do */
1429 return;
1432 if (!done_init) {
1433 int i;
1435 /* The logfile can be set before this is invoked. Free it if so. */
1436 if (Globals.szLogFile != NULL) {
1437 string_free(&Globals.szLogFile);
1438 Globals.szLogFile = NULL;
1441 memset((void *)&Globals, '\0', sizeof(Globals));
1443 for (i = 0; parm_table[i].label; i++)
1444 if ((parm_table[i].type == P_STRING ||
1445 parm_table[i].type == P_USTRING) &&
1446 parm_table[i].ptr)
1447 string_set((char **)parm_table[i].ptr, "");
1449 string_set(&sDefault.fstype, FSTYPE_STRING);
1450 string_set(&sDefault.szPrintjobUsername, "%U");
1452 init_printer_values(&sDefault);
1454 done_init = True;
1458 DEBUG(3, ("Initialising global parameters\n"));
1460 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1461 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1463 /* use the new 'hash2' method by default, with a prefix of 1 */
1464 string_set(&Globals.szManglingMethod, "hash2");
1465 Globals.mangle_prefix = 1;
1467 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1469 /* using UTF8 by default allows us to support all chars */
1470 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1472 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1473 /* If the system supports nl_langinfo(), try to grab the value
1474 from the user's locale */
1475 string_set(&Globals.display_charset, "LOCALE");
1476 #else
1477 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1478 #endif
1480 /* Use codepage 850 as a default for the dos character set */
1481 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1484 * Allow the default PASSWD_CHAT to be overridden in local.h.
1486 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1488 set_global_myname(myhostname());
1489 string_set(&Globals.szNetbiosName,global_myname());
1491 set_global_myworkgroup(WORKGROUP);
1492 string_set(&Globals.szWorkgroup, lp_workgroup());
1494 string_set(&Globals.szPasswdProgram, "");
1495 string_set(&Globals.szPidDir, dyn_PIDDIR);
1496 string_set(&Globals.szLockDir, dyn_LOCKDIR);
1497 string_set(&Globals.szSocketAddress, "0.0.0.0");
1498 pstrcpy(s, "Samba ");
1499 pstrcat(s, SAMBA_VERSION_STRING);
1500 string_set(&Globals.szServerString, s);
1501 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1502 DEFAULT_MINOR_VERSION);
1503 string_set(&Globals.szAnnounceVersion, s);
1504 #ifdef DEVELOPER
1505 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1506 #endif
1508 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1510 string_set(&Globals.szLogonDrive, "");
1511 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1512 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1513 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1515 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1516 string_set(&Globals.szPasswordServer, "*");
1518 Globals.AlgorithmicRidBase = BASE_RID;
1520 Globals.bLoadPrinters = True;
1521 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
1523 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1524 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1525 Globals.max_xmit = 0x4104;
1526 Globals.max_mux = 50; /* This is *needed* for profile support. */
1527 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
1528 Globals.bDisableSpoolss = False;
1529 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1530 Globals.pwordlevel = 0;
1531 Globals.unamelevel = 0;
1532 Globals.deadtime = 0;
1533 Globals.bLargeReadwrite = True;
1534 Globals.max_log_size = 5000;
1535 Globals.max_open_files = MAX_OPEN_FILES;
1536 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1537 Globals.maxprotocol = PROTOCOL_NT1;
1538 Globals.minprotocol = PROTOCOL_CORE;
1539 Globals.security = SEC_USER;
1540 Globals.paranoid_server_security = True;
1541 Globals.bEncryptPasswords = True;
1542 Globals.bUpdateEncrypt = False;
1543 Globals.clientSchannel = Auto;
1544 Globals.serverSchannel = Auto;
1545 Globals.bReadRaw = True;
1546 Globals.bWriteRaw = True;
1547 Globals.bNullPasswords = False;
1548 Globals.bObeyPamRestrictions = False;
1549 Globals.syslog = 1;
1550 Globals.bSyslogOnly = False;
1551 Globals.bTimestampLogs = True;
1552 string_set(&Globals.szLogLevel, "0");
1553 Globals.bDebugPrefixTimestamp = False;
1554 Globals.bDebugHiresTimestamp = False;
1555 Globals.bDebugPid = False;
1556 Globals.bDebugUid = False;
1557 Globals.bDebugClass = False;
1558 Globals.bEnableCoreFiles = True;
1559 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1560 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1561 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1562 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1563 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1564 Globals.lm_interval = 60;
1565 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1566 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1567 Globals.bNISHomeMap = False;
1568 #ifdef WITH_NISPLUS_HOME
1569 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1570 #else
1571 string_set(&Globals.szNISHomeMapName, "auto.home");
1572 #endif
1573 #endif
1574 Globals.bTimeServer = False;
1575 Globals.bBindInterfacesOnly = False;
1576 Globals.bUnixPasswdSync = False;
1577 Globals.bPamPasswordChange = False;
1578 Globals.bPasswdChatDebug = False;
1579 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1580 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
1581 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1582 Globals.bStatCache = True; /* use stat cache by default */
1583 Globals.iMaxStatCacheSize = 1024; /* one Meg by default. */
1584 Globals.restrict_anonymous = 0;
1585 Globals.bClientLanManAuth = False; /* Do NOT use the LanMan hash if it is available */
1586 Globals.bClientPlaintextAuth = False; /* Do NOT use a plaintext password even if is requested by the server */
1587 Globals.bLanmanAuth = False; /* Do NOT use the LanMan hash, even if it is supplied */
1588 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is supplied by the client (otherwise NTLMv2) */
1589 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1590 /* Note, that we will use NTLM2 session security (which is different), if it is available */
1592 Globals.map_to_guest = 0; /* By Default, "Never" */
1593 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
1594 Globals.enhanced_browsing = true;
1595 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
1596 #ifdef MMAP_BLACKLIST
1597 Globals.bUseMmap = False;
1598 #else
1599 Globals.bUseMmap = True;
1600 #endif
1601 Globals.bUnixExtensions = True;
1602 Globals.bResetOnZeroVC = False;
1604 /* hostname lookups can be very expensive and are broken on
1605 a large number of sites (tridge) */
1606 Globals.bHostnameLookups = False;
1608 string_set(&Globals.szPassdbBackend, "smbpasswd");
1609 string_set(&Globals.szLdapSuffix, "");
1610 string_set(&Globals.szLdapMachineSuffix, "");
1611 string_set(&Globals.szLdapUserSuffix, "");
1612 string_set(&Globals.szLdapGroupSuffix, "");
1613 string_set(&Globals.szLdapIdmapSuffix, "");
1615 string_set(&Globals.szLdapAdminDn, "");
1616 Globals.ldap_ssl = LDAP_SSL_ON;
1617 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1618 Globals.ldap_delete_dn = False;
1619 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1620 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1621 Globals.ldap_page_size = LDAP_PAGE_SIZE;
1623 /* This is what we tell the afs client. in reality we set the token
1624 * to never expire, though, when this runs out the afs client will
1625 * forget the token. Set to 0 to get NEVERDATE.*/
1626 Globals.iAfsTokenLifetime = 604800;
1628 /* these parameters are set to defaults that are more appropriate
1629 for the increasing samba install base:
1631 as a member of the workgroup, that will possibly become a
1632 _local_ master browser (lm = True). this is opposed to a forced
1633 local master browser startup (pm = True).
1635 doesn't provide WINS server service by default (wsupp = False),
1636 and doesn't provide domain master browser services by default, either.
1640 Globals.bMsAddPrinterWizard = True;
1641 Globals.os_level = 20;
1642 Globals.bLocalMaster = True;
1643 Globals.iDomainMaster = Auto; /* depending on bDomainLogons */
1644 Globals.bDomainLogons = False;
1645 Globals.bBrowseList = True;
1646 Globals.bWINSsupport = False;
1647 Globals.bWINSproxy = False;
1649 Globals.bDNSproxy = True;
1651 /* this just means to use them if they exist */
1652 Globals.bKernelOplocks = True;
1654 Globals.bAllowTrustedDomains = True;
1656 string_set(&Globals.szTemplateShell, "/bin/false");
1657 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1658 string_set(&Globals.szWinbindSeparator, "\\");
1660 string_set(&Globals.szCupsServer, "");
1661 string_set(&Globals.szIPrintServer, "");
1663 string_set(&Globals.ctdbdSocket, "");
1664 Globals.szClusterAddresses = NULL;
1665 Globals.clustering = False;
1667 Globals.winbind_cache_time = 300; /* 5 minutes */
1668 Globals.bWinbindEnumUsers = False;
1669 Globals.bWinbindEnumGroups = False;
1670 Globals.bWinbindUseDefaultDomain = False;
1671 Globals.bWinbindTrustedDomainsOnly = False;
1672 Globals.bWinbindNestedGroups = True;
1673 Globals.winbind_expand_groups = 1;
1674 Globals.szWinbindNssInfo = str_list_make("template", NULL);
1675 Globals.bWinbindRefreshTickets = False;
1676 Globals.bWinbindOfflineLogon = False;
1678 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
1679 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
1681 Globals.bPassdbExpandExplicit = False;
1683 Globals.name_cache_timeout = 660; /* In seconds */
1685 Globals.bUseSpnego = True;
1686 Globals.bClientUseSpnego = True;
1688 Globals.client_signing = Auto;
1689 Globals.server_signing = False;
1691 Globals.bDeferSharingViolations = True;
1692 string_set(&Globals.smb_ports, SMB_PORTS);
1694 Globals.bEnablePrivileges = True;
1695 Globals.bHostMSDfs = True;
1696 Globals.bASUSupport = False;
1698 /* User defined shares. */
1699 pstrcpy(s, dyn_STATEDIR());
1700 pstrcat(s, "/usershares");
1701 string_set(&Globals.szUsersharePath, s);
1702 string_set(&Globals.szUsershareTemplateShare, "");
1703 Globals.iUsershareMaxShares = 0;
1704 /* By default disallow sharing of directories not owned by the sharer. */
1705 Globals.bUsershareOwnerOnly = True;
1706 /* By default disallow guest access to usershares. */
1707 Globals.bUsershareAllowGuests = False;
1709 Globals.iKeepalive = DEFAULT_KEEPALIVE;
1711 /* By default no shares out of the registry */
1712 Globals.bRegistryShares = False;
1714 Globals.iminreceivefile = 0;
1717 /*******************************************************************
1718 Convenience routine to grab string parameters into temporary memory
1719 and run standard_sub_basic on them. The buffers can be written to by
1720 callers without affecting the source string.
1721 ********************************************************************/
1723 static char *lp_string(const char *s)
1725 char *ret, *tmpstr;
1727 /* The follow debug is useful for tracking down memory problems
1728 especially if you have an inner loop that is calling a lp_*()
1729 function that returns a string. Perhaps this debug should be
1730 present all the time? */
1732 #if 0
1733 DEBUG(10, ("lp_string(%s)\n", s));
1734 #endif
1736 tmpstr = alloc_sub_basic(get_current_username(),
1737 current_user_info.domain, s);
1738 if (trim_char(tmpstr, '\"', '\"')) {
1739 if (strchr(tmpstr,'\"') != NULL) {
1740 SAFE_FREE(tmpstr);
1741 tmpstr = alloc_sub_basic(get_current_username(),
1742 current_user_info.domain, s);
1745 ret = talloc_strdup(talloc_tos(), tmpstr);
1746 SAFE_FREE(tmpstr);
1748 return (ret);
1752 In this section all the functions that are used to access the
1753 parameters from the rest of the program are defined
1756 #define FN_GLOBAL_STRING(fn_name,ptr) \
1757 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1758 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1759 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1760 #define FN_GLOBAL_LIST(fn_name,ptr) \
1761 const char **fn_name(void) {return(*(const char ***)(ptr));}
1762 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1763 bool fn_name(void) {return(*(bool *)(ptr));}
1764 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1765 char fn_name(void) {return(*(char *)(ptr));}
1766 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1767 int fn_name(void) {return(*(int *)(ptr));}
1769 #define FN_LOCAL_STRING(fn_name,val) \
1770 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1771 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1772 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1773 #define FN_LOCAL_LIST(fn_name,val) \
1774 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1775 #define FN_LOCAL_BOOL(fn_name,val) \
1776 bool fn_name(int i) {return(bool)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1777 #define FN_LOCAL_INTEGER(fn_name,val) \
1778 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1780 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1781 bool fn_name(const struct share_params *p) {return(bool)(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1782 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1783 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1784 #define FN_LOCAL_PARM_STRING(fn_name,val) \
1785 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));}
1786 #define FN_LOCAL_CHAR(fn_name,val) \
1787 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1789 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1790 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1791 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1792 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1793 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1794 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1795 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1796 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1797 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1798 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1799 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1800 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1801 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1802 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1803 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1804 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1805 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1806 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1807 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1808 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1809 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1810 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1811 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1812 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1813 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1814 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1815 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1816 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1817 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1818 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1819 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1820 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1821 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1822 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1823 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1824 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1825 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1826 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1827 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1828 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1829 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1830 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1831 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1832 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1833 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1834 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1835 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1836 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1837 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1838 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1839 * lp_passdb_backend() should be replace by the this macro again after
1840 * some releases.
1841 * */
1842 const char *lp_passdb_backend(void)
1844 char *delim, *quote;
1846 delim = strchr( Globals.szPassdbBackend, ' ');
1847 /* no space at all */
1848 if (delim == NULL) {
1849 goto out;
1852 quote = strchr(Globals.szPassdbBackend, '"');
1853 /* no quote char or non in the first part */
1854 if (quote == NULL || quote > delim) {
1855 *delim = '\0';
1856 goto warn;
1859 quote = strchr(quote+1, '"');
1860 if (quote == NULL) {
1861 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
1862 goto out;
1863 } else if (*(quote+1) == '\0') {
1864 /* space, fitting quote char, and one backend only */
1865 goto out;
1866 } else {
1867 /* terminate string after the fitting quote char */
1868 *(quote+1) = '\0';
1871 warn:
1872 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
1873 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
1874 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
1875 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
1877 out:
1878 return Globals.szPassdbBackend;
1880 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1881 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1882 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1883 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1884 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1886 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1887 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1888 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1889 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1890 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1891 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1893 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1895 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1896 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1897 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1899 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1901 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1902 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1903 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1904 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1905 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1906 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1907 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1908 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1909 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1910 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1911 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
1912 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1913 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1914 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
1915 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
1917 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
1918 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
1919 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
1920 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
1921 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
1922 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
1923 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1925 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1926 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1927 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1928 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1929 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1930 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1931 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1932 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1933 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1934 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1935 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1936 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1937 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1938 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1940 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1942 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
1943 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1944 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1945 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1946 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1947 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1948 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1949 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1950 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1951 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1952 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1953 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1954 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1955 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1956 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1957 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1958 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1959 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1960 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1961 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1962 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1963 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1964 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1965 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1966 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
1967 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1968 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1969 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1970 FN_GLOBAL_BOOL(lp_debug_class, &Globals.bDebugClass)
1971 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1972 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1973 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1974 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1975 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1976 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1977 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1978 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1979 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1980 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1981 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1982 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1983 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1984 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1985 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1986 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1987 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1988 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1989 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1990 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1991 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1992 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1993 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1994 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1995 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1996 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1997 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1998 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1999 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
2000 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
2001 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
2002 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
2003 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
2004 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
2005 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
2006 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
2007 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
2008 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
2009 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
2010 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
2011 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
2012 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
2013 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
2014 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
2015 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
2016 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
2017 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
2018 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
2019 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
2020 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
2021 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
2022 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
2023 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
2024 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
2025 FN_GLOBAL_BOOL(_lp_disable_spoolss, &Globals.bDisableSpoolss)
2026 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
2027 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
2028 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
2029 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
2030 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
2031 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
2032 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
2033 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
2034 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
2036 FN_LOCAL_STRING(lp_preexec, szPreExec)
2037 FN_LOCAL_STRING(lp_postexec, szPostExec)
2038 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
2039 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
2040 FN_LOCAL_STRING(lp_servicename, szService)
2041 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
2042 FN_LOCAL_STRING(lp_pathname, szPath)
2043 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
2044 FN_LOCAL_STRING(lp_username, szUsername)
2045 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
2046 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
2047 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
2048 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
2049 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
2050 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
2051 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
2052 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
2053 FN_GLOBAL_LIST(lp_cluster_addresses, &Globals.szClusterAddresses)
2054 FN_GLOBAL_BOOL(lp_clustering, &Globals.clustering);
2055 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
2056 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
2057 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
2058 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
2059 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
2060 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
2061 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
2062 static FN_LOCAL_STRING(_lp_printername, szPrintername)
2063 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
2064 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
2065 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
2066 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
2067 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
2068 FN_LOCAL_STRING(lp_comment, comment)
2069 FN_LOCAL_STRING(lp_force_user, force_user)
2070 FN_LOCAL_STRING(lp_force_group, force_group)
2071 FN_LOCAL_LIST(lp_readlist, readlist)
2072 FN_LOCAL_LIST(lp_writelist, writelist)
2073 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
2074 FN_LOCAL_STRING(lp_fstype, fstype)
2075 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
2076 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
2077 static FN_LOCAL_STRING(lp_volume, volume)
2078 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2079 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2080 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2081 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
2082 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
2083 FN_LOCAL_STRING(lp_dfree_command, szDfree)
2084 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
2085 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
2086 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
2087 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
2088 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
2089 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
2090 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
2091 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2092 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2093 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2094 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2095 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2096 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2097 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2098 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2099 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2100 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2101 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2102 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2103 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2104 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
2105 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
2106 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
2107 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2108 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2109 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2110 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2111 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
2112 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2113 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2114 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2115 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2116 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2117 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2118 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2119 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2120 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2121 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2122 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2123 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2124 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2125 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2126 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2127 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2128 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2129 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2130 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2131 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2132 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2133 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2134 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2135 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2136 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2137 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2138 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2139 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2140 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2141 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2142 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2143 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2144 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2145 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2146 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2147 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2148 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2149 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2150 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2151 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2152 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2153 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2154 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2155 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2156 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2157 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2158 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2159 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2160 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2161 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2162 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2163 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2164 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
2165 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2166 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2167 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2168 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2169 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2170 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2171 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2172 FN_GLOBAL_INTEGER(lp_min_receive_file_size, &Globals.iminreceivefile);
2173 FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrapping)
2175 /* local prototypes */
2177 static int map_parameter(const char *pszParmName);
2178 static int map_parameter_canonical(const char *pszParmName, bool *inverse);
2179 static bool set_boolean(bool *pb, const char *pszParmValue);
2180 static const char *get_boolean(bool bool_value);
2181 static int getservicebyname(const char *pszServiceName,
2182 service * pserviceDest);
2183 static void copy_service(service * pserviceDest,
2184 service * pserviceSource,
2185 struct bitmap *pcopymapDest);
2186 static bool do_parameter(const char *pszParmName, const char *pszParmValue);
2187 static bool do_section(const char *pszSectionName);
2188 static void init_copymap(service * pservice);
2189 static bool hash_a_service(const char *name, int number);
2190 static void free_service_byindex(int iService);
2191 static char * canonicalize_servicename(const char *name);
2192 static void show_parameter(int parmIndex);
2193 static bool is_synonym_of(int parm1, int parm2, bool *inverse);
2195 /* This is a helper function for parametrical options support. */
2196 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2197 /* Actual parametrical functions are quite simple */
2198 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2200 bool global_section = False;
2201 char* param_key;
2202 param_opt_struct *data;
2204 if (snum >= iNumServices) return NULL;
2206 if (snum < 0) {
2207 data = Globals.param_opt;
2208 global_section = True;
2209 } else {
2210 data = ServicePtrs[snum]->param_opt;
2213 asprintf(&param_key, "%s:%s", type, option);
2214 if (!param_key) {
2215 DEBUG(0,("asprintf failed!\n"));
2216 return NULL;
2219 while (data) {
2220 if (strcmp(data->key, param_key) == 0) {
2221 string_free(&param_key);
2222 return data;
2224 data = data->next;
2227 if (!global_section) {
2228 /* Try to fetch the same option but from globals */
2229 /* but only if we are not already working with Globals */
2230 data = Globals.param_opt;
2231 while (data) {
2232 if (strcmp(data->key, param_key) == 0) {
2233 string_free(&param_key);
2234 return data;
2236 data = data->next;
2240 string_free(&param_key);
2242 return NULL;
2246 #define MISSING_PARAMETER(name) \
2247 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2249 /*******************************************************************
2250 convenience routine to return int parameters.
2251 ********************************************************************/
2252 static int lp_int(const char *s)
2255 if (!s || !*s) {
2256 MISSING_PARAMETER(lp_int);
2257 return (-1);
2260 return (int)strtol(s, NULL, 0);
2263 /*******************************************************************
2264 convenience routine to return unsigned long parameters.
2265 ********************************************************************/
2266 static unsigned long lp_ulong(const char *s)
2269 if (!s || !*s) {
2270 MISSING_PARAMETER(lp_ulong);
2271 return (0);
2274 return strtoul(s, NULL, 0);
2277 /*******************************************************************
2278 convenience routine to return boolean parameters.
2279 ********************************************************************/
2280 static bool lp_bool(const char *s)
2282 bool ret = False;
2284 if (!s || !*s) {
2285 MISSING_PARAMETER(lp_bool);
2286 return False;
2289 if (!set_boolean(&ret,s)) {
2290 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2291 return False;
2294 return ret;
2297 /*******************************************************************
2298 convenience routine to return enum parameters.
2299 ********************************************************************/
2300 static int lp_enum(const char *s,const struct enum_list *_enum)
2302 int i;
2304 if (!s || !*s || !_enum) {
2305 MISSING_PARAMETER(lp_enum);
2306 return (-1);
2309 for (i=0; _enum[i].name; i++) {
2310 if (strequal(_enum[i].name,s))
2311 return _enum[i].value;
2314 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2315 return (-1);
2318 #undef MISSING_PARAMETER
2320 /* DO NOT USE lp_parm_string ANYMORE!!!!
2321 * use lp_parm_const_string or lp_parm_talloc_string
2323 * lp_parm_string is only used to let old modules find this symbol
2325 #undef lp_parm_string
2326 char *lp_parm_string(const char *servicename, const char *type, const char *option);
2327 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2329 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2332 /* Return parametric option from a given service. Type is a part of option before ':' */
2333 /* Parametric option has following syntax: 'Type: option = value' */
2334 /* the returned value is talloced on the talloc_tos() */
2335 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2337 param_opt_struct *data = get_parametrics(snum, type, option);
2339 if (data == NULL||data->value==NULL) {
2340 if (def) {
2341 return lp_string(def);
2342 } else {
2343 return NULL;
2347 return lp_string(data->value);
2350 /* Return parametric option from a given service. Type is a part of option before ':' */
2351 /* Parametric option has following syntax: 'Type: option = value' */
2352 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2354 param_opt_struct *data = get_parametrics(snum, type, option);
2356 if (data == NULL||data->value==NULL)
2357 return def;
2359 return data->value;
2362 /* Return parametric option from a given service. Type is a part of option before ':' */
2363 /* Parametric option has following syntax: 'Type: option = value' */
2365 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2367 param_opt_struct *data = get_parametrics(snum, type, option);
2369 if (data == NULL||data->value==NULL)
2370 return (const char **)def;
2372 if (data->list==NULL) {
2373 data->list = str_list_make(data->value, NULL);
2376 return (const char **)data->list;
2379 /* Return parametric option from a given service. Type is a part of option before ':' */
2380 /* Parametric option has following syntax: 'Type: option = value' */
2382 int lp_parm_int(int snum, const char *type, const char *option, int def)
2384 param_opt_struct *data = get_parametrics(snum, type, option);
2386 if (data && data->value && *data->value)
2387 return lp_int(data->value);
2389 return def;
2392 /* Return parametric option from a given service. Type is a part of option before ':' */
2393 /* Parametric option has following syntax: 'Type: option = value' */
2395 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2397 param_opt_struct *data = get_parametrics(snum, type, option);
2399 if (data && data->value && *data->value)
2400 return lp_ulong(data->value);
2402 return def;
2405 /* Return parametric option from a given service. Type is a part of option before ':' */
2406 /* Parametric option has following syntax: 'Type: option = value' */
2408 bool lp_parm_bool(int snum, const char *type, const char *option, bool def)
2410 param_opt_struct *data = get_parametrics(snum, type, option);
2412 if (data && data->value && *data->value)
2413 return lp_bool(data->value);
2415 return def;
2418 /* Return parametric option from a given service. Type is a part of option before ':' */
2419 /* Parametric option has following syntax: 'Type: option = value' */
2421 int lp_parm_enum(int snum, const char *type, const char *option,
2422 const struct enum_list *_enum, int def)
2424 param_opt_struct *data = get_parametrics(snum, type, option);
2426 if (data && data->value && *data->value && _enum)
2427 return lp_enum(data->value, _enum);
2429 return def;
2433 /***************************************************************************
2434 Initialise a service to the defaults.
2435 ***************************************************************************/
2437 static void init_service(service * pservice)
2439 memset((char *)pservice, '\0', sizeof(service));
2440 copy_service(pservice, &sDefault, NULL);
2443 /***************************************************************************
2444 Free the dynamically allocated parts of a service struct.
2445 ***************************************************************************/
2447 static void free_service(service *pservice)
2449 int i;
2450 param_opt_struct *data, *pdata;
2451 if (!pservice)
2452 return;
2454 if (pservice->szService)
2455 DEBUG(5, ("free_service: Freeing service %s\n",
2456 pservice->szService));
2458 string_free(&pservice->szService);
2459 bitmap_free(pservice->copymap);
2461 for (i = 0; parm_table[i].label; i++) {
2462 if ((parm_table[i].type == P_STRING ||
2463 parm_table[i].type == P_USTRING) &&
2464 parm_table[i].p_class == P_LOCAL)
2465 string_free((char **)
2466 (((char *)pservice) +
2467 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2468 else if (parm_table[i].type == P_LIST &&
2469 parm_table[i].p_class == P_LOCAL)
2470 str_list_free((char ***)
2471 (((char *)pservice) +
2472 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2475 data = pservice->param_opt;
2476 if (data)
2477 DEBUG(5,("Freeing parametrics:\n"));
2478 while (data) {
2479 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2480 string_free(&data->key);
2481 string_free(&data->value);
2482 str_list_free(&data->list);
2483 pdata = data->next;
2484 SAFE_FREE(data);
2485 data = pdata;
2488 ZERO_STRUCTP(pservice);
2492 /***************************************************************************
2493 remove a service indexed in the ServicePtrs array from the ServiceHash
2494 and free the dynamically allocated parts
2495 ***************************************************************************/
2497 static void free_service_byindex(int idx)
2499 if ( !LP_SNUM_OK(idx) )
2500 return;
2502 ServicePtrs[idx]->valid = False;
2503 invalid_services[num_invalid_services++] = idx;
2505 /* we have to cleanup the hash record */
2507 if (ServicePtrs[idx]->szService) {
2508 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2510 tdb_delete_bystring(ServiceHash, canon_name );
2513 free_service(ServicePtrs[idx]);
2516 /***************************************************************************
2517 Add a new service to the services array initialising it with the given
2518 service.
2519 ***************************************************************************/
2521 static int add_a_service(const service *pservice, const char *name)
2523 int i;
2524 service tservice;
2525 int num_to_alloc = iNumServices + 1;
2526 param_opt_struct *data, *pdata;
2528 tservice = *pservice;
2530 /* it might already exist */
2531 if (name) {
2532 i = getservicebyname(name, NULL);
2533 if (i >= 0) {
2534 /* Clean all parametric options for service */
2535 /* They will be added during parsing again */
2536 data = ServicePtrs[i]->param_opt;
2537 while (data) {
2538 string_free(&data->key);
2539 string_free(&data->value);
2540 str_list_free(&data->list);
2541 pdata = data->next;
2542 SAFE_FREE(data);
2543 data = pdata;
2545 ServicePtrs[i]->param_opt = NULL;
2546 return (i);
2550 /* find an invalid one */
2551 i = iNumServices;
2552 if (num_invalid_services > 0) {
2553 i = invalid_services[--num_invalid_services];
2556 /* if not, then create one */
2557 if (i == iNumServices) {
2558 service **tsp;
2559 int *tinvalid;
2561 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2562 if (tsp == NULL) {
2563 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2564 return (-1);
2566 ServicePtrs = tsp;
2567 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2568 if (!ServicePtrs[iNumServices]) {
2569 DEBUG(0,("add_a_service: out of memory!\n"));
2570 return (-1);
2572 iNumServices++;
2574 /* enlarge invalid_services here for now... */
2575 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2576 num_to_alloc);
2577 if (tinvalid == NULL) {
2578 DEBUG(0,("add_a_service: failed to enlarge "
2579 "invalid_services!\n"));
2580 return (-1);
2582 invalid_services = tinvalid;
2583 } else {
2584 free_service_byindex(i);
2587 ServicePtrs[i]->valid = True;
2589 init_service(ServicePtrs[i]);
2590 copy_service(ServicePtrs[i], &tservice, NULL);
2591 if (name)
2592 string_set(&ServicePtrs[i]->szService, name);
2594 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2595 i, ServicePtrs[i]->szService));
2597 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2598 return (-1);
2601 return (i);
2604 /***************************************************************************
2605 Convert a string to uppercase and remove whitespaces.
2606 ***************************************************************************/
2608 static char *canonicalize_servicename(const char *src)
2610 static fstring canon; /* is fstring large enough? */
2612 if ( !src ) {
2613 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2614 return NULL;
2617 fstrcpy( canon, src );
2618 strlower_m( canon );
2620 return canon;
2623 /***************************************************************************
2624 Add a name/index pair for the services array to the hash table.
2625 ***************************************************************************/
2627 static bool hash_a_service(const char *name, int idx)
2629 char *canon_name;
2631 if ( !ServiceHash ) {
2632 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2633 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2634 (O_RDWR|O_CREAT), 0600);
2635 if ( !ServiceHash ) {
2636 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2637 return False;
2641 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2642 idx, name));
2644 if ( !(canon_name = canonicalize_servicename( name )) )
2645 return False;
2647 tdb_store_int32(ServiceHash, canon_name, idx);
2649 return True;
2652 /***************************************************************************
2653 Add a new home service, with the specified home directory, defaults coming
2654 from service ifrom.
2655 ***************************************************************************/
2657 bool lp_add_home(const char *pszHomename, int iDefaultService,
2658 const char *user, const char *pszHomedir)
2660 int i;
2661 pstring newHomedir;
2663 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2665 if (i < 0)
2666 return (False);
2668 if (!(*(ServicePtrs[iDefaultService]->szPath))
2669 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2670 pstrcpy(newHomedir, pszHomedir);
2671 string_set(&ServicePtrs[i]->szPath, newHomedir);
2674 if (!(*(ServicePtrs[i]->comment))) {
2675 pstring comment;
2676 slprintf(comment, sizeof(comment) - 1,
2677 "Home directory of %s", user);
2678 string_set(&ServicePtrs[i]->comment, comment);
2681 /* set the browseable flag from the global default */
2683 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2685 ServicePtrs[i]->autoloaded = True;
2687 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2688 user, ServicePtrs[i]->szPath ));
2690 return (True);
2693 /***************************************************************************
2694 Add a new service, based on an old one.
2695 ***************************************************************************/
2697 int lp_add_service(const char *pszService, int iDefaultService)
2699 if (iDefaultService < 0) {
2700 return add_a_service(&sDefault, pszService);
2703 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2706 /***************************************************************************
2707 Add the IPC service.
2708 ***************************************************************************/
2710 static bool lp_add_ipc(const char *ipc_name, bool guest_ok)
2712 pstring comment;
2713 int i = add_a_service(&sDefault, ipc_name);
2715 if (i < 0)
2716 return (False);
2718 slprintf(comment, sizeof(comment) - 1,
2719 "IPC Service (%s)", Globals.szServerString);
2721 string_set(&ServicePtrs[i]->szPath, tmpdir());
2722 string_set(&ServicePtrs[i]->szUsername, "");
2723 string_set(&ServicePtrs[i]->comment, comment);
2724 string_set(&ServicePtrs[i]->fstype, "IPC");
2725 ServicePtrs[i]->iMaxConnections = 0;
2726 ServicePtrs[i]->bAvailable = True;
2727 ServicePtrs[i]->bRead_only = True;
2728 ServicePtrs[i]->bGuest_only = False;
2729 ServicePtrs[i]->bGuest_ok = guest_ok;
2730 ServicePtrs[i]->bPrint_ok = False;
2731 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2733 DEBUG(3, ("adding IPC service\n"));
2735 return (True);
2738 /***************************************************************************
2739 Add a new printer service, with defaults coming from service iFrom.
2740 ***************************************************************************/
2742 bool lp_add_printer(const char *pszPrintername, int iDefaultService)
2744 const char *comment = "From Printcap";
2745 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2747 if (i < 0)
2748 return (False);
2750 /* note that we do NOT default the availability flag to True - */
2751 /* we take it from the default service passed. This allows all */
2752 /* dynamic printers to be disabled by disabling the [printers] */
2753 /* entry (if/when the 'available' keyword is implemented!). */
2755 /* the printer name is set to the service name. */
2756 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2757 string_set(&ServicePtrs[i]->comment, comment);
2759 /* set the browseable flag from the gloabl default */
2760 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2762 /* Printers cannot be read_only. */
2763 ServicePtrs[i]->bRead_only = False;
2764 /* No share modes on printer services. */
2765 ServicePtrs[i]->bShareModes = False;
2766 /* No oplocks on printer services. */
2767 ServicePtrs[i]->bOpLocks = False;
2768 /* Printer services must be printable. */
2769 ServicePtrs[i]->bPrint_ok = True;
2771 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2773 return (True);
2777 /***************************************************************************
2778 Check whether the given parameter name is valid.
2779 Parametric options (names containing a colon) are considered valid.
2780 ***************************************************************************/
2782 bool lp_parameter_is_valid(const char *pszParmName)
2784 return ((map_parameter(pszParmName) != -1) ||
2785 (strchr(pszParmName, ':') != NULL));
2788 /***************************************************************************
2789 Check whether the given name is the name of a global parameter.
2790 Returns True for strings belonging to parameters of class
2791 P_GLOBAL, False for all other strings, also for parametric options
2792 and strings not belonging to any option.
2793 ***************************************************************************/
2795 bool lp_parameter_is_global(const char *pszParmName)
2797 int num = map_parameter(pszParmName);
2799 if (num >= 0) {
2800 return (parm_table[num].p_class == P_GLOBAL);
2803 return False;
2806 /**************************************************************************
2807 Check whether the given name is the canonical name of a parameter.
2808 Returns False if it is not a valid parameter Name.
2809 For parametric options, True is returned.
2810 **************************************************************************/
2812 bool lp_parameter_is_canonical(const char *parm_name)
2814 if (!lp_parameter_is_valid(parm_name)) {
2815 return False;
2818 return (map_parameter(parm_name) ==
2819 map_parameter_canonical(parm_name, NULL));
2822 /**************************************************************************
2823 Determine the canonical name for a parameter.
2824 Indicate when it is an inverse (boolean) synonym instead of a
2825 "usual" synonym.
2826 **************************************************************************/
2828 bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm,
2829 bool *inverse)
2831 int num;
2833 if (!lp_parameter_is_valid(parm_name)) {
2834 *canon_parm = NULL;
2835 return False;
2838 num = map_parameter_canonical(parm_name, inverse);
2839 if (num < 0) {
2840 /* parametric option */
2841 *canon_parm = parm_name;
2842 } else {
2843 *canon_parm = parm_table[num].label;
2846 return True;
2850 /**************************************************************************
2851 Determine the canonical name for a parameter.
2852 Turn the value given into the inverse boolean expression when
2853 the synonym is an invers boolean synonym.
2855 Return True if parm_name is a valid parameter name and
2856 in case it is an invers boolean synonym, if the val string could
2857 successfully be converted to the reverse bool.
2858 Return false in all other cases.
2859 **************************************************************************/
2861 bool lp_canonicalize_parameter_with_value(const char *parm_name,
2862 const char *val,
2863 const char **canon_parm,
2864 const char **canon_val)
2866 int num;
2867 bool inverse;
2869 if (!lp_parameter_is_valid(parm_name)) {
2870 *canon_parm = NULL;
2871 *canon_val = NULL;
2872 return False;
2875 num = map_parameter_canonical(parm_name, &inverse);
2876 if (num < 0) {
2877 /* parametric option */
2878 *canon_parm = parm_name;
2879 *canon_val = val;
2880 } else {
2881 *canon_parm = parm_table[num].label;
2882 if (inverse) {
2883 if (!lp_invert_boolean(val, canon_val)) {
2884 *canon_val = NULL;
2885 return False;
2887 } else {
2888 *canon_val = val;
2892 return True;
2895 /***************************************************************************
2896 Map a parameter's string representation to something we can use.
2897 Returns False if the parameter string is not recognised, else TRUE.
2898 ***************************************************************************/
2900 static int map_parameter(const char *pszParmName)
2902 int iIndex;
2904 if (*pszParmName == '-')
2905 return (-1);
2907 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2908 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2909 return (iIndex);
2911 /* Warn only if it isn't parametric option */
2912 if (strchr(pszParmName, ':') == NULL)
2913 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2914 /* We do return 'fail' for parametric options as well because they are
2915 stored in different storage
2917 return (-1);
2920 /***************************************************************************
2921 Map a parameter's string representation to the index of the canonical
2922 form of the parameter (it might be a synonym).
2923 Returns -1 if the parameter string is not recognised.
2924 ***************************************************************************/
2926 static int map_parameter_canonical(const char *pszParmName, bool *inverse)
2928 int parm_num, canon_num;
2929 bool loc_inverse = False;
2931 parm_num = map_parameter(pszParmName);
2932 if ((parm_num < 0) || !(parm_table[parm_num].flags & FLAG_HIDE)) {
2933 /* invalid, parametric or no canidate for synonyms ... */
2934 goto done;
2937 for (canon_num = 0; parm_table[canon_num].label; canon_num++) {
2938 if (is_synonym_of(parm_num, canon_num, &loc_inverse)) {
2939 parm_num = canon_num;
2940 goto done;
2944 done:
2945 if (inverse != NULL) {
2946 *inverse = loc_inverse;
2948 return parm_num;
2951 /***************************************************************************
2952 return true if parameter number parm1 is a synonym of parameter
2953 number parm2 (parm2 being the principal name).
2954 set inverse to True if parm1 is P_BOOLREV and parm2 is P_BOOL,
2955 False otherwise.
2956 ***************************************************************************/
2958 static bool is_synonym_of(int parm1, int parm2, bool *inverse)
2960 if ((parm_table[parm1].ptr == parm_table[parm2].ptr) &&
2961 (parm_table[parm1].flags & FLAG_HIDE) &&
2962 !(parm_table[parm2].flags & FLAG_HIDE))
2964 if (inverse != NULL) {
2965 if ((parm_table[parm1].type == P_BOOLREV) &&
2966 (parm_table[parm2].type == P_BOOL))
2968 *inverse = True;
2969 } else {
2970 *inverse = False;
2973 return True;
2975 return False;
2978 /***************************************************************************
2979 Show one parameter's name, type, [values,] and flags.
2980 (helper functions for show_parameter_list)
2981 ***************************************************************************/
2983 static void show_parameter(int parmIndex)
2985 int enumIndex, flagIndex;
2986 int parmIndex2;
2987 bool hadFlag;
2988 bool hadSyn;
2989 bool inverse;
2990 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2991 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2992 "P_UGSTRING", "P_ENUM", "P_SEP"};
2993 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2994 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2995 FLAG_HIDE, FLAG_DOS_STRING};
2996 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2997 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2998 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
3000 printf("%s=%s", parm_table[parmIndex].label,
3001 type[parm_table[parmIndex].type]);
3002 if (parm_table[parmIndex].type == P_ENUM) {
3003 printf(",");
3004 for (enumIndex=0;
3005 parm_table[parmIndex].enum_list[enumIndex].name;
3006 enumIndex++)
3008 printf("%s%s",
3009 enumIndex ? "|" : "",
3010 parm_table[parmIndex].enum_list[enumIndex].name);
3013 printf(",");
3014 hadFlag = False;
3015 for (flagIndex=0; flag_names[flagIndex]; flagIndex++) {
3016 if (parm_table[parmIndex].flags & flags[flagIndex]) {
3017 printf("%s%s",
3018 hadFlag ? "|" : "",
3019 flag_names[flagIndex]);
3020 hadFlag = True;
3024 /* output synonyms */
3025 hadSyn = False;
3026 for (parmIndex2=0; parm_table[parmIndex2].label; parmIndex2++) {
3027 if (is_synonym_of(parmIndex, parmIndex2, &inverse)) {
3028 printf(" (%ssynonym of %s)", inverse ? "inverse " : "",
3029 parm_table[parmIndex2].label);
3030 } else if (is_synonym_of(parmIndex2, parmIndex, &inverse)) {
3031 if (!hadSyn) {
3032 printf(" (synonyms: ");
3033 hadSyn = True;
3034 } else {
3035 printf(", ");
3037 printf("%s%s", parm_table[parmIndex2].label,
3038 inverse ? "[i]" : "");
3041 if (hadSyn) {
3042 printf(")");
3045 printf("\n");
3048 /***************************************************************************
3049 Show all parameter's name, type, [values,] and flags.
3050 ***************************************************************************/
3052 void show_parameter_list(void)
3054 int classIndex, parmIndex;
3055 const char *section_names[] = { "local", "global", NULL};
3057 for (classIndex=0; section_names[classIndex]; classIndex++) {
3058 printf("[%s]\n", section_names[classIndex]);
3059 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
3060 if (parm_table[parmIndex].p_class == classIndex) {
3061 show_parameter(parmIndex);
3067 /***************************************************************************
3068 Set a boolean variable from the text value stored in the passed string.
3069 Returns True in success, False if the passed string does not correctly
3070 represent a boolean.
3071 ***************************************************************************/
3073 static bool set_boolean(bool *pb, const char *pszParmValue)
3075 bool bRetval;
3076 bool value;
3078 bRetval = True;
3079 value = False;
3080 if (strwicmp(pszParmValue, "yes") == 0 ||
3081 strwicmp(pszParmValue, "true") == 0 ||
3082 strwicmp(pszParmValue, "1") == 0)
3083 value = True;
3084 else if (strwicmp(pszParmValue, "no") == 0 ||
3085 strwicmp(pszParmValue, "False") == 0 ||
3086 strwicmp(pszParmValue, "0") == 0)
3087 value = False;
3088 else {
3089 DEBUG(2,
3090 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
3091 pszParmValue));
3092 bRetval = False;
3095 if ((pb != NULL) && (bRetval != False)) {
3096 *pb = value;
3099 return (bRetval);
3103 /***************************************************************************
3104 Check if a given string correctly represents a boolean value.
3105 ***************************************************************************/
3107 bool lp_string_is_valid_boolean(const char *parm_value)
3109 return set_boolean(NULL, parm_value);
3112 /***************************************************************************
3113 Get the standard string representation of a boolean value ("yes" or "no")
3114 ***************************************************************************/
3116 static const char *get_boolean(bool bool_value)
3118 static const char *yes_str = "yes";
3119 static const char *no_str = "no";
3121 return (bool_value ? yes_str : no_str);
3124 /***************************************************************************
3125 Provide the string of the negated boolean value associated to the boolean
3126 given as a string. Returns False if the passed string does not correctly
3127 represent a boolean.
3128 ***************************************************************************/
3130 bool lp_invert_boolean(const char *str, const char **inverse_str)
3132 bool val;
3134 if (!set_boolean(&val, str)) {
3135 return False;
3138 *inverse_str = get_boolean(!val);
3139 return True;
3142 /***************************************************************************
3143 Provide the canonical string representation of a boolean value given
3144 as a string. Return True on success, False if the string given does
3145 not correctly represent a boolean.
3146 ***************************************************************************/
3148 bool lp_canonicalize_boolean(const char *str, const char**canon_str)
3150 bool val;
3152 if (!set_boolean(&val, str)) {
3153 return False;
3156 *canon_str = get_boolean(val);
3157 return True;
3160 /***************************************************************************
3161 Find a service by name. Otherwise works like get_service.
3162 ***************************************************************************/
3164 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
3166 int iService = -1;
3167 char *canon_name;
3169 if (ServiceHash != NULL) {
3170 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
3171 return -1;
3173 iService = tdb_fetch_int32(ServiceHash, canon_name );
3175 if (LP_SNUM_OK(iService)) {
3176 if (pserviceDest != NULL) {
3177 copy_service(pserviceDest, ServicePtrs[iService], NULL);
3179 } else {
3180 iService = -1;
3184 return (iService);
3187 /***************************************************************************
3188 Copy a service structure to another.
3189 If pcopymapDest is NULL then copy all fields
3190 ***************************************************************************/
3192 static void copy_service(service * pserviceDest, service * pserviceSource,
3193 struct bitmap *pcopymapDest)
3195 int i;
3196 bool bcopyall = (pcopymapDest == NULL);
3197 param_opt_struct *data, *pdata, *paramo;
3198 bool not_added;
3200 for (i = 0; parm_table[i].label; i++)
3201 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
3202 (bcopyall || bitmap_query(pcopymapDest,i))) {
3203 void *def_ptr = parm_table[i].ptr;
3204 void *src_ptr =
3205 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
3206 &sDefault);
3207 void *dest_ptr =
3208 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
3209 &sDefault);
3211 switch (parm_table[i].type) {
3212 case P_BOOL:
3213 case P_BOOLREV:
3214 *(bool *)dest_ptr = *(bool *)src_ptr;
3215 break;
3217 case P_INTEGER:
3218 case P_ENUM:
3219 case P_OCTAL:
3220 *(int *)dest_ptr = *(int *)src_ptr;
3221 break;
3223 case P_CHAR:
3224 *(char *)dest_ptr = *(char *)src_ptr;
3225 break;
3227 case P_STRING:
3228 string_set((char **)dest_ptr,
3229 *(char **)src_ptr);
3230 break;
3232 case P_USTRING:
3233 string_set((char **)dest_ptr,
3234 *(char **)src_ptr);
3235 strupper_m(*(char **)dest_ptr);
3236 break;
3237 case P_LIST:
3238 str_list_free((char ***)dest_ptr);
3239 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
3240 break;
3241 default:
3242 break;
3246 if (bcopyall) {
3247 init_copymap(pserviceDest);
3248 if (pserviceSource->copymap)
3249 bitmap_copy(pserviceDest->copymap,
3250 pserviceSource->copymap);
3253 data = pserviceSource->param_opt;
3254 while (data) {
3255 not_added = True;
3256 pdata = pserviceDest->param_opt;
3257 /* Traverse destination */
3258 while (pdata) {
3259 /* If we already have same option, override it */
3260 if (strcmp(pdata->key, data->key) == 0) {
3261 string_free(&pdata->value);
3262 str_list_free(&data->list);
3263 pdata->value = SMB_STRDUP(data->value);
3264 not_added = False;
3265 break;
3267 pdata = pdata->next;
3269 if (not_added) {
3270 paramo = SMB_XMALLOC_P(param_opt_struct);
3271 paramo->key = SMB_STRDUP(data->key);
3272 paramo->value = SMB_STRDUP(data->value);
3273 paramo->list = NULL;
3274 DLIST_ADD(pserviceDest->param_opt, paramo);
3276 data = data->next;
3280 /***************************************************************************
3281 Check a service for consistency. Return False if the service is in any way
3282 incomplete or faulty, else True.
3283 ***************************************************************************/
3285 bool service_ok(int iService)
3287 bool bRetval;
3289 bRetval = True;
3290 if (ServicePtrs[iService]->szService[0] == '\0') {
3291 DEBUG(0, ("The following message indicates an internal error:\n"));
3292 DEBUG(0, ("No service name in service entry.\n"));
3293 bRetval = False;
3296 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3297 /* I can't see why you'd want a non-printable printer service... */
3298 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3299 if (!ServicePtrs[iService]->bPrint_ok) {
3300 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3301 ServicePtrs[iService]->szService));
3302 ServicePtrs[iService]->bPrint_ok = True;
3304 /* [printers] service must also be non-browsable. */
3305 if (ServicePtrs[iService]->bBrowseable)
3306 ServicePtrs[iService]->bBrowseable = False;
3309 if (ServicePtrs[iService]->szPath[0] == '\0' &&
3310 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3311 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3313 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3314 ServicePtrs[iService]->szService));
3315 ServicePtrs[iService]->bAvailable = False;
3318 /* If a service is flagged unavailable, log the fact at level 1. */
3319 if (!ServicePtrs[iService]->bAvailable)
3320 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3321 ServicePtrs[iService]->szService));
3323 return (bRetval);
3327 * lp_regdb_open - regdb helper function
3329 * this should be considered an interim solution that becomes
3330 * superfluous once the registry code has been rewritten
3331 * do allow use of the tdb portion of the registry alone.
3333 * in the meanwhile this provides a lean access
3334 * to the registry globals.
3337 static struct tdb_wrap *lp_regdb_open(void)
3339 struct tdb_wrap *reg_tdb = NULL;
3340 const char *vstring = "INFO/version";
3341 uint32 vers_id;
3343 become_root();
3344 reg_tdb = tdb_wrap_open(NULL, state_path("registry.tdb"), 0,
3345 REG_TDB_FLAGS, O_RDWR, 0600);
3346 unbecome_root();
3347 if (!reg_tdb) {
3348 DEBUG(1, ("lp_regdb_open: failed to open %s: %s\n",
3349 state_path("registry.tdb"), strerror(errno)));
3350 goto done;
3352 else {
3353 DEBUG(10, ("lp_regdb_open: reg tdb opened.\n"));
3356 vers_id = tdb_fetch_int32(reg_tdb->tdb, vstring);
3357 if (vers_id != REGVER_V1) {
3358 DEBUG(10, ("lp_regdb_open: INFO: registry tdb %s has wrong "
3359 "INFO/version (got %d, expected %d)\n",
3360 state_path("registry.tdb"), vers_id, REGVER_V1));
3361 /* this is apparently not implemented in the tdb */
3364 done:
3365 return reg_tdb;
3369 * process_registry_globals
3371 * this is the interim version of process_registry globals
3373 * until we can do it as we would like using the api and only
3374 * using the tdb portion of the registry (see below),
3375 * this just provides the needed functionality of regdb_fetch_values
3376 * and regdb_unpack_values, circumventing any fancy stuff, to
3377 * give us access to the registry globals.
3379 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
3381 bool ret = False;
3382 struct tdb_wrap *reg_tdb = NULL;
3383 WERROR err;
3384 char *keystr;
3385 TDB_DATA data;
3386 /* vars for the tdb unpack loop */
3387 int len = 0;
3388 int i;
3389 int buflen;
3390 uint8 *buf;
3391 uint32 type;
3392 uint32 size;
3393 uint32 num_values = 0;
3394 uint8 *data_p;
3395 pstring valname;
3396 char * valstr;
3397 struct registry_value *value = NULL;
3399 include_registry_globals = True;
3401 ZERO_STRUCT(data);
3403 reg_tdb = lp_regdb_open();
3404 if (!reg_tdb) {
3405 DEBUG(1, ("Error opening the registry!\n"));
3406 goto done;
3409 /* reg_tdb is from now on used as talloc ctx.
3410 * freeing it closes the tdb (if refcount is 0) */
3412 keystr = talloc_asprintf(reg_tdb,"%s/%s/%s", REG_VALUE_PREFIX,
3413 KEY_SMBCONF, GLOBAL_NAME);
3414 normalize_dbkey(keystr);
3416 DEBUG(10, ("process_registry_globals: fetching key '%s'\n",
3417 keystr));
3419 data = tdb_fetch_bystring(reg_tdb->tdb, keystr);
3420 if (!data.dptr) {
3421 ret = True;
3422 goto done;
3425 buf = data.dptr;
3426 buflen = data.dsize;
3428 /* unpack number of values */
3429 len = tdb_unpack(buf, buflen, "d", &num_values);
3430 DEBUG(10, ("process_registry_globals: got %d values from tdb\n",
3431 num_values));
3433 /* unpack the values */
3434 for (i=0; i < num_values; i++) {
3435 type = REG_NONE;
3436 size = 0;
3437 data_p = NULL;
3438 len += tdb_unpack(buf+len, buflen-len, "fdB",
3439 valname,
3440 &type,
3441 &size,
3442 &data_p);
3443 if (registry_smbconf_valname_forbidden(valname)) {
3444 DEBUG(10, ("process_registry_globals: Ignoring "
3445 "parameter '%s' in registry.\n", valname));
3446 continue;
3448 DEBUG(10, ("process_registry_globals: got value '%s'\n",
3449 valname));
3450 if (size && data_p) {
3451 err = registry_pull_value(reg_tdb,
3452 &value,
3453 type,
3454 data_p,
3455 size,
3456 size);
3457 SAFE_FREE(data_p);
3458 if (!W_ERROR_IS_OK(err)) {
3459 goto done;
3461 switch(type) {
3462 case REG_DWORD:
3463 valstr = talloc_asprintf(reg_tdb, "%d",
3464 value->v.dword);
3465 pfunc(valname, valstr);
3466 break;
3467 case REG_SZ:
3468 pfunc(valname, value->v.sz.str);
3469 break;
3470 default:
3471 /* ignore other types */
3472 break;
3477 ret = pfunc("registry shares", "yes");
3478 regdb_last_seqnum = tdb_get_seqnum(reg_tdb->tdb);
3480 done:
3481 TALLOC_FREE(reg_tdb);
3482 SAFE_FREE(data.dptr);
3483 return ret;
3486 #if 0
3488 * this is process_registry_globals as it _should_ be (roughly)
3489 * using the reg_api functions...
3492 static bool process_registry_globals(bool (*pfunc)(const char *, const char *))
3494 bool ret = False;
3495 TALLOC_CTX *ctx = NULL;
3496 char *regpath = NULL;
3497 WERROR werr = WERR_OK;
3498 struct registry_key *key = NULL;
3499 struct registry_value *value = NULL;
3500 char *valname = NULL;
3501 char *valstr = NULL;
3502 uint32 idx = 0;
3503 NT_USER_TOKEN *token;
3505 ctx = talloc_init("process_registry_globals");
3506 if (!ctx) {
3507 smb_panic("Failed to create talloc context!");
3510 include_registry_globals = True;
3512 if (!registry_init_regdb()) {
3513 DEBUG(1, ("Error initializing the registry.\n"));
3514 goto done;
3517 if (!(token = registry_create_admin_token(ctx))) {
3518 DEBUG(1, ("Error creating admin token\n"));
3519 goto done;
3522 regpath = talloc_asprintf(ctx,"%s\\%s", KEY_SMBCONF, GLOBAL_NAME);
3523 werr = reg_open_path(ctx, regpath, REG_KEY_READ, token, &key);
3524 if (!W_ERROR_IS_OK(werr)) {
3525 DEBUG(1, ("Registry smbconf global section does not exist.\n"));
3526 DEBUGADD(1, ("Error opening registry path '%s\\%s: %s\n",
3527 KEY_SMBCONF, GLOBAL_NAME, dos_errstr(werr)));
3528 goto done;
3531 for (idx = 0;
3532 W_ERROR_IS_OK(werr = reg_enumvalue(ctx, key, idx, &valname,
3533 &value));
3534 idx++)
3536 DEBUG(5, ("got global registry parameter '%s'\n", valname));
3537 switch(value->type) {
3538 case REG_DWORD:
3539 valstr = talloc_asprintf(ctx, "%d", value->v.dword);
3540 pfunc(valname, valstr);
3541 TALLOC_FREE(valstr);
3542 break;
3543 case REG_SZ:
3544 pfunc(valname, value->v.sz.str);
3545 break;
3546 default:
3547 /* ignore other types */
3548 break;
3550 TALLOC_FREE(value);
3551 TALLOC_FREE(valstr);
3554 ret = pfunc("registry shares", "yes");
3556 regdb_last_seqnum = regdb_get_seqnum();
3558 done:
3559 talloc_destroy(ctx);
3560 return ret;
3562 #endif /* if 0 */
3564 static struct file_lists {
3565 struct file_lists *next;
3566 char *name;
3567 char *subfname;
3568 time_t modtime;
3569 } *file_lists = NULL;
3571 /*******************************************************************
3572 Keep a linked list of all config files so we know when one has changed
3573 it's date and needs to be reloaded.
3574 ********************************************************************/
3576 static void add_to_file_list(const char *fname, const char *subfname)
3578 struct file_lists *f = file_lists;
3580 while (f) {
3581 if (f->name && !strcmp(f->name, fname))
3582 break;
3583 f = f->next;
3586 if (!f) {
3587 f = SMB_MALLOC_P(struct file_lists);
3588 if (!f)
3589 return;
3590 f->next = file_lists;
3591 f->name = SMB_STRDUP(fname);
3592 if (!f->name) {
3593 SAFE_FREE(f);
3594 return;
3596 f->subfname = SMB_STRDUP(subfname);
3597 if (!f->subfname) {
3598 SAFE_FREE(f);
3599 return;
3601 file_lists = f;
3602 f->modtime = file_modtime(subfname);
3603 } else {
3604 time_t t = file_modtime(subfname);
3605 if (t)
3606 f->modtime = t;
3610 /*******************************************************************
3611 Check if a config file has changed date.
3612 ********************************************************************/
3614 bool lp_file_list_changed(void)
3616 struct file_lists *f = file_lists;
3617 struct tdb_wrap *reg_tdb = NULL;
3619 DEBUG(6, ("lp_file_list_changed()\n"));
3621 if (include_registry_globals) {
3622 reg_tdb = lp_regdb_open();
3623 if (reg_tdb && (regdb_last_seqnum != tdb_get_seqnum(reg_tdb->tdb)))
3625 DEBUGADD(6, ("regdb seqnum changed: old = %d, new = %d\n",
3626 regdb_last_seqnum, tdb_get_seqnum(reg_tdb->tdb)));
3627 TALLOC_FREE(reg_tdb);
3628 return True;
3632 while (f) {
3633 pstring n2;
3634 time_t mod_time;
3636 pstrcpy(n2, f->name);
3637 standard_sub_basic( get_current_username(),
3638 current_user_info.domain,
3639 n2, sizeof(n2) );
3641 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3642 f->name, n2, ctime(&f->modtime)));
3644 mod_time = file_modtime(n2);
3646 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3647 DEBUGADD(6,
3648 ("file %s modified: %s\n", n2,
3649 ctime(&mod_time)));
3650 f->modtime = mod_time;
3651 SAFE_FREE(f->subfname);
3652 f->subfname = SMB_STRDUP(n2);
3653 return (True);
3655 f = f->next;
3657 return (False);
3660 /***************************************************************************
3661 Run standard_sub_basic on netbios name... needed because global_myname
3662 is not accessed through any lp_ macro.
3663 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3664 ***************************************************************************/
3666 static bool handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3668 bool ret;
3669 pstring netbios_name;
3671 pstrcpy(netbios_name, pszParmValue);
3673 standard_sub_basic(get_current_username(), current_user_info.domain,
3674 netbios_name, sizeof(netbios_name));
3676 ret = set_global_myname(netbios_name);
3677 string_set(&Globals.szNetbiosName,global_myname());
3679 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3680 global_myname()));
3682 return ret;
3685 static bool handle_charset(int snum, const char *pszParmValue, char **ptr)
3687 if (strcmp(*ptr, pszParmValue) != 0) {
3688 string_set(ptr, pszParmValue);
3689 init_iconv();
3691 return True;
3696 static bool handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3698 bool ret;
3700 ret = set_global_myworkgroup(pszParmValue);
3701 string_set(&Globals.szWorkgroup,lp_workgroup());
3703 return ret;
3706 static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3708 bool ret;
3710 ret = set_global_scope(pszParmValue);
3711 string_set(&Globals.szNetbiosScope,global_scope());
3713 return ret;
3716 static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3718 str_list_free(&Globals.szNetbiosAliases);
3719 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3720 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3723 /***************************************************************************
3724 Handle the include operation.
3725 ***************************************************************************/
3727 static bool handle_include(int snum, const char *pszParmValue, char **ptr)
3729 pstring fname;
3730 pstrcpy(fname, pszParmValue);
3732 if (strequal(fname, INCLUDE_REGISTRY_NAME)) {
3733 if (bInGlobalSection) {
3734 return process_registry_globals(do_parameter);
3736 else {
3737 DEBUG(1, ("\"include = registry\" only effective "
3738 "in %s section\n", GLOBAL_NAME));
3739 return False;
3743 standard_sub_basic(get_current_username(), current_user_info.domain,
3744 fname,sizeof(fname));
3746 add_to_file_list(pszParmValue, fname);
3748 string_set(ptr, fname);
3750 if (file_exist(fname, NULL))
3751 return (pm_process(fname, do_section, do_parameter));
3753 DEBUG(2, ("Can't find include file %s\n", fname));
3755 return (False);
3758 /***************************************************************************
3759 Handle the interpretation of the copy parameter.
3760 ***************************************************************************/
3762 static bool handle_copy(int snum, const char *pszParmValue, char **ptr)
3764 bool bRetval;
3765 int iTemp;
3766 service serviceTemp;
3768 string_set(ptr, pszParmValue);
3770 init_service(&serviceTemp);
3772 bRetval = False;
3774 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3776 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3777 if (iTemp == iServiceIndex) {
3778 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3779 } else {
3780 copy_service(ServicePtrs[iServiceIndex],
3781 &serviceTemp,
3782 ServicePtrs[iServiceIndex]->copymap);
3783 bRetval = True;
3785 } else {
3786 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3787 bRetval = False;
3790 free_service(&serviceTemp);
3791 return (bRetval);
3794 /***************************************************************************
3795 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3796 parameters is:
3798 [global]
3800 idmap uid = 1000-1999
3801 idmap gid = 700-899
3803 We only do simple parsing checks here. The strings are parsed into useful
3804 structures in the idmap daemon code.
3806 ***************************************************************************/
3808 /* Some lp_ routines to return idmap [ug]id information */
3810 static uid_t idmap_uid_low, idmap_uid_high;
3811 static gid_t idmap_gid_low, idmap_gid_high;
3813 bool lp_idmap_uid(uid_t *low, uid_t *high)
3815 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3816 return False;
3818 if (low)
3819 *low = idmap_uid_low;
3821 if (high)
3822 *high = idmap_uid_high;
3824 return True;
3827 bool lp_idmap_gid(gid_t *low, gid_t *high)
3829 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3830 return False;
3832 if (low)
3833 *low = idmap_gid_low;
3835 if (high)
3836 *high = idmap_gid_high;
3838 return True;
3841 /* Do some simple checks on "idmap [ug]id" parameter values */
3843 static bool handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3845 uint32 low, high;
3847 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3848 return False;
3850 /* Parse OK */
3852 string_set(ptr, pszParmValue);
3854 idmap_uid_low = low;
3855 idmap_uid_high = high;
3857 return True;
3860 static bool handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3862 uint32 low, high;
3864 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3865 return False;
3867 /* Parse OK */
3869 string_set(ptr, pszParmValue);
3871 idmap_gid_low = low;
3872 idmap_gid_high = high;
3874 return True;
3877 /***************************************************************************
3878 Handle the DEBUG level list.
3879 ***************************************************************************/
3881 static bool handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3883 pstring pszParmValue;
3885 pstrcpy(pszParmValue, pszParmValueIn);
3886 string_set(ptr, pszParmValueIn);
3887 return debug_parse_levels( pszParmValue );
3890 /***************************************************************************
3891 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3892 ***************************************************************************/
3894 static const char *append_ldap_suffix( const char *str )
3896 const char *suffix_string;
3899 suffix_string = talloc_asprintf(talloc_tos(), "%s,%s", str,
3900 Globals.szLdapSuffix );
3901 if ( !suffix_string ) {
3902 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3903 return "";
3906 return suffix_string;
3909 const char *lp_ldap_machine_suffix(void)
3911 if (Globals.szLdapMachineSuffix[0])
3912 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3914 return lp_string(Globals.szLdapSuffix);
3917 const char *lp_ldap_user_suffix(void)
3919 if (Globals.szLdapUserSuffix[0])
3920 return append_ldap_suffix(Globals.szLdapUserSuffix);
3922 return lp_string(Globals.szLdapSuffix);
3925 const char *lp_ldap_group_suffix(void)
3927 if (Globals.szLdapGroupSuffix[0])
3928 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3930 return lp_string(Globals.szLdapSuffix);
3933 const char *lp_ldap_idmap_suffix(void)
3935 if (Globals.szLdapIdmapSuffix[0])
3936 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3938 return lp_string(Globals.szLdapSuffix);
3941 /****************************************************************************
3942 set the value for a P_ENUM
3943 ***************************************************************************/
3945 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3946 int *ptr )
3948 int i;
3950 for (i = 0; parm->enum_list[i].name; i++) {
3951 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3952 *ptr = parm->enum_list[i].value;
3953 break;
3958 /***************************************************************************
3959 ***************************************************************************/
3961 static bool handle_printing(int snum, const char *pszParmValue, char **ptr)
3963 static int parm_num = -1;
3964 service *s;
3966 if ( parm_num == -1 )
3967 parm_num = map_parameter( "printing" );
3969 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3971 if ( snum < 0 )
3972 s = &sDefault;
3973 else
3974 s = ServicePtrs[snum];
3976 init_printer_values( s );
3978 return True;
3982 /***************************************************************************
3983 Initialise a copymap.
3984 ***************************************************************************/
3986 static void init_copymap(service * pservice)
3988 int i;
3989 if (pservice->copymap) {
3990 bitmap_free(pservice->copymap);
3992 pservice->copymap = bitmap_allocate(NUMPARAMETERS);
3993 if (!pservice->copymap)
3994 DEBUG(0,
3995 ("Couldn't allocate copymap!! (size %d)\n",
3996 (int)NUMPARAMETERS));
3997 else
3998 for (i = 0; i < NUMPARAMETERS; i++)
3999 bitmap_set(pservice->copymap, i);
4002 /***************************************************************************
4003 Return the local pointer to a parameter given the service number and the
4004 pointer into the default structure.
4005 ***************************************************************************/
4007 void *lp_local_ptr(int snum, void *ptr)
4009 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
4012 /***************************************************************************
4013 Process a parameter for a particular service number. If snum < 0
4014 then assume we are in the globals.
4015 ***************************************************************************/
4017 bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
4019 int parmnum, i, slen;
4020 void *parm_ptr = NULL; /* where we are going to store the result */
4021 void *def_ptr = NULL;
4022 pstring param_key;
4023 char *sep;
4024 param_opt_struct *paramo, *data;
4025 bool not_added;
4027 parmnum = map_parameter(pszParmName);
4029 if (parmnum < 0) {
4030 if ((sep=strchr(pszParmName, ':')) != NULL) {
4031 *sep = '\0';
4032 ZERO_STRUCT(param_key);
4033 pstr_sprintf(param_key, "%s:", pszParmName);
4034 slen = strlen(param_key);
4035 pstrcat(param_key, sep+1);
4036 trim_char(param_key+slen, ' ', ' ');
4037 not_added = True;
4038 data = (snum < 0) ? Globals.param_opt :
4039 ServicePtrs[snum]->param_opt;
4040 /* Traverse destination */
4041 while (data) {
4042 /* If we already have same option, override it */
4043 if (strcmp(data->key, param_key) == 0) {
4044 string_free(&data->value);
4045 str_list_free(&data->list);
4046 data->value = SMB_STRDUP(pszParmValue);
4047 not_added = False;
4048 break;
4050 data = data->next;
4052 if (not_added) {
4053 paramo = SMB_XMALLOC_P(param_opt_struct);
4054 paramo->key = SMB_STRDUP(param_key);
4055 paramo->value = SMB_STRDUP(pszParmValue);
4056 paramo->list = NULL;
4057 if (snum < 0) {
4058 DLIST_ADD(Globals.param_opt, paramo);
4059 } else {
4060 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
4064 *sep = ':';
4065 return (True);
4067 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
4068 return (True);
4071 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
4072 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
4073 pszParmName));
4076 def_ptr = parm_table[parmnum].ptr;
4078 /* we might point at a service, the default service or a global */
4079 if (snum < 0) {
4080 parm_ptr = def_ptr;
4081 } else {
4082 if (parm_table[parmnum].p_class == P_GLOBAL) {
4083 DEBUG(0,
4084 ("Global parameter %s found in service section!\n",
4085 pszParmName));
4086 return (True);
4088 parm_ptr =
4089 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
4090 &sDefault);
4093 if (snum >= 0) {
4094 if (!ServicePtrs[snum]->copymap)
4095 init_copymap(ServicePtrs[snum]);
4097 /* this handles the aliases - set the copymap for other entries with
4098 the same data pointer */
4099 for (i = 0; parm_table[i].label; i++)
4100 if (parm_table[i].ptr == parm_table[parmnum].ptr)
4101 bitmap_clear(ServicePtrs[snum]->copymap, i);
4104 /* if it is a special case then go ahead */
4105 if (parm_table[parmnum].special) {
4106 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
4107 return (True);
4110 /* now switch on the type of variable it is */
4111 switch (parm_table[parmnum].type)
4113 case P_BOOL:
4114 *(bool *)parm_ptr = lp_bool(pszParmValue);
4115 break;
4117 case P_BOOLREV:
4118 *(bool *)parm_ptr = !lp_bool(pszParmValue);
4119 break;
4121 case P_INTEGER:
4122 *(int *)parm_ptr = lp_int(pszParmValue);
4123 break;
4125 case P_CHAR:
4126 *(char *)parm_ptr = *pszParmValue;
4127 break;
4129 case P_OCTAL:
4130 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
4131 if ( i != 1 ) {
4132 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
4134 break;
4136 case P_LIST:
4137 str_list_free((char ***)parm_ptr);
4138 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
4139 break;
4141 case P_STRING:
4142 string_set((char **)parm_ptr, pszParmValue);
4143 break;
4145 case P_USTRING:
4146 string_set((char **)parm_ptr, pszParmValue);
4147 strupper_m(*(char **)parm_ptr);
4148 break;
4150 case P_GSTRING:
4151 pstrcpy((char *)parm_ptr, pszParmValue);
4152 break;
4154 case P_UGSTRING:
4155 pstrcpy((char *)parm_ptr, pszParmValue);
4156 strupper_m((char *)parm_ptr);
4157 break;
4159 case P_ENUM:
4160 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
4161 break;
4162 case P_SEP:
4163 break;
4166 return (True);
4169 /***************************************************************************
4170 Process a parameter.
4171 ***************************************************************************/
4173 static bool do_parameter(const char *pszParmName, const char *pszParmValue)
4175 if (!bInGlobalSection && bGlobalOnly)
4176 return (True);
4178 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
4180 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
4181 pszParmName, pszParmValue));
4184 /***************************************************************************
4185 Print a parameter of the specified type.
4186 ***************************************************************************/
4188 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
4190 int i;
4191 switch (p->type)
4193 case P_ENUM:
4194 for (i = 0; p->enum_list[i].name; i++) {
4195 if (*(int *)ptr == p->enum_list[i].value) {
4196 fprintf(f, "%s",
4197 p->enum_list[i].name);
4198 break;
4201 break;
4203 case P_BOOL:
4204 fprintf(f, "%s", BOOLSTR(*(bool *)ptr));
4205 break;
4207 case P_BOOLREV:
4208 fprintf(f, "%s", BOOLSTR(!*(bool *)ptr));
4209 break;
4211 case P_INTEGER:
4212 fprintf(f, "%d", *(int *)ptr);
4213 break;
4215 case P_CHAR:
4216 fprintf(f, "%c", *(char *)ptr);
4217 break;
4219 case P_OCTAL:
4220 fprintf(f, "%s", octal_string(*(int *)ptr));
4221 break;
4223 case P_LIST:
4224 if ((char ***)ptr && *(char ***)ptr) {
4225 char **list = *(char ***)ptr;
4227 for (; *list; list++) {
4228 /* surround strings with whitespace in double quotes */
4229 if ( strchr_m( *list, ' ' ) )
4230 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
4231 else
4232 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
4235 break;
4237 case P_GSTRING:
4238 case P_UGSTRING:
4239 if ((char *)ptr) {
4240 fprintf(f, "%s", (char *)ptr);
4242 break;
4244 case P_STRING:
4245 case P_USTRING:
4246 if (*(char **)ptr) {
4247 fprintf(f, "%s", *(char **)ptr);
4249 break;
4250 case P_SEP:
4251 break;
4255 /***************************************************************************
4256 Check if two parameters are equal.
4257 ***************************************************************************/
4259 static bool equal_parameter(parm_type type, void *ptr1, void *ptr2)
4261 switch (type) {
4262 case P_BOOL:
4263 case P_BOOLREV:
4264 return (*((bool *)ptr1) == *((bool *)ptr2));
4266 case P_INTEGER:
4267 case P_ENUM:
4268 case P_OCTAL:
4269 return (*((int *)ptr1) == *((int *)ptr2));
4271 case P_CHAR:
4272 return (*((char *)ptr1) == *((char *)ptr2));
4274 case P_LIST:
4275 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
4277 case P_GSTRING:
4278 case P_UGSTRING:
4280 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
4281 if (p1 && !*p1)
4282 p1 = NULL;
4283 if (p2 && !*p2)
4284 p2 = NULL;
4285 return (p1 == p2 || strequal(p1, p2));
4287 case P_STRING:
4288 case P_USTRING:
4290 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
4291 if (p1 && !*p1)
4292 p1 = NULL;
4293 if (p2 && !*p2)
4294 p2 = NULL;
4295 return (p1 == p2 || strequal(p1, p2));
4297 case P_SEP:
4298 break;
4300 return (False);
4303 /***************************************************************************
4304 Initialize any local varients in the sDefault table.
4305 ***************************************************************************/
4307 void init_locals(void)
4309 /* None as yet. */
4312 /***************************************************************************
4313 Process a new section (service). At this stage all sections are services.
4314 Later we'll have special sections that permit server parameters to be set.
4315 Returns True on success, False on failure.
4316 ***************************************************************************/
4318 static bool do_section(const char *pszSectionName)
4320 bool bRetval;
4321 bool isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
4322 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
4323 bRetval = False;
4325 /* if we were in a global section then do the local inits */
4326 if (bInGlobalSection && !isglobal)
4327 init_locals();
4329 /* if we've just struck a global section, note the fact. */
4330 bInGlobalSection = isglobal;
4332 /* check for multiple global sections */
4333 if (bInGlobalSection) {
4334 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
4335 return (True);
4338 if (!bInGlobalSection && bGlobalOnly)
4339 return (True);
4341 /* if we have a current service, tidy it up before moving on */
4342 bRetval = True;
4344 if (iServiceIndex >= 0)
4345 bRetval = service_ok(iServiceIndex);
4347 /* if all is still well, move to the next record in the services array */
4348 if (bRetval) {
4349 /* We put this here to avoid an odd message order if messages are */
4350 /* issued by the post-processing of a previous section. */
4351 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
4353 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
4354 < 0) {
4355 DEBUG(0, ("Failed to add a new service\n"));
4356 return (False);
4360 return (bRetval);
4364 /***************************************************************************
4365 Determine if a partcular base parameter is currentl set to the default value.
4366 ***************************************************************************/
4368 static bool is_default(int i)
4370 if (!defaults_saved)
4371 return False;
4372 switch (parm_table[i].type) {
4373 case P_LIST:
4374 return str_list_compare (parm_table[i].def.lvalue,
4375 *(char ***)parm_table[i].ptr);
4376 case P_STRING:
4377 case P_USTRING:
4378 return strequal(parm_table[i].def.svalue,
4379 *(char **)parm_table[i].ptr);
4380 case P_GSTRING:
4381 case P_UGSTRING:
4382 return strequal(parm_table[i].def.svalue,
4383 (char *)parm_table[i].ptr);
4384 case P_BOOL:
4385 case P_BOOLREV:
4386 return parm_table[i].def.bvalue ==
4387 *(bool *)parm_table[i].ptr;
4388 case P_CHAR:
4389 return parm_table[i].def.cvalue ==
4390 *(char *)parm_table[i].ptr;
4391 case P_INTEGER:
4392 case P_OCTAL:
4393 case P_ENUM:
4394 return parm_table[i].def.ivalue ==
4395 *(int *)parm_table[i].ptr;
4396 case P_SEP:
4397 break;
4399 return False;
4402 /***************************************************************************
4403 Display the contents of the global structure.
4404 ***************************************************************************/
4406 static void dump_globals(FILE *f)
4408 int i;
4409 param_opt_struct *data;
4411 fprintf(f, "[global]\n");
4413 for (i = 0; parm_table[i].label; i++)
4414 if (parm_table[i].p_class == P_GLOBAL &&
4415 parm_table[i].ptr &&
4416 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
4417 if (defaults_saved && is_default(i))
4418 continue;
4419 fprintf(f, "\t%s = ", parm_table[i].label);
4420 print_parameter(&parm_table[i], parm_table[i].ptr, f);
4421 fprintf(f, "\n");
4423 if (Globals.param_opt != NULL) {
4424 data = Globals.param_opt;
4425 while(data) {
4426 fprintf(f, "\t%s = %s\n", data->key, data->value);
4427 data = data->next;
4433 /***************************************************************************
4434 Return True if a local parameter is currently set to the global default.
4435 ***************************************************************************/
4437 bool lp_is_default(int snum, struct parm_struct *parm)
4439 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
4441 return equal_parameter(parm->type,
4442 ((char *)ServicePtrs[snum]) + pdiff,
4443 ((char *)&sDefault) + pdiff);
4446 /***************************************************************************
4447 Display the contents of a single services record.
4448 ***************************************************************************/
4450 static void dump_a_service(service * pService, FILE * f)
4452 int i;
4453 param_opt_struct *data;
4455 if (pService != &sDefault)
4456 fprintf(f, "[%s]\n", pService->szService);
4458 for (i = 0; parm_table[i].label; i++) {
4460 if (parm_table[i].p_class == P_LOCAL &&
4461 parm_table[i].ptr &&
4462 (*parm_table[i].label != '-') &&
4463 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4466 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
4468 if (pService == &sDefault) {
4469 if (defaults_saved && is_default(i))
4470 continue;
4471 } else {
4472 if (equal_parameter(parm_table[i].type,
4473 ((char *)pService) +
4474 pdiff,
4475 ((char *)&sDefault) +
4476 pdiff))
4477 continue;
4480 fprintf(f, "\t%s = ", parm_table[i].label);
4481 print_parameter(&parm_table[i],
4482 ((char *)pService) + pdiff, f);
4483 fprintf(f, "\n");
4487 if (pService->param_opt != NULL) {
4488 data = pService->param_opt;
4489 while(data) {
4490 fprintf(f, "\t%s = %s\n", data->key, data->value);
4491 data = data->next;
4496 /***************************************************************************
4497 Display the contents of a parameter of a single services record.
4498 ***************************************************************************/
4500 bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal)
4502 int i;
4503 bool result = False;
4504 parm_class p_class;
4505 unsigned flag = 0;
4506 fstring local_parm_name;
4507 char *parm_opt;
4508 const char *parm_opt_value;
4510 /* check for parametrical option */
4511 fstrcpy( local_parm_name, parm_name);
4512 parm_opt = strchr( local_parm_name, ':');
4514 if (parm_opt) {
4515 *parm_opt = '\0';
4516 parm_opt++;
4517 if (strlen(parm_opt)) {
4518 parm_opt_value = lp_parm_const_string( snum,
4519 local_parm_name, parm_opt, NULL);
4520 if (parm_opt_value) {
4521 printf( "%s\n", parm_opt_value);
4522 result = True;
4525 return result;
4528 /* check for a key and print the value */
4529 if (isGlobal) {
4530 p_class = P_GLOBAL;
4531 flag = FLAG_GLOBAL;
4532 } else
4533 p_class = P_LOCAL;
4535 for (i = 0; parm_table[i].label; i++) {
4536 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
4537 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
4538 parm_table[i].ptr &&
4539 (*parm_table[i].label != '-') &&
4540 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4542 void *ptr;
4544 if (isGlobal) {
4545 ptr = parm_table[i].ptr;
4546 } else {
4547 service * pService = ServicePtrs[snum];
4548 ptr = ((char *)pService) +
4549 PTR_DIFF(parm_table[i].ptr, &sDefault);
4552 print_parameter(&parm_table[i],
4553 ptr, f);
4554 fprintf(f, "\n");
4555 result = True;
4556 break;
4560 return result;
4563 /***************************************************************************
4564 Return info about the requested parameter (given as a string).
4565 Return NULL when the string is not a valid parameter name.
4566 ***************************************************************************/
4568 struct parm_struct *lp_get_parameter(const char *param_name)
4570 int num = map_parameter(param_name);
4572 if (num < 0) {
4573 return NULL;
4576 return &parm_table[num];
4579 /***************************************************************************
4580 Return info about the next parameter in a service.
4581 snum==GLOBAL_SECTION_SNUM gives the globals.
4582 Return NULL when out of parameters.
4583 ***************************************************************************/
4585 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
4587 if (snum < 0) {
4588 /* do the globals */
4589 for (; parm_table[*i].label; (*i)++) {
4590 if (parm_table[*i].p_class == P_SEPARATOR)
4591 return &parm_table[(*i)++];
4593 if (!parm_table[*i].ptr
4594 || (*parm_table[*i].label == '-'))
4595 continue;
4597 if ((*i) > 0
4598 && (parm_table[*i].ptr ==
4599 parm_table[(*i) - 1].ptr))
4600 continue;
4602 if (is_default(*i) && !allparameters)
4603 continue;
4605 return &parm_table[(*i)++];
4607 } else {
4608 service *pService = ServicePtrs[snum];
4610 for (; parm_table[*i].label; (*i)++) {
4611 if (parm_table[*i].p_class == P_SEPARATOR)
4612 return &parm_table[(*i)++];
4614 if (parm_table[*i].p_class == P_LOCAL &&
4615 parm_table[*i].ptr &&
4616 (*parm_table[*i].label != '-') &&
4617 ((*i) == 0 ||
4618 (parm_table[*i].ptr !=
4619 parm_table[(*i) - 1].ptr)))
4621 int pdiff =
4622 PTR_DIFF(parm_table[*i].ptr,
4623 &sDefault);
4625 if (allparameters ||
4626 !equal_parameter(parm_table[*i].type,
4627 ((char *)pService) +
4628 pdiff,
4629 ((char *)&sDefault) +
4630 pdiff))
4632 return &parm_table[(*i)++];
4638 return NULL;
4642 #if 0
4643 /***************************************************************************
4644 Display the contents of a single copy structure.
4645 ***************************************************************************/
4646 static void dump_copy_map(bool *pcopymap)
4648 int i;
4649 if (!pcopymap)
4650 return;
4652 printf("\n\tNon-Copied parameters:\n");
4654 for (i = 0; parm_table[i].label; i++)
4655 if (parm_table[i].p_class == P_LOCAL &&
4656 parm_table[i].ptr && !pcopymap[i] &&
4657 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4659 printf("\t\t%s\n", parm_table[i].label);
4662 #endif
4664 /***************************************************************************
4665 Return TRUE if the passed service number is within range.
4666 ***************************************************************************/
4668 bool lp_snum_ok(int iService)
4670 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4673 /***************************************************************************
4674 Auto-load some home services.
4675 ***************************************************************************/
4677 static void lp_add_auto_services(char *str)
4679 char *s;
4680 char *p;
4681 int homes;
4683 if (!str)
4684 return;
4686 s = SMB_STRDUP(str);
4687 if (!s)
4688 return;
4690 homes = lp_servicenumber(HOMES_NAME);
4692 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4693 char *home = get_user_home_dir(p);
4695 if (lp_servicenumber(p) >= 0)
4696 continue;
4698 if (home && homes >= 0)
4699 lp_add_home(p, homes, p, home);
4701 SAFE_FREE(s);
4704 /***************************************************************************
4705 Auto-load one printer.
4706 ***************************************************************************/
4708 void lp_add_one_printer(char *name, char *comment)
4710 int printers = lp_servicenumber(PRINTERS_NAME);
4711 int i;
4713 if (lp_servicenumber(name) < 0) {
4714 lp_add_printer(name, printers);
4715 if ((i = lp_servicenumber(name)) >= 0) {
4716 string_set(&ServicePtrs[i]->comment, comment);
4717 ServicePtrs[i]->autoloaded = True;
4722 /***************************************************************************
4723 Have we loaded a services file yet?
4724 ***************************************************************************/
4726 bool lp_loaded(void)
4728 return (bLoaded);
4731 /***************************************************************************
4732 Unload unused services.
4733 ***************************************************************************/
4735 void lp_killunused(bool (*snumused) (int))
4737 int i;
4738 for (i = 0; i < iNumServices; i++) {
4739 if (!VALID(i))
4740 continue;
4742 /* don't kill autoloaded or usershare services */
4743 if ( ServicePtrs[i]->autoloaded ||
4744 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4745 continue;
4748 if (!snumused || !snumused(i)) {
4749 free_service_byindex(i);
4754 /***************************************************************************
4755 Unload a service.
4756 ***************************************************************************/
4758 void lp_killservice(int iServiceIn)
4760 if (VALID(iServiceIn)) {
4761 free_service_byindex(iServiceIn);
4765 /***************************************************************************
4766 Save the curent values of all global and sDefault parameters into the
4767 defaults union. This allows swat and testparm to show only the
4768 changed (ie. non-default) parameters.
4769 ***************************************************************************/
4771 static void lp_save_defaults(void)
4773 int i;
4774 for (i = 0; parm_table[i].label; i++) {
4775 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4776 continue;
4777 switch (parm_table[i].type) {
4778 case P_LIST:
4779 str_list_copy(&(parm_table[i].def.lvalue),
4780 *(const char ***)parm_table[i].ptr);
4781 break;
4782 case P_STRING:
4783 case P_USTRING:
4784 if (parm_table[i].ptr) {
4785 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4786 } else {
4787 parm_table[i].def.svalue = NULL;
4789 break;
4790 case P_GSTRING:
4791 case P_UGSTRING:
4792 if (parm_table[i].ptr) {
4793 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4794 } else {
4795 parm_table[i].def.svalue = NULL;
4797 break;
4798 case P_BOOL:
4799 case P_BOOLREV:
4800 parm_table[i].def.bvalue =
4801 *(bool *)parm_table[i].ptr;
4802 break;
4803 case P_CHAR:
4804 parm_table[i].def.cvalue =
4805 *(char *)parm_table[i].ptr;
4806 break;
4807 case P_INTEGER:
4808 case P_OCTAL:
4809 case P_ENUM:
4810 parm_table[i].def.ivalue =
4811 *(int *)parm_table[i].ptr;
4812 break;
4813 case P_SEP:
4814 break;
4817 defaults_saved = True;
4820 /*******************************************************************
4821 Set the server type we will announce as via nmbd.
4822 ********************************************************************/
4824 static const struct srv_role_tab {
4825 uint32 role;
4826 const char *role_str;
4827 } srv_role_tab [] = {
4828 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4829 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4830 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4831 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4832 { 0, NULL }
4835 const char* server_role_str(uint32 role)
4837 int i = 0;
4838 for (i=0; srv_role_tab[i].role_str; i++) {
4839 if (role == srv_role_tab[i].role) {
4840 return srv_role_tab[i].role_str;
4843 return NULL;
4846 static void set_server_role(void)
4848 server_role = ROLE_STANDALONE;
4850 switch (lp_security()) {
4851 case SEC_SHARE:
4852 if (lp_domain_logons())
4853 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4854 break;
4855 case SEC_SERVER:
4856 if (lp_domain_logons())
4857 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4858 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4859 server_role = ROLE_STANDALONE;
4860 break;
4861 case SEC_DOMAIN:
4862 if (lp_domain_logons()) {
4863 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4864 server_role = ROLE_DOMAIN_BDC;
4865 break;
4867 server_role = ROLE_DOMAIN_MEMBER;
4868 break;
4869 case SEC_ADS:
4870 if (lp_domain_logons()) {
4871 server_role = ROLE_DOMAIN_PDC;
4872 break;
4874 server_role = ROLE_DOMAIN_MEMBER;
4875 break;
4876 case SEC_USER:
4877 if (lp_domain_logons()) {
4879 if (Globals.iDomainMaster) /* auto or yes */
4880 server_role = ROLE_DOMAIN_PDC;
4881 else
4882 server_role = ROLE_DOMAIN_BDC;
4884 break;
4885 default:
4886 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4887 break;
4890 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4893 /***********************************************************
4894 If we should send plaintext/LANMAN passwords in the clinet
4895 ************************************************************/
4897 static void set_allowed_client_auth(void)
4899 if (Globals.bClientNTLMv2Auth) {
4900 Globals.bClientLanManAuth = False;
4902 if (!Globals.bClientLanManAuth) {
4903 Globals.bClientPlaintextAuth = False;
4907 /***************************************************************************
4908 JRA.
4909 The following code allows smbd to read a user defined share file.
4910 Yes, this is my intent. Yes, I'm comfortable with that...
4912 THE FOLLOWING IS SECURITY CRITICAL CODE.
4914 It washes your clothes, it cleans your house, it guards you while you sleep...
4915 Do not f%^k with it....
4916 ***************************************************************************/
4918 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4920 /***************************************************************************
4921 Check allowed stat state of a usershare file.
4922 Ensure we print out who is dicking with us so the admin can
4923 get their sorry ass fired.
4924 ***************************************************************************/
4926 static bool check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4928 if (!S_ISREG(psbuf->st_mode)) {
4929 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4930 "not a regular file\n",
4931 fname, (unsigned int)psbuf->st_uid ));
4932 return False;
4935 /* Ensure this doesn't have the other write bit set. */
4936 if (psbuf->st_mode & S_IWOTH) {
4937 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4938 "public write. Refusing to allow as a usershare file.\n",
4939 fname, (unsigned int)psbuf->st_uid ));
4940 return False;
4943 /* Should be 10k or less. */
4944 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4945 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4946 "too large (%u) to be a user share file.\n",
4947 fname, (unsigned int)psbuf->st_uid,
4948 (unsigned int)psbuf->st_size ));
4949 return False;
4952 return True;
4955 /***************************************************************************
4956 Parse the contents of a usershare file.
4957 ***************************************************************************/
4959 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4960 SMB_STRUCT_STAT *psbuf,
4961 const char *servicename,
4962 int snum,
4963 char **lines,
4964 int numlines,
4965 pstring sharepath,
4966 pstring comment,
4967 SEC_DESC **ppsd,
4968 bool *pallow_guest)
4970 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4971 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4972 int us_vers;
4973 SMB_STRUCT_DIR *dp;
4974 SMB_STRUCT_STAT sbuf;
4976 *pallow_guest = False;
4978 if (numlines < 4) {
4979 return USERSHARE_MALFORMED_FILE;
4982 if (strcmp(lines[0], "#VERSION 1") == 0) {
4983 us_vers = 1;
4984 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4985 us_vers = 2;
4986 if (numlines < 5) {
4987 return USERSHARE_MALFORMED_FILE;
4989 } else {
4990 return USERSHARE_BAD_VERSION;
4993 if (strncmp(lines[1], "path=", 5) != 0) {
4994 return USERSHARE_MALFORMED_PATH;
4997 pstrcpy(sharepath, &lines[1][5]);
4998 trim_string(sharepath, " ", " ");
5000 if (strncmp(lines[2], "comment=", 8) != 0) {
5001 return USERSHARE_MALFORMED_COMMENT_DEF;
5004 pstrcpy(comment, &lines[2][8]);
5005 trim_string(comment, " ", " ");
5006 trim_char(comment, '"', '"');
5008 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
5009 return USERSHARE_MALFORMED_ACL_DEF;
5012 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
5013 return USERSHARE_ACL_ERR;
5016 if (us_vers == 2) {
5017 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
5018 return USERSHARE_MALFORMED_ACL_DEF;
5020 if (lines[4][9] == 'y') {
5021 *pallow_guest = True;
5025 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
5026 /* Path didn't change, no checks needed. */
5027 return USERSHARE_OK;
5030 /* The path *must* be absolute. */
5031 if (sharepath[0] != '/') {
5032 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
5033 servicename, sharepath));
5034 return USERSHARE_PATH_NOT_ABSOLUTE;
5037 /* If there is a usershare prefix deny list ensure one of these paths
5038 doesn't match the start of the user given path. */
5039 if (prefixdenylist) {
5040 int i;
5041 for ( i=0; prefixdenylist[i]; i++ ) {
5042 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
5043 servicename, i, prefixdenylist[i], sharepath ));
5044 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
5045 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
5046 "usershare prefix deny list entries.\n",
5047 servicename, sharepath));
5048 return USERSHARE_PATH_IS_DENIED;
5053 /* If there is a usershare prefix allow list ensure one of these paths
5054 does match the start of the user given path. */
5056 if (prefixallowlist) {
5057 int i;
5058 for ( i=0; prefixallowlist[i]; i++ ) {
5059 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
5060 servicename, i, prefixallowlist[i], sharepath ));
5061 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
5062 break;
5065 if (prefixallowlist[i] == NULL) {
5066 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
5067 "usershare prefix allow list entries.\n",
5068 servicename, sharepath));
5069 return USERSHARE_PATH_NOT_ALLOWED;
5073 /* Ensure this is pointing to a directory. */
5074 dp = sys_opendir(sharepath);
5076 if (!dp) {
5077 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
5078 servicename, sharepath));
5079 return USERSHARE_PATH_NOT_DIRECTORY;
5082 /* Ensure the owner of the usershare file has permission to share
5083 this directory. */
5085 if (sys_stat(sharepath, &sbuf) == -1) {
5086 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
5087 servicename, sharepath, strerror(errno) ));
5088 sys_closedir(dp);
5089 return USERSHARE_POSIX_ERR;
5092 sys_closedir(dp);
5094 if (!S_ISDIR(sbuf.st_mode)) {
5095 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
5096 servicename, sharepath ));
5097 return USERSHARE_PATH_NOT_DIRECTORY;
5100 /* Check if sharing is restricted to owner-only. */
5101 /* psbuf is the stat of the usershare definition file,
5102 sbuf is the stat of the target directory to be shared. */
5104 if (lp_usershare_owner_only()) {
5105 /* root can share anything. */
5106 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
5107 return USERSHARE_PATH_NOT_ALLOWED;
5111 return USERSHARE_OK;
5114 /***************************************************************************
5115 Deal with a usershare file.
5116 Returns:
5117 >= 0 - snum
5118 -1 - Bad name, invalid contents.
5119 - service name already existed and not a usershare, problem
5120 with permissions to share directory etc.
5121 ***************************************************************************/
5123 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
5125 SMB_STRUCT_STAT sbuf;
5126 SMB_STRUCT_STAT lsbuf;
5127 pstring fname;
5128 pstring sharepath;
5129 pstring comment;
5130 fstring service_name;
5131 char **lines = NULL;
5132 int numlines = 0;
5133 int fd = -1;
5134 int iService = -1;
5135 TALLOC_CTX *ctx = NULL;
5136 SEC_DESC *psd = NULL;
5137 bool guest_ok = False;
5139 /* Ensure share name doesn't contain invalid characters. */
5140 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
5141 DEBUG(0,("process_usershare_file: share name %s contains "
5142 "invalid characters (any of %s)\n",
5143 file_name, INVALID_SHARENAME_CHARS ));
5144 return -1;
5147 fstrcpy(service_name, file_name);
5149 pstrcpy(fname, dir_name);
5150 pstrcat(fname, "/");
5151 pstrcat(fname, file_name);
5153 /* Minimize the race condition by doing an lstat before we
5154 open and fstat. Ensure this isn't a symlink link. */
5156 if (sys_lstat(fname, &lsbuf) != 0) {
5157 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
5158 fname, strerror(errno) ));
5159 return -1;
5162 /* This must be a regular file, not a symlink, directory or
5163 other strange filetype. */
5164 if (!check_usershare_stat(fname, &lsbuf)) {
5165 return -1;
5168 /* See if there is already a servicenum for this name. */
5169 /* tdb_fetch_int32 returns -1 if not found. */
5170 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
5172 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
5173 /* Nothing changed - Mark valid and return. */
5174 DEBUG(10,("process_usershare_file: service %s not changed.\n",
5175 service_name ));
5176 ServicePtrs[iService]->usershare = USERSHARE_VALID;
5177 return iService;
5180 /* Try and open the file read only - no symlinks allowed. */
5181 #ifdef O_NOFOLLOW
5182 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
5183 #else
5184 fd = sys_open(fname, O_RDONLY, 0);
5185 #endif
5187 if (fd == -1) {
5188 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
5189 fname, strerror(errno) ));
5190 return -1;
5193 /* Now fstat to be *SURE* it's a regular file. */
5194 if (sys_fstat(fd, &sbuf) != 0) {
5195 close(fd);
5196 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
5197 fname, strerror(errno) ));
5198 return -1;
5201 /* Is it the same dev/inode as was lstated ? */
5202 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
5203 close(fd);
5204 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
5205 "Symlink spoofing going on ?\n", fname ));
5206 return -1;
5209 /* This must be a regular file, not a symlink, directory or
5210 other strange filetype. */
5211 if (!check_usershare_stat(fname, &sbuf)) {
5212 return -1;
5215 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
5217 close(fd);
5218 if (lines == NULL) {
5219 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
5220 fname, (unsigned int)sbuf.st_uid ));
5221 return -1;
5224 /* Should we allow printers to be shared... ? */
5225 ctx = talloc_init("usershare_sd_xctx");
5226 if (!ctx) {
5227 file_lines_free(lines);
5228 return 1;
5231 if (parse_usershare_file(ctx, &sbuf, service_name,
5232 iService, lines, numlines, sharepath,
5233 comment, &psd, &guest_ok) != USERSHARE_OK) {
5234 talloc_destroy(ctx);
5235 file_lines_free(lines);
5236 return -1;
5239 file_lines_free(lines);
5241 /* Everything ok - add the service possibly using a template. */
5242 if (iService < 0) {
5243 const service *sp = &sDefault;
5244 if (snum_template != -1) {
5245 sp = ServicePtrs[snum_template];
5248 if ((iService = add_a_service(sp, service_name)) < 0) {
5249 DEBUG(0, ("process_usershare_file: Failed to add "
5250 "new service %s\n", service_name));
5251 talloc_destroy(ctx);
5252 return -1;
5255 /* Read only is controlled by usershare ACL below. */
5256 ServicePtrs[iService]->bRead_only = False;
5259 /* Write the ACL of the new/modified share. */
5260 if (!set_share_security(service_name, psd)) {
5261 DEBUG(0, ("process_usershare_file: Failed to set share "
5262 "security for user share %s\n",
5263 service_name ));
5264 lp_remove_service(iService);
5265 talloc_destroy(ctx);
5266 return -1;
5269 talloc_destroy(ctx);
5271 /* If from a template it may be marked invalid. */
5272 ServicePtrs[iService]->valid = True;
5274 /* Set the service as a valid usershare. */
5275 ServicePtrs[iService]->usershare = USERSHARE_VALID;
5277 /* Set guest access. */
5278 if (lp_usershare_allow_guests()) {
5279 ServicePtrs[iService]->bGuest_ok = guest_ok;
5282 /* And note when it was loaded. */
5283 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
5284 string_set(&ServicePtrs[iService]->szPath, sharepath);
5285 string_set(&ServicePtrs[iService]->comment, comment);
5287 return iService;
5290 /***************************************************************************
5291 Checks if a usershare entry has been modified since last load.
5292 ***************************************************************************/
5294 static bool usershare_exists(int iService, time_t *last_mod)
5296 SMB_STRUCT_STAT lsbuf;
5297 const char *usersharepath = Globals.szUsersharePath;
5298 pstring fname;
5300 pstrcpy(fname, usersharepath);
5301 pstrcat(fname, "/");
5302 pstrcat(fname, ServicePtrs[iService]->szService);
5304 if (sys_lstat(fname, &lsbuf) != 0) {
5305 return False;
5308 if (!S_ISREG(lsbuf.st_mode)) {
5309 return False;
5312 *last_mod = lsbuf.st_mtime;
5313 return True;
5316 /***************************************************************************
5317 Load a usershare service by name. Returns a valid servicenumber or -1.
5318 ***************************************************************************/
5320 int load_usershare_service(const char *servicename)
5322 SMB_STRUCT_STAT sbuf;
5323 const char *usersharepath = Globals.szUsersharePath;
5324 int max_user_shares = Globals.iUsershareMaxShares;
5325 int snum_template = -1;
5327 if (*usersharepath == 0 || max_user_shares == 0) {
5328 return -1;
5331 if (sys_stat(usersharepath, &sbuf) != 0) {
5332 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
5333 usersharepath, strerror(errno) ));
5334 return -1;
5337 if (!S_ISDIR(sbuf.st_mode)) {
5338 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
5339 usersharepath ));
5340 return -1;
5344 * This directory must be owned by root, and have the 't' bit set.
5345 * It also must not be writable by "other".
5348 #ifdef S_ISVTX
5349 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
5350 #else
5351 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
5352 #endif
5353 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
5354 "or does not have the sticky bit 't' set or is writable by anyone.\n",
5355 usersharepath ));
5356 return -1;
5359 /* Ensure the template share exists if it's set. */
5360 if (Globals.szUsershareTemplateShare[0]) {
5361 /* We can't use lp_servicenumber here as we are recommending that
5362 template shares have -valid=False set. */
5363 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
5364 if (ServicePtrs[snum_template]->szService &&
5365 strequal(ServicePtrs[snum_template]->szService,
5366 Globals.szUsershareTemplateShare)) {
5367 break;
5371 if (snum_template == -1) {
5372 DEBUG(0,("load_usershare_service: usershare template share %s "
5373 "does not exist.\n",
5374 Globals.szUsershareTemplateShare ));
5375 return -1;
5379 return process_usershare_file(usersharepath, servicename, snum_template);
5382 /***************************************************************************
5383 Load all user defined shares from the user share directory.
5384 We only do this if we're enumerating the share list.
5385 This is the function that can delete usershares that have
5386 been removed.
5387 ***************************************************************************/
5389 int load_usershare_shares(void)
5391 SMB_STRUCT_DIR *dp;
5392 SMB_STRUCT_STAT sbuf;
5393 SMB_STRUCT_DIRENT *de;
5394 int num_usershares = 0;
5395 int max_user_shares = Globals.iUsershareMaxShares;
5396 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
5397 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
5398 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
5399 int iService;
5400 int snum_template = -1;
5401 const char *usersharepath = Globals.szUsersharePath;
5402 int ret = lp_numservices();
5404 if (max_user_shares == 0 || *usersharepath == '\0') {
5405 return lp_numservices();
5408 if (sys_stat(usersharepath, &sbuf) != 0) {
5409 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
5410 usersharepath, strerror(errno) ));
5411 return ret;
5415 * This directory must be owned by root, and have the 't' bit set.
5416 * It also must not be writable by "other".
5419 #ifdef S_ISVTX
5420 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
5421 #else
5422 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
5423 #endif
5424 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
5425 "or does not have the sticky bit 't' set or is writable by anyone.\n",
5426 usersharepath ));
5427 return ret;
5430 /* Ensure the template share exists if it's set. */
5431 if (Globals.szUsershareTemplateShare[0]) {
5432 /* We can't use lp_servicenumber here as we are recommending that
5433 template shares have -valid=False set. */
5434 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
5435 if (ServicePtrs[snum_template]->szService &&
5436 strequal(ServicePtrs[snum_template]->szService,
5437 Globals.szUsershareTemplateShare)) {
5438 break;
5442 if (snum_template == -1) {
5443 DEBUG(0,("load_usershare_shares: usershare template share %s "
5444 "does not exist.\n",
5445 Globals.szUsershareTemplateShare ));
5446 return ret;
5450 /* Mark all existing usershares as pending delete. */
5451 for (iService = iNumServices - 1; iService >= 0; iService--) {
5452 if (VALID(iService) && ServicePtrs[iService]->usershare) {
5453 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
5457 dp = sys_opendir(usersharepath);
5458 if (!dp) {
5459 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
5460 usersharepath, strerror(errno) ));
5461 return ret;
5464 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
5465 (de = sys_readdir(dp));
5466 num_dir_entries++ ) {
5467 int r;
5468 const char *n = de->d_name;
5470 /* Ignore . and .. */
5471 if (*n == '.') {
5472 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
5473 continue;
5477 if (n[0] == ':') {
5478 /* Temporary file used when creating a share. */
5479 num_tmp_dir_entries++;
5482 /* Allow 20% tmp entries. */
5483 if (num_tmp_dir_entries > allowed_tmp_entries) {
5484 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
5485 "in directory %s\n",
5486 num_tmp_dir_entries, usersharepath));
5487 break;
5490 r = process_usershare_file(usersharepath, n, snum_template);
5491 if (r == 0) {
5492 /* Update the services count. */
5493 num_usershares++;
5494 if (num_usershares >= max_user_shares) {
5495 DEBUG(0,("load_usershare_shares: max user shares reached "
5496 "on file %s in directory %s\n",
5497 n, usersharepath ));
5498 break;
5500 } else if (r == -1) {
5501 num_bad_dir_entries++;
5504 /* Allow 20% bad entries. */
5505 if (num_bad_dir_entries > allowed_bad_entries) {
5506 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
5507 "in directory %s\n",
5508 num_bad_dir_entries, usersharepath));
5509 break;
5512 /* Allow 20% bad entries. */
5513 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
5514 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
5515 "in directory %s\n",
5516 num_dir_entries, usersharepath));
5517 break;
5521 sys_closedir(dp);
5523 /* Sweep through and delete any non-refreshed usershares that are
5524 not currently in use. */
5525 for (iService = iNumServices - 1; iService >= 0; iService--) {
5526 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
5527 if (conn_snum_used(iService)) {
5528 continue;
5530 /* Remove from the share ACL db. */
5531 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
5532 lp_servicename(iService) ));
5533 delete_share_security(lp_servicename(iService));
5534 free_service_byindex(iService);
5538 return lp_numservices();
5541 /********************************************************
5542 Destroy global resources allocated in this file
5543 ********************************************************/
5545 void gfree_loadparm(void)
5547 struct file_lists *f;
5548 struct file_lists *next;
5549 int i;
5551 /* Free the file lists */
5553 f = file_lists;
5554 while( f ) {
5555 next = f->next;
5556 SAFE_FREE( f->name );
5557 SAFE_FREE( f->subfname );
5558 SAFE_FREE( f );
5559 f = next;
5562 /* Free resources allocated to services */
5564 for ( i = 0; i < iNumServices; i++ ) {
5565 if ( VALID(i) ) {
5566 free_service_byindex(i);
5570 SAFE_FREE( ServicePtrs );
5571 iNumServices = 0;
5573 /* Now release all resources allocated to global
5574 parameters and the default service */
5576 for (i = 0; parm_table[i].label; i++)
5578 if ( parm_table[i].type == P_STRING
5579 || parm_table[i].type == P_USTRING )
5581 string_free( (char**)parm_table[i].ptr );
5583 else if (parm_table[i].type == P_LIST) {
5584 str_list_free( (char***)parm_table[i].ptr );
5589 /***************************************************************************
5590 Load the services array from the services file. Return True on success,
5591 False on failure.
5592 ***************************************************************************/
5594 bool lp_load(const char *pszFname,
5595 bool global_only,
5596 bool save_defaults,
5597 bool add_ipc,
5598 bool initialize_globals)
5600 pstring n2;
5601 bool bRetval;
5602 param_opt_struct *data, *pdata;
5604 pstrcpy(n2, pszFname);
5606 standard_sub_basic( get_current_username(), current_user_info.domain,
5607 n2,sizeof(n2) );
5609 add_to_file_list(pszFname, n2);
5611 bRetval = False;
5613 DEBUG(3, ("lp_load: refreshing parameters\n"));
5615 bInGlobalSection = True;
5616 bGlobalOnly = global_only;
5618 init_globals(! initialize_globals);
5619 debug_init();
5621 if (save_defaults) {
5622 init_locals();
5623 lp_save_defaults();
5626 if (Globals.param_opt != NULL) {
5627 data = Globals.param_opt;
5628 while (data) {
5629 string_free(&data->key);
5630 string_free(&data->value);
5631 str_list_free(&data->list);
5632 pdata = data->next;
5633 SAFE_FREE(data);
5634 data = pdata;
5636 Globals.param_opt = NULL;
5639 /* We get sections first, so have to start 'behind' to make up */
5640 iServiceIndex = -1;
5641 bRetval = pm_process(n2, do_section, do_parameter);
5643 /* finish up the last section */
5644 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5645 if (bRetval)
5646 if (iServiceIndex >= 0)
5647 bRetval = service_ok(iServiceIndex);
5649 lp_add_auto_services(lp_auto_services());
5651 if (add_ipc) {
5652 /* When 'restrict anonymous = 2' guest connections to ipc$
5653 are denied */
5654 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5655 if ( lp_enable_asu_support() )
5656 lp_add_ipc("ADMIN$", False);
5659 set_server_role();
5660 set_default_server_announce_type();
5661 set_allowed_client_auth();
5663 bLoaded = True;
5665 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5666 /* if bWINSsupport is true and we are in the client */
5667 if (in_client && Globals.bWINSsupport) {
5668 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5671 init_iconv();
5673 return (bRetval);
5676 /***************************************************************************
5677 Reset the max number of services.
5678 ***************************************************************************/
5680 void lp_resetnumservices(void)
5682 iNumServices = 0;
5685 /***************************************************************************
5686 Return the max number of services.
5687 ***************************************************************************/
5689 int lp_numservices(void)
5691 return (iNumServices);
5694 /***************************************************************************
5695 Display the contents of the services array in human-readable form.
5696 ***************************************************************************/
5698 void lp_dump(FILE *f, bool show_defaults, int maxtoprint)
5700 int iService;
5702 if (show_defaults)
5703 defaults_saved = False;
5705 dump_globals(f);
5707 dump_a_service(&sDefault, f);
5709 for (iService = 0; iService < maxtoprint; iService++) {
5710 fprintf(f,"\n");
5711 lp_dump_one(f, show_defaults, iService);
5715 /***************************************************************************
5716 Display the contents of one service in human-readable form.
5717 ***************************************************************************/
5719 void lp_dump_one(FILE * f, bool show_defaults, int snum)
5721 if (VALID(snum)) {
5722 if (ServicePtrs[snum]->szService[0] == '\0')
5723 return;
5724 dump_a_service(ServicePtrs[snum], f);
5728 /***************************************************************************
5729 Return the number of the service with the given name, or -1 if it doesn't
5730 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5731 getservicebyname()! This works ONLY if all services have been loaded, and
5732 does not copy the found service.
5733 ***************************************************************************/
5735 int lp_servicenumber(const char *pszServiceName)
5737 int iService;
5738 fstring serviceName;
5740 if (!pszServiceName) {
5741 return GLOBAL_SECTION_SNUM;
5744 for (iService = iNumServices - 1; iService >= 0; iService--) {
5745 if (VALID(iService) && ServicePtrs[iService]->szService) {
5747 * The substitution here is used to support %U is
5748 * service names
5750 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5751 standard_sub_basic(get_current_username(),
5752 current_user_info.domain,
5753 serviceName,sizeof(serviceName));
5754 if (strequal(serviceName, pszServiceName)) {
5755 break;
5760 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5761 time_t last_mod;
5763 if (!usershare_exists(iService, &last_mod)) {
5764 /* Remove the share security tdb entry for it. */
5765 delete_share_security(lp_servicename(iService));
5766 /* Remove it from the array. */
5767 free_service_byindex(iService);
5768 /* Doesn't exist anymore. */
5769 return GLOBAL_SECTION_SNUM;
5772 /* Has it been modified ? If so delete and reload. */
5773 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5774 /* Remove it from the array. */
5775 free_service_byindex(iService);
5776 /* and now reload it. */
5777 iService = load_usershare_service(pszServiceName);
5781 if (iService < 0) {
5782 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5783 return GLOBAL_SECTION_SNUM;
5786 return (iService);
5789 bool share_defined(const char *service_name)
5791 return (lp_servicenumber(service_name) != -1);
5794 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5795 const char *sharename)
5797 struct share_params *result;
5798 char *sname;
5799 int snum;
5801 if (!(sname = SMB_STRDUP(sharename))) {
5802 return NULL;
5805 snum = find_service(sname);
5806 SAFE_FREE(sname);
5808 if (snum < 0) {
5809 return NULL;
5812 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5813 DEBUG(0, ("talloc failed\n"));
5814 return NULL;
5817 result->service = snum;
5818 return result;
5821 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5823 struct share_iterator *result;
5825 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5826 DEBUG(0, ("talloc failed\n"));
5827 return NULL;
5830 result->next_id = 0;
5831 return result;
5834 struct share_params *next_share(struct share_iterator *list)
5836 struct share_params *result;
5838 while (!lp_snum_ok(list->next_id) &&
5839 (list->next_id < lp_numservices())) {
5840 list->next_id += 1;
5843 if (list->next_id >= lp_numservices()) {
5844 return NULL;
5847 if (!(result = TALLOC_P(list, struct share_params))) {
5848 DEBUG(0, ("talloc failed\n"));
5849 return NULL;
5852 result->service = list->next_id;
5853 list->next_id += 1;
5854 return result;
5857 struct share_params *next_printer(struct share_iterator *list)
5859 struct share_params *result;
5861 while ((result = next_share(list)) != NULL) {
5862 if (lp_print_ok(result->service)) {
5863 break;
5866 return result;
5870 * This is a hack for a transition period until we transformed all code from
5871 * service numbers to struct share_params.
5874 struct share_params *snum2params_static(int snum)
5876 static struct share_params result;
5877 result.service = snum;
5878 return &result;
5881 /*******************************************************************
5882 A useful volume label function.
5883 ********************************************************************/
5885 const char *volume_label(int snum)
5887 char *ret;
5888 const char *label = lp_volume(snum);
5889 if (!*label) {
5890 label = lp_servicename(snum);
5893 /* This returns a 33 byte guarenteed null terminated string. */
5894 ret = talloc_strndup(talloc_tos(), label, 32);
5895 if (!ret) {
5896 return "";
5898 return ret;
5901 /*******************************************************************
5902 Set the server type we will announce as via nmbd.
5903 ********************************************************************/
5905 static void set_default_server_announce_type(void)
5907 default_server_announce = 0;
5908 default_server_announce |= SV_TYPE_WORKSTATION;
5909 default_server_announce |= SV_TYPE_SERVER;
5910 default_server_announce |= SV_TYPE_SERVER_UNIX;
5912 /* note that the flag should be set only if we have a
5913 printer service but nmbd doesn't actually load the
5914 services so we can't tell --jerry */
5916 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5918 switch (lp_announce_as()) {
5919 case ANNOUNCE_AS_NT_SERVER:
5920 default_server_announce |= SV_TYPE_SERVER_NT;
5921 /* fall through... */
5922 case ANNOUNCE_AS_NT_WORKSTATION:
5923 default_server_announce |= SV_TYPE_NT;
5924 break;
5925 case ANNOUNCE_AS_WIN95:
5926 default_server_announce |= SV_TYPE_WIN95_PLUS;
5927 break;
5928 case ANNOUNCE_AS_WFW:
5929 default_server_announce |= SV_TYPE_WFW;
5930 break;
5931 default:
5932 break;
5935 switch (lp_server_role()) {
5936 case ROLE_DOMAIN_MEMBER:
5937 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5938 break;
5939 case ROLE_DOMAIN_PDC:
5940 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5941 break;
5942 case ROLE_DOMAIN_BDC:
5943 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5944 break;
5945 case ROLE_STANDALONE:
5946 default:
5947 break;
5949 if (lp_time_server())
5950 default_server_announce |= SV_TYPE_TIME_SOURCE;
5952 if (lp_host_msdfs())
5953 default_server_announce |= SV_TYPE_DFS_SERVER;
5956 /***********************************************************
5957 returns role of Samba server
5958 ************************************************************/
5960 int lp_server_role(void)
5962 return server_role;
5965 /***********************************************************
5966 If we are PDC then prefer us as DMB
5967 ************************************************************/
5969 bool lp_domain_master(void)
5971 if (Globals.iDomainMaster == Auto)
5972 return (lp_server_role() == ROLE_DOMAIN_PDC);
5974 return (bool)Globals.iDomainMaster;
5977 /***********************************************************
5978 If we are DMB then prefer us as LMB
5979 ************************************************************/
5981 bool lp_preferred_master(void)
5983 if (Globals.iPreferredMaster == Auto)
5984 return (lp_local_master() && lp_domain_master());
5986 return (bool)Globals.iPreferredMaster;
5989 /*******************************************************************
5990 Remove a service.
5991 ********************************************************************/
5993 void lp_remove_service(int snum)
5995 ServicePtrs[snum]->valid = False;
5996 invalid_services[num_invalid_services++] = snum;
5999 /*******************************************************************
6000 Copy a service.
6001 ********************************************************************/
6003 void lp_copy_service(int snum, const char *new_name)
6005 do_section(new_name);
6006 if (snum >= 0) {
6007 snum = lp_servicenumber(new_name);
6008 if (snum >= 0)
6009 lp_do_parameter(snum, "copy", lp_servicename(snum));
6014 /*******************************************************************
6015 Get the default server type we will announce as via nmbd.
6016 ********************************************************************/
6018 int lp_default_server_announce(void)
6020 return default_server_announce;
6023 /*******************************************************************
6024 Split the announce version into major and minor numbers.
6025 ********************************************************************/
6027 int lp_major_announce_version(void)
6029 static bool got_major = False;
6030 static int major_version = DEFAULT_MAJOR_VERSION;
6031 char *vers;
6032 char *p;
6034 if (got_major)
6035 return major_version;
6037 got_major = True;
6038 if ((vers = lp_announce_version()) == NULL)
6039 return major_version;
6041 if ((p = strchr_m(vers, '.')) == 0)
6042 return major_version;
6044 *p = '\0';
6045 major_version = atoi(vers);
6046 return major_version;
6049 int lp_minor_announce_version(void)
6051 static bool got_minor = False;
6052 static int minor_version = DEFAULT_MINOR_VERSION;
6053 char *vers;
6054 char *p;
6056 if (got_minor)
6057 return minor_version;
6059 got_minor = True;
6060 if ((vers = lp_announce_version()) == NULL)
6061 return minor_version;
6063 if ((p = strchr_m(vers, '.')) == 0)
6064 return minor_version;
6066 p++;
6067 minor_version = atoi(p);
6068 return minor_version;
6071 /***********************************************************
6072 Set the global name resolution order (used in smbclient).
6073 ************************************************************/
6075 void lp_set_name_resolve_order(const char *new_order)
6077 string_set(&Globals.szNameResolveOrder, new_order);
6080 const char *lp_printername(int snum)
6082 const char *ret = _lp_printername(snum);
6083 if (ret == NULL || (ret != NULL && *ret == '\0'))
6084 ret = lp_const_servicename(snum);
6086 return ret;
6090 /***********************************************************
6091 Allow daemons such as winbindd to fix their logfile name.
6092 ************************************************************/
6094 void lp_set_logfile(const char *name)
6096 string_set(&Globals.szLogFile, name);
6097 pstrcpy(debugf, name);
6100 /*******************************************************************
6101 Return the max print jobs per queue.
6102 ********************************************************************/
6104 int lp_maxprintjobs(int snum)
6106 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
6107 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
6108 maxjobs = PRINT_MAX_JOBID - 1;
6110 return maxjobs;
6113 const char *lp_printcapname(void)
6115 if ((Globals.szPrintcapname != NULL) &&
6116 (Globals.szPrintcapname[0] != '\0'))
6117 return Globals.szPrintcapname;
6119 if (sDefault.iPrinting == PRINT_CUPS) {
6120 #ifdef HAVE_CUPS
6121 return "cups";
6122 #else
6123 return "lpstat";
6124 #endif
6127 if (sDefault.iPrinting == PRINT_BSD)
6128 return "/etc/printcap";
6130 return PRINTCAP_NAME;
6133 /*******************************************************************
6134 Ensure we don't use sendfile if server smb signing is active.
6135 ********************************************************************/
6137 static uint32 spoolss_state;
6139 bool lp_disable_spoolss( void )
6141 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
6142 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
6144 return spoolss_state == SVCCTL_STOPPED ? True : False;
6147 void lp_set_spoolss_state( uint32 state )
6149 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
6151 spoolss_state = state;
6154 uint32 lp_get_spoolss_state( void )
6156 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
6159 /*******************************************************************
6160 Ensure we don't use sendfile if server smb signing is active.
6161 ********************************************************************/
6163 bool lp_use_sendfile(int snum)
6165 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
6166 if (Protocol < PROTOCOL_NT1) {
6167 return False;
6169 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
6172 /*******************************************************************
6173 Turn off sendfile if we find the underlying OS doesn't support it.
6174 ********************************************************************/
6176 void set_use_sendfile(int snum, bool val)
6178 if (LP_SNUM_OK(snum))
6179 ServicePtrs[snum]->bUseSendfile = val;
6180 else
6181 sDefault.bUseSendfile = val;
6184 /*******************************************************************
6185 Turn off storing DOS attributes if this share doesn't support it.
6186 ********************************************************************/
6188 void set_store_dos_attributes(int snum, bool val)
6190 if (!LP_SNUM_OK(snum))
6191 return;
6192 ServicePtrs[(snum)]->bStoreDosAttributes = val;
6195 void lp_set_mangling_method(const char *new_method)
6197 string_set(&Globals.szManglingMethod, new_method);
6200 /*******************************************************************
6201 Global state for POSIX pathname processing.
6202 ********************************************************************/
6204 static bool posix_pathnames;
6206 bool lp_posix_pathnames(void)
6208 return posix_pathnames;
6211 /*******************************************************************
6212 Change everything needed to ensure POSIX pathname processing (currently
6213 not much).
6214 ********************************************************************/
6216 void lp_set_posix_pathnames(void)
6218 posix_pathnames = True;
6221 /*******************************************************************
6222 Global state for POSIX lock processing - CIFS unix extensions.
6223 ********************************************************************/
6225 bool posix_default_lock_was_set;
6226 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
6228 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
6230 if (posix_default_lock_was_set) {
6231 return posix_cifsx_locktype;
6232 } else {
6233 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
6237 /*******************************************************************
6238 ********************************************************************/
6240 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
6242 posix_default_lock_was_set = True;
6243 posix_cifsx_locktype = val;