r23472: add missing default setting for 'winbind nss info' (merge from 3.0.26)
[Samba.git] / source / param / loadparm.c
blob27357868da313d0df772a4fb9de61f7ec98c73df
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 2 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, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 * Load parameters.
31 * This module provides suitable callback functions for the params
32 * module. It builds the internal table of service details which is
33 * then used by the rest of the server.
35 * To add a parameter:
37 * 1) add it to the global or service structure definition
38 * 2) add it to the parm_table
39 * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
40 * 4) If it's a global then initialise it in init_globals. If a local
41 * (ie. service) parameter then initialise it in the sDefault structure
44 * Notes:
45 * The configuration file is processed sequentially for speed. It is NOT
46 * accessed randomly as happens in 'real' Windows. For this reason, there
47 * is a fair bit of sequence-dependent code here - ie., code which assumes
48 * that certain things happen before others. In particular, the code which
49 * happens at the boundary between sections is delicately poised, so be
50 * careful!
54 #include "includes.h"
56 BOOL in_client = False; /* Not in the client by default */
57 BOOL bLoaded = False;
59 extern pstring user_socket_options;
60 extern enum protocol_types Protocol;
61 extern userdom_struct current_user_info;
63 #ifndef GLOBAL_NAME
64 #define GLOBAL_NAME "global"
65 #endif
67 #ifndef PRINTERS_NAME
68 #define PRINTERS_NAME "printers"
69 #endif
71 #ifndef HOMES_NAME
72 #define HOMES_NAME "homes"
73 #endif
75 /* some helpful bits */
76 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
77 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
79 #define USERSHARE_VALID 1
80 #define USERSHARE_PENDING_DELETE 2
82 BOOL use_getwd_cache = True;
84 extern int extra_time_offset;
86 static BOOL defaults_saved = False;
88 typedef struct _param_opt_struct param_opt_struct;
89 struct _param_opt_struct {
90 param_opt_struct *prev, *next;
91 char *key;
92 char *value;
93 char **list;
96 /*
97 * This structure describes global (ie., server-wide) parameters.
99 typedef struct {
100 char *smb_ports;
101 char *dos_charset;
102 char *unix_charset;
103 char *display_charset;
104 char *szPrintcapname;
105 char *szAddPortCommand;
106 char *szEnumPortsCommand;
107 char *szAddPrinterCommand;
108 char *szDeletePrinterCommand;
109 char *szOs2DriverMap;
110 char *szLockDir;
111 char *szPidDir;
112 char *szRootdir;
113 char *szDefaultService;
114 char *szGetQuota;
115 char *szSetQuota;
116 char *szMsgCommand;
117 char *szServerString;
118 char *szAutoServices;
119 char *szPasswdProgram;
120 char *szPasswdChat;
121 char *szLogFile;
122 char *szConfigFile;
123 char *szSMBPasswdFile;
124 char *szPrivateDir;
125 char *szPassdbBackend;
126 char **szPreloadModules;
127 char *szPasswordServer;
128 char *szSocketOptions;
129 char *szRealm;
130 char *szAfsUsernameMap;
131 int iAfsTokenLifetime;
132 char *szLogNtTokenCommand;
133 char *szUsernameMap;
134 char *szLogonScript;
135 char *szLogonPath;
136 char *szLogonDrive;
137 char *szLogonHome;
138 char **szWINSservers;
139 char **szInterfaces;
140 char *szRemoteAnnounce;
141 char *szRemoteBrowseSync;
142 char *szSocketAddress;
143 char *szNISHomeMapName;
144 char *szAnnounceVersion; /* This is initialised in init_globals */
145 char *szWorkgroup;
146 char *szNetbiosName;
147 char **szNetbiosAliases;
148 char *szNetbiosScope;
149 char *szNameResolveOrder;
150 char *szPanicAction;
151 char *szAddUserScript;
152 char *szRenameUserScript;
153 char *szDelUserScript;
154 char *szAddGroupScript;
155 char *szDelGroupScript;
156 char *szAddUserToGroupScript;
157 char *szDelUserFromGroupScript;
158 char *szSetPrimaryGroupScript;
159 char *szAddMachineScript;
160 char *szShutdownScript;
161 char *szAbortShutdownScript;
162 char *szUsernameMapScript;
163 char *szCheckPasswordScript;
164 char *szWINSHook;
165 char *szUtmpDir;
166 char *szWtmpDir;
167 BOOL bUtmp;
168 char *szIdmapUID;
169 char *szIdmapGID;
170 BOOL bPassdbExpandExplicit;
171 int AlgorithmicRidBase;
172 char *szTemplateHomedir;
173 char *szTemplateShell;
174 char *szWinbindSeparator;
175 BOOL bWinbindEnumUsers;
176 BOOL bWinbindEnumGroups;
177 BOOL bWinbindUseDefaultDomain;
178 BOOL bWinbindTrustedDomainsOnly;
179 BOOL bWinbindNestedGroups;
180 int winbind_expand_groups;
181 BOOL bWinbindRefreshTickets;
182 BOOL bWinbindOfflineLogon;
183 BOOL bWinbindNormalizeNames;
184 BOOL bWinbindRpcOnly;
185 char **szIdmapDomains;
186 char **szIdmapBackend; /* deprecated */
187 char *szIdmapAllocBackend;
188 char *szAddShareCommand;
189 char *szChangeShareCommand;
190 char *szDeleteShareCommand;
191 char **szEventLogs;
192 char *szGuestaccount;
193 char *szManglingMethod;
194 char **szServicesList;
195 char *szUsersharePath;
196 char *szUsershareTemplateShare;
197 char **szUsersharePrefixAllowList;
198 char **szUsersharePrefixDenyList;
199 int mangle_prefix;
200 int max_log_size;
201 char *szLogLevel;
202 int max_xmit;
203 int max_mux;
204 int max_open_files;
205 int open_files_db_hash_size;
206 int pwordlevel;
207 int unamelevel;
208 int deadtime;
209 int maxprotocol;
210 int minprotocol;
211 int security;
212 char **AuthMethods;
213 BOOL paranoid_server_security;
214 int maxdisksize;
215 int lpqcachetime;
216 int iMaxSmbdProcesses;
217 BOOL bDisableSpoolss;
218 int syslog;
219 int os_level;
220 int enhanced_browsing;
221 int max_ttl;
222 int max_wins_ttl;
223 int min_wins_ttl;
224 int lm_announce;
225 int lm_interval;
226 int announce_as; /* This is initialised in init_globals */
227 int machine_password_timeout;
228 int map_to_guest;
229 int oplock_break_wait_time;
230 int winbind_cache_time;
231 int winbind_max_idle_children;
232 char **szWinbindNssInfo;
233 int iLockSpinTime;
234 char *szLdapMachineSuffix;
235 char *szLdapUserSuffix;
236 char *szLdapIdmapSuffix;
237 char *szLdapGroupSuffix;
238 int ldap_ssl;
239 char *szLdapSuffix;
240 char *szLdapAdminDn;
241 int iAclCompat;
242 char *szCupsServer;
243 char *szIPrintServer;
244 char *ctdbdSocket;
245 BOOL clustering;
246 int ldap_passwd_sync;
247 int ldap_replication_sleep;
248 int ldap_timeout; /* This is initialised in init_globals */
249 int ldap_page_size;
250 BOOL ldap_delete_dn;
251 BOOL bMsAddPrinterWizard;
252 BOOL bDNSproxy;
253 BOOL bWINSsupport;
254 BOOL bWINSproxy;
255 BOOL bLocalMaster;
256 BOOL bPreferredMaster;
257 BOOL bDomainMaster;
258 BOOL bDomainLogons;
259 BOOL bEncryptPasswords;
260 BOOL bUpdateEncrypt;
261 int clientSchannel;
262 int serverSchannel;
263 BOOL bNullPasswords;
264 BOOL bObeyPamRestrictions;
265 BOOL bLoadPrinters;
266 int PrintcapCacheTime;
267 BOOL bLargeReadwrite;
268 BOOL bReadRaw;
269 BOOL bWriteRaw;
270 BOOL bReadbmpx;
271 BOOL bSyslogOnly;
272 BOOL bBrowseList;
273 BOOL bNISHomeMap;
274 BOOL bTimeServer;
275 BOOL bBindInterfacesOnly;
276 BOOL bPamPasswordChange;
277 BOOL bUnixPasswdSync;
278 BOOL bPasswdChatDebug;
279 int iPasswdChatTimeout;
280 BOOL bTimestampLogs;
281 BOOL bNTSmbSupport;
282 BOOL bNTPipeSupport;
283 BOOL bNTStatusSupport;
284 BOOL bStatCache;
285 int iMaxStatCacheSize;
286 BOOL bKernelOplocks;
287 BOOL bAllowTrustedDomains;
288 BOOL bLanmanAuth;
289 BOOL bNTLMAuth;
290 BOOL bUseSpnego;
291 BOOL bClientLanManAuth;
292 BOOL bClientNTLMv2Auth;
293 BOOL bClientPlaintextAuth;
294 BOOL bClientUseSpnego;
295 BOOL bDebugPrefixTimestamp;
296 BOOL bDebugHiresTimestamp;
297 BOOL bDebugPid;
298 BOOL bDebugUid;
299 BOOL bEnableCoreFiles;
300 BOOL bHostMSDfs;
301 BOOL bUseMmap;
302 BOOL bHostnameLookups;
303 BOOL bUnixExtensions;
304 BOOL bDisableNetbios;
305 BOOL bUseKerberosKeytab;
306 BOOL bDeferSharingViolations;
307 BOOL bEnablePrivileges;
308 BOOL bASUSupport;
309 BOOL bUsershareOwnerOnly;
310 BOOL bUsershareAllowGuests;
311 BOOL bRegistryShares;
312 int restrict_anonymous;
313 int name_cache_timeout;
314 int client_signing;
315 int server_signing;
316 int iUsershareMaxShares;
317 int iIdmapCacheTime;
318 int iIdmapNegativeCacheTime;
320 BOOL bResetOnZeroVC;
321 int iKeepalive;
322 param_opt_struct *param_opt;
323 } global;
325 static global Globals;
328 * This structure describes a single service.
330 typedef struct {
331 BOOL valid;
332 BOOL autoloaded;
333 int usershare;
334 time_t usershare_last_mod;
335 char *szService;
336 char *szPath;
337 char *szUsername;
338 char **szInvalidUsers;
339 char **szValidUsers;
340 char **szAdminUsers;
341 char *szCopy;
342 char *szInclude;
343 char *szPreExec;
344 char *szPostExec;
345 char *szRootPreExec;
346 char *szRootPostExec;
347 char *szCupsOptions;
348 char *szPrintcommand;
349 char *szLpqcommand;
350 char *szLprmcommand;
351 char *szLppausecommand;
352 char *szLpresumecommand;
353 char *szQueuepausecommand;
354 char *szQueueresumecommand;
355 char *szPrintername;
356 char *szPrintjobUsername;
357 char *szDontdescend;
358 char **szHostsallow;
359 char **szHostsdeny;
360 char *szMagicScript;
361 char *szMagicOutput;
362 char *szMangledMap;
363 char *szVetoFiles;
364 char *szHideFiles;
365 char *szVetoOplockFiles;
366 char *comment;
367 char *force_user;
368 char *force_group;
369 char **readlist;
370 char **writelist;
371 char **printer_admin;
372 char *volume;
373 char *fstype;
374 char **szVfsObjects;
375 char *szMSDfsProxy;
376 char *szDfree;
377 int iMinPrintSpace;
378 int iMaxPrintJobs;
379 int iMaxReportedPrintJobs;
380 int iWriteCacheSize;
381 int iCreate_mask;
382 int iCreate_force_mode;
383 int iSecurity_mask;
384 int iSecurity_force_mode;
385 int iDir_mask;
386 int iDir_force_mode;
387 int iDir_Security_mask;
388 int iDir_Security_force_mode;
389 int iMaxConnections;
390 int iDefaultCase;
391 int iPrinting;
392 int iOplockContentionLimit;
393 int iCSCPolicy;
394 int iBlock_size;
395 int iDfreeCacheTime;
396 BOOL bPreexecClose;
397 BOOL bRootpreexecClose;
398 int iCaseSensitive;
399 BOOL bCasePreserve;
400 BOOL bShortCasePreserve;
401 BOOL bHideDotFiles;
402 BOOL bHideSpecialFiles;
403 BOOL bHideUnReadable;
404 BOOL bHideUnWriteableFiles;
405 BOOL bBrowseable;
406 BOOL bAvailable;
407 BOOL bRead_only;
408 BOOL bNo_set_dir;
409 BOOL bGuest_only;
410 BOOL bGuest_ok;
411 BOOL bPrint_ok;
412 BOOL bMap_system;
413 BOOL bMap_hidden;
414 BOOL bMap_archive;
415 BOOL bStoreDosAttributes;
416 BOOL bDmapiSupport;
417 BOOL bLocking;
418 int iStrictLocking;
419 BOOL bPosixLocking;
420 BOOL bShareModes;
421 BOOL bOpLocks;
422 BOOL bLevel2OpLocks;
423 BOOL bOnlyUser;
424 BOOL bMangledNames;
425 BOOL bWidelinks;
426 BOOL bSymlinks;
427 BOOL bSyncAlways;
428 BOOL bStrictAllocate;
429 BOOL bStrictSync;
430 char magic_char;
431 BOOL *copymap;
432 BOOL bDeleteReadonly;
433 BOOL bFakeOplocks;
434 BOOL bDeleteVetoFiles;
435 BOOL bDosFilemode;
436 BOOL bDosFiletimes;
437 BOOL bDosFiletimeResolution;
438 BOOL bFakeDirCreateTimes;
439 BOOL bBlockingLocks;
440 BOOL bInheritPerms;
441 BOOL bInheritACLS;
442 BOOL bInheritOwner;
443 BOOL bMSDfsRoot;
444 BOOL bUseClientDriver;
445 BOOL bDefaultDevmode;
446 BOOL bForcePrintername;
447 BOOL bNTAclSupport;
448 BOOL bForceUnknownAclUser;
449 BOOL bUseSendfile;
450 BOOL bProfileAcls;
451 BOOL bMap_acl_inherit;
452 BOOL bAfs_Share;
453 BOOL bEASupport;
454 BOOL bAclCheckPermissions;
455 BOOL bAclMapFullControl;
456 BOOL bAclGroupControl;
457 BOOL bChangeNotify;
458 BOOL bKernelChangeNotify;
459 int iallocation_roundup_size;
460 int iAioReadSize;
461 int iAioWriteSize;
462 int iMap_readonly;
463 param_opt_struct *param_opt;
465 char dummy[3]; /* for alignment */
466 } service;
469 /* This is a default service used to prime a services structure */
470 static service sDefault = {
471 True, /* valid */
472 False, /* not autoloaded */
473 0, /* not a usershare */
474 (time_t)0, /* No last mod time */
475 NULL, /* szService */
476 NULL, /* szPath */
477 NULL, /* szUsername */
478 NULL, /* szInvalidUsers */
479 NULL, /* szValidUsers */
480 NULL, /* szAdminUsers */
481 NULL, /* szCopy */
482 NULL, /* szInclude */
483 NULL, /* szPreExec */
484 NULL, /* szPostExec */
485 NULL, /* szRootPreExec */
486 NULL, /* szRootPostExec */
487 NULL, /* szCupsOptions */
488 NULL, /* szPrintcommand */
489 NULL, /* szLpqcommand */
490 NULL, /* szLprmcommand */
491 NULL, /* szLppausecommand */
492 NULL, /* szLpresumecommand */
493 NULL, /* szQueuepausecommand */
494 NULL, /* szQueueresumecommand */
495 NULL, /* szPrintername */
496 NULL, /* szPrintjobUsername */
497 NULL, /* szDontdescend */
498 NULL, /* szHostsallow */
499 NULL, /* szHostsdeny */
500 NULL, /* szMagicScript */
501 NULL, /* szMagicOutput */
502 NULL, /* szMangledMap */
503 NULL, /* szVetoFiles */
504 NULL, /* szHideFiles */
505 NULL, /* szVetoOplockFiles */
506 NULL, /* comment */
507 NULL, /* force user */
508 NULL, /* force group */
509 NULL, /* readlist */
510 NULL, /* writelist */
511 NULL, /* printer admin */
512 NULL, /* volume */
513 NULL, /* fstype */
514 NULL, /* vfs objects */
515 NULL, /* szMSDfsProxy */
516 NULL, /* szDfree */
517 0, /* iMinPrintSpace */
518 1000, /* iMaxPrintJobs */
519 0, /* iMaxReportedPrintJobs */
520 0, /* iWriteCacheSize */
521 0744, /* iCreate_mask */
522 0000, /* iCreate_force_mode */
523 0777, /* iSecurity_mask */
524 0, /* iSecurity_force_mode */
525 0755, /* iDir_mask */
526 0000, /* iDir_force_mode */
527 0777, /* iDir_Security_mask */
528 0, /* iDir_Security_force_mode */
529 0, /* iMaxConnections */
530 CASE_LOWER, /* iDefaultCase */
531 DEFAULT_PRINTING, /* iPrinting */
532 2, /* iOplockContentionLimit */
533 0, /* iCSCPolicy */
534 1024, /* iBlock_size */
535 0, /* iDfreeCacheTime */
536 False, /* bPreexecClose */
537 False, /* bRootpreexecClose */
538 Auto, /* case sensitive */
539 True, /* case preserve */
540 True, /* short case preserve */
541 True, /* bHideDotFiles */
542 False, /* bHideSpecialFiles */
543 False, /* bHideUnReadable */
544 False, /* bHideUnWriteableFiles */
545 True, /* bBrowseable */
546 True, /* bAvailable */
547 True, /* bRead_only */
548 True, /* bNo_set_dir */
549 False, /* bGuest_only */
550 False, /* bGuest_ok */
551 False, /* bPrint_ok */
552 False, /* bMap_system */
553 False, /* bMap_hidden */
554 True, /* bMap_archive */
555 False, /* bStoreDosAttributes */
556 False, /* bDmapiSupport */
557 True, /* bLocking */
558 Auto, /* iStrictLocking */
559 True, /* bPosixLocking */
560 True, /* bShareModes */
561 True, /* bOpLocks */
562 True, /* bLevel2OpLocks */
563 False, /* bOnlyUser */
564 True, /* bMangledNames */
565 True, /* bWidelinks */
566 True, /* bSymlinks */
567 False, /* bSyncAlways */
568 False, /* bStrictAllocate */
569 False, /* bStrictSync */
570 '~', /* magic char */
571 NULL, /* copymap */
572 False, /* bDeleteReadonly */
573 False, /* bFakeOplocks */
574 False, /* bDeleteVetoFiles */
575 False, /* bDosFilemode */
576 True, /* bDosFiletimes */
577 False, /* bDosFiletimeResolution */
578 False, /* bFakeDirCreateTimes */
579 True, /* bBlockingLocks */
580 False, /* bInheritPerms */
581 False, /* bInheritACLS */
582 False, /* bInheritOwner */
583 False, /* bMSDfsRoot */
584 False, /* bUseClientDriver */
585 True, /* bDefaultDevmode */
586 False, /* bForcePrintername */
587 True, /* bNTAclSupport */
588 False, /* bForceUnknownAclUser */
589 False, /* bUseSendfile */
590 False, /* bProfileAcls */
591 False, /* bMap_acl_inherit */
592 False, /* bAfs_Share */
593 False, /* bEASupport */
594 True, /* bAclCheckPermissions */
595 True, /* bAclMapFullControl */
596 False, /* bAclGroupControl */
597 True, /* bChangeNotify */
598 True, /* bKernelChangeNotify */
599 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
600 0, /* iAioReadSize */
601 0, /* iAioWriteSize */
602 MAP_READONLY_YES, /* iMap_readonly */
604 NULL, /* Parametric options */
606 "" /* dummy */
609 /* local variables */
610 static service **ServicePtrs = NULL;
611 static int iNumServices = 0;
612 static int iServiceIndex = 0;
613 static TDB_CONTEXT *ServiceHash;
614 static int *invalid_services = NULL;
615 static int num_invalid_services = 0;
616 static BOOL bInGlobalSection = True;
617 static BOOL bGlobalOnly = False;
618 static int server_role;
619 static int default_server_announce;
621 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
623 /* prototypes for the special type handlers */
624 static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
625 static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
626 static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
627 static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
628 static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
629 static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
630 static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
631 static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
632 static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
633 static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
634 static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
636 static void set_server_role(void);
637 static void set_default_server_announce_type(void);
638 static void set_allowed_client_auth(void);
640 static const struct enum_list enum_protocol[] = {
641 {PROTOCOL_NT1, "NT1"},
642 {PROTOCOL_LANMAN2, "LANMAN2"},
643 {PROTOCOL_LANMAN1, "LANMAN1"},
644 {PROTOCOL_CORE, "CORE"},
645 {PROTOCOL_COREPLUS, "COREPLUS"},
646 {PROTOCOL_COREPLUS, "CORE+"},
647 {-1, NULL}
650 static const struct enum_list enum_security[] = {
651 {SEC_SHARE, "SHARE"},
652 {SEC_USER, "USER"},
653 {SEC_SERVER, "SERVER"},
654 {SEC_DOMAIN, "DOMAIN"},
655 #ifdef HAVE_ADS
656 {SEC_ADS, "ADS"},
657 #endif
658 {-1, NULL}
661 static const struct enum_list enum_printing[] = {
662 {PRINT_SYSV, "sysv"},
663 {PRINT_AIX, "aix"},
664 {PRINT_HPUX, "hpux"},
665 {PRINT_BSD, "bsd"},
666 {PRINT_QNX, "qnx"},
667 {PRINT_PLP, "plp"},
668 {PRINT_LPRNG, "lprng"},
669 {PRINT_CUPS, "cups"},
670 {PRINT_IPRINT, "iprint"},
671 {PRINT_LPRNT, "nt"},
672 {PRINT_LPROS2, "os2"},
673 #ifdef DEVELOPER
674 {PRINT_TEST, "test"},
675 {PRINT_VLP, "vlp"},
676 #endif /* DEVELOPER */
677 {-1, NULL}
680 static const struct enum_list enum_ldap_ssl[] = {
681 {LDAP_SSL_OFF, "no"},
682 {LDAP_SSL_OFF, "No"},
683 {LDAP_SSL_OFF, "off"},
684 {LDAP_SSL_OFF, "Off"},
685 {LDAP_SSL_START_TLS, "start tls"},
686 {LDAP_SSL_START_TLS, "Start_tls"},
687 {-1, NULL}
690 static const struct enum_list enum_ldap_passwd_sync[] = {
691 {LDAP_PASSWD_SYNC_OFF, "no"},
692 {LDAP_PASSWD_SYNC_OFF, "No"},
693 {LDAP_PASSWD_SYNC_OFF, "off"},
694 {LDAP_PASSWD_SYNC_OFF, "Off"},
695 {LDAP_PASSWD_SYNC_ON, "Yes"},
696 {LDAP_PASSWD_SYNC_ON, "yes"},
697 {LDAP_PASSWD_SYNC_ON, "on"},
698 {LDAP_PASSWD_SYNC_ON, "On"},
699 {LDAP_PASSWD_SYNC_ONLY, "Only"},
700 {LDAP_PASSWD_SYNC_ONLY, "only"},
701 {-1, NULL}
704 /* Types of machine we can announce as. */
705 #define ANNOUNCE_AS_NT_SERVER 1
706 #define ANNOUNCE_AS_WIN95 2
707 #define ANNOUNCE_AS_WFW 3
708 #define ANNOUNCE_AS_NT_WORKSTATION 4
710 static const struct enum_list enum_announce_as[] = {
711 {ANNOUNCE_AS_NT_SERVER, "NT"},
712 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
713 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
714 {ANNOUNCE_AS_WIN95, "win95"},
715 {ANNOUNCE_AS_WFW, "WfW"},
716 {-1, NULL}
719 static const struct enum_list enum_map_readonly[] = {
720 {MAP_READONLY_NO, "no"},
721 {MAP_READONLY_NO, "false"},
722 {MAP_READONLY_NO, "0"},
723 {MAP_READONLY_YES, "yes"},
724 {MAP_READONLY_YES, "true"},
725 {MAP_READONLY_YES, "1"},
726 {MAP_READONLY_PERMISSIONS, "permissions"},
727 {MAP_READONLY_PERMISSIONS, "perms"},
728 {-1, NULL}
731 static const struct enum_list enum_case[] = {
732 {CASE_LOWER, "lower"},
733 {CASE_UPPER, "upper"},
734 {-1, NULL}
737 static const struct enum_list enum_bool_auto[] = {
738 {False, "No"},
739 {False, "False"},
740 {False, "0"},
741 {True, "Yes"},
742 {True, "True"},
743 {True, "1"},
744 {Auto, "Auto"},
745 {-1, NULL}
748 /* Client-side offline caching policy types */
749 #define CSC_POLICY_MANUAL 0
750 #define CSC_POLICY_DOCUMENTS 1
751 #define CSC_POLICY_PROGRAMS 2
752 #define CSC_POLICY_DISABLE 3
754 static const struct enum_list enum_csc_policy[] = {
755 {CSC_POLICY_MANUAL, "manual"},
756 {CSC_POLICY_DOCUMENTS, "documents"},
757 {CSC_POLICY_PROGRAMS, "programs"},
758 {CSC_POLICY_DISABLE, "disable"},
759 {-1, NULL}
762 /* SMB signing types. */
763 static const struct enum_list enum_smb_signing_vals[] = {
764 {False, "No"},
765 {False, "False"},
766 {False, "0"},
767 {False, "Off"},
768 {False, "disabled"},
769 {True, "Yes"},
770 {True, "True"},
771 {True, "1"},
772 {True, "On"},
773 {True, "enabled"},
774 {Auto, "auto"},
775 {Required, "required"},
776 {Required, "mandatory"},
777 {Required, "force"},
778 {Required, "forced"},
779 {Required, "enforced"},
780 {-1, NULL}
783 /* ACL compatibility options. */
784 static const struct enum_list enum_acl_compat_vals[] = {
785 { ACL_COMPAT_AUTO, "auto" },
786 { ACL_COMPAT_WINNT, "winnt" },
787 { ACL_COMPAT_WIN2K, "win2k" },
788 { -1, NULL}
792 Do you want session setups at user level security with a invalid
793 password to be rejected or allowed in as guest? WinNT rejects them
794 but it can be a pain as it means "net view" needs to use a password
796 You have 3 choices in the setting of map_to_guest:
798 "Never" means session setups with an invalid password
799 are rejected. This is the default.
801 "Bad User" means session setups with an invalid password
802 are rejected, unless the username does not exist, in which case it
803 is treated as a guest login
805 "Bad Password" means session setups with an invalid password
806 are treated as a guest login
808 Note that map_to_guest only has an effect in user or server
809 level security.
812 static const struct enum_list enum_map_to_guest[] = {
813 {NEVER_MAP_TO_GUEST, "Never"},
814 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
815 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
816 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
817 {-1, NULL}
820 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
822 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
823 * screen in SWAT. This is used to exclude parameters as well as to squash all
824 * parameters that have been duplicated by pseudonyms.
826 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
827 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
828 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
829 * respective views.
831 * NOTE2: Handling of duplicated (synonym) paramters:
832 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
833 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
834 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
835 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
838 static struct parm_struct parm_table[] = {
839 {N_("Base Options"), P_SEP, P_SEPARATOR},
841 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
842 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
843 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
844 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
845 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
846 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
847 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
848 #ifdef WITH_ADS
849 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
850 #endif
851 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
852 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
853 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
854 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
855 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
856 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
858 {N_("Security Options"), P_SEP, P_SEPARATOR},
860 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
861 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
862 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
863 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
864 {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
865 {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
866 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
867 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
868 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
869 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
870 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
871 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
872 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
873 {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
874 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
875 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
876 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
877 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
878 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
879 {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
881 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
882 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
883 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
884 {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
885 {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
886 {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
887 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
888 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
889 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
890 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
891 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
892 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
893 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
894 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
895 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
896 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
898 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
899 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
900 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
902 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
903 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
904 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
905 {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
906 {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
907 {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED },
908 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
909 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
910 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
912 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
913 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
914 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
915 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
917 {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
918 {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
919 {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
920 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
921 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
922 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
923 {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
924 {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
925 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
926 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
927 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
928 {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
929 {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
930 {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
931 {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
932 {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
933 {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
934 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
935 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
937 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
938 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
940 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
941 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
942 {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
943 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
944 {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
945 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
946 {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED},
948 {N_("Logging Options"), P_SEP, P_SEPARATOR},
950 {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
951 {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
952 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
953 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
954 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
956 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
957 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
958 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
959 {"debug prefix timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugPrefixTimestamp, NULL, NULL, FLAG_ADVANCED},
960 {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
961 {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
962 {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
963 {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
965 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
967 {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
968 {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED},
969 {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED},
970 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
971 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
972 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
973 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
974 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
975 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED},
976 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
977 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
978 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
979 {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED},
981 {"acl compatibility", P_ENUM, P_GLOBAL, &Globals.iAclCompat, NULL, enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
982 {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
983 {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
984 {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
985 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
986 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
987 {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
989 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
990 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
991 {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
992 {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
993 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
994 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
996 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
997 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
998 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
999 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
1000 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
1001 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
1002 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
1003 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1004 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
1005 {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
1007 {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
1008 {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
1010 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1012 {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1013 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
1014 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
1015 {"keepalive", P_INTEGER, P_GLOBAL, &Globals.iKeepalive, NULL, NULL, FLAG_ADVANCED},
1016 {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1017 {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1019 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
1020 {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
1021 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1022 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
1023 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
1024 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
1025 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1026 {"open files database hash size", P_INTEGER, P_GLOBAL, &Globals.open_files_db_hash_size, NULL, NULL, FLAG_ADVANCED},
1028 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
1029 {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1030 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1031 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1032 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
1033 {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1034 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
1035 {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
1037 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
1038 {"ctdbd socket", P_STRING, P_GLOBAL, &Globals.ctdbdSocket, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1039 {"clustering", P_BOOL, P_GLOBAL, &Globals.clustering, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1041 {N_("Printing Options"), P_SEP, P_SEPARATOR},
1043 {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1044 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1045 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1046 {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1047 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1048 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
1049 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1050 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
1051 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1052 {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1053 {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1054 {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1055 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1056 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1057 {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE},
1058 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1059 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1060 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1061 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1062 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1063 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1065 {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED},
1066 {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
1067 {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
1068 {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
1069 {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
1070 {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
1072 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1073 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
1074 {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1075 {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1076 {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1077 {"printjob username", P_STRING, P_LOCAL, &sDefault.szPrintjobUsername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1079 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
1080 {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
1081 {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
1083 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
1084 {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1085 {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},
1086 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1087 {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1088 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1089 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1090 {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1091 {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1092 {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1093 {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1094 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1095 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1096 {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1097 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1098 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1099 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1100 {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1101 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1102 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED },
1103 {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
1104 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
1105 {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1106 {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1109 {N_("Domain Options"), P_SEP, P_SEPARATOR},
1111 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1113 {N_("Logon Options"), P_SEP, P_SEPARATOR},
1115 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
1116 {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1117 {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
1118 {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
1119 {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
1120 {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
1121 {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
1122 {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
1123 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
1124 {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
1125 {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
1126 {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED},
1128 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
1129 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
1130 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
1131 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
1132 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
1134 {N_("Browse Options"), P_SEP, P_SEPARATOR},
1136 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1137 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
1138 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
1139 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1140 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1141 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1142 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1143 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
1144 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1145 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1146 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
1148 {N_("WINS Options"), P_SEP, P_SEPARATOR},
1150 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
1151 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
1153 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1154 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1155 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
1157 {N_("Locking Options"), P_SEP, P_SEPARATOR},
1159 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1160 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1161 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1162 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1163 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1164 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1166 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1167 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1168 {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1169 {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1170 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1171 {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1172 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1174 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
1176 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
1177 {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
1178 {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
1179 {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
1180 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
1181 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
1182 {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
1183 {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1184 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
1185 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
1186 {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1187 {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1188 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
1190 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
1191 {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
1192 {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
1193 {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
1195 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
1196 {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1198 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1199 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1200 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1201 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
1202 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
1203 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
1204 #ifdef WITH_UTMP
1205 {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
1206 {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
1207 {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
1208 #endif
1210 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1211 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1212 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
1213 {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED},
1214 {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED},
1215 {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
1216 {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
1217 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
1218 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
1219 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
1220 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
1221 {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
1222 {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1223 {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1224 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
1225 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
1226 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1228 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1229 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1230 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1231 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
1233 {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1234 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1235 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1236 {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1237 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1238 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1239 {"registry shares", P_BOOL, P_GLOBAL, &Globals.bRegistryShares, NULL, NULL, FLAG_ADVANCED},
1240 {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
1241 {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1242 {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED},
1243 {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1244 {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED},
1245 {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED},
1246 {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1247 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1248 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1249 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1250 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1251 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1252 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1253 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1254 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1255 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1256 {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1257 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1258 {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1260 {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1261 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
1263 {N_("VFS module options"), P_SEP, P_SEPARATOR},
1265 {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1266 {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
1269 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1270 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1271 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
1273 {N_("Winbind options"), P_SEP, P_SEPARATOR},
1275 {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1276 {"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED},
1277 {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED },
1278 {"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED},
1279 {"idmap cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapCacheTime, NULL, NULL, FLAG_ADVANCED},
1280 {"idmap negative cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeCacheTime, NULL, NULL, FLAG_ADVANCED},
1281 {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED },
1282 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE },
1283 {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED },
1284 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE },
1285 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
1286 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
1287 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
1288 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
1289 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
1290 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
1291 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
1292 {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
1293 {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
1294 {"winbind expand groups", P_INTEGER, P_GLOBAL, &Globals.winbind_expand_groups, NULL, NULL, FLAG_ADVANCED},
1295 {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
1296 {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
1297 {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1298 {"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
1299 {"winbind rpc only", P_BOOL, P_GLOBAL, &Globals.bWinbindRpcOnly, NULL, NULL, FLAG_ADVANCED},
1301 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1304 /***************************************************************************
1305 Initialise the sDefault parameter structure for the printer values.
1306 ***************************************************************************/
1308 static void init_printer_values(service *pService)
1310 /* choose defaults depending on the type of printing */
1311 switch (pService->iPrinting) {
1312 case PRINT_BSD:
1313 case PRINT_AIX:
1314 case PRINT_LPRNT:
1315 case PRINT_LPROS2:
1316 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1317 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1318 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1319 break;
1321 case PRINT_LPRNG:
1322 case PRINT_PLP:
1323 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1324 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1325 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1326 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1327 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1328 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1329 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1330 break;
1332 case PRINT_CUPS:
1333 case PRINT_IPRINT:
1334 #ifdef HAVE_CUPS
1335 /* set the lpq command to contain the destination printer
1336 name only. This is used by cups_queue_get() */
1337 string_set(&pService->szLpqcommand, "%p");
1338 string_set(&pService->szLprmcommand, "");
1339 string_set(&pService->szPrintcommand, "");
1340 string_set(&pService->szLppausecommand, "");
1341 string_set(&pService->szLpresumecommand, "");
1342 string_set(&pService->szQueuepausecommand, "");
1343 string_set(&pService->szQueueresumecommand, "");
1344 #else
1345 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1346 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1347 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1348 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1349 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1350 string_set(&pService->szQueuepausecommand, "disable '%p'");
1351 string_set(&pService->szQueueresumecommand, "enable '%p'");
1352 #endif /* HAVE_CUPS */
1353 break;
1355 case PRINT_SYSV:
1356 case PRINT_HPUX:
1357 string_set(&pService->szLpqcommand, "lpstat -o%p");
1358 string_set(&pService->szLprmcommand, "cancel %p-%j");
1359 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1360 string_set(&pService->szQueuepausecommand, "disable %p");
1361 string_set(&pService->szQueueresumecommand, "enable %p");
1362 #ifndef HPUX
1363 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1364 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1365 #endif /* HPUX */
1366 break;
1368 case PRINT_QNX:
1369 string_set(&pService->szLpqcommand, "lpq -P%p");
1370 string_set(&pService->szLprmcommand, "lprm -P%p %j");
1371 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1372 break;
1374 #ifdef DEVELOPER
1375 case PRINT_TEST:
1376 case PRINT_VLP:
1377 string_set(&pService->szPrintcommand, "vlp print %p %s");
1378 string_set(&pService->szLpqcommand, "vlp lpq %p");
1379 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1380 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1381 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1382 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1383 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1384 break;
1385 #endif /* DEVELOPER */
1390 /***************************************************************************
1391 Initialise the global parameter structure.
1392 ***************************************************************************/
1394 static void init_globals(BOOL first_time_only)
1396 static BOOL done_init = False;
1397 pstring s;
1399 /* If requested to initialize only once and we've already done it... */
1400 if (first_time_only && done_init) {
1401 /* ... then we have nothing more to do */
1402 return;
1405 if (!done_init) {
1406 int i;
1408 /* The logfile can be set before this is invoked. Free it if so. */
1409 if (Globals.szLogFile != NULL) {
1410 string_free(&Globals.szLogFile);
1411 Globals.szLogFile = NULL;
1414 memset((void *)&Globals, '\0', sizeof(Globals));
1416 for (i = 0; parm_table[i].label; i++)
1417 if ((parm_table[i].type == P_STRING ||
1418 parm_table[i].type == P_USTRING) &&
1419 parm_table[i].ptr)
1420 string_set((char **)parm_table[i].ptr, "");
1422 string_set(&sDefault.fstype, FSTYPE_STRING);
1423 string_set(&sDefault.szPrintjobUsername, "%U");
1425 init_printer_values(&sDefault);
1427 done_init = True;
1431 DEBUG(3, ("Initialising global parameters\n"));
1433 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1434 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1436 /* use the new 'hash2' method by default, with a prefix of 1 */
1437 string_set(&Globals.szManglingMethod, "hash2");
1438 Globals.mangle_prefix = 1;
1440 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1442 /* using UTF8 by default allows us to support all chars */
1443 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1445 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1446 /* If the system supports nl_langinfo(), try to grab the value
1447 from the user's locale */
1448 string_set(&Globals.display_charset, "LOCALE");
1449 #else
1450 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1451 #endif
1453 /* Use codepage 850 as a default for the dos character set */
1454 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1457 * Allow the default PASSWD_CHAT to be overridden in local.h.
1459 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1461 set_global_myname(myhostname());
1462 string_set(&Globals.szNetbiosName,global_myname());
1464 set_global_myworkgroup(WORKGROUP);
1465 string_set(&Globals.szWorkgroup, lp_workgroup());
1467 string_set(&Globals.szPasswdProgram, "");
1468 string_set(&Globals.szPidDir, dyn_PIDDIR);
1469 string_set(&Globals.szLockDir, dyn_LOCKDIR);
1470 string_set(&Globals.szSocketAddress, "0.0.0.0");
1471 pstrcpy(s, "Samba ");
1472 pstrcat(s, SAMBA_VERSION_STRING);
1473 string_set(&Globals.szServerString, s);
1474 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1475 DEFAULT_MINOR_VERSION);
1476 string_set(&Globals.szAnnounceVersion, s);
1477 #ifdef DEVELOPER
1478 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1479 #endif
1481 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1483 string_set(&Globals.szLogonDrive, "");
1484 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1485 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1486 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1488 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1489 string_set(&Globals.szPasswordServer, "*");
1491 Globals.AlgorithmicRidBase = BASE_RID;
1493 Globals.bLoadPrinters = True;
1494 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
1496 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1497 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1498 Globals.max_xmit = 0x4104;
1499 Globals.max_mux = 50; /* This is *needed* for profile support. */
1500 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
1501 Globals.bDisableSpoolss = False;
1502 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1503 Globals.pwordlevel = 0;
1504 Globals.unamelevel = 0;
1505 Globals.deadtime = 0;
1506 Globals.bLargeReadwrite = True;
1507 Globals.max_log_size = 5000;
1508 Globals.max_open_files = MAX_OPEN_FILES;
1509 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1510 Globals.maxprotocol = PROTOCOL_NT1;
1511 Globals.minprotocol = PROTOCOL_CORE;
1512 Globals.security = SEC_USER;
1513 Globals.paranoid_server_security = True;
1514 Globals.bEncryptPasswords = True;
1515 Globals.bUpdateEncrypt = False;
1516 Globals.clientSchannel = Auto;
1517 Globals.serverSchannel = Auto;
1518 Globals.bReadRaw = True;
1519 Globals.bWriteRaw = True;
1520 Globals.bReadbmpx = False;
1521 Globals.bNullPasswords = False;
1522 Globals.bObeyPamRestrictions = False;
1523 Globals.syslog = 1;
1524 Globals.bSyslogOnly = False;
1525 Globals.bTimestampLogs = True;
1526 string_set(&Globals.szLogLevel, "0");
1527 Globals.bDebugPrefixTimestamp = False;
1528 Globals.bDebugHiresTimestamp = False;
1529 Globals.bDebugPid = False;
1530 Globals.bDebugUid = False;
1531 Globals.bEnableCoreFiles = True;
1532 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1533 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1534 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1535 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1536 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1537 Globals.lm_interval = 60;
1538 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1539 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1540 Globals.bNISHomeMap = False;
1541 #ifdef WITH_NISPLUS_HOME
1542 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1543 #else
1544 string_set(&Globals.szNISHomeMapName, "auto.home");
1545 #endif
1546 #endif
1547 Globals.bTimeServer = False;
1548 Globals.bBindInterfacesOnly = False;
1549 Globals.bUnixPasswdSync = False;
1550 Globals.bPamPasswordChange = False;
1551 Globals.bPasswdChatDebug = False;
1552 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1553 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
1554 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1555 Globals.bStatCache = True; /* use stat cache by default */
1556 Globals.iMaxStatCacheSize = 1024; /* one Meg by default. */
1557 Globals.restrict_anonymous = 0;
1558 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1559 Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
1560 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1561 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1562 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1563 /* Note, that we will use NTLM2 session security (which is different), if it is available */
1565 Globals.map_to_guest = 0; /* By Default, "Never" */
1566 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
1567 Globals.enhanced_browsing = True;
1568 Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
1569 #ifdef MMAP_BLACKLIST
1570 Globals.bUseMmap = False;
1571 #else
1572 Globals.bUseMmap = True;
1573 #endif
1574 Globals.bUnixExtensions = True;
1575 Globals.bResetOnZeroVC = False;
1577 /* hostname lookups can be very expensive and are broken on
1578 a large number of sites (tridge) */
1579 Globals.bHostnameLookups = False;
1581 string_set(&Globals.szPassdbBackend, "smbpasswd");
1582 string_set(&Globals.szLdapSuffix, "");
1583 string_set(&Globals.szLdapMachineSuffix, "");
1584 string_set(&Globals.szLdapUserSuffix, "");
1585 string_set(&Globals.szLdapGroupSuffix, "");
1586 string_set(&Globals.szLdapIdmapSuffix, "");
1588 string_set(&Globals.szLdapAdminDn, "");
1589 Globals.ldap_ssl = LDAP_SSL_ON;
1590 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1591 Globals.ldap_delete_dn = False;
1592 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1593 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1594 Globals.ldap_page_size = LDAP_PAGE_SIZE;
1596 /* This is what we tell the afs client. in reality we set the token
1597 * to never expire, though, when this runs out the afs client will
1598 * forget the token. Set to 0 to get NEVERDATE.*/
1599 Globals.iAfsTokenLifetime = 604800;
1601 /* these parameters are set to defaults that are more appropriate
1602 for the increasing samba install base:
1604 as a member of the workgroup, that will possibly become a
1605 _local_ master browser (lm = True). this is opposed to a forced
1606 local master browser startup (pm = True).
1608 doesn't provide WINS server service by default (wsupp = False),
1609 and doesn't provide domain master browser services by default, either.
1613 Globals.bMsAddPrinterWizard = True;
1614 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1615 Globals.os_level = 20;
1616 Globals.bLocalMaster = True;
1617 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1618 Globals.bDomainLogons = False;
1619 Globals.bBrowseList = True;
1620 Globals.bWINSsupport = False;
1621 Globals.bWINSproxy = False;
1623 Globals.bDNSproxy = True;
1625 /* this just means to use them if they exist */
1626 Globals.bKernelOplocks = True;
1628 Globals.bAllowTrustedDomains = True;
1630 string_set(&Globals.szTemplateShell, "/bin/false");
1631 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1632 string_set(&Globals.szWinbindSeparator, "\\");
1634 string_set(&Globals.szCupsServer, "");
1635 string_set(&Globals.szIPrintServer, "");
1637 string_set(&Globals.ctdbdSocket, "");
1638 Globals.clustering = False;
1640 Globals.winbind_cache_time = 300; /* 5 minutes */
1641 Globals.bWinbindEnumUsers = False;
1642 Globals.bWinbindEnumGroups = False;
1643 Globals.bWinbindUseDefaultDomain = False;
1644 Globals.bWinbindTrustedDomainsOnly = False;
1645 Globals.bWinbindNestedGroups = True;
1646 Globals.winbind_expand_groups = 1;
1647 Globals.szWinbindNssInfo = str_list_make("template", NULL);
1648 Globals.bWinbindRefreshTickets = False;
1649 Globals.bWinbindOfflineLogon = False;
1651 Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
1652 Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
1654 Globals.bPassdbExpandExplicit = False;
1656 Globals.name_cache_timeout = 660; /* In seconds */
1658 Globals.bUseSpnego = True;
1659 Globals.bClientUseSpnego = True;
1661 Globals.client_signing = Auto;
1662 Globals.server_signing = False;
1664 Globals.bDeferSharingViolations = True;
1665 string_set(&Globals.smb_ports, SMB_PORTS);
1667 Globals.bEnablePrivileges = True;
1668 Globals.bHostMSDfs = True;
1669 Globals.bASUSupport = False;
1671 /* User defined shares. */
1672 pstrcpy(s, dyn_LOCKDIR);
1673 pstrcat(s, "/usershares");
1674 string_set(&Globals.szUsersharePath, s);
1675 string_set(&Globals.szUsershareTemplateShare, "");
1676 Globals.iUsershareMaxShares = 0;
1677 /* By default disallow sharing of directories not owned by the sharer. */
1678 Globals.bUsershareOwnerOnly = True;
1679 /* By default disallow guest access to usershares. */
1680 Globals.bUsershareAllowGuests = False;
1682 Globals.iKeepalive = DEFAULT_KEEPALIVE;
1684 /* By default no shares out of the registry */
1685 Globals.bRegistryShares = False;
1688 static TALLOC_CTX *lp_talloc;
1690 /******************************************************************* a
1691 Free up temporary memory - called from the main loop.
1692 ********************************************************************/
1694 void lp_TALLOC_FREE(void)
1696 if (!lp_talloc)
1697 return;
1698 TALLOC_FREE(lp_talloc);
1699 lp_talloc = NULL;
1702 TALLOC_CTX *tmp_talloc_ctx(void)
1704 if (lp_talloc == NULL) {
1705 lp_talloc = talloc_init("tmp_talloc_ctx");
1708 if (lp_talloc == NULL) {
1709 smb_panic("Could not create temporary talloc context\n");
1712 return lp_talloc;
1715 /*******************************************************************
1716 Convenience routine to grab string parameters into temporary memory
1717 and run standard_sub_basic on them. The buffers can be written to by
1718 callers without affecting the source string.
1719 ********************************************************************/
1721 static char *lp_string(const char *s)
1723 char *ret, *tmpstr;
1725 /* The follow debug is useful for tracking down memory problems
1726 especially if you have an inner loop that is calling a lp_*()
1727 function that returns a string. Perhaps this debug should be
1728 present all the time? */
1730 #if 0
1731 DEBUG(10, ("lp_string(%s)\n", s));
1732 #endif
1734 if (!lp_talloc)
1735 lp_talloc = talloc_init("lp_talloc");
1737 tmpstr = alloc_sub_basic(get_current_username(),
1738 current_user_info.domain, s);
1739 if (trim_char(tmpstr, '\"', '\"')) {
1740 if (strchr(tmpstr,'\"') != NULL) {
1741 SAFE_FREE(tmpstr);
1742 tmpstr = alloc_sub_basic(get_current_username(),
1743 current_user_info.domain, s);
1746 ret = talloc_strdup(lp_talloc, tmpstr);
1747 SAFE_FREE(tmpstr);
1749 return (ret);
1753 In this section all the functions that are used to access the
1754 parameters from the rest of the program are defined
1757 #define FN_GLOBAL_STRING(fn_name,ptr) \
1758 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1759 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1760 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1761 #define FN_GLOBAL_LIST(fn_name,ptr) \
1762 const char **fn_name(void) {return(*(const char ***)(ptr));}
1763 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1764 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1765 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1766 char fn_name(void) {return(*(char *)(ptr));}
1767 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1768 int fn_name(void) {return(*(int *)(ptr));}
1770 #define FN_LOCAL_STRING(fn_name,val) \
1771 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1772 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1773 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1774 #define FN_LOCAL_LIST(fn_name,val) \
1775 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1776 #define FN_LOCAL_BOOL(fn_name,val) \
1777 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1778 #define FN_LOCAL_INTEGER(fn_name,val) \
1779 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1781 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
1782 BOOL fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1783 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
1784 int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1785 #define FN_LOCAL_PARM_STRING(fn_name,val) \
1786 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));}
1787 #define FN_LOCAL_CHAR(fn_name,val) \
1788 char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
1790 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1791 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1792 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1793 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1794 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1795 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1796 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1797 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1798 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1799 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1800 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1801 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1802 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1803 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1804 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1805 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1806 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1807 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1808 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1809 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1810 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1811 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1812 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1813 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1814 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1815 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1816 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1817 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1818 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1819 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1820 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1821 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1822 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1823 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1824 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1825 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1826 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1827 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1828 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1829 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1830 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1831 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1832 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1833 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1834 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1835 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1836 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1837 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1838 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1839 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1840 * lp_passdb_backend() should be replace by the this macro again after
1841 * some releases.
1842 * */
1843 const char *lp_passdb_backend(void)
1845 char *delim, *quote;
1847 delim = strchr( Globals.szPassdbBackend, ' ');
1848 /* no space at all */
1849 if (delim == NULL) {
1850 goto out;
1853 quote = strchr(Globals.szPassdbBackend, '"');
1854 /* no quote char or non in the first part */
1855 if (quote == NULL || quote > delim) {
1856 *delim = '\0';
1857 goto warn;
1860 quote = strchr(quote+1, '"');
1861 if (quote == NULL) {
1862 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
1863 goto out;
1864 } else if (*(quote+1) == '\0') {
1865 /* space, fitting quote char, and one backend only */
1866 goto out;
1867 } else {
1868 /* terminate string after the fitting quote char */
1869 *(quote+1) = '\0';
1872 warn:
1873 DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends. This\n"
1874 "is deprecated since Samba 3.0.23. Please check WHATSNEW.txt or the section 'Passdb\n"
1875 "Changes' from the ChangeNotes as part of the Samba HOWTO collection. Only the first\n"
1876 "backend (%s) is used. The rest is ignored.\n", Globals.szPassdbBackend));
1878 out:
1879 return Globals.szPassdbBackend;
1881 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1882 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1883 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1884 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1885 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1887 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1888 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1889 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1890 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1891 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1892 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1894 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1896 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1897 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1898 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1900 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1902 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1903 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1904 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1905 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1906 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1907 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1908 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1909 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1910 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1911 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1912 FN_GLOBAL_INTEGER(lp_winbind_expand_groups, &Globals.winbind_expand_groups)
1913 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1914 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1915 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
1916 FN_GLOBAL_BOOL(lp_winbind_rpc_only, &Globals.bWinbindRpcOnly)
1918 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
1919 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
1920 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
1921 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
1922 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
1923 FN_GLOBAL_INTEGER(lp_keepalive, &Globals.iKeepalive)
1924 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1926 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1927 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1928 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1929 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1930 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1931 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1932 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1933 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1934 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1935 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1936 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1937 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1938 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1939 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1941 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1943 FN_GLOBAL_BOOL(lp_registry_shares, &Globals.bRegistryShares)
1944 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1945 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1946 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1947 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1948 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1949 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1950 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1951 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1952 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1953 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1954 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1955 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1956 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1957 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1958 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1959 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1960 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1961 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1962 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1963 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1964 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1965 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1966 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1967 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1968 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
1969 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1970 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1971 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1972 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1973 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1974 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1975 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1976 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1977 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1978 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1979 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1980 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1981 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1982 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1983 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1984 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1985 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1986 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1987 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1988 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1989 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1990 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1991 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1992 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1993 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1994 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1995 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1996 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1997 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1998 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1999 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
2000 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
2001 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
2002 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
2003 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
2004 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
2005 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
2006 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
2007 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
2008 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
2009 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
2010 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
2011 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
2012 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
2013 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
2014 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
2015 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
2016 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
2017 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
2018 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
2019 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
2020 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
2021 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
2022 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
2023 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
2024 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
2025 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
2026 FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
2027 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
2028 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
2029 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
2030 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
2031 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
2032 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
2033 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
2034 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
2035 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
2037 FN_LOCAL_STRING(lp_preexec, szPreExec)
2038 FN_LOCAL_STRING(lp_postexec, szPostExec)
2039 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
2040 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
2041 FN_LOCAL_STRING(lp_servicename, szService)
2042 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
2043 FN_LOCAL_STRING(lp_pathname, szPath)
2044 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
2045 FN_LOCAL_STRING(lp_username, szUsername)
2046 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
2047 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
2048 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
2049 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
2050 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
2051 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
2052 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
2053 FN_GLOBAL_CONST_STRING(lp_ctdbd_socket, &Globals.ctdbdSocket)
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_PARM_STRING(lp_mangled_map, szMangledMap)
2079 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
2080 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
2081 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
2082 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
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_CHAR(lp_magicchar, magic_char)
2165 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2166 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2167 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2168 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2169 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2170 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2172 /* local prototypes */
2174 static int map_parameter(const char *pszParmName);
2175 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
2176 static int getservicebyname(const char *pszServiceName,
2177 service * pserviceDest);
2178 static void copy_service(service * pserviceDest,
2179 service * pserviceSource, BOOL *pcopymapDest);
2180 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
2181 static BOOL do_section(const char *pszSectionName);
2182 static void init_copymap(service * pservice);
2183 static BOOL hash_a_service(const char *name, int number);
2184 static void free_service_byindex(int iService);
2185 static char * canonicalize_servicename(const char *name);
2187 /* This is a helper function for parametrical options support. */
2188 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2189 /* Actual parametrical functions are quite simple */
2190 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2192 BOOL global_section = False;
2193 char* param_key;
2194 param_opt_struct *data;
2196 if (snum >= iNumServices) return NULL;
2198 if (snum < 0) {
2199 data = Globals.param_opt;
2200 global_section = True;
2201 } else {
2202 data = ServicePtrs[snum]->param_opt;
2205 asprintf(&param_key, "%s:%s", type, option);
2206 if (!param_key) {
2207 DEBUG(0,("asprintf failed!\n"));
2208 return NULL;
2211 while (data) {
2212 if (strcmp(data->key, param_key) == 0) {
2213 string_free(&param_key);
2214 return data;
2216 data = data->next;
2219 if (!global_section) {
2220 /* Try to fetch the same option but from globals */
2221 /* but only if we are not already working with Globals */
2222 data = Globals.param_opt;
2223 while (data) {
2224 if (strcmp(data->key, param_key) == 0) {
2225 string_free(&param_key);
2226 return data;
2228 data = data->next;
2232 string_free(&param_key);
2234 return NULL;
2238 #define MISSING_PARAMETER(name) \
2239 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2241 /*******************************************************************
2242 convenience routine to return int parameters.
2243 ********************************************************************/
2244 static int lp_int(const char *s)
2247 if (!s || !*s) {
2248 MISSING_PARAMETER(lp_int);
2249 return (-1);
2252 return (int)strtol(s, NULL, 0);
2255 /*******************************************************************
2256 convenience routine to return unsigned long parameters.
2257 ********************************************************************/
2258 static unsigned long lp_ulong(const char *s)
2261 if (!s || !*s) {
2262 MISSING_PARAMETER(lp_ulong);
2263 return (0);
2266 return strtoul(s, NULL, 0);
2269 /*******************************************************************
2270 convenience routine to return boolean parameters.
2271 ********************************************************************/
2272 static BOOL lp_bool(const char *s)
2274 BOOL ret = False;
2276 if (!s || !*s) {
2277 MISSING_PARAMETER(lp_bool);
2278 return False;
2281 if (!set_boolean(&ret,s)) {
2282 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2283 return False;
2286 return ret;
2289 /*******************************************************************
2290 convenience routine to return enum parameters.
2291 ********************************************************************/
2292 static int lp_enum(const char *s,const struct enum_list *_enum)
2294 int i;
2296 if (!s || !*s || !_enum) {
2297 MISSING_PARAMETER(lp_enum);
2298 return (-1);
2301 for (i=0; _enum[i].name; i++) {
2302 if (strequal(_enum[i].name,s))
2303 return _enum[i].value;
2306 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2307 return (-1);
2310 #undef MISSING_PARAMETER
2312 /* DO NOT USE lp_parm_string ANYMORE!!!!
2313 * use lp_parm_const_string or lp_parm_talloc_string
2315 * lp_parm_string is only used to let old modules find this symbol
2317 #undef lp_parm_string
2318 char *lp_parm_string(const char *servicename, const char *type, const char *option);
2319 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2321 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2324 /* Return parametric option from a given service. Type is a part of option before ':' */
2325 /* Parametric option has following syntax: 'Type: option = value' */
2326 /* the returned value is talloced in lp_talloc */
2327 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2329 param_opt_struct *data = get_parametrics(snum, type, option);
2331 if (data == NULL||data->value==NULL) {
2332 if (def) {
2333 return lp_string(def);
2334 } else {
2335 return NULL;
2339 return lp_string(data->value);
2342 /* Return parametric option from a given service. Type is a part of option before ':' */
2343 /* Parametric option has following syntax: 'Type: option = value' */
2344 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2346 param_opt_struct *data = get_parametrics(snum, type, option);
2348 if (data == NULL||data->value==NULL)
2349 return def;
2351 return data->value;
2354 /* Return parametric option from a given service. Type is a part of option before ':' */
2355 /* Parametric option has following syntax: 'Type: option = value' */
2357 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2359 param_opt_struct *data = get_parametrics(snum, type, option);
2361 if (data == NULL||data->value==NULL)
2362 return (const char **)def;
2364 if (data->list==NULL) {
2365 data->list = str_list_make(data->value, NULL);
2368 return (const char **)data->list;
2371 /* Return parametric option from a given service. Type is a part of option before ':' */
2372 /* Parametric option has following syntax: 'Type: option = value' */
2374 int lp_parm_int(int snum, const char *type, const char *option, int def)
2376 param_opt_struct *data = get_parametrics(snum, type, option);
2378 if (data && data->value && *data->value)
2379 return lp_int(data->value);
2381 return def;
2384 /* Return parametric option from a given service. Type is a part of option before ':' */
2385 /* Parametric option has following syntax: 'Type: option = value' */
2387 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2389 param_opt_struct *data = get_parametrics(snum, type, option);
2391 if (data && data->value && *data->value)
2392 return lp_ulong(data->value);
2394 return def;
2397 /* Return parametric option from a given service. Type is a part of option before ':' */
2398 /* Parametric option has following syntax: 'Type: option = value' */
2400 BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2402 param_opt_struct *data = get_parametrics(snum, type, option);
2404 if (data && data->value && *data->value)
2405 return lp_bool(data->value);
2407 return def;
2410 /* Return parametric option from a given service. Type is a part of option before ':' */
2411 /* Parametric option has following syntax: 'Type: option = value' */
2413 int lp_parm_enum(int snum, const char *type, const char *option,
2414 const struct enum_list *_enum, int def)
2416 param_opt_struct *data = get_parametrics(snum, type, option);
2418 if (data && data->value && *data->value && _enum)
2419 return lp_enum(data->value, _enum);
2421 return def;
2425 /***************************************************************************
2426 Initialise a service to the defaults.
2427 ***************************************************************************/
2429 static void init_service(service * pservice)
2431 memset((char *)pservice, '\0', sizeof(service));
2432 copy_service(pservice, &sDefault, NULL);
2435 /***************************************************************************
2436 Free the dynamically allocated parts of a service struct.
2437 ***************************************************************************/
2439 static void free_service(service *pservice)
2441 int i;
2442 param_opt_struct *data, *pdata;
2443 if (!pservice)
2444 return;
2446 if (pservice->szService)
2447 DEBUG(5, ("free_service: Freeing service %s\n",
2448 pservice->szService));
2450 string_free(&pservice->szService);
2451 SAFE_FREE(pservice->copymap);
2453 for (i = 0; parm_table[i].label; i++) {
2454 if ((parm_table[i].type == P_STRING ||
2455 parm_table[i].type == P_USTRING) &&
2456 parm_table[i].p_class == P_LOCAL)
2457 string_free((char **)
2458 (((char *)pservice) +
2459 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2460 else if (parm_table[i].type == P_LIST &&
2461 parm_table[i].p_class == P_LOCAL)
2462 str_list_free((char ***)
2463 (((char *)pservice) +
2464 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2467 data = pservice->param_opt;
2468 if (data)
2469 DEBUG(5,("Freeing parametrics:\n"));
2470 while (data) {
2471 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2472 string_free(&data->key);
2473 string_free(&data->value);
2474 str_list_free(&data->list);
2475 pdata = data->next;
2476 SAFE_FREE(data);
2477 data = pdata;
2480 ZERO_STRUCTP(pservice);
2484 /***************************************************************************
2485 remove a service indexed in the ServicePtrs array from the ServiceHash
2486 and free the dynamically allocated parts
2487 ***************************************************************************/
2489 static void free_service_byindex(int idx)
2491 if ( !LP_SNUM_OK(idx) )
2492 return;
2494 ServicePtrs[idx]->valid = False;
2495 invalid_services[num_invalid_services++] = idx;
2497 /* we have to cleanup the hash record */
2499 if (ServicePtrs[idx]->szService) {
2500 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2502 tdb_delete_bystring(ServiceHash, canon_name );
2505 free_service(ServicePtrs[idx]);
2508 /***************************************************************************
2509 Add a new service to the services array initialising it with the given
2510 service.
2511 ***************************************************************************/
2513 static int add_a_service(const service *pservice, const char *name)
2515 int i;
2516 service tservice;
2517 int num_to_alloc = iNumServices + 1;
2518 param_opt_struct *data, *pdata;
2520 tservice = *pservice;
2522 /* it might already exist */
2523 if (name) {
2524 i = getservicebyname(name, NULL);
2525 if (i >= 0) {
2526 /* Clean all parametric options for service */
2527 /* They will be added during parsing again */
2528 data = ServicePtrs[i]->param_opt;
2529 while (data) {
2530 string_free(&data->key);
2531 string_free(&data->value);
2532 str_list_free(&data->list);
2533 pdata = data->next;
2534 SAFE_FREE(data);
2535 data = pdata;
2537 ServicePtrs[i]->param_opt = NULL;
2538 return (i);
2542 /* find an invalid one */
2543 i = iNumServices;
2544 if (num_invalid_services > 0) {
2545 i = invalid_services[--num_invalid_services];
2548 /* if not, then create one */
2549 if (i == iNumServices) {
2550 service **tsp;
2551 int *tinvalid;
2553 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2554 if (tsp == NULL) {
2555 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2556 return (-1);
2558 ServicePtrs = tsp;
2559 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2560 if (!ServicePtrs[iNumServices]) {
2561 DEBUG(0,("add_a_service: out of memory!\n"));
2562 return (-1);
2564 iNumServices++;
2566 /* enlarge invalid_services here for now... */
2567 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2568 num_to_alloc);
2569 if (tinvalid == NULL) {
2570 DEBUG(0,("add_a_service: failed to enlarge "
2571 "invalid_services!\n"));
2572 return (-1);
2574 invalid_services = tinvalid;
2575 } else {
2576 free_service_byindex(i);
2579 ServicePtrs[i]->valid = True;
2581 init_service(ServicePtrs[i]);
2582 copy_service(ServicePtrs[i], &tservice, NULL);
2583 if (name)
2584 string_set(&ServicePtrs[i]->szService, name);
2586 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2587 i, ServicePtrs[i]->szService));
2589 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2590 return (-1);
2593 return (i);
2596 /***************************************************************************
2597 Canonicalize by converting to lowercase.
2598 ***************************************************************************/
2600 static char *canonicalize_servicename(const char *src)
2602 static fstring canon; /* is fstring large enough? */
2604 if ( !src ) {
2605 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2606 return NULL;
2609 fstrcpy( canon, src );
2610 strlower_m( canon );
2612 return canon;
2615 /***************************************************************************
2616 Add a name/index pair for the services array to the hash table.
2617 ***************************************************************************/
2619 static BOOL hash_a_service(const char *name, int idx)
2621 char *canon_name;
2623 if ( !ServiceHash ) {
2624 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2625 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2626 (O_RDWR|O_CREAT), 0600);
2627 if ( !ServiceHash ) {
2628 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2629 return False;
2633 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2634 idx, name));
2636 if ( !(canon_name = canonicalize_servicename( name )) )
2637 return False;
2639 tdb_store_int32(ServiceHash, canon_name, idx);
2641 return True;
2644 /***************************************************************************
2645 Add a new home service, with the specified home directory, defaults coming
2646 from service ifrom.
2647 ***************************************************************************/
2649 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
2650 const char *user, const char *pszHomedir)
2652 int i;
2653 pstring newHomedir;
2655 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2657 if (i < 0)
2658 return (False);
2660 if (!(*(ServicePtrs[iDefaultService]->szPath))
2661 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2662 pstrcpy(newHomedir, pszHomedir);
2663 string_set(&ServicePtrs[i]->szPath, newHomedir);
2666 if (!(*(ServicePtrs[i]->comment))) {
2667 pstring comment;
2668 slprintf(comment, sizeof(comment) - 1,
2669 "Home directory of %s", user);
2670 string_set(&ServicePtrs[i]->comment, comment);
2673 /* set the browseable flag from the global default */
2675 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2677 ServicePtrs[i]->autoloaded = True;
2679 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2680 user, ServicePtrs[i]->szPath ));
2682 return (True);
2685 /***************************************************************************
2686 Add a new service, based on an old one.
2687 ***************************************************************************/
2689 int lp_add_service(const char *pszService, int iDefaultService)
2691 if (iDefaultService < 0) {
2692 return add_a_service(&sDefault, pszService);
2695 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2698 /***************************************************************************
2699 Add the IPC service.
2700 ***************************************************************************/
2702 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2704 pstring comment;
2705 int i = add_a_service(&sDefault, ipc_name);
2707 if (i < 0)
2708 return (False);
2710 slprintf(comment, sizeof(comment) - 1,
2711 "IPC Service (%s)", Globals.szServerString);
2713 string_set(&ServicePtrs[i]->szPath, tmpdir());
2714 string_set(&ServicePtrs[i]->szUsername, "");
2715 string_set(&ServicePtrs[i]->comment, comment);
2716 string_set(&ServicePtrs[i]->fstype, "IPC");
2717 ServicePtrs[i]->iMaxConnections = 0;
2718 ServicePtrs[i]->bAvailable = True;
2719 ServicePtrs[i]->bRead_only = True;
2720 ServicePtrs[i]->bGuest_only = False;
2721 ServicePtrs[i]->bGuest_ok = guest_ok;
2722 ServicePtrs[i]->bPrint_ok = False;
2723 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2725 DEBUG(3, ("adding IPC service\n"));
2727 return (True);
2730 /***************************************************************************
2731 Add a new printer service, with defaults coming from service iFrom.
2732 ***************************************************************************/
2734 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2736 const char *comment = "From Printcap";
2737 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2739 if (i < 0)
2740 return (False);
2742 /* note that we do NOT default the availability flag to True - */
2743 /* we take it from the default service passed. This allows all */
2744 /* dynamic printers to be disabled by disabling the [printers] */
2745 /* entry (if/when the 'available' keyword is implemented!). */
2747 /* the printer name is set to the service name. */
2748 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2749 string_set(&ServicePtrs[i]->comment, comment);
2751 /* set the browseable flag from the gloabl default */
2752 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2754 /* Printers cannot be read_only. */
2755 ServicePtrs[i]->bRead_only = False;
2756 /* No share modes on printer services. */
2757 ServicePtrs[i]->bShareModes = False;
2758 /* No oplocks on printer services. */
2759 ServicePtrs[i]->bOpLocks = False;
2760 /* Printer services must be printable. */
2761 ServicePtrs[i]->bPrint_ok = True;
2763 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2765 return (True);
2768 /***************************************************************************
2769 Map a parameter's string representation to something we can use.
2770 Returns False if the parameter string is not recognised, else TRUE.
2771 ***************************************************************************/
2773 static int map_parameter(const char *pszParmName)
2775 int iIndex;
2777 if (*pszParmName == '-')
2778 return (-1);
2780 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2781 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2782 return (iIndex);
2784 /* Warn only if it isn't parametric option */
2785 if (strchr(pszParmName, ':') == NULL)
2786 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2787 /* We do return 'fail' for parametric options as well because they are
2788 stored in different storage
2790 return (-1);
2793 /***************************************************************************
2794 Show all parameter's name, type, [values,] and flags.
2795 ***************************************************************************/
2797 void show_parameter_list(void)
2799 int classIndex, parmIndex, enumIndex, flagIndex;
2800 BOOL hadFlag;
2801 const char *section_names[] = { "local", "global", NULL};
2802 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2803 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2804 "P_UGSTRING", "P_ENUM", "P_SEP"};
2805 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2806 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2807 FLAG_HIDE, FLAG_DOS_STRING};
2808 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2809 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2810 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2812 for ( classIndex=0; section_names[classIndex]; classIndex++) {
2813 printf("[%s]\n", section_names[classIndex]);
2814 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2815 if (parm_table[parmIndex].p_class == classIndex) {
2816 printf("%s=%s",
2817 parm_table[parmIndex].label,
2818 type[parm_table[parmIndex].type]);
2819 switch (parm_table[parmIndex].type) {
2820 case P_ENUM:
2821 printf(",");
2822 for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2823 printf("%s%s",
2824 enumIndex ? "|" : "",
2825 parm_table[parmIndex].enum_list[enumIndex].name);
2826 break;
2827 default:
2828 break;
2830 printf(",");
2831 hadFlag = False;
2832 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2833 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2834 printf("%s%s",
2835 hadFlag ? "|" : "",
2836 flag_names[flagIndex]);
2837 hadFlag = True;
2840 printf("\n");
2846 /***************************************************************************
2847 Set a boolean variable from the text value stored in the passed string.
2848 Returns True in success, False if the passed string does not correctly
2849 represent a boolean.
2850 ***************************************************************************/
2852 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2854 BOOL bRetval;
2856 bRetval = True;
2857 if (strwicmp(pszParmValue, "yes") == 0 ||
2858 strwicmp(pszParmValue, "true") == 0 ||
2859 strwicmp(pszParmValue, "1") == 0)
2860 *pb = True;
2861 else if (strwicmp(pszParmValue, "no") == 0 ||
2862 strwicmp(pszParmValue, "False") == 0 ||
2863 strwicmp(pszParmValue, "0") == 0)
2864 *pb = False;
2865 else {
2866 DEBUG(0,
2867 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2868 pszParmValue));
2869 bRetval = False;
2871 return (bRetval);
2874 /***************************************************************************
2875 Find a service by name. Otherwise works like get_service.
2876 ***************************************************************************/
2878 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2880 int iService = -1;
2881 char *canon_name;
2883 if (ServiceHash != NULL) {
2884 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2885 return -1;
2887 iService = tdb_fetch_int32(ServiceHash, canon_name );
2889 if (LP_SNUM_OK(iService)) {
2890 if (pserviceDest != NULL) {
2891 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2893 } else {
2894 iService = -1;
2898 return (iService);
2901 /***************************************************************************
2902 Copy a service structure to another.
2903 If pcopymapDest is NULL then copy all fields
2904 ***************************************************************************/
2906 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2908 int i;
2909 BOOL bcopyall = (pcopymapDest == NULL);
2910 param_opt_struct *data, *pdata, *paramo;
2911 BOOL not_added;
2913 for (i = 0; parm_table[i].label; i++)
2914 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2915 (bcopyall || pcopymapDest[i])) {
2916 void *def_ptr = parm_table[i].ptr;
2917 void *src_ptr =
2918 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2919 &sDefault);
2920 void *dest_ptr =
2921 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2922 &sDefault);
2924 switch (parm_table[i].type) {
2925 case P_BOOL:
2926 case P_BOOLREV:
2927 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2928 break;
2930 case P_INTEGER:
2931 case P_ENUM:
2932 case P_OCTAL:
2933 *(int *)dest_ptr = *(int *)src_ptr;
2934 break;
2936 case P_CHAR:
2937 *(char *)dest_ptr = *(char *)src_ptr;
2938 break;
2940 case P_STRING:
2941 string_set((char **)dest_ptr,
2942 *(char **)src_ptr);
2943 break;
2945 case P_USTRING:
2946 string_set((char **)dest_ptr,
2947 *(char **)src_ptr);
2948 strupper_m(*(char **)dest_ptr);
2949 break;
2950 case P_LIST:
2951 str_list_free((char ***)dest_ptr);
2952 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2953 break;
2954 default:
2955 break;
2959 if (bcopyall) {
2960 init_copymap(pserviceDest);
2961 if (pserviceSource->copymap)
2962 memcpy((void *)pserviceDest->copymap,
2963 (void *)pserviceSource->copymap,
2964 sizeof(BOOL) * NUMPARAMETERS);
2967 data = pserviceSource->param_opt;
2968 while (data) {
2969 not_added = True;
2970 pdata = pserviceDest->param_opt;
2971 /* Traverse destination */
2972 while (pdata) {
2973 /* If we already have same option, override it */
2974 if (strcmp(pdata->key, data->key) == 0) {
2975 string_free(&pdata->value);
2976 str_list_free(&data->list);
2977 pdata->value = SMB_STRDUP(data->value);
2978 not_added = False;
2979 break;
2981 pdata = pdata->next;
2983 if (not_added) {
2984 paramo = SMB_XMALLOC_P(param_opt_struct);
2985 paramo->key = SMB_STRDUP(data->key);
2986 paramo->value = SMB_STRDUP(data->value);
2987 paramo->list = NULL;
2988 DLIST_ADD(pserviceDest->param_opt, paramo);
2990 data = data->next;
2994 /***************************************************************************
2995 Check a service for consistency. Return False if the service is in any way
2996 incomplete or faulty, else True.
2997 ***************************************************************************/
2999 BOOL service_ok(int iService)
3001 BOOL bRetval;
3003 bRetval = True;
3004 if (ServicePtrs[iService]->szService[0] == '\0') {
3005 DEBUG(0, ("The following message indicates an internal error:\n"));
3006 DEBUG(0, ("No service name in service entry.\n"));
3007 bRetval = False;
3010 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
3011 /* I can't see why you'd want a non-printable printer service... */
3012 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
3013 if (!ServicePtrs[iService]->bPrint_ok) {
3014 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
3015 ServicePtrs[iService]->szService));
3016 ServicePtrs[iService]->bPrint_ok = True;
3018 /* [printers] service must also be non-browsable. */
3019 if (ServicePtrs[iService]->bBrowseable)
3020 ServicePtrs[iService]->bBrowseable = False;
3023 if (ServicePtrs[iService]->szPath[0] == '\0' &&
3024 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
3025 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
3027 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
3028 ServicePtrs[iService]->szService));
3029 ServicePtrs[iService]->bAvailable = False;
3032 /* If a service is flagged unavailable, log the fact at level 1. */
3033 if (!ServicePtrs[iService]->bAvailable)
3034 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
3035 ServicePtrs[iService]->szService));
3037 return (bRetval);
3040 static struct file_lists {
3041 struct file_lists *next;
3042 char *name;
3043 char *subfname;
3044 time_t modtime;
3045 } *file_lists = NULL;
3047 /*******************************************************************
3048 Keep a linked list of all config files so we know when one has changed
3049 it's date and needs to be reloaded.
3050 ********************************************************************/
3052 static void add_to_file_list(const char *fname, const char *subfname)
3054 struct file_lists *f = file_lists;
3056 while (f) {
3057 if (f->name && !strcmp(f->name, fname))
3058 break;
3059 f = f->next;
3062 if (!f) {
3063 f = SMB_MALLOC_P(struct file_lists);
3064 if (!f)
3065 return;
3066 f->next = file_lists;
3067 f->name = SMB_STRDUP(fname);
3068 if (!f->name) {
3069 SAFE_FREE(f);
3070 return;
3072 f->subfname = SMB_STRDUP(subfname);
3073 if (!f->subfname) {
3074 SAFE_FREE(f);
3075 return;
3077 file_lists = f;
3078 f->modtime = file_modtime(subfname);
3079 } else {
3080 time_t t = file_modtime(subfname);
3081 if (t)
3082 f->modtime = t;
3086 /*******************************************************************
3087 Check if a config file has changed date.
3088 ********************************************************************/
3090 BOOL lp_file_list_changed(void)
3092 struct file_lists *f = file_lists;
3094 DEBUG(6, ("lp_file_list_changed()\n"));
3096 while (f) {
3097 pstring n2;
3098 time_t mod_time;
3100 pstrcpy(n2, f->name);
3101 standard_sub_basic( get_current_username(),
3102 current_user_info.domain,
3103 n2, sizeof(n2) );
3105 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3106 f->name, n2, ctime(&f->modtime)));
3108 mod_time = file_modtime(n2);
3110 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3111 DEBUGADD(6,
3112 ("file %s modified: %s\n", n2,
3113 ctime(&mod_time)));
3114 f->modtime = mod_time;
3115 SAFE_FREE(f->subfname);
3116 f->subfname = SMB_STRDUP(n2);
3117 return (True);
3119 f = f->next;
3121 return (False);
3124 /***************************************************************************
3125 Run standard_sub_basic on netbios name... needed because global_myname
3126 is not accessed through any lp_ macro.
3127 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3128 ***************************************************************************/
3130 static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3132 BOOL ret;
3133 pstring netbios_name;
3135 pstrcpy(netbios_name, pszParmValue);
3137 standard_sub_basic(get_current_username(), current_user_info.domain,
3138 netbios_name, sizeof(netbios_name));
3140 ret = set_global_myname(netbios_name);
3141 string_set(&Globals.szNetbiosName,global_myname());
3143 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3144 global_myname()));
3146 return ret;
3149 static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3151 if (strcmp(*ptr, pszParmValue) != 0) {
3152 string_set(ptr, pszParmValue);
3153 init_iconv();
3155 return True;
3160 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3162 BOOL ret;
3164 ret = set_global_myworkgroup(pszParmValue);
3165 string_set(&Globals.szWorkgroup,lp_workgroup());
3167 return ret;
3170 static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3172 BOOL ret;
3174 ret = set_global_scope(pszParmValue);
3175 string_set(&Globals.szNetbiosScope,global_scope());
3177 return ret;
3180 static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3182 str_list_free(&Globals.szNetbiosAliases);
3183 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3184 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3187 /***************************************************************************
3188 Handle the include operation.
3189 ***************************************************************************/
3191 static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3193 pstring fname;
3194 pstrcpy(fname, pszParmValue);
3196 standard_sub_basic(get_current_username(), current_user_info.domain,
3197 fname,sizeof(fname));
3199 add_to_file_list(pszParmValue, fname);
3201 string_set(ptr, fname);
3203 if (file_exist(fname, NULL))
3204 return (pm_process(fname, do_section, do_parameter));
3206 DEBUG(2, ("Can't find include file %s\n", fname));
3208 return (False);
3211 /***************************************************************************
3212 Handle the interpretation of the copy parameter.
3213 ***************************************************************************/
3215 static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3217 BOOL bRetval;
3218 int iTemp;
3219 service serviceTemp;
3221 string_set(ptr, pszParmValue);
3223 init_service(&serviceTemp);
3225 bRetval = False;
3227 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3229 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3230 if (iTemp == iServiceIndex) {
3231 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3232 } else {
3233 copy_service(ServicePtrs[iServiceIndex],
3234 &serviceTemp,
3235 ServicePtrs[iServiceIndex]->copymap);
3236 bRetval = True;
3238 } else {
3239 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3240 bRetval = False;
3243 free_service(&serviceTemp);
3244 return (bRetval);
3247 /***************************************************************************
3248 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3249 parameters is:
3251 [global]
3253 idmap uid = 1000-1999
3254 idmap gid = 700-899
3256 We only do simple parsing checks here. The strings are parsed into useful
3257 structures in the idmap daemon code.
3259 ***************************************************************************/
3261 /* Some lp_ routines to return idmap [ug]id information */
3263 static uid_t idmap_uid_low, idmap_uid_high;
3264 static gid_t idmap_gid_low, idmap_gid_high;
3266 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3268 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3269 return False;
3271 if (low)
3272 *low = idmap_uid_low;
3274 if (high)
3275 *high = idmap_uid_high;
3277 return True;
3280 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3282 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3283 return False;
3285 if (low)
3286 *low = idmap_gid_low;
3288 if (high)
3289 *high = idmap_gid_high;
3291 return True;
3294 /* Do some simple checks on "idmap [ug]id" parameter values */
3296 static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3298 uint32 low, high;
3300 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3301 return False;
3303 /* Parse OK */
3305 string_set(ptr, pszParmValue);
3307 idmap_uid_low = low;
3308 idmap_uid_high = high;
3310 return True;
3313 static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3315 uint32 low, high;
3317 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3318 return False;
3320 /* Parse OK */
3322 string_set(ptr, pszParmValue);
3324 idmap_gid_low = low;
3325 idmap_gid_high = high;
3327 return True;
3330 /***************************************************************************
3331 Handle the DEBUG level list.
3332 ***************************************************************************/
3334 static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3336 pstring pszParmValue;
3338 pstrcpy(pszParmValue, pszParmValueIn);
3339 string_set(ptr, pszParmValueIn);
3340 return debug_parse_levels( pszParmValue );
3343 /***************************************************************************
3344 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3345 ***************************************************************************/
3347 static const char *append_ldap_suffix( const char *str )
3349 const char *suffix_string;
3352 if (!lp_talloc)
3353 lp_talloc = talloc_init("lp_talloc");
3355 suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3356 if ( !suffix_string ) {
3357 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3358 return "";
3361 return suffix_string;
3364 const char *lp_ldap_machine_suffix(void)
3366 if (Globals.szLdapMachineSuffix[0])
3367 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3369 return lp_string(Globals.szLdapSuffix);
3372 const char *lp_ldap_user_suffix(void)
3374 if (Globals.szLdapUserSuffix[0])
3375 return append_ldap_suffix(Globals.szLdapUserSuffix);
3377 return lp_string(Globals.szLdapSuffix);
3380 const char *lp_ldap_group_suffix(void)
3382 if (Globals.szLdapGroupSuffix[0])
3383 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3385 return lp_string(Globals.szLdapSuffix);
3388 const char *lp_ldap_idmap_suffix(void)
3390 if (Globals.szLdapIdmapSuffix[0])
3391 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3393 return lp_string(Globals.szLdapSuffix);
3396 /****************************************************************************
3397 set the value for a P_ENUM
3398 ***************************************************************************/
3400 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3401 int *ptr )
3403 int i;
3405 for (i = 0; parm->enum_list[i].name; i++) {
3406 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3407 *ptr = parm->enum_list[i].value;
3408 break;
3413 /***************************************************************************
3414 ***************************************************************************/
3416 static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3418 static int parm_num = -1;
3419 service *s;
3421 if ( parm_num == -1 )
3422 parm_num = map_parameter( "printing" );
3424 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3426 if ( snum < 0 )
3427 s = &sDefault;
3428 else
3429 s = ServicePtrs[snum];
3431 init_printer_values( s );
3433 return True;
3437 /***************************************************************************
3438 Initialise a copymap.
3439 ***************************************************************************/
3441 static void init_copymap(service * pservice)
3443 int i;
3444 SAFE_FREE(pservice->copymap);
3445 pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3446 if (!pservice->copymap)
3447 DEBUG(0,
3448 ("Couldn't allocate copymap!! (size %d)\n",
3449 (int)NUMPARAMETERS));
3450 else
3451 for (i = 0; i < NUMPARAMETERS; i++)
3452 pservice->copymap[i] = True;
3455 /***************************************************************************
3456 Return the local pointer to a parameter given the service number and the
3457 pointer into the default structure.
3458 ***************************************************************************/
3460 void *lp_local_ptr(int snum, void *ptr)
3462 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3465 /***************************************************************************
3466 Process a parameter for a particular service number. If snum < 0
3467 then assume we are in the globals.
3468 ***************************************************************************/
3470 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3472 int parmnum, i, slen;
3473 void *parm_ptr = NULL; /* where we are going to store the result */
3474 void *def_ptr = NULL;
3475 pstring param_key;
3476 char *sep;
3477 param_opt_struct *paramo, *data;
3478 BOOL not_added;
3480 parmnum = map_parameter(pszParmName);
3482 if (parmnum < 0) {
3483 if ((sep=strchr(pszParmName, ':')) != NULL) {
3484 *sep = '\0';
3485 ZERO_STRUCT(param_key);
3486 pstr_sprintf(param_key, "%s:", pszParmName);
3487 slen = strlen(param_key);
3488 pstrcat(param_key, sep+1);
3489 trim_char(param_key+slen, ' ', ' ');
3490 not_added = True;
3491 data = (snum < 0) ? Globals.param_opt :
3492 ServicePtrs[snum]->param_opt;
3493 /* Traverse destination */
3494 while (data) {
3495 /* If we already have same option, override it */
3496 if (strcmp(data->key, param_key) == 0) {
3497 string_free(&data->value);
3498 str_list_free(&data->list);
3499 data->value = SMB_STRDUP(pszParmValue);
3500 not_added = False;
3501 break;
3503 data = data->next;
3505 if (not_added) {
3506 paramo = SMB_XMALLOC_P(param_opt_struct);
3507 paramo->key = SMB_STRDUP(param_key);
3508 paramo->value = SMB_STRDUP(pszParmValue);
3509 paramo->list = NULL;
3510 if (snum < 0) {
3511 DLIST_ADD(Globals.param_opt, paramo);
3512 } else {
3513 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3517 *sep = ':';
3518 return (True);
3520 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3521 return (True);
3524 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3525 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3526 pszParmName));
3529 def_ptr = parm_table[parmnum].ptr;
3531 /* we might point at a service, the default service or a global */
3532 if (snum < 0) {
3533 parm_ptr = def_ptr;
3534 } else {
3535 if (parm_table[parmnum].p_class == P_GLOBAL) {
3536 DEBUG(0,
3537 ("Global parameter %s found in service section!\n",
3538 pszParmName));
3539 return (True);
3541 parm_ptr =
3542 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3543 &sDefault);
3545 if (!ServicePtrs[snum]->copymap)
3546 init_copymap(ServicePtrs[snum]);
3548 /* this handles the aliases - set the copymap for other entries with
3549 the same data pointer */
3550 for (i = 0; parm_table[i].label; i++)
3551 if (parm_table[i].ptr == parm_table[parmnum].ptr)
3552 ServicePtrs[snum]->copymap[i] = False;
3555 /* if it is a special case then go ahead */
3556 if (parm_table[parmnum].special) {
3557 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3558 return (True);
3561 /* now switch on the type of variable it is */
3562 switch (parm_table[parmnum].type)
3564 case P_BOOL:
3565 *(BOOL *)parm_ptr = lp_bool(pszParmValue);
3566 break;
3568 case P_BOOLREV:
3569 *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
3570 break;
3572 case P_INTEGER:
3573 *(int *)parm_ptr = lp_int(pszParmValue);
3574 break;
3576 case P_CHAR:
3577 *(char *)parm_ptr = *pszParmValue;
3578 break;
3580 case P_OCTAL:
3581 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3582 if ( i != 1 ) {
3583 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3585 break;
3587 case P_LIST:
3588 str_list_free((char ***)parm_ptr);
3589 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3590 break;
3592 case P_STRING:
3593 string_set((char **)parm_ptr, pszParmValue);
3594 break;
3596 case P_USTRING:
3597 string_set((char **)parm_ptr, pszParmValue);
3598 strupper_m(*(char **)parm_ptr);
3599 break;
3601 case P_GSTRING:
3602 pstrcpy((char *)parm_ptr, pszParmValue);
3603 break;
3605 case P_UGSTRING:
3606 pstrcpy((char *)parm_ptr, pszParmValue);
3607 strupper_m((char *)parm_ptr);
3608 break;
3610 case P_ENUM:
3611 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3612 break;
3613 case P_SEP:
3614 break;
3617 return (True);
3620 /***************************************************************************
3621 Process a parameter.
3622 ***************************************************************************/
3624 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3626 if (!bInGlobalSection && bGlobalOnly)
3627 return (True);
3629 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3631 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3632 pszParmName, pszParmValue));
3635 /***************************************************************************
3636 Print a parameter of the specified type.
3637 ***************************************************************************/
3639 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3641 int i;
3642 switch (p->type)
3644 case P_ENUM:
3645 for (i = 0; p->enum_list[i].name; i++) {
3646 if (*(int *)ptr == p->enum_list[i].value) {
3647 fprintf(f, "%s",
3648 p->enum_list[i].name);
3649 break;
3652 break;
3654 case P_BOOL:
3655 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3656 break;
3658 case P_BOOLREV:
3659 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3660 break;
3662 case P_INTEGER:
3663 fprintf(f, "%d", *(int *)ptr);
3664 break;
3666 case P_CHAR:
3667 fprintf(f, "%c", *(char *)ptr);
3668 break;
3670 case P_OCTAL:
3671 fprintf(f, "%s", octal_string(*(int *)ptr));
3672 break;
3674 case P_LIST:
3675 if ((char ***)ptr && *(char ***)ptr) {
3676 char **list = *(char ***)ptr;
3678 for (; *list; list++) {
3679 /* surround strings with whitespace in double quotes */
3680 if ( strchr_m( *list, ' ' ) )
3681 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3682 else
3683 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3686 break;
3688 case P_GSTRING:
3689 case P_UGSTRING:
3690 if ((char *)ptr) {
3691 fprintf(f, "%s", (char *)ptr);
3693 break;
3695 case P_STRING:
3696 case P_USTRING:
3697 if (*(char **)ptr) {
3698 fprintf(f, "%s", *(char **)ptr);
3700 break;
3701 case P_SEP:
3702 break;
3706 /***************************************************************************
3707 Check if two parameters are equal.
3708 ***************************************************************************/
3710 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3712 switch (type) {
3713 case P_BOOL:
3714 case P_BOOLREV:
3715 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3717 case P_INTEGER:
3718 case P_ENUM:
3719 case P_OCTAL:
3720 return (*((int *)ptr1) == *((int *)ptr2));
3722 case P_CHAR:
3723 return (*((char *)ptr1) == *((char *)ptr2));
3725 case P_LIST:
3726 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3728 case P_GSTRING:
3729 case P_UGSTRING:
3731 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3732 if (p1 && !*p1)
3733 p1 = NULL;
3734 if (p2 && !*p2)
3735 p2 = NULL;
3736 return (p1 == p2 || strequal(p1, p2));
3738 case P_STRING:
3739 case P_USTRING:
3741 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3742 if (p1 && !*p1)
3743 p1 = NULL;
3744 if (p2 && !*p2)
3745 p2 = NULL;
3746 return (p1 == p2 || strequal(p1, p2));
3748 case P_SEP:
3749 break;
3751 return (False);
3754 /***************************************************************************
3755 Initialize any local varients in the sDefault table.
3756 ***************************************************************************/
3758 void init_locals(void)
3760 /* None as yet. */
3763 /***************************************************************************
3764 Process a new section (service). At this stage all sections are services.
3765 Later we'll have special sections that permit server parameters to be set.
3766 Returns True on success, False on failure.
3767 ***************************************************************************/
3769 static BOOL do_section(const char *pszSectionName)
3771 BOOL bRetval;
3772 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3773 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3774 bRetval = False;
3776 /* if we were in a global section then do the local inits */
3777 if (bInGlobalSection && !isglobal)
3778 init_locals();
3780 /* if we've just struck a global section, note the fact. */
3781 bInGlobalSection = isglobal;
3783 /* check for multiple global sections */
3784 if (bInGlobalSection) {
3785 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3786 return (True);
3789 if (!bInGlobalSection && bGlobalOnly)
3790 return (True);
3792 /* if we have a current service, tidy it up before moving on */
3793 bRetval = True;
3795 if (iServiceIndex >= 0)
3796 bRetval = service_ok(iServiceIndex);
3798 /* if all is still well, move to the next record in the services array */
3799 if (bRetval) {
3800 /* We put this here to avoid an odd message order if messages are */
3801 /* issued by the post-processing of a previous section. */
3802 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3804 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3805 < 0) {
3806 DEBUG(0, ("Failed to add a new service\n"));
3807 return (False);
3811 return (bRetval);
3815 /***************************************************************************
3816 Determine if a partcular base parameter is currentl set to the default value.
3817 ***************************************************************************/
3819 static BOOL is_default(int i)
3821 if (!defaults_saved)
3822 return False;
3823 switch (parm_table[i].type) {
3824 case P_LIST:
3825 return str_list_compare (parm_table[i].def.lvalue,
3826 *(char ***)parm_table[i].ptr);
3827 case P_STRING:
3828 case P_USTRING:
3829 return strequal(parm_table[i].def.svalue,
3830 *(char **)parm_table[i].ptr);
3831 case P_GSTRING:
3832 case P_UGSTRING:
3833 return strequal(parm_table[i].def.svalue,
3834 (char *)parm_table[i].ptr);
3835 case P_BOOL:
3836 case P_BOOLREV:
3837 return parm_table[i].def.bvalue ==
3838 *(BOOL *)parm_table[i].ptr;
3839 case P_CHAR:
3840 return parm_table[i].def.cvalue ==
3841 *(char *)parm_table[i].ptr;
3842 case P_INTEGER:
3843 case P_OCTAL:
3844 case P_ENUM:
3845 return parm_table[i].def.ivalue ==
3846 *(int *)parm_table[i].ptr;
3847 case P_SEP:
3848 break;
3850 return False;
3853 /***************************************************************************
3854 Display the contents of the global structure.
3855 ***************************************************************************/
3857 static void dump_globals(FILE *f)
3859 int i;
3860 param_opt_struct *data;
3862 fprintf(f, "[global]\n");
3864 for (i = 0; parm_table[i].label; i++)
3865 if (parm_table[i].p_class == P_GLOBAL &&
3866 parm_table[i].ptr &&
3867 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3868 if (defaults_saved && is_default(i))
3869 continue;
3870 fprintf(f, "\t%s = ", parm_table[i].label);
3871 print_parameter(&parm_table[i], parm_table[i].ptr, f);
3872 fprintf(f, "\n");
3874 if (Globals.param_opt != NULL) {
3875 data = Globals.param_opt;
3876 while(data) {
3877 fprintf(f, "\t%s = %s\n", data->key, data->value);
3878 data = data->next;
3884 /***************************************************************************
3885 Return True if a local parameter is currently set to the global default.
3886 ***************************************************************************/
3888 BOOL lp_is_default(int snum, struct parm_struct *parm)
3890 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3892 return equal_parameter(parm->type,
3893 ((char *)ServicePtrs[snum]) + pdiff,
3894 ((char *)&sDefault) + pdiff);
3897 /***************************************************************************
3898 Display the contents of a single services record.
3899 ***************************************************************************/
3901 static void dump_a_service(service * pService, FILE * f)
3903 int i;
3904 param_opt_struct *data;
3906 if (pService != &sDefault)
3907 fprintf(f, "[%s]\n", pService->szService);
3909 for (i = 0; parm_table[i].label; i++) {
3911 if (parm_table[i].p_class == P_LOCAL &&
3912 parm_table[i].ptr &&
3913 (*parm_table[i].label != '-') &&
3914 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3917 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3919 if (pService == &sDefault) {
3920 if (defaults_saved && is_default(i))
3921 continue;
3922 } else {
3923 if (equal_parameter(parm_table[i].type,
3924 ((char *)pService) +
3925 pdiff,
3926 ((char *)&sDefault) +
3927 pdiff))
3928 continue;
3931 fprintf(f, "\t%s = ", parm_table[i].label);
3932 print_parameter(&parm_table[i],
3933 ((char *)pService) + pdiff, f);
3934 fprintf(f, "\n");
3938 if (pService->param_opt != NULL) {
3939 data = pService->param_opt;
3940 while(data) {
3941 fprintf(f, "\t%s = %s\n", data->key, data->value);
3942 data = data->next;
3947 /***************************************************************************
3948 Display the contents of a parameter of a single services record.
3949 ***************************************************************************/
3951 BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
3953 int i;
3954 BOOL result = False;
3955 parm_class p_class;
3956 unsigned flag = 0;
3957 fstring local_parm_name;
3958 char *parm_opt;
3959 const char *parm_opt_value;
3961 /* check for parametrical option */
3962 fstrcpy( local_parm_name, parm_name);
3963 parm_opt = strchr( local_parm_name, ':');
3965 if (parm_opt) {
3966 *parm_opt = '\0';
3967 parm_opt++;
3968 if (strlen(parm_opt)) {
3969 parm_opt_value = lp_parm_const_string( snum,
3970 local_parm_name, parm_opt, NULL);
3971 if (parm_opt_value) {
3972 printf( "%s\n", parm_opt_value);
3973 result = True;
3976 return result;
3979 /* check for a key and print the value */
3980 if (isGlobal) {
3981 p_class = P_GLOBAL;
3982 flag = FLAG_GLOBAL;
3983 } else
3984 p_class = P_LOCAL;
3986 for (i = 0; parm_table[i].label; i++) {
3987 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3988 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3989 parm_table[i].ptr &&
3990 (*parm_table[i].label != '-') &&
3991 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3993 void *ptr;
3995 if (isGlobal) {
3996 ptr = parm_table[i].ptr;
3997 } else {
3998 service * pService = ServicePtrs[snum];
3999 ptr = ((char *)pService) +
4000 PTR_DIFF(parm_table[i].ptr, &sDefault);
4003 print_parameter(&parm_table[i],
4004 ptr, f);
4005 fprintf(f, "\n");
4006 result = True;
4007 break;
4011 return result;
4014 /***************************************************************************
4015 Return info about the next parameter in a service.
4016 snum==GLOBAL_SECTION_SNUM gives the globals.
4017 Return NULL when out of parameters.
4018 ***************************************************************************/
4020 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
4022 if (snum < 0) {
4023 /* do the globals */
4024 for (; parm_table[*i].label; (*i)++) {
4025 if (parm_table[*i].p_class == P_SEPARATOR)
4026 return &parm_table[(*i)++];
4028 if (!parm_table[*i].ptr
4029 || (*parm_table[*i].label == '-'))
4030 continue;
4032 if ((*i) > 0
4033 && (parm_table[*i].ptr ==
4034 parm_table[(*i) - 1].ptr))
4035 continue;
4037 return &parm_table[(*i)++];
4039 } else {
4040 service *pService = ServicePtrs[snum];
4042 for (; parm_table[*i].label; (*i)++) {
4043 if (parm_table[*i].p_class == P_SEPARATOR)
4044 return &parm_table[(*i)++];
4046 if (parm_table[*i].p_class == P_LOCAL &&
4047 parm_table[*i].ptr &&
4048 (*parm_table[*i].label != '-') &&
4049 ((*i) == 0 ||
4050 (parm_table[*i].ptr !=
4051 parm_table[(*i) - 1].ptr)))
4053 int pdiff =
4054 PTR_DIFF(parm_table[*i].ptr,
4055 &sDefault);
4057 if (allparameters ||
4058 !equal_parameter(parm_table[*i].type,
4059 ((char *)pService) +
4060 pdiff,
4061 ((char *)&sDefault) +
4062 pdiff))
4064 return &parm_table[(*i)++];
4070 return NULL;
4074 #if 0
4075 /***************************************************************************
4076 Display the contents of a single copy structure.
4077 ***************************************************************************/
4078 static void dump_copy_map(BOOL *pcopymap)
4080 int i;
4081 if (!pcopymap)
4082 return;
4084 printf("\n\tNon-Copied parameters:\n");
4086 for (i = 0; parm_table[i].label; i++)
4087 if (parm_table[i].p_class == P_LOCAL &&
4088 parm_table[i].ptr && !pcopymap[i] &&
4089 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
4091 printf("\t\t%s\n", parm_table[i].label);
4094 #endif
4096 /***************************************************************************
4097 Return TRUE if the passed service number is within range.
4098 ***************************************************************************/
4100 BOOL lp_snum_ok(int iService)
4102 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4105 /***************************************************************************
4106 Auto-load some home services.
4107 ***************************************************************************/
4109 static void lp_add_auto_services(char *str)
4111 char *s;
4112 char *p;
4113 int homes;
4115 if (!str)
4116 return;
4118 s = SMB_STRDUP(str);
4119 if (!s)
4120 return;
4122 homes = lp_servicenumber(HOMES_NAME);
4124 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4125 char *home = get_user_home_dir(p);
4127 if (lp_servicenumber(p) >= 0)
4128 continue;
4130 if (home && homes >= 0)
4131 lp_add_home(p, homes, p, home);
4133 SAFE_FREE(s);
4136 /***************************************************************************
4137 Auto-load one printer.
4138 ***************************************************************************/
4140 void lp_add_one_printer(char *name, char *comment)
4142 int printers = lp_servicenumber(PRINTERS_NAME);
4143 int i;
4145 if (lp_servicenumber(name) < 0) {
4146 lp_add_printer(name, printers);
4147 if ((i = lp_servicenumber(name)) >= 0) {
4148 string_set(&ServicePtrs[i]->comment, comment);
4149 ServicePtrs[i]->autoloaded = True;
4154 /***************************************************************************
4155 Have we loaded a services file yet?
4156 ***************************************************************************/
4158 BOOL lp_loaded(void)
4160 return (bLoaded);
4163 /***************************************************************************
4164 Unload unused services.
4165 ***************************************************************************/
4167 void lp_killunused(BOOL (*snumused) (int))
4169 int i;
4170 for (i = 0; i < iNumServices; i++) {
4171 if (!VALID(i))
4172 continue;
4174 /* don't kill autoloaded or usershare services */
4175 if ( ServicePtrs[i]->autoloaded ||
4176 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4177 continue;
4180 if (!snumused || !snumused(i)) {
4181 free_service_byindex(i);
4186 /***************************************************************************
4187 Unload a service.
4188 ***************************************************************************/
4190 void lp_killservice(int iServiceIn)
4192 if (VALID(iServiceIn)) {
4193 free_service_byindex(iServiceIn);
4197 /***************************************************************************
4198 Save the curent values of all global and sDefault parameters into the
4199 defaults union. This allows swat and testparm to show only the
4200 changed (ie. non-default) parameters.
4201 ***************************************************************************/
4203 static void lp_save_defaults(void)
4205 int i;
4206 for (i = 0; parm_table[i].label; i++) {
4207 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4208 continue;
4209 switch (parm_table[i].type) {
4210 case P_LIST:
4211 str_list_copy(&(parm_table[i].def.lvalue),
4212 *(const char ***)parm_table[i].ptr);
4213 break;
4214 case P_STRING:
4215 case P_USTRING:
4216 if (parm_table[i].ptr) {
4217 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4218 } else {
4219 parm_table[i].def.svalue = NULL;
4221 break;
4222 case P_GSTRING:
4223 case P_UGSTRING:
4224 if (parm_table[i].ptr) {
4225 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4226 } else {
4227 parm_table[i].def.svalue = NULL;
4229 break;
4230 case P_BOOL:
4231 case P_BOOLREV:
4232 parm_table[i].def.bvalue =
4233 *(BOOL *)parm_table[i].ptr;
4234 break;
4235 case P_CHAR:
4236 parm_table[i].def.cvalue =
4237 *(char *)parm_table[i].ptr;
4238 break;
4239 case P_INTEGER:
4240 case P_OCTAL:
4241 case P_ENUM:
4242 parm_table[i].def.ivalue =
4243 *(int *)parm_table[i].ptr;
4244 break;
4245 case P_SEP:
4246 break;
4249 defaults_saved = True;
4252 /*******************************************************************
4253 Set the server type we will announce as via nmbd.
4254 ********************************************************************/
4256 static const struct srv_role_tab {
4257 uint32 role;
4258 const char *role_str;
4259 } srv_role_tab [] = {
4260 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4261 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4262 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4263 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4264 { 0, NULL }
4267 const char* server_role_str(uint32 role)
4269 int i = 0;
4270 for (i=0; srv_role_tab[i].role_str; i++) {
4271 if (role == srv_role_tab[i].role) {
4272 return srv_role_tab[i].role_str;
4275 return NULL;
4278 static void set_server_role(void)
4280 server_role = ROLE_STANDALONE;
4282 switch (lp_security()) {
4283 case SEC_SHARE:
4284 if (lp_domain_logons())
4285 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4286 break;
4287 case SEC_SERVER:
4288 if (lp_domain_logons())
4289 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4290 /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
4291 server_role = ROLE_STANDALONE;
4292 break;
4293 case SEC_DOMAIN:
4294 if (lp_domain_logons()) {
4295 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4296 server_role = ROLE_DOMAIN_BDC;
4297 break;
4299 server_role = ROLE_DOMAIN_MEMBER;
4300 break;
4301 case SEC_ADS:
4302 if (lp_domain_logons()) {
4303 server_role = ROLE_DOMAIN_PDC;
4304 break;
4306 server_role = ROLE_DOMAIN_MEMBER;
4307 break;
4308 case SEC_USER:
4309 if (lp_domain_logons()) {
4311 if (Globals.bDomainMaster) /* auto or yes */
4312 server_role = ROLE_DOMAIN_PDC;
4313 else
4314 server_role = ROLE_DOMAIN_BDC;
4316 break;
4317 default:
4318 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4319 break;
4322 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4325 /***********************************************************
4326 If we should send plaintext/LANMAN passwords in the clinet
4327 ************************************************************/
4329 static void set_allowed_client_auth(void)
4331 if (Globals.bClientNTLMv2Auth) {
4332 Globals.bClientLanManAuth = False;
4334 if (!Globals.bClientLanManAuth) {
4335 Globals.bClientPlaintextAuth = False;
4339 /***************************************************************************
4340 JRA.
4341 The following code allows smbd to read a user defined share file.
4342 Yes, this is my intent. Yes, I'm comfortable with that...
4344 THE FOLLOWING IS SECURITY CRITICAL CODE.
4346 It washes your clothes, it cleans your house, it guards you while you sleep...
4347 Do not f%^k with it....
4348 ***************************************************************************/
4350 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4352 /***************************************************************************
4353 Check allowed stat state of a usershare file.
4354 Ensure we print out who is dicking with us so the admin can
4355 get their sorry ass fired.
4356 ***************************************************************************/
4358 static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4360 if (!S_ISREG(psbuf->st_mode)) {
4361 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4362 "not a regular file\n",
4363 fname, (unsigned int)psbuf->st_uid ));
4364 return False;
4367 /* Ensure this doesn't have the other write bit set. */
4368 if (psbuf->st_mode & S_IWOTH) {
4369 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4370 "public write. Refusing to allow as a usershare file.\n",
4371 fname, (unsigned int)psbuf->st_uid ));
4372 return False;
4375 /* Should be 10k or less. */
4376 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4377 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4378 "too large (%u) to be a user share file.\n",
4379 fname, (unsigned int)psbuf->st_uid,
4380 (unsigned int)psbuf->st_size ));
4381 return False;
4384 return True;
4387 /***************************************************************************
4388 Parse the contents of a usershare file.
4389 ***************************************************************************/
4391 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4392 SMB_STRUCT_STAT *psbuf,
4393 const char *servicename,
4394 int snum,
4395 char **lines,
4396 int numlines,
4397 pstring sharepath,
4398 pstring comment,
4399 SEC_DESC **ppsd,
4400 BOOL *pallow_guest)
4402 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4403 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4404 int us_vers;
4405 SMB_STRUCT_DIR *dp;
4406 SMB_STRUCT_STAT sbuf;
4408 *pallow_guest = False;
4410 if (numlines < 4) {
4411 return USERSHARE_MALFORMED_FILE;
4414 if (strcmp(lines[0], "#VERSION 1") == 0) {
4415 us_vers = 1;
4416 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4417 us_vers = 2;
4418 if (numlines < 5) {
4419 return USERSHARE_MALFORMED_FILE;
4421 } else {
4422 return USERSHARE_BAD_VERSION;
4425 if (strncmp(lines[1], "path=", 5) != 0) {
4426 return USERSHARE_MALFORMED_PATH;
4429 pstrcpy(sharepath, &lines[1][5]);
4430 trim_string(sharepath, " ", " ");
4432 if (strncmp(lines[2], "comment=", 8) != 0) {
4433 return USERSHARE_MALFORMED_COMMENT_DEF;
4436 pstrcpy(comment, &lines[2][8]);
4437 trim_string(comment, " ", " ");
4438 trim_char(comment, '"', '"');
4440 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4441 return USERSHARE_MALFORMED_ACL_DEF;
4444 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4445 return USERSHARE_ACL_ERR;
4448 if (us_vers == 2) {
4449 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4450 return USERSHARE_MALFORMED_ACL_DEF;
4452 if (lines[4][9] == 'y') {
4453 *pallow_guest = True;
4457 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4458 /* Path didn't change, no checks needed. */
4459 return USERSHARE_OK;
4462 /* The path *must* be absolute. */
4463 if (sharepath[0] != '/') {
4464 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4465 servicename, sharepath));
4466 return USERSHARE_PATH_NOT_ABSOLUTE;
4469 /* If there is a usershare prefix deny list ensure one of these paths
4470 doesn't match the start of the user given path. */
4471 if (prefixdenylist) {
4472 int i;
4473 for ( i=0; prefixdenylist[i]; i++ ) {
4474 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4475 servicename, i, prefixdenylist[i], sharepath ));
4476 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4477 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4478 "usershare prefix deny list entries.\n",
4479 servicename, sharepath));
4480 return USERSHARE_PATH_IS_DENIED;
4485 /* If there is a usershare prefix allow list ensure one of these paths
4486 does match the start of the user given path. */
4488 if (prefixallowlist) {
4489 int i;
4490 for ( i=0; prefixallowlist[i]; i++ ) {
4491 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4492 servicename, i, prefixallowlist[i], sharepath ));
4493 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4494 break;
4497 if (prefixallowlist[i] == NULL) {
4498 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4499 "usershare prefix allow list entries.\n",
4500 servicename, sharepath));
4501 return USERSHARE_PATH_NOT_ALLOWED;
4505 /* Ensure this is pointing to a directory. */
4506 dp = sys_opendir(sharepath);
4508 if (!dp) {
4509 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4510 servicename, sharepath));
4511 return USERSHARE_PATH_NOT_DIRECTORY;
4514 /* Ensure the owner of the usershare file has permission to share
4515 this directory. */
4517 if (sys_stat(sharepath, &sbuf) == -1) {
4518 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4519 servicename, sharepath, strerror(errno) ));
4520 sys_closedir(dp);
4521 return USERSHARE_POSIX_ERR;
4524 sys_closedir(dp);
4526 if (!S_ISDIR(sbuf.st_mode)) {
4527 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4528 servicename, sharepath ));
4529 return USERSHARE_PATH_NOT_DIRECTORY;
4532 /* Check if sharing is restricted to owner-only. */
4533 /* psbuf is the stat of the usershare definition file,
4534 sbuf is the stat of the target directory to be shared. */
4536 if (lp_usershare_owner_only()) {
4537 /* root can share anything. */
4538 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4539 return USERSHARE_PATH_NOT_ALLOWED;
4543 return USERSHARE_OK;
4546 /***************************************************************************
4547 Deal with a usershare file.
4548 Returns:
4549 >= 0 - snum
4550 -1 - Bad name, invalid contents.
4551 - service name already existed and not a usershare, problem
4552 with permissions to share directory etc.
4553 ***************************************************************************/
4555 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4557 SMB_STRUCT_STAT sbuf;
4558 SMB_STRUCT_STAT lsbuf;
4559 pstring fname;
4560 pstring sharepath;
4561 pstring comment;
4562 fstring service_name;
4563 char **lines = NULL;
4564 int numlines = 0;
4565 int fd = -1;
4566 int iService = -1;
4567 TALLOC_CTX *ctx = NULL;
4568 SEC_DESC *psd = NULL;
4569 BOOL guest_ok = False;
4571 /* Ensure share name doesn't contain invalid characters. */
4572 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4573 DEBUG(0,("process_usershare_file: share name %s contains "
4574 "invalid characters (any of %s)\n",
4575 file_name, INVALID_SHARENAME_CHARS ));
4576 return -1;
4579 fstrcpy(service_name, file_name);
4581 pstrcpy(fname, dir_name);
4582 pstrcat(fname, "/");
4583 pstrcat(fname, file_name);
4585 /* Minimize the race condition by doing an lstat before we
4586 open and fstat. Ensure this isn't a symlink link. */
4588 if (sys_lstat(fname, &lsbuf) != 0) {
4589 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4590 fname, strerror(errno) ));
4591 return -1;
4594 /* This must be a regular file, not a symlink, directory or
4595 other strange filetype. */
4596 if (!check_usershare_stat(fname, &lsbuf)) {
4597 return -1;
4600 /* See if there is already a servicenum for this name. */
4601 /* tdb_fetch_int32 returns -1 if not found. */
4602 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4604 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4605 /* Nothing changed - Mark valid and return. */
4606 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4607 service_name ));
4608 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4609 return iService;
4612 /* Try and open the file read only - no symlinks allowed. */
4613 #ifdef O_NOFOLLOW
4614 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4615 #else
4616 fd = sys_open(fname, O_RDONLY, 0);
4617 #endif
4619 if (fd == -1) {
4620 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4621 fname, strerror(errno) ));
4622 return -1;
4625 /* Now fstat to be *SURE* it's a regular file. */
4626 if (sys_fstat(fd, &sbuf) != 0) {
4627 close(fd);
4628 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4629 fname, strerror(errno) ));
4630 return -1;
4633 /* Is it the same dev/inode as was lstated ? */
4634 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4635 close(fd);
4636 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4637 "Symlink spoofing going on ?\n", fname ));
4638 return -1;
4641 /* This must be a regular file, not a symlink, directory or
4642 other strange filetype. */
4643 if (!check_usershare_stat(fname, &sbuf)) {
4644 return -1;
4647 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4649 close(fd);
4650 if (lines == NULL) {
4651 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4652 fname, (unsigned int)sbuf.st_uid ));
4653 return -1;
4656 /* Should we allow printers to be shared... ? */
4657 ctx = talloc_init("usershare_sd_xctx");
4658 if (!ctx) {
4659 file_lines_free(lines);
4660 return 1;
4663 if (parse_usershare_file(ctx, &sbuf, service_name,
4664 iService, lines, numlines, sharepath,
4665 comment, &psd, &guest_ok) != USERSHARE_OK) {
4666 talloc_destroy(ctx);
4667 file_lines_free(lines);
4668 return -1;
4671 file_lines_free(lines);
4673 /* Everything ok - add the service possibly using a template. */
4674 if (iService < 0) {
4675 const service *sp = &sDefault;
4676 if (snum_template != -1) {
4677 sp = ServicePtrs[snum_template];
4680 if ((iService = add_a_service(sp, service_name)) < 0) {
4681 DEBUG(0, ("process_usershare_file: Failed to add "
4682 "new service %s\n", service_name));
4683 talloc_destroy(ctx);
4684 return -1;
4687 /* Read only is controlled by usershare ACL below. */
4688 ServicePtrs[iService]->bRead_only = False;
4691 /* Write the ACL of the new/modified share. */
4692 if (!set_share_security(service_name, psd)) {
4693 DEBUG(0, ("process_usershare_file: Failed to set share "
4694 "security for user share %s\n",
4695 service_name ));
4696 lp_remove_service(iService);
4697 talloc_destroy(ctx);
4698 return -1;
4701 talloc_destroy(ctx);
4703 /* If from a template it may be marked invalid. */
4704 ServicePtrs[iService]->valid = True;
4706 /* Set the service as a valid usershare. */
4707 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4709 /* Set guest access. */
4710 if (lp_usershare_allow_guests()) {
4711 ServicePtrs[iService]->bGuest_ok = guest_ok;
4714 /* And note when it was loaded. */
4715 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4716 string_set(&ServicePtrs[iService]->szPath, sharepath);
4717 string_set(&ServicePtrs[iService]->comment, comment);
4719 return iService;
4722 /***************************************************************************
4723 Checks if a usershare entry has been modified since last load.
4724 ***************************************************************************/
4726 static BOOL usershare_exists(int iService, time_t *last_mod)
4728 SMB_STRUCT_STAT lsbuf;
4729 const char *usersharepath = Globals.szUsersharePath;
4730 pstring fname;
4732 pstrcpy(fname, usersharepath);
4733 pstrcat(fname, "/");
4734 pstrcat(fname, ServicePtrs[iService]->szService);
4736 if (sys_lstat(fname, &lsbuf) != 0) {
4737 return False;
4740 if (!S_ISREG(lsbuf.st_mode)) {
4741 return False;
4744 *last_mod = lsbuf.st_mtime;
4745 return True;
4748 /***************************************************************************
4749 Load a usershare service by name. Returns a valid servicenumber or -1.
4750 ***************************************************************************/
4752 int load_usershare_service(const char *servicename)
4754 SMB_STRUCT_STAT sbuf;
4755 const char *usersharepath = Globals.szUsersharePath;
4756 int max_user_shares = Globals.iUsershareMaxShares;
4757 int snum_template = -1;
4759 if (*usersharepath == 0 || max_user_shares == 0) {
4760 return -1;
4763 if (sys_stat(usersharepath, &sbuf) != 0) {
4764 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4765 usersharepath, strerror(errno) ));
4766 return -1;
4769 if (!S_ISDIR(sbuf.st_mode)) {
4770 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4771 usersharepath ));
4772 return -1;
4776 * This directory must be owned by root, and have the 't' bit set.
4777 * It also must not be writable by "other".
4780 #ifdef S_ISVTX
4781 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4782 #else
4783 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4784 #endif
4785 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4786 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4787 usersharepath ));
4788 return -1;
4791 /* Ensure the template share exists if it's set. */
4792 if (Globals.szUsershareTemplateShare[0]) {
4793 /* We can't use lp_servicenumber here as we are recommending that
4794 template shares have -valid=False set. */
4795 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4796 if (ServicePtrs[snum_template]->szService &&
4797 strequal(ServicePtrs[snum_template]->szService,
4798 Globals.szUsershareTemplateShare)) {
4799 break;
4803 if (snum_template == -1) {
4804 DEBUG(0,("load_usershare_service: usershare template share %s "
4805 "does not exist.\n",
4806 Globals.szUsershareTemplateShare ));
4807 return -1;
4811 return process_usershare_file(usersharepath, servicename, snum_template);
4814 /***************************************************************************
4815 Load all user defined shares from the user share directory.
4816 We only do this if we're enumerating the share list.
4817 This is the function that can delete usershares that have
4818 been removed.
4819 ***************************************************************************/
4821 int load_usershare_shares(void)
4823 SMB_STRUCT_DIR *dp;
4824 SMB_STRUCT_STAT sbuf;
4825 SMB_STRUCT_DIRENT *de;
4826 int num_usershares = 0;
4827 int max_user_shares = Globals.iUsershareMaxShares;
4828 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4829 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4830 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4831 int iService;
4832 int snum_template = -1;
4833 const char *usersharepath = Globals.szUsersharePath;
4834 int ret = lp_numservices();
4836 if (max_user_shares == 0 || *usersharepath == '\0') {
4837 return lp_numservices();
4840 if (sys_stat(usersharepath, &sbuf) != 0) {
4841 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4842 usersharepath, strerror(errno) ));
4843 return ret;
4847 * This directory must be owned by root, and have the 't' bit set.
4848 * It also must not be writable by "other".
4851 #ifdef S_ISVTX
4852 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4853 #else
4854 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4855 #endif
4856 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4857 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4858 usersharepath ));
4859 return ret;
4862 /* Ensure the template share exists if it's set. */
4863 if (Globals.szUsershareTemplateShare[0]) {
4864 /* We can't use lp_servicenumber here as we are recommending that
4865 template shares have -valid=False set. */
4866 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4867 if (ServicePtrs[snum_template]->szService &&
4868 strequal(ServicePtrs[snum_template]->szService,
4869 Globals.szUsershareTemplateShare)) {
4870 break;
4874 if (snum_template == -1) {
4875 DEBUG(0,("load_usershare_shares: usershare template share %s "
4876 "does not exist.\n",
4877 Globals.szUsershareTemplateShare ));
4878 return ret;
4882 /* Mark all existing usershares as pending delete. */
4883 for (iService = iNumServices - 1; iService >= 0; iService--) {
4884 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4885 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4889 dp = sys_opendir(usersharepath);
4890 if (!dp) {
4891 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4892 usersharepath, strerror(errno) ));
4893 return ret;
4896 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4897 (de = sys_readdir(dp));
4898 num_dir_entries++ ) {
4899 int r;
4900 const char *n = de->d_name;
4902 /* Ignore . and .. */
4903 if (*n == '.') {
4904 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4905 continue;
4909 if (n[0] == ':') {
4910 /* Temporary file used when creating a share. */
4911 num_tmp_dir_entries++;
4914 /* Allow 20% tmp entries. */
4915 if (num_tmp_dir_entries > allowed_tmp_entries) {
4916 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4917 "in directory %s\n",
4918 num_tmp_dir_entries, usersharepath));
4919 break;
4922 r = process_usershare_file(usersharepath, n, snum_template);
4923 if (r == 0) {
4924 /* Update the services count. */
4925 num_usershares++;
4926 if (num_usershares >= max_user_shares) {
4927 DEBUG(0,("load_usershare_shares: max user shares reached "
4928 "on file %s in directory %s\n",
4929 n, usersharepath ));
4930 break;
4932 } else if (r == -1) {
4933 num_bad_dir_entries++;
4936 /* Allow 20% bad entries. */
4937 if (num_bad_dir_entries > allowed_bad_entries) {
4938 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4939 "in directory %s\n",
4940 num_bad_dir_entries, usersharepath));
4941 break;
4944 /* Allow 20% bad entries. */
4945 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4946 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4947 "in directory %s\n",
4948 num_dir_entries, usersharepath));
4949 break;
4953 sys_closedir(dp);
4955 /* Sweep through and delete any non-refreshed usershares that are
4956 not currently in use. */
4957 for (iService = iNumServices - 1; iService >= 0; iService--) {
4958 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4959 if (conn_snum_used(iService)) {
4960 continue;
4962 /* Remove from the share ACL db. */
4963 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4964 lp_servicename(iService) ));
4965 delete_share_security(snum2params_static(iService));
4966 free_service_byindex(iService);
4970 return lp_numservices();
4973 /********************************************************
4974 Destroy global resources allocated in this file
4975 ********************************************************/
4977 void gfree_loadparm(void)
4979 struct file_lists *f;
4980 struct file_lists *next;
4981 int i;
4983 lp_TALLOC_FREE();
4985 /* Free the file lists */
4987 f = file_lists;
4988 while( f ) {
4989 next = f->next;
4990 SAFE_FREE( f->name );
4991 SAFE_FREE( f->subfname );
4992 SAFE_FREE( f );
4993 f = next;
4996 /* Free resources allocated to services */
4998 for ( i = 0; i < iNumServices; i++ ) {
4999 if ( VALID(i) ) {
5000 free_service_byindex(i);
5004 SAFE_FREE( ServicePtrs );
5005 iNumServices = 0;
5007 /* Now release all resources allocated to global
5008 parameters and the default service */
5010 for (i = 0; parm_table[i].label; i++)
5012 if ( parm_table[i].type == P_STRING
5013 || parm_table[i].type == P_USTRING )
5015 string_free( (char**)parm_table[i].ptr );
5017 else if (parm_table[i].type == P_LIST) {
5018 str_list_free( (char***)parm_table[i].ptr );
5023 /***************************************************************************
5024 Load the services array from the services file. Return True on success,
5025 False on failure.
5026 ***************************************************************************/
5028 BOOL lp_load(const char *pszFname,
5029 BOOL global_only,
5030 BOOL save_defaults,
5031 BOOL add_ipc,
5032 BOOL initialize_globals)
5034 pstring n2;
5035 BOOL bRetval;
5036 param_opt_struct *data, *pdata;
5038 pstrcpy(n2, pszFname);
5040 standard_sub_basic( get_current_username(), current_user_info.domain,
5041 n2,sizeof(n2) );
5043 add_to_file_list(pszFname, n2);
5045 bRetval = False;
5047 DEBUG(3, ("lp_load: refreshing parameters\n"));
5049 bInGlobalSection = True;
5050 bGlobalOnly = global_only;
5052 init_globals(! initialize_globals);
5053 debug_init();
5055 if (save_defaults) {
5056 init_locals();
5057 lp_save_defaults();
5060 if (Globals.param_opt != NULL) {
5061 data = Globals.param_opt;
5062 while (data) {
5063 string_free(&data->key);
5064 string_free(&data->value);
5065 str_list_free(&data->list);
5066 pdata = data->next;
5067 SAFE_FREE(data);
5068 data = pdata;
5070 Globals.param_opt = NULL;
5073 /* We get sections first, so have to start 'behind' to make up */
5074 iServiceIndex = -1;
5075 bRetval = pm_process(n2, do_section, do_parameter);
5077 /* finish up the last section */
5078 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
5079 if (bRetval)
5080 if (iServiceIndex >= 0)
5081 bRetval = service_ok(iServiceIndex);
5083 lp_add_auto_services(lp_auto_services());
5085 if (add_ipc) {
5086 /* When 'restrict anonymous = 2' guest connections to ipc$
5087 are denied */
5088 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
5089 if ( lp_enable_asu_support() )
5090 lp_add_ipc("ADMIN$", False);
5093 set_server_role();
5094 set_default_server_announce_type();
5095 set_allowed_client_auth();
5097 bLoaded = True;
5099 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
5100 /* if bWINSsupport is true and we are in the client */
5101 if (in_client && Globals.bWINSsupport) {
5102 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5105 init_iconv();
5107 return (bRetval);
5110 /***************************************************************************
5111 Reset the max number of services.
5112 ***************************************************************************/
5114 void lp_resetnumservices(void)
5116 iNumServices = 0;
5119 /***************************************************************************
5120 Return the max number of services.
5121 ***************************************************************************/
5123 int lp_numservices(void)
5125 return (iNumServices);
5128 /***************************************************************************
5129 Display the contents of the services array in human-readable form.
5130 ***************************************************************************/
5132 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
5134 int iService;
5136 if (show_defaults)
5137 defaults_saved = False;
5139 dump_globals(f);
5141 dump_a_service(&sDefault, f);
5143 for (iService = 0; iService < maxtoprint; iService++) {
5144 fprintf(f,"\n");
5145 lp_dump_one(f, show_defaults, iService);
5149 /***************************************************************************
5150 Display the contents of one service in human-readable form.
5151 ***************************************************************************/
5153 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
5155 if (VALID(snum)) {
5156 if (ServicePtrs[snum]->szService[0] == '\0')
5157 return;
5158 dump_a_service(ServicePtrs[snum], f);
5162 /***************************************************************************
5163 Return the number of the service with the given name, or -1 if it doesn't
5164 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5165 getservicebyname()! This works ONLY if all services have been loaded, and
5166 does not copy the found service.
5167 ***************************************************************************/
5169 int lp_servicenumber(const char *pszServiceName)
5171 int iService;
5172 fstring serviceName;
5174 if (!pszServiceName) {
5175 return GLOBAL_SECTION_SNUM;
5178 for (iService = iNumServices - 1; iService >= 0; iService--) {
5179 if (VALID(iService) && ServicePtrs[iService]->szService) {
5181 * The substitution here is used to support %U is
5182 * service names
5184 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5185 standard_sub_basic(get_current_username(),
5186 current_user_info.domain,
5187 serviceName,sizeof(serviceName));
5188 if (strequal(serviceName, pszServiceName)) {
5189 break;
5194 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5195 time_t last_mod;
5197 if (!usershare_exists(iService, &last_mod)) {
5198 /* Remove the share security tdb entry for it. */
5199 delete_share_security(snum2params_static(iService));
5200 /* Remove it from the array. */
5201 free_service_byindex(iService);
5202 /* Doesn't exist anymore. */
5203 return GLOBAL_SECTION_SNUM;
5206 /* Has it been modified ? If so delete and reload. */
5207 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5208 /* Remove it from the array. */
5209 free_service_byindex(iService);
5210 /* and now reload it. */
5211 iService = load_usershare_service(pszServiceName);
5215 if (iService < 0) {
5216 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5217 return GLOBAL_SECTION_SNUM;
5220 return (iService);
5223 BOOL share_defined(const char *service_name)
5225 return (lp_servicenumber(service_name) != -1);
5228 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
5229 const char *sharename)
5231 struct share_params *result;
5232 char *sname;
5233 int snum;
5235 if (!(sname = SMB_STRDUP(sharename))) {
5236 return NULL;
5239 snum = find_service(sname);
5240 SAFE_FREE(sname);
5242 if (snum < 0) {
5243 return NULL;
5246 if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
5247 DEBUG(0, ("talloc failed\n"));
5248 return NULL;
5251 result->service = snum;
5252 return result;
5255 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
5257 struct share_iterator *result;
5259 if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
5260 DEBUG(0, ("talloc failed\n"));
5261 return NULL;
5264 result->next_id = 0;
5265 return result;
5268 struct share_params *next_share(struct share_iterator *list)
5270 struct share_params *result;
5272 while (!lp_snum_ok(list->next_id) &&
5273 (list->next_id < lp_numservices())) {
5274 list->next_id += 1;
5277 if (list->next_id >= lp_numservices()) {
5278 return NULL;
5281 if (!(result = TALLOC_P(list, struct share_params))) {
5282 DEBUG(0, ("talloc failed\n"));
5283 return NULL;
5286 result->service = list->next_id;
5287 list->next_id += 1;
5288 return result;
5291 struct share_params *next_printer(struct share_iterator *list)
5293 struct share_params *result;
5295 while ((result = next_share(list)) != NULL) {
5296 if (lp_print_ok(result->service)) {
5297 break;
5300 return result;
5304 * This is a hack for a transition period until we transformed all code from
5305 * service numbers to struct share_params.
5308 struct share_params *snum2params_static(int snum)
5310 static struct share_params result;
5311 result.service = snum;
5312 return &result;
5315 /*******************************************************************
5316 A useful volume label function.
5317 ********************************************************************/
5319 const char *volume_label(int snum)
5321 char *ret;
5322 const char *label = lp_volume(snum);
5323 if (!*label) {
5324 label = lp_servicename(snum);
5327 /* This returns a 33 byte guarenteed null terminated string. */
5328 ret = talloc_strndup(main_loop_talloc_get(), label, 32);
5329 if (!ret) {
5330 return "";
5332 return ret;
5335 /*******************************************************************
5336 Set the server type we will announce as via nmbd.
5337 ********************************************************************/
5339 static void set_default_server_announce_type(void)
5341 default_server_announce = 0;
5342 default_server_announce |= SV_TYPE_WORKSTATION;
5343 default_server_announce |= SV_TYPE_SERVER;
5344 default_server_announce |= SV_TYPE_SERVER_UNIX;
5346 /* note that the flag should be set only if we have a
5347 printer service but nmbd doesn't actually load the
5348 services so we can't tell --jerry */
5350 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5352 switch (lp_announce_as()) {
5353 case ANNOUNCE_AS_NT_SERVER:
5354 default_server_announce |= SV_TYPE_SERVER_NT;
5355 /* fall through... */
5356 case ANNOUNCE_AS_NT_WORKSTATION:
5357 default_server_announce |= SV_TYPE_NT;
5358 break;
5359 case ANNOUNCE_AS_WIN95:
5360 default_server_announce |= SV_TYPE_WIN95_PLUS;
5361 break;
5362 case ANNOUNCE_AS_WFW:
5363 default_server_announce |= SV_TYPE_WFW;
5364 break;
5365 default:
5366 break;
5369 switch (lp_server_role()) {
5370 case ROLE_DOMAIN_MEMBER:
5371 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5372 break;
5373 case ROLE_DOMAIN_PDC:
5374 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5375 break;
5376 case ROLE_DOMAIN_BDC:
5377 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5378 break;
5379 case ROLE_STANDALONE:
5380 default:
5381 break;
5383 if (lp_time_server())
5384 default_server_announce |= SV_TYPE_TIME_SOURCE;
5386 if (lp_host_msdfs())
5387 default_server_announce |= SV_TYPE_DFS_SERVER;
5390 /***********************************************************
5391 returns role of Samba server
5392 ************************************************************/
5394 int lp_server_role(void)
5396 return server_role;
5399 /***********************************************************
5400 If we are PDC then prefer us as DMB
5401 ************************************************************/
5403 BOOL lp_domain_master(void)
5405 if (Globals.bDomainMaster == Auto)
5406 return (lp_server_role() == ROLE_DOMAIN_PDC);
5408 return Globals.bDomainMaster;
5411 /***********************************************************
5412 If we are DMB then prefer us as LMB
5413 ************************************************************/
5415 BOOL lp_preferred_master(void)
5417 if (Globals.bPreferredMaster == Auto)
5418 return (lp_local_master() && lp_domain_master());
5420 return Globals.bPreferredMaster;
5423 /*******************************************************************
5424 Remove a service.
5425 ********************************************************************/
5427 void lp_remove_service(int snum)
5429 ServicePtrs[snum]->valid = False;
5430 invalid_services[num_invalid_services++] = snum;
5433 /*******************************************************************
5434 Copy a service.
5435 ********************************************************************/
5437 void lp_copy_service(int snum, const char *new_name)
5439 do_section(new_name);
5440 if (snum >= 0) {
5441 snum = lp_servicenumber(new_name);
5442 if (snum >= 0)
5443 lp_do_parameter(snum, "copy", lp_servicename(snum));
5448 /*******************************************************************
5449 Get the default server type we will announce as via nmbd.
5450 ********************************************************************/
5452 int lp_default_server_announce(void)
5454 return default_server_announce;
5457 /*******************************************************************
5458 Split the announce version into major and minor numbers.
5459 ********************************************************************/
5461 int lp_major_announce_version(void)
5463 static BOOL got_major = False;
5464 static int major_version = DEFAULT_MAJOR_VERSION;
5465 char *vers;
5466 char *p;
5468 if (got_major)
5469 return major_version;
5471 got_major = True;
5472 if ((vers = lp_announce_version()) == NULL)
5473 return major_version;
5475 if ((p = strchr_m(vers, '.')) == 0)
5476 return major_version;
5478 *p = '\0';
5479 major_version = atoi(vers);
5480 return major_version;
5483 int lp_minor_announce_version(void)
5485 static BOOL got_minor = False;
5486 static int minor_version = DEFAULT_MINOR_VERSION;
5487 char *vers;
5488 char *p;
5490 if (got_minor)
5491 return minor_version;
5493 got_minor = True;
5494 if ((vers = lp_announce_version()) == NULL)
5495 return minor_version;
5497 if ((p = strchr_m(vers, '.')) == 0)
5498 return minor_version;
5500 p++;
5501 minor_version = atoi(p);
5502 return minor_version;
5505 /***********************************************************
5506 Set the global name resolution order (used in smbclient).
5507 ************************************************************/
5509 void lp_set_name_resolve_order(const char *new_order)
5511 string_set(&Globals.szNameResolveOrder, new_order);
5514 const char *lp_printername(int snum)
5516 const char *ret = _lp_printername(snum);
5517 if (ret == NULL || (ret != NULL && *ret == '\0'))
5518 ret = lp_const_servicename(snum);
5520 return ret;
5524 /***********************************************************
5525 Allow daemons such as winbindd to fix their logfile name.
5526 ************************************************************/
5528 void lp_set_logfile(const char *name)
5530 string_set(&Globals.szLogFile, name);
5531 pstrcpy(debugf, name);
5534 /*******************************************************************
5535 Return the max print jobs per queue.
5536 ********************************************************************/
5538 int lp_maxprintjobs(int snum)
5540 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5541 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5542 maxjobs = PRINT_MAX_JOBID - 1;
5544 return maxjobs;
5547 const char *lp_printcapname(void)
5549 if ((Globals.szPrintcapname != NULL) &&
5550 (Globals.szPrintcapname[0] != '\0'))
5551 return Globals.szPrintcapname;
5553 if (sDefault.iPrinting == PRINT_CUPS) {
5554 #ifdef HAVE_CUPS
5555 return "cups";
5556 #else
5557 return "lpstat";
5558 #endif
5561 if (sDefault.iPrinting == PRINT_BSD)
5562 return "/etc/printcap";
5564 return PRINTCAP_NAME;
5567 /*******************************************************************
5568 Ensure we don't use sendfile if server smb signing is active.
5569 ********************************************************************/
5571 static uint32 spoolss_state;
5573 BOOL lp_disable_spoolss( void )
5575 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5576 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5578 return spoolss_state == SVCCTL_STOPPED ? True : False;
5581 void lp_set_spoolss_state( uint32 state )
5583 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5585 spoolss_state = state;
5588 uint32 lp_get_spoolss_state( void )
5590 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5593 /*******************************************************************
5594 Ensure we don't use sendfile if server smb signing is active.
5595 ********************************************************************/
5597 BOOL lp_use_sendfile(int snum)
5599 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5600 if (Protocol < PROTOCOL_NT1) {
5601 return False;
5603 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5606 /*******************************************************************
5607 Turn off sendfile if we find the underlying OS doesn't support it.
5608 ********************************************************************/
5610 void set_use_sendfile(int snum, BOOL val)
5612 if (LP_SNUM_OK(snum))
5613 ServicePtrs[snum]->bUseSendfile = val;
5614 else
5615 sDefault.bUseSendfile = val;
5618 /*******************************************************************
5619 Turn off storing DOS attributes if this share doesn't support it.
5620 ********************************************************************/
5622 void set_store_dos_attributes(int snum, BOOL val)
5624 if (!LP_SNUM_OK(snum))
5625 return;
5626 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5629 void lp_set_mangling_method(const char *new_method)
5631 string_set(&Globals.szManglingMethod, new_method);
5634 /*******************************************************************
5635 Global state for POSIX pathname processing.
5636 ********************************************************************/
5638 static BOOL posix_pathnames;
5640 BOOL lp_posix_pathnames(void)
5642 return posix_pathnames;
5645 /*******************************************************************
5646 Change everything needed to ensure POSIX pathname processing (currently
5647 not much).
5648 ********************************************************************/
5650 void lp_set_posix_pathnames(void)
5652 posix_pathnames = True;
5655 /*******************************************************************
5656 Global state for POSIX lock processing - CIFS unix extensions.
5657 ********************************************************************/
5659 BOOL posix_default_lock_was_set;
5660 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5662 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
5664 if (posix_default_lock_was_set) {
5665 return posix_cifsx_locktype;
5666 } else {
5667 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
5671 /*******************************************************************
5672 ********************************************************************/
5674 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
5676 posix_default_lock_was_set = True;
5677 posix_cifsx_locktype = val;