r15837: starting sync up for 3.0.23rc1 (in sync with SAMBA_3_0 r15822)
[Samba.git] / source / param / loadparm.c
blobfadd4d0ee3f6e3b9881e429acb69fbd651ebc015
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;
62 #ifndef GLOBAL_NAME
63 #define GLOBAL_NAME "global"
64 #endif
66 #ifndef PRINTERS_NAME
67 #define PRINTERS_NAME "printers"
68 #endif
70 #ifndef HOMES_NAME
71 #define HOMES_NAME "homes"
72 #endif
74 /* some helpful bits */
75 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
76 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
78 #define USERSHARE_VALID 1
79 #define USERSHARE_PENDING_DELETE 2
81 int keepalive = DEFAULT_KEEPALIVE;
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 BOOL bWinbindRefreshTickets;
181 BOOL bWinbindOfflineLogon;
182 char **szIdmapBackend;
183 char *szAddShareCommand;
184 char *szChangeShareCommand;
185 char *szDeleteShareCommand;
186 char **szEventLogs;
187 char *szGuestaccount;
188 char *szManglingMethod;
189 char **szServicesList;
190 char *szUsersharePath;
191 char *szUsershareTemplateShare;
192 char **szUsersharePrefixAllowList;
193 char **szUsersharePrefixDenyList;
194 int mangle_prefix;
195 int max_log_size;
196 char *szLogLevel;
197 int max_xmit;
198 int max_mux;
199 int max_open_files;
200 int open_files_db_hash_size;
201 int pwordlevel;
202 int unamelevel;
203 int deadtime;
204 int maxprotocol;
205 int minprotocol;
206 int security;
207 char **AuthMethods;
208 BOOL paranoid_server_security;
209 int maxdisksize;
210 int lpqcachetime;
211 int iMaxSmbdProcesses;
212 BOOL bDisableSpoolss;
213 int syslog;
214 int os_level;
215 int enhanced_browsing;
216 int max_ttl;
217 int max_wins_ttl;
218 int min_wins_ttl;
219 int lm_announce;
220 int lm_interval;
221 int announce_as; /* This is initialised in init_globals */
222 int machine_password_timeout;
223 int map_to_guest;
224 int oplock_break_wait_time;
225 int winbind_cache_time;
226 int winbind_max_idle_children;
227 char **szWinbindNssInfo;
228 int iLockSpinCount;
229 int iLockSpinTime;
230 char *szLdapMachineSuffix;
231 char *szLdapUserSuffix;
232 char *szLdapIdmapSuffix;
233 char *szLdapGroupSuffix;
234 int ldap_ssl;
235 char *szLdapSuffix;
236 char *szLdapAdminDn;
237 char *szAclCompat;
238 char *szCupsServer;
239 char *szIPrintServer;
240 int ldap_passwd_sync;
241 int ldap_replication_sleep;
242 int ldap_timeout; /* This is initialised in init_globals */
243 int ldap_page_size;
244 BOOL ldap_delete_dn;
245 BOOL bMsAddPrinterWizard;
246 BOOL bDNSproxy;
247 BOOL bWINSsupport;
248 BOOL bWINSproxy;
249 BOOL bLocalMaster;
250 BOOL bPreferredMaster;
251 BOOL bDomainMaster;
252 BOOL bDomainLogons;
253 BOOL bEncryptPasswords;
254 BOOL bUpdateEncrypt;
255 int clientSchannel;
256 int serverSchannel;
257 BOOL bNullPasswords;
258 BOOL bObeyPamRestrictions;
259 BOOL bLoadPrinters;
260 int PrintcapCacheTime;
261 BOOL bLargeReadwrite;
262 BOOL bReadRaw;
263 BOOL bWriteRaw;
264 BOOL bReadbmpx;
265 BOOL bSyslogOnly;
266 BOOL bBrowseList;
267 BOOL bNISHomeMap;
268 BOOL bTimeServer;
269 BOOL bBindInterfacesOnly;
270 BOOL bPamPasswordChange;
271 BOOL bUnixPasswdSync;
272 BOOL bPasswdChatDebug;
273 int iPasswdChatTimeout;
274 BOOL bTimestampLogs;
275 BOOL bNTSmbSupport;
276 BOOL bNTPipeSupport;
277 BOOL bNTStatusSupport;
278 BOOL bStatCache;
279 int iMaxStatCacheSize;
280 BOOL bKernelOplocks;
281 BOOL bAllowTrustedDomains;
282 BOOL bLanmanAuth;
283 BOOL bNTLMAuth;
284 BOOL bUseSpnego;
285 BOOL bClientLanManAuth;
286 BOOL bClientNTLMv2Auth;
287 BOOL bClientPlaintextAuth;
288 BOOL bClientUseSpnego;
289 BOOL bDebugHiresTimestamp;
290 BOOL bDebugPid;
291 BOOL bDebugUid;
292 BOOL bEnableCoreFiles;
293 BOOL bHostMSDfs;
294 BOOL bUseMmap;
295 BOOL bHostnameLookups;
296 BOOL bUnixExtensions;
297 BOOL bDisableNetbios;
298 BOOL bKernelChangeNotify;
299 BOOL bFamChangeNotify;
300 BOOL bUseKerberosKeytab;
301 BOOL bDeferSharingViolations;
302 BOOL bEnablePrivileges;
303 BOOL bASUSupport;
304 BOOL bUsershareOwnerOnly;
305 BOOL bUsershareAllowGuests;
306 int restrict_anonymous;
307 int name_cache_timeout;
308 int client_signing;
309 int server_signing;
310 int iUsershareMaxShares;
312 BOOL bResetOnZeroVC;
313 param_opt_struct *param_opt;
314 } global;
316 static global Globals;
319 * This structure describes a single service.
321 typedef struct {
322 BOOL valid;
323 BOOL autoloaded;
324 int usershare;
325 time_t usershare_last_mod;
326 char *szService;
327 char *szPath;
328 char *szUsername;
329 char **szInvalidUsers;
330 char **szValidUsers;
331 char **szAdminUsers;
332 char *szCopy;
333 char *szInclude;
334 char *szPreExec;
335 char *szPostExec;
336 char *szRootPreExec;
337 char *szRootPostExec;
338 char *szCupsOptions;
339 char *szPrintcommand;
340 char *szLpqcommand;
341 char *szLprmcommand;
342 char *szLppausecommand;
343 char *szLpresumecommand;
344 char *szQueuepausecommand;
345 char *szQueueresumecommand;
346 char *szPrintername;
347 char *szDontdescend;
348 char **szHostsallow;
349 char **szHostsdeny;
350 char *szMagicScript;
351 char *szMagicOutput;
352 char *szMangledMap;
353 char *szVetoFiles;
354 char *szHideFiles;
355 char *szVetoOplockFiles;
356 char *comment;
357 char *force_user;
358 char *force_group;
359 char **readlist;
360 char **writelist;
361 char **printer_admin;
362 char *volume;
363 char *fstype;
364 char **szVfsObjects;
365 char *szMSDfsProxy;
366 char *szAioWriteBehind;
367 char *szDfree;
368 int iMinPrintSpace;
369 int iMaxPrintJobs;
370 int iMaxReportedPrintJobs;
371 int iWriteCacheSize;
372 int iCreate_mask;
373 int iCreate_force_mode;
374 int iSecurity_mask;
375 int iSecurity_force_mode;
376 int iDir_mask;
377 int iDir_force_mode;
378 int iDir_Security_mask;
379 int iDir_Security_force_mode;
380 int iMaxConnections;
381 int iDefaultCase;
382 int iPrinting;
383 int iOplockContentionLimit;
384 int iCSCPolicy;
385 int iBlock_size;
386 int iDfreeCacheTime;
387 BOOL bPreexecClose;
388 BOOL bRootpreexecClose;
389 int iCaseSensitive;
390 BOOL bCasePreserve;
391 BOOL bShortCasePreserve;
392 BOOL bHideDotFiles;
393 BOOL bHideSpecialFiles;
394 BOOL bHideUnReadable;
395 BOOL bHideUnWriteableFiles;
396 BOOL bBrowseable;
397 BOOL bAvailable;
398 BOOL bRead_only;
399 BOOL bNo_set_dir;
400 BOOL bGuest_only;
401 BOOL bGuest_ok;
402 BOOL bPrint_ok;
403 BOOL bMap_system;
404 BOOL bMap_hidden;
405 BOOL bMap_archive;
406 BOOL bStoreDosAttributes;
407 BOOL bDmapiSupport;
408 BOOL bLocking;
409 int iStrictLocking;
410 BOOL bPosixLocking;
411 BOOL bShareModes;
412 BOOL bOpLocks;
413 BOOL bLevel2OpLocks;
414 BOOL bOnlyUser;
415 BOOL bMangledNames;
416 BOOL bWidelinks;
417 BOOL bSymlinks;
418 BOOL bSyncAlways;
419 BOOL bStrictAllocate;
420 BOOL bStrictSync;
421 char magic_char;
422 BOOL *copymap;
423 BOOL bDeleteReadonly;
424 BOOL bFakeOplocks;
425 BOOL bDeleteVetoFiles;
426 BOOL bDosFilemode;
427 BOOL bDosFiletimes;
428 BOOL bDosFiletimeResolution;
429 BOOL bFakeDirCreateTimes;
430 BOOL bBlockingLocks;
431 BOOL bInheritPerms;
432 BOOL bInheritACLS;
433 BOOL bInheritOwner;
434 BOOL bMSDfsRoot;
435 BOOL bUseClientDriver;
436 BOOL bDefaultDevmode;
437 BOOL bForcePrintername;
438 BOOL bNTAclSupport;
439 BOOL bForceUnknownAclUser;
440 BOOL bUseSendfile;
441 BOOL bProfileAcls;
442 BOOL bMap_acl_inherit;
443 BOOL bAfs_Share;
444 BOOL bEASupport;
445 BOOL bAclCheckPermissions;
446 BOOL bAclMapFullControl;
447 BOOL bAclGroupControl;
448 int iallocation_roundup_size;
449 int iAioReadSize;
450 int iAioWriteSize;
451 int iMap_readonly;
452 int ichange_notify_timeout;
453 param_opt_struct *param_opt;
455 char dummy[3]; /* for alignment */
456 } service;
459 /* This is a default service used to prime a services structure */
460 static service sDefault = {
461 True, /* valid */
462 False, /* not autoloaded */
463 0, /* not a usershare */
464 (time_t)0, /* No last mod time */
465 NULL, /* szService */
466 NULL, /* szPath */
467 NULL, /* szUsername */
468 NULL, /* szInvalidUsers */
469 NULL, /* szValidUsers */
470 NULL, /* szAdminUsers */
471 NULL, /* szCopy */
472 NULL, /* szInclude */
473 NULL, /* szPreExec */
474 NULL, /* szPostExec */
475 NULL, /* szRootPreExec */
476 NULL, /* szRootPostExec */
477 NULL, /* szCupsOptions */
478 NULL, /* szPrintcommand */
479 NULL, /* szLpqcommand */
480 NULL, /* szLprmcommand */
481 NULL, /* szLppausecommand */
482 NULL, /* szLpresumecommand */
483 NULL, /* szQueuepausecommand */
484 NULL, /* szQueueresumecommand */
485 NULL, /* szPrintername */
486 NULL, /* szDontdescend */
487 NULL, /* szHostsallow */
488 NULL, /* szHostsdeny */
489 NULL, /* szMagicScript */
490 NULL, /* szMagicOutput */
491 NULL, /* szMangledMap */
492 NULL, /* szVetoFiles */
493 NULL, /* szHideFiles */
494 NULL, /* szVetoOplockFiles */
495 NULL, /* comment */
496 NULL, /* force user */
497 NULL, /* force group */
498 NULL, /* readlist */
499 NULL, /* writelist */
500 NULL, /* printer admin */
501 NULL, /* volume */
502 NULL, /* fstype */
503 NULL, /* vfs objects */
504 NULL, /* szMSDfsProxy */
505 NULL, /* szAioWriteBehind */
506 NULL, /* szDfree */
507 0, /* iMinPrintSpace */
508 1000, /* iMaxPrintJobs */
509 0, /* iMaxReportedPrintJobs */
510 0, /* iWriteCacheSize */
511 0744, /* iCreate_mask */
512 0000, /* iCreate_force_mode */
513 0777, /* iSecurity_mask */
514 0, /* iSecurity_force_mode */
515 0755, /* iDir_mask */
516 0000, /* iDir_force_mode */
517 0777, /* iDir_Security_mask */
518 0, /* iDir_Security_force_mode */
519 0, /* iMaxConnections */
520 CASE_LOWER, /* iDefaultCase */
521 DEFAULT_PRINTING, /* iPrinting */
522 2, /* iOplockContentionLimit */
523 0, /* iCSCPolicy */
524 1024, /* iBlock_size */
525 0, /* iDfreeCacheTime */
526 False, /* bPreexecClose */
527 False, /* bRootpreexecClose */
528 Auto, /* case sensitive */
529 True, /* case preserve */
530 True, /* short case preserve */
531 True, /* bHideDotFiles */
532 False, /* bHideSpecialFiles */
533 False, /* bHideUnReadable */
534 False, /* bHideUnWriteableFiles */
535 True, /* bBrowseable */
536 True, /* bAvailable */
537 True, /* bRead_only */
538 True, /* bNo_set_dir */
539 False, /* bGuest_only */
540 False, /* bGuest_ok */
541 False, /* bPrint_ok */
542 False, /* bMap_system */
543 False, /* bMap_hidden */
544 True, /* bMap_archive */
545 False, /* bStoreDosAttributes */
546 False, /* bDmapiSupport */
547 True, /* bLocking */
548 Auto, /* iStrictLocking */
549 True, /* bPosixLocking */
550 True, /* bShareModes */
551 True, /* bOpLocks */
552 True, /* bLevel2OpLocks */
553 False, /* bOnlyUser */
554 True, /* bMangledNames */
555 True, /* bWidelinks */
556 True, /* bSymlinks */
557 False, /* bSyncAlways */
558 False, /* bStrictAllocate */
559 False, /* bStrictSync */
560 '~', /* magic char */
561 NULL, /* copymap */
562 False, /* bDeleteReadonly */
563 False, /* bFakeOplocks */
564 False, /* bDeleteVetoFiles */
565 False, /* bDosFilemode */
566 True, /* bDosFiletimes */
567 False, /* bDosFiletimeResolution */
568 False, /* bFakeDirCreateTimes */
569 True, /* bBlockingLocks */
570 False, /* bInheritPerms */
571 False, /* bInheritACLS */
572 False, /* bInheritOwner */
573 True, /* bMSDfsRoot */
574 False, /* bUseClientDriver */
575 True, /* bDefaultDevmode */
576 False, /* bForcePrintername */
577 True, /* bNTAclSupport */
578 False, /* bForceUnknownAclUser */
579 False, /* bUseSendfile */
580 False, /* bProfileAcls */
581 False, /* bMap_acl_inherit */
582 False, /* bAfs_Share */
583 False, /* bEASupport */
584 True, /* bAclCheckPermissions */
585 True, /* bAclMapFullControl */
586 False, /* bAclGroupControl */
587 SMB_ROUNDUP_ALLOCATION_SIZE, /* iallocation_roundup_size */
588 0, /* iAioReadSize */
589 0, /* iAioWriteSize */
590 MAP_READONLY_YES, /* iMap_readonly */
591 60, /* ichange_notify_timeout = 1 minute default. */
593 NULL, /* Parametric options */
595 "" /* dummy */
598 /* local variables */
599 static service **ServicePtrs = NULL;
600 static int iNumServices = 0;
601 static int iServiceIndex = 0;
602 static TDB_CONTEXT *ServiceHash;
603 static int *invalid_services = NULL;
604 static int num_invalid_services = 0;
605 static BOOL bInGlobalSection = True;
606 static BOOL bGlobalOnly = False;
607 static int server_role;
608 static int default_server_announce;
610 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
612 /* prototypes for the special type handlers */
613 static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
614 static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
615 static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
616 static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
617 static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
618 static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
619 static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
620 static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
621 static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
622 static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
623 static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
625 static void set_server_role(void);
626 static void set_default_server_announce_type(void);
627 static void set_allowed_client_auth(void);
629 static const struct enum_list enum_protocol[] = {
630 {PROTOCOL_NT1, "NT1"},
631 {PROTOCOL_LANMAN2, "LANMAN2"},
632 {PROTOCOL_LANMAN1, "LANMAN1"},
633 {PROTOCOL_CORE, "CORE"},
634 {PROTOCOL_COREPLUS, "COREPLUS"},
635 {PROTOCOL_COREPLUS, "CORE+"},
636 {-1, NULL}
639 static const struct enum_list enum_security[] = {
640 {SEC_SHARE, "SHARE"},
641 {SEC_USER, "USER"},
642 {SEC_SERVER, "SERVER"},
643 {SEC_DOMAIN, "DOMAIN"},
644 #ifdef HAVE_ADS
645 {SEC_ADS, "ADS"},
646 #endif
647 {-1, NULL}
650 static const struct enum_list enum_printing[] = {
651 {PRINT_SYSV, "sysv"},
652 {PRINT_AIX, "aix"},
653 {PRINT_HPUX, "hpux"},
654 {PRINT_BSD, "bsd"},
655 {PRINT_QNX, "qnx"},
656 {PRINT_PLP, "plp"},
657 {PRINT_LPRNG, "lprng"},
658 {PRINT_CUPS, "cups"},
659 {PRINT_IPRINT, "iprint"},
660 {PRINT_LPRNT, "nt"},
661 {PRINT_LPROS2, "os2"},
662 #ifdef DEVELOPER
663 {PRINT_TEST, "test"},
664 {PRINT_VLP, "vlp"},
665 #endif /* DEVELOPER */
666 {-1, NULL}
669 static const struct enum_list enum_ldap_ssl[] = {
670 {LDAP_SSL_OFF, "no"},
671 {LDAP_SSL_OFF, "No"},
672 {LDAP_SSL_OFF, "off"},
673 {LDAP_SSL_OFF, "Off"},
674 {LDAP_SSL_START_TLS, "start tls"},
675 {LDAP_SSL_START_TLS, "Start_tls"},
676 {-1, NULL}
679 static const struct enum_list enum_ldap_passwd_sync[] = {
680 {LDAP_PASSWD_SYNC_OFF, "no"},
681 {LDAP_PASSWD_SYNC_OFF, "No"},
682 {LDAP_PASSWD_SYNC_OFF, "off"},
683 {LDAP_PASSWD_SYNC_OFF, "Off"},
684 {LDAP_PASSWD_SYNC_ON, "Yes"},
685 {LDAP_PASSWD_SYNC_ON, "yes"},
686 {LDAP_PASSWD_SYNC_ON, "on"},
687 {LDAP_PASSWD_SYNC_ON, "On"},
688 {LDAP_PASSWD_SYNC_ONLY, "Only"},
689 {LDAP_PASSWD_SYNC_ONLY, "only"},
690 {-1, NULL}
693 /* Types of machine we can announce as. */
694 #define ANNOUNCE_AS_NT_SERVER 1
695 #define ANNOUNCE_AS_WIN95 2
696 #define ANNOUNCE_AS_WFW 3
697 #define ANNOUNCE_AS_NT_WORKSTATION 4
699 static const struct enum_list enum_announce_as[] = {
700 {ANNOUNCE_AS_NT_SERVER, "NT"},
701 {ANNOUNCE_AS_NT_SERVER, "NT Server"},
702 {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
703 {ANNOUNCE_AS_WIN95, "win95"},
704 {ANNOUNCE_AS_WFW, "WfW"},
705 {-1, NULL}
708 static const struct enum_list enum_map_readonly[] = {
709 {MAP_READONLY_NO, "no"},
710 {MAP_READONLY_NO, "false"},
711 {MAP_READONLY_NO, "0"},
712 {MAP_READONLY_YES, "yes"},
713 {MAP_READONLY_YES, "true"},
714 {MAP_READONLY_YES, "1"},
715 {MAP_READONLY_PERMISSIONS, "permissions"},
716 {MAP_READONLY_PERMISSIONS, "perms"},
717 {-1, NULL}
720 static const struct enum_list enum_case[] = {
721 {CASE_LOWER, "lower"},
722 {CASE_UPPER, "upper"},
723 {-1, NULL}
726 static const struct enum_list enum_bool_auto[] = {
727 {False, "No"},
728 {False, "False"},
729 {False, "0"},
730 {True, "Yes"},
731 {True, "True"},
732 {True, "1"},
733 {Auto, "Auto"},
734 {-1, NULL}
737 /* Client-side offline caching policy types */
738 #define CSC_POLICY_MANUAL 0
739 #define CSC_POLICY_DOCUMENTS 1
740 #define CSC_POLICY_PROGRAMS 2
741 #define CSC_POLICY_DISABLE 3
743 static const struct enum_list enum_csc_policy[] = {
744 {CSC_POLICY_MANUAL, "manual"},
745 {CSC_POLICY_DOCUMENTS, "documents"},
746 {CSC_POLICY_PROGRAMS, "programs"},
747 {CSC_POLICY_DISABLE, "disable"},
748 {-1, NULL}
751 /* SMB signing types. */
752 static const struct enum_list enum_smb_signing_vals[] = {
753 {False, "No"},
754 {False, "False"},
755 {False, "0"},
756 {False, "Off"},
757 {False, "disabled"},
758 {True, "Yes"},
759 {True, "True"},
760 {True, "1"},
761 {True, "On"},
762 {True, "enabled"},
763 {Auto, "auto"},
764 {Required, "required"},
765 {Required, "mandatory"},
766 {Required, "force"},
767 {Required, "forced"},
768 {Required, "enforced"},
769 {-1, NULL}
772 /* ACL compatibility options. */
773 static const struct enum_list enum_acl_compat_vals[] = {
774 { ACL_COMPAT_AUTO, "auto" },
775 { ACL_COMPAT_WINNT, "winnt" },
776 { ACL_COMPAT_WIN2K, "win2k" },
777 { -1, NULL}
781 Do you want session setups at user level security with a invalid
782 password to be rejected or allowed in as guest? WinNT rejects them
783 but it can be a pain as it means "net view" needs to use a password
785 You have 3 choices in the setting of map_to_guest:
787 "Never" means session setups with an invalid password
788 are rejected. This is the default.
790 "Bad User" means session setups with an invalid password
791 are rejected, unless the username does not exist, in which case it
792 is treated as a guest login
794 "Bad Password" means session setups with an invalid password
795 are treated as a guest login
797 Note that map_to_guest only has an effect in user or server
798 level security.
801 static const struct enum_list enum_map_to_guest[] = {
802 {NEVER_MAP_TO_GUEST, "Never"},
803 {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
804 {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
805 {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
806 {-1, NULL}
809 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
811 * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
812 * screen in SWAT. This is used to exclude parameters as well as to squash all
813 * parameters that have been duplicated by pseudonyms.
815 * NOTE: To display a parameter in BASIC view set FLAG_BASIC
816 * Any parameter that does NOT have FLAG_ADVANCED will not disply at all
817 * Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
818 * respective views.
820 * NOTE2: Handling of duplicated (synonym) paramters:
821 * Only the first occurance of a parameter should be enabled by FLAG_BASIC
822 * and/or FLAG_ADVANCED. All duplicates following the first mention should be
823 * set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
824 * name first, and all synonyms must follow it with the FLAG_HIDE attribute.
827 static struct parm_struct parm_table[] = {
828 {N_("Base Options"), P_SEP, P_SEPARATOR},
830 {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED},
831 {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED},
832 {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED},
833 {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
834 {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
835 {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE},
836 {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
837 #ifdef WITH_ADS
838 {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
839 #endif
840 {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
841 {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases, NULL, FLAG_ADVANCED},
842 {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope, NULL, FLAG_ADVANCED},
843 {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED },
844 {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
845 {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
847 {N_("Security Options"), P_SEP, P_SEPARATOR},
849 {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
850 {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED},
851 {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
852 {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED},
853 {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
854 {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
855 {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED},
856 {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED},
857 {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED},
858 {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED},
859 {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
860 {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
861 {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
862 {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
863 {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
864 {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
865 {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
866 {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE},
867 {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
868 {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED},
870 {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED},
871 {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED},
872 {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED},
873 {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED},
874 {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED},
875 {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED},
876 {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED},
877 {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED},
878 {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED},
879 {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED},
880 {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED},
881 {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED},
882 {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED},
883 {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED},
884 {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED},
885 {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED},
887 {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
888 {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
889 {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE},
891 {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
892 {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
893 {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
894 {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
895 {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
896 {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED },
897 {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
898 {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
899 {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED},
901 {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE},
902 {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
903 {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
904 {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE},
906 {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
907 {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE | FLAG_DEPRECATED },
908 {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
909 {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
910 {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE},
911 {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
912 {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
913 {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
914 {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
915 {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
916 {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
917 {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
918 {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
919 {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
920 {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
921 {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
922 {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
923 {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
924 {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE},
926 {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
927 {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE},
929 {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
930 {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
931 {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE},
932 {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
933 {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE},
934 {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
935 {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED},
937 {N_("Logging Options"), P_SEP, P_SEPARATOR},
939 {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED},
940 {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE},
941 {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED},
942 {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED},
943 {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED},
945 {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED},
946 {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
947 {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED},
948 {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED},
949 {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED},
950 {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED},
951 {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
953 {N_("Protocol Options"), P_SEP, P_SEPARATOR},
955 {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED},
956 {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED},
957 {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED},
958 {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
959 {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED},
960 {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED},
961 {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
962 {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED},
963 {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED},
964 {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED},
965 {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED},
966 {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED},
967 {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED},
968 {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED},
970 {"acl compatibility", P_STRING, P_GLOBAL, &Globals.szAclCompat, NULL, enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
971 {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
972 {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
973 {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
974 {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED},
975 {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED},
976 {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
978 {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED},
979 {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, FLAG_ADVANCED},
980 {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
981 {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
982 {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED},
983 {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED},
985 {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
986 {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED},
987 {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED},
988 {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED},
989 {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED},
990 {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED},
991 {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED},
992 {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
993 {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED},
994 {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED},
996 {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED},
997 {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
999 {N_("Tuning Options"), P_SEP, P_SEPARATOR},
1001 {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1002 {"change notify timeout", P_INTEGER, P_LOCAL, &sDefault.ichange_notify_timeout, NULL, NULL, FLAG_ADVANCED},
1003 {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED},
1004 {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED},
1005 {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED},
1006 {"kernel change notify", P_BOOL, P_GLOBAL, &Globals.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED},
1007 {"fam change notify", P_BOOL, P_GLOBAL, &Globals.bFamChangeNotify, NULL, NULL, FLAG_ADVANCED},
1009 {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED},
1010 {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED},
1011 {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1012 {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED},
1013 {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED},
1014 {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED},
1015 {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1016 {"open files database hash size", P_INTEGER, P_GLOBAL, &Globals.open_files_db_hash_size, NULL, NULL, FLAG_ADVANCED},
1018 {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED},
1019 {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1020 {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1021 {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1022 {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED},
1023 {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1024 {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED},
1025 {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED},
1027 {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED},
1029 {N_("Printing Options"), P_SEP, P_SEPARATOR},
1031 {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1032 {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1033 {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1034 {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1035 {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1036 {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE},
1037 {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1038 {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE},
1039 {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1040 {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1041 {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1042 {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1043 {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1044 {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1045 {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE},
1046 {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1047 {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1048 {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1049 {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1050 {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1051 {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL},
1053 {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED},
1054 {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED},
1055 {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED},
1056 {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED},
1057 {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED},
1058 {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED},
1060 {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1061 {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE},
1062 {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1063 {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1064 {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
1066 {N_("Filename Handling"), P_SEP, P_SEPARATOR},
1067 {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED},
1068 {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED},
1070 {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE},
1071 {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1072 {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE},
1073 {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1074 {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1075 {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1076 {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1077 {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1078 {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1079 {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1080 {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1081 {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1082 {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1083 {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL },
1084 {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1085 {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1086 {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1087 {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1088 {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1089 {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED },
1090 {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED},
1091 {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED},
1092 {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1093 {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1096 {N_("Domain Options"), P_SEP, P_SEPARATOR},
1098 {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
1100 {N_("Logon Options"), P_SEP, P_SEPARATOR},
1102 {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED},
1103 {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
1104 {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED},
1105 {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED},
1106 {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED},
1107 {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED},
1108 {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED},
1109 {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED},
1110 {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED},
1111 {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED},
1112 {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED},
1113 {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED},
1115 {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED},
1116 {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED},
1117 {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED},
1118 {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED},
1119 {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED},
1121 {N_("Browse Options"), P_SEP, P_SEPARATOR},
1123 {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1124 {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED},
1125 {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED},
1126 {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1127 {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
1128 {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED},
1129 {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED},
1130 {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED},
1131 {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1132 {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE},
1133 {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED},
1135 {N_("WINS Options"), P_SEP, P_SEPARATOR},
1137 {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED},
1138 {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED},
1140 {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1141 {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD},
1142 {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED},
1144 {N_("Locking Options"), P_SEP, P_SEPARATOR},
1146 {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1147 {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1148 {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1149 {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1150 {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1151 {"lock spin count", P_INTEGER, P_GLOBAL, &Globals.iLockSpinCount, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1152 {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1154 {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1155 {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1156 {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
1157 {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1158 {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1159 {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1160 {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1162 {N_("Ldap Options"), P_SEP, P_SEPARATOR},
1164 {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED},
1165 {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED},
1166 {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED},
1167 {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED},
1168 {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED},
1169 {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED},
1170 {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE},
1171 {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
1172 {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED},
1173 {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED},
1174 {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
1175 {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
1176 {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED},
1178 {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR},
1179 {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED},
1180 {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED},
1181 {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED},
1183 {N_("EventLog Options"), P_SEP, P_SEPARATOR},
1184 {"eventlog list", P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
1186 {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
1187 {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1188 {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED},
1189 {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED},
1190 {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE},
1191 {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED},
1192 #ifdef WITH_UTMP
1193 {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED},
1194 {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED},
1195 {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED},
1196 #endif
1198 {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1199 {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED},
1200 {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED},
1201 {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED},
1202 {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED},
1203 {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED},
1204 {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED},
1205 {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED},
1206 {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED},
1207 {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED},
1208 {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED},
1209 {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED},
1210 {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
1211 {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
1212 {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED},
1213 {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED},
1214 {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
1216 {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
1217 {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
1218 {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1219 {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED},
1221 {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1222 {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1223 {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1224 {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1225 {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1226 {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
1227 {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
1228 {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
1229 {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED},
1230 {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
1231 {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED},
1232 {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED},
1233 {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
1234 {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
1235 {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1236 {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1237 {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1238 {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1239 {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1240 {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1241 {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1242 {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1243 {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1244 {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1245 {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1247 {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
1248 {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED},
1250 {N_("VFS module options"), P_SEP, P_SEPARATOR},
1252 {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1253 {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE},
1256 {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1257 {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE},
1258 {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED},
1260 {N_("Winbind options"), P_SEP, P_SEPARATOR},
1262 {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
1263 {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED},
1264 {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED},
1265 {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE},
1266 {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED},
1267 {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE},
1268 {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED},
1269 {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED},
1270 {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED},
1271 {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED},
1272 {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED},
1273 {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED},
1274 {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED},
1275 {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED},
1276 {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED},
1277 {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED},
1278 {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED},
1279 {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
1281 {NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
1284 /***************************************************************************
1285 Initialise the sDefault parameter structure for the printer values.
1286 ***************************************************************************/
1288 static void init_printer_values(service *pService)
1290 /* choose defaults depending on the type of printing */
1291 switch (pService->iPrinting) {
1292 case PRINT_BSD:
1293 case PRINT_AIX:
1294 case PRINT_LPRNT:
1295 case PRINT_LPROS2:
1296 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1297 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1298 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1299 break;
1301 case PRINT_LPRNG:
1302 case PRINT_PLP:
1303 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1304 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1305 string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
1306 string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
1307 string_set(&pService->szQueueresumecommand, "lpc start '%p'");
1308 string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
1309 string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
1310 break;
1312 case PRINT_CUPS:
1313 case PRINT_IPRINT:
1314 #ifdef HAVE_CUPS
1315 /* set the lpq command to contain the destination printer
1316 name only. This is used by cups_queue_get() */
1317 string_set(&pService->szLpqcommand, "%p");
1318 string_set(&pService->szLprmcommand, "");
1319 string_set(&pService->szPrintcommand, "");
1320 string_set(&pService->szLppausecommand, "");
1321 string_set(&pService->szLpresumecommand, "");
1322 string_set(&pService->szQueuepausecommand, "");
1323 string_set(&pService->szQueueresumecommand, "");
1324 #else
1325 string_set(&pService->szLpqcommand, "lpq -P'%p'");
1326 string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
1327 string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
1328 string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
1329 string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
1330 string_set(&pService->szQueuepausecommand, "disable '%p'");
1331 string_set(&pService->szQueueresumecommand, "enable '%p'");
1332 #endif /* HAVE_CUPS */
1333 break;
1335 case PRINT_SYSV:
1336 case PRINT_HPUX:
1337 string_set(&pService->szLpqcommand, "lpstat -o%p");
1338 string_set(&pService->szLprmcommand, "cancel %p-%j");
1339 string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
1340 string_set(&pService->szQueuepausecommand, "disable %p");
1341 string_set(&pService->szQueueresumecommand, "enable %p");
1342 #ifndef HPUX
1343 string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
1344 string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
1345 #endif /* HPUX */
1346 break;
1348 case PRINT_QNX:
1349 string_set(&pService->szLpqcommand, "lpq -P%p");
1350 string_set(&pService->szLprmcommand, "lprm -P%p %j");
1351 string_set(&pService->szPrintcommand, "lp -r -P%p %s");
1352 break;
1354 #ifdef DEVELOPER
1355 case PRINT_TEST:
1356 case PRINT_VLP:
1357 string_set(&pService->szPrintcommand, "vlp print %p %s");
1358 string_set(&pService->szLpqcommand, "vlp lpq %p");
1359 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
1360 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
1361 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
1362 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
1363 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
1364 break;
1365 #endif /* DEVELOPER */
1370 /***************************************************************************
1371 Initialise the global parameter structure.
1372 ***************************************************************************/
1374 static void init_globals(BOOL first_time_only)
1376 static BOOL done_init = False;
1377 pstring s;
1379 /* If requested to initialize only once and we've already done it... */
1380 if (first_time_only && done_init) {
1381 /* ... then we have nothing more to do */
1382 return;
1385 if (!done_init) {
1386 int i;
1388 /* The logfile can be set before this is invoked. Free it if so. */
1389 if (Globals.szLogFile != NULL) {
1390 string_free(&Globals.szLogFile);
1391 Globals.szLogFile = NULL;
1394 memset((void *)&Globals, '\0', sizeof(Globals));
1396 for (i = 0; parm_table[i].label; i++)
1397 if ((parm_table[i].type == P_STRING ||
1398 parm_table[i].type == P_USTRING) &&
1399 parm_table[i].ptr)
1400 string_set((char **)parm_table[i].ptr, "");
1402 string_set(&sDefault.fstype, FSTYPE_STRING);
1404 init_printer_values(&sDefault);
1406 done_init = True;
1410 DEBUG(3, ("Initialising global parameters\n"));
1412 string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
1413 string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
1415 /* use the new 'hash2' method by default, with a prefix of 1 */
1416 string_set(&Globals.szManglingMethod, "hash2");
1417 Globals.mangle_prefix = 1;
1419 string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
1421 /* using UTF8 by default allows us to support all chars */
1422 string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
1424 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
1425 /* If the system supports nl_langinfo(), try to grab the value
1426 from the user's locale */
1427 string_set(&Globals.display_charset, "LOCALE");
1428 #else
1429 string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
1430 #endif
1432 /* Use codepage 850 as a default for the dos character set */
1433 string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
1436 * Allow the default PASSWD_CHAT to be overridden in local.h.
1438 string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
1440 set_global_myname(myhostname());
1441 string_set(&Globals.szNetbiosName,global_myname());
1443 set_global_myworkgroup(WORKGROUP);
1444 string_set(&Globals.szWorkgroup, lp_workgroup());
1446 string_set(&Globals.szPasswdProgram, "");
1447 string_set(&Globals.szPidDir, dyn_PIDDIR);
1448 string_set(&Globals.szLockDir, dyn_LOCKDIR);
1449 string_set(&Globals.szSocketAddress, "0.0.0.0");
1450 pstrcpy(s, "Samba ");
1451 pstrcat(s, SAMBA_VERSION_STRING);
1452 string_set(&Globals.szServerString, s);
1453 slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
1454 DEFAULT_MINOR_VERSION);
1455 string_set(&Globals.szAnnounceVersion, s);
1456 #ifdef DEVELOPER
1457 string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
1458 #endif
1460 pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
1462 string_set(&Globals.szLogonDrive, "");
1463 /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
1464 string_set(&Globals.szLogonHome, "\\\\%N\\%U");
1465 string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
1467 string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
1468 string_set(&Globals.szPasswordServer, "*");
1470 Globals.AlgorithmicRidBase = BASE_RID;
1472 Globals.bLoadPrinters = True;
1473 Globals.PrintcapCacheTime = 750; /* 12.5 minutes */
1475 /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
1476 /* Discovered by 2 days of pain by Don McCall @ HP :-). */
1477 Globals.max_xmit = 0x4104;
1478 Globals.max_mux = 50; /* This is *needed* for profile support. */
1479 Globals.lpqcachetime = 30; /* changed to handle large print servers better -- jerry */
1480 Globals.bDisableSpoolss = False;
1481 Globals.iMaxSmbdProcesses = 0;/* no limit specified */
1482 Globals.pwordlevel = 0;
1483 Globals.unamelevel = 0;
1484 Globals.deadtime = 0;
1485 Globals.bLargeReadwrite = True;
1486 Globals.max_log_size = 5000;
1487 Globals.max_open_files = MAX_OPEN_FILES;
1488 Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
1489 Globals.maxprotocol = PROTOCOL_NT1;
1490 Globals.minprotocol = PROTOCOL_CORE;
1491 Globals.security = SEC_USER;
1492 Globals.paranoid_server_security = True;
1493 Globals.bEncryptPasswords = True;
1494 Globals.bUpdateEncrypt = False;
1495 Globals.clientSchannel = Auto;
1496 Globals.serverSchannel = Auto;
1497 Globals.bReadRaw = True;
1498 Globals.bWriteRaw = True;
1499 Globals.bReadbmpx = False;
1500 Globals.bNullPasswords = False;
1501 Globals.bObeyPamRestrictions = False;
1502 Globals.syslog = 1;
1503 Globals.bSyslogOnly = False;
1504 Globals.bTimestampLogs = True;
1505 string_set(&Globals.szLogLevel, "0");
1506 Globals.bDebugHiresTimestamp = False;
1507 Globals.bDebugPid = False;
1508 Globals.bDebugUid = False;
1509 Globals.bEnableCoreFiles = True;
1510 Globals.max_ttl = 60 * 60 * 24 * 3; /* 3 days default. */
1511 Globals.max_wins_ttl = 60 * 60 * 24 * 6; /* 6 days default. */
1512 Globals.min_wins_ttl = 60 * 60 * 6; /* 6 hours default. */
1513 Globals.machine_password_timeout = 60 * 60 * 24 * 7; /* 7 days default. */
1514 Globals.bKernelChangeNotify = True; /* On if we have it. */
1515 Globals.bFamChangeNotify = True; /* On if we have it. */
1516 Globals.lm_announce = 2; /* = Auto: send only if LM clients found */
1517 Globals.lm_interval = 60;
1518 Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
1519 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
1520 Globals.bNISHomeMap = False;
1521 #ifdef WITH_NISPLUS_HOME
1522 string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
1523 #else
1524 string_set(&Globals.szNISHomeMapName, "auto.home");
1525 #endif
1526 #endif
1527 Globals.bTimeServer = False;
1528 Globals.bBindInterfacesOnly = False;
1529 Globals.bUnixPasswdSync = False;
1530 Globals.bPamPasswordChange = False;
1531 Globals.bPasswdChatDebug = False;
1532 Globals.iPasswdChatTimeout = 2; /* 2 second default. */
1533 Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
1534 Globals.bNTStatusSupport = True; /* Use NT status by default. */
1535 Globals.bStatCache = True; /* use stat cache by default */
1536 Globals.iMaxStatCacheSize = 0; /* unlimited size in kb by default. */
1537 Globals.restrict_anonymous = 0;
1538 Globals.bClientLanManAuth = True; /* Do use the LanMan hash if it is available */
1539 Globals.bClientPlaintextAuth = True; /* Do use a plaintext password if is requested by the server */
1540 Globals.bLanmanAuth = True; /* Do use the LanMan hash if it is available */
1541 Globals.bNTLMAuth = True; /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
1542 Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
1543 /* Note, that we will use NTLM2 session security (which is different), if it is available */
1545 Globals.map_to_guest = 0; /* By Default, "Never" */
1546 Globals.oplock_break_wait_time = 0; /* By Default, 0 msecs. */
1547 Globals.enhanced_browsing = True;
1548 Globals.iLockSpinCount = 3; /* Try 3 times. */
1549 Globals.iLockSpinTime = 10; /* usec. */
1550 #ifdef MMAP_BLACKLIST
1551 Globals.bUseMmap = False;
1552 #else
1553 Globals.bUseMmap = True;
1554 #endif
1555 Globals.bUnixExtensions = True;
1556 Globals.bResetOnZeroVC = False;
1558 /* hostname lookups can be very expensive and are broken on
1559 a large number of sites (tridge) */
1560 Globals.bHostnameLookups = False;
1562 string_set(&Globals.szPassdbBackend, "smbpasswd");
1563 string_set(&Globals.szLdapSuffix, "");
1564 string_set(&Globals.szLdapMachineSuffix, "");
1565 string_set(&Globals.szLdapUserSuffix, "");
1566 string_set(&Globals.szLdapGroupSuffix, "");
1567 string_set(&Globals.szLdapIdmapSuffix, "");
1569 string_set(&Globals.szLdapAdminDn, "");
1570 Globals.ldap_ssl = LDAP_SSL_ON;
1571 Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
1572 Globals.ldap_delete_dn = False;
1573 Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
1574 Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
1575 Globals.ldap_page_size = LDAP_PAGE_SIZE;
1577 /* This is what we tell the afs client. in reality we set the token
1578 * to never expire, though, when this runs out the afs client will
1579 * forget the token. Set to 0 to get NEVERDATE.*/
1580 Globals.iAfsTokenLifetime = 604800;
1582 /* these parameters are set to defaults that are more appropriate
1583 for the increasing samba install base:
1585 as a member of the workgroup, that will possibly become a
1586 _local_ master browser (lm = True). this is opposed to a forced
1587 local master browser startup (pm = True).
1589 doesn't provide WINS server service by default (wsupp = False),
1590 and doesn't provide domain master browser services by default, either.
1594 Globals.bMsAddPrinterWizard = True;
1595 Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
1596 Globals.os_level = 20;
1597 Globals.bLocalMaster = True;
1598 Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
1599 Globals.bDomainLogons = False;
1600 Globals.bBrowseList = True;
1601 Globals.bWINSsupport = False;
1602 Globals.bWINSproxy = False;
1604 Globals.bDNSproxy = True;
1606 /* this just means to use them if they exist */
1607 Globals.bKernelOplocks = True;
1609 Globals.bAllowTrustedDomains = True;
1611 string_set(&Globals.szTemplateShell, "/bin/false");
1612 string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
1613 string_set(&Globals.szWinbindSeparator, "\\");
1614 string_set(&Globals.szAclCompat, "");
1615 string_set(&Globals.szCupsServer, "");
1616 string_set(&Globals.szIPrintServer, "");
1618 Globals.winbind_cache_time = 300; /* 5 minutes */
1619 Globals.bWinbindEnumUsers = False;
1620 Globals.bWinbindEnumGroups = False;
1621 Globals.bWinbindUseDefaultDomain = False;
1622 Globals.bWinbindTrustedDomainsOnly = False;
1623 Globals.bWinbindNestedGroups = True;
1624 Globals.szWinbindNssInfo = str_list_make("template", NULL);
1625 Globals.bWinbindRefreshTickets = False;
1626 Globals.bWinbindOfflineLogon = False;
1628 Globals.bPassdbExpandExplicit = False;
1630 Globals.name_cache_timeout = 660; /* In seconds */
1632 Globals.bUseSpnego = True;
1633 Globals.bClientUseSpnego = True;
1635 Globals.client_signing = Auto;
1636 Globals.server_signing = False;
1638 Globals.bDeferSharingViolations = True;
1639 string_set(&Globals.smb_ports, SMB_PORTS);
1641 Globals.bEnablePrivileges = True;
1642 Globals.bHostMSDfs = True;
1643 Globals.bASUSupport = False;
1645 /* User defined shares. */
1646 pstrcpy(s, dyn_LOCKDIR);
1647 pstrcat(s, "/usershares");
1648 string_set(&Globals.szUsersharePath, s);
1649 string_set(&Globals.szUsershareTemplateShare, "");
1650 Globals.iUsershareMaxShares = 0;
1651 /* By default disallow sharing of directories not owned by the sharer. */
1652 Globals.bUsershareOwnerOnly = True;
1653 /* By default disallow guest access to usershares. */
1654 Globals.bUsershareAllowGuests = False;
1657 static TALLOC_CTX *lp_talloc;
1659 /******************************************************************* a
1660 Free up temporary memory - called from the main loop.
1661 ********************************************************************/
1663 void lp_TALLOC_FREE(void)
1665 if (!lp_talloc)
1666 return;
1667 TALLOC_FREE(lp_talloc);
1668 lp_talloc = NULL;
1671 TALLOC_CTX *tmp_talloc_ctx(void)
1673 if (lp_talloc == NULL) {
1674 lp_talloc = talloc_init(NULL);
1677 if (lp_talloc == NULL) {
1678 smb_panic("Could not create temporary talloc context\n");
1681 return lp_talloc;
1684 /*******************************************************************
1685 Convenience routine to grab string parameters into temporary memory
1686 and run standard_sub_basic on them. The buffers can be written to by
1687 callers without affecting the source string.
1688 ********************************************************************/
1690 static char *lp_string(const char *s)
1692 char *ret, *tmpstr;
1694 /* The follow debug is useful for tracking down memory problems
1695 especially if you have an inner loop that is calling a lp_*()
1696 function that returns a string. Perhaps this debug should be
1697 present all the time? */
1699 #if 0
1700 DEBUG(10, ("lp_string(%s)\n", s));
1701 #endif
1703 if (!lp_talloc)
1704 lp_talloc = talloc_init("lp_talloc");
1706 tmpstr = alloc_sub_basic(get_current_username(), s);
1707 if (trim_char(tmpstr, '\"', '\"')) {
1708 if (strchr(tmpstr,'\"') != NULL) {
1709 SAFE_FREE(tmpstr);
1710 tmpstr = alloc_sub_basic(get_current_username(),s);
1713 ret = talloc_strdup(lp_talloc, tmpstr);
1714 SAFE_FREE(tmpstr);
1716 return (ret);
1720 In this section all the functions that are used to access the
1721 parameters from the rest of the program are defined
1724 #define FN_GLOBAL_STRING(fn_name,ptr) \
1725 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1726 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1727 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1728 #define FN_GLOBAL_LIST(fn_name,ptr) \
1729 const char **fn_name(void) {return(*(const char ***)(ptr));}
1730 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1731 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1732 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1733 char fn_name(void) {return(*(char *)(ptr));}
1734 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1735 int fn_name(void) {return(*(int *)(ptr));}
1737 #define FN_LOCAL_STRING(fn_name,val) \
1738 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1739 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1740 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1741 #define FN_LOCAL_LIST(fn_name,val) \
1742 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1743 #define FN_LOCAL_BOOL(fn_name,val) \
1744 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1745 #define FN_LOCAL_CHAR(fn_name,val) \
1746 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1747 #define FN_LOCAL_INTEGER(fn_name,val) \
1748 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1750 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1751 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1752 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1753 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1754 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1755 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1756 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1757 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1758 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1759 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1760 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1761 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1762 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1763 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1764 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1765 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1766 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1767 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1768 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1769 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1770 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1771 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1772 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1773 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1774 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1775 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1776 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1777 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1778 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1779 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1780 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1781 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1782 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1783 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1784 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1785 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1786 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1787 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1788 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1789 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1790 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1791 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1792 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1793 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1794 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1795 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1796 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1797 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1798 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1799 FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1800 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1801 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1802 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1803 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1804 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1806 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1807 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1808 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1809 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1810 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1811 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1813 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1815 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1816 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1817 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1819 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1821 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1822 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1823 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1824 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1825 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.szAclCompat)
1826 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1827 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1828 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1829 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1830 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1831 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1832 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1834 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend)
1835 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1837 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1838 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1839 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1840 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1841 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1842 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1843 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1844 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1845 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1846 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1847 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1848 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1849 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1850 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1852 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1854 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1855 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1856 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1857 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1858 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1859 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1860 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1861 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1862 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1863 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1864 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1865 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1866 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1867 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1868 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1869 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1870 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1871 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1872 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1873 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1874 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1875 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1876 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1877 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1878 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1879 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1880 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1881 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1882 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1883 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1884 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1885 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1886 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1887 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1888 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1889 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1890 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1891 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1892 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1893 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1894 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1895 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1896 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1897 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1898 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1899 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1900 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1901 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1902 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1903 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1904 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1905 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1906 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1907 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1908 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1909 FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
1910 FN_GLOBAL_BOOL(lp_fam_change_notify, &Globals.bFamChangeNotify)
1911 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
1912 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
1913 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
1914 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
1915 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1916 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1917 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1918 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1919 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1920 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1921 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
1922 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1923 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1924 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1925 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1926 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1927 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1928 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1929 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1930 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1931 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1932 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1933 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1934 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
1935 FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
1936 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1937 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1938 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1939 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1940 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1941 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1942 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1943 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1944 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1945 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
1947 FN_LOCAL_STRING(lp_preexec, szPreExec)
1948 FN_LOCAL_STRING(lp_postexec, szPostExec)
1949 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1950 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1951 FN_LOCAL_STRING(lp_servicename, szService)
1952 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1953 FN_LOCAL_STRING(lp_pathname, szPath)
1954 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1955 FN_LOCAL_STRING(lp_username, szUsername)
1956 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1957 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1958 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1959 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
1960 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
1961 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
1962 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
1963 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1964 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1965 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1966 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1967 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1968 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1969 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1970 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1971 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1972 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1973 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
1974 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
1975 FN_LOCAL_STRING(lp_comment, comment)
1976 FN_LOCAL_STRING(lp_force_user, force_user)
1977 FN_LOCAL_STRING(lp_force_group, force_group)
1978 FN_LOCAL_LIST(lp_readlist, readlist)
1979 FN_LOCAL_LIST(lp_writelist, writelist)
1980 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
1981 FN_LOCAL_STRING(lp_fstype, fstype)
1982 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
1983 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1984 static FN_LOCAL_STRING(lp_volume, volume)
1985 FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
1986 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
1987 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
1988 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
1989 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1990 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
1991 FN_LOCAL_STRING(lp_dfree_command, szDfree)
1992 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1993 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
1994 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
1995 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
1996 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
1997 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
1998 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
1999 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
2000 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2001 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2002 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2003 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2004 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2005 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2006 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2007 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2008 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2009 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2010 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2011 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2012 FN_LOCAL_BOOL(lp_locking, bLocking)
2013 FN_LOCAL_INTEGER(lp_strict_locking, iStrictLocking)
2014 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
2015 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2016 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2017 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2018 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2019 FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
2020 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2021 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2022 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2023 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2024 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2025 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2026 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2027 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2028 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2029 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2030 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2031 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2032 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2033 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2034 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2035 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2036 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2037 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2038 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2039 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2040 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2041 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2042 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2043 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2044 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2045 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2046 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2047 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2048 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2049 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2050 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2051 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2052 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2053 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2054 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2055 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2056 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2057 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2058 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2059 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2060 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2061 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2062 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2063 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2064 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2065 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2066 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2067 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2068 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2069 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2070 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2071 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2072 FN_LOCAL_INTEGER(lp_change_notify_timeout, ichange_notify_timeout)
2073 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2074 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2075 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2076 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2077 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2078 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2079 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2081 /* local prototypes */
2083 static int map_parameter(const char *pszParmName);
2084 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
2085 static int getservicebyname(const char *pszServiceName,
2086 service * pserviceDest);
2087 static void copy_service(service * pserviceDest,
2088 service * pserviceSource, BOOL *pcopymapDest);
2089 static BOOL service_ok(int iService);
2090 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
2091 static BOOL do_section(const char *pszSectionName);
2092 static void init_copymap(service * pservice);
2093 static BOOL hash_a_service(const char *name, int number);
2094 static void free_service_byindex(int iService);
2095 static char * canonicalize_servicename(const char *name);
2097 /* This is a helper function for parametrical options support. */
2098 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2099 /* Actual parametrical functions are quite simple */
2100 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2102 BOOL global_section = False;
2103 char* param_key;
2104 param_opt_struct *data;
2106 if (snum >= iNumServices) return NULL;
2108 if (snum < 0) {
2109 data = Globals.param_opt;
2110 global_section = True;
2111 } else {
2112 data = ServicePtrs[snum]->param_opt;
2115 asprintf(&param_key, "%s:%s", type, option);
2116 if (!param_key) {
2117 DEBUG(0,("asprintf failed!\n"));
2118 return NULL;
2121 while (data) {
2122 if (strcmp(data->key, param_key) == 0) {
2123 string_free(&param_key);
2124 return data;
2126 data = data->next;
2129 if (!global_section) {
2130 /* Try to fetch the same option but from globals */
2131 /* but only if we are not already working with Globals */
2132 data = Globals.param_opt;
2133 while (data) {
2134 if (strcmp(data->key, param_key) == 0) {
2135 string_free(&param_key);
2136 return data;
2138 data = data->next;
2142 string_free(&param_key);
2144 return NULL;
2148 #define MISSING_PARAMETER(name) \
2149 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2151 /*******************************************************************
2152 convenience routine to return int parameters.
2153 ********************************************************************/
2154 static int lp_int(const char *s)
2157 if (!s || !*s) {
2158 MISSING_PARAMETER(lp_int);
2159 return (-1);
2162 return atoi(s);
2165 /*******************************************************************
2166 convenience routine to return unsigned long parameters.
2167 ********************************************************************/
2168 static unsigned long lp_ulong(const char *s)
2171 if (!s || !*s) {
2172 MISSING_PARAMETER(lp_ulong);
2173 return (0);
2176 return strtoul(s, NULL, 10);
2179 /*******************************************************************
2180 convenience routine to return boolean parameters.
2181 ********************************************************************/
2182 static BOOL lp_bool(const char *s)
2184 BOOL ret = False;
2186 if (!s || !*s) {
2187 MISSING_PARAMETER(lp_bool);
2188 return False;
2191 if (!set_boolean(&ret,s)) {
2192 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2193 return False;
2196 return ret;
2199 /*******************************************************************
2200 convenience routine to return enum parameters.
2201 ********************************************************************/
2202 static int lp_enum(const char *s,const struct enum_list *_enum)
2204 int i;
2206 if (!s || !*s || !_enum) {
2207 MISSING_PARAMETER(lp_enum);
2208 return (-1);
2211 for (i=0; _enum[i].name; i++) {
2212 if (strequal(_enum[i].name,s))
2213 return _enum[i].value;
2216 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2217 return (-1);
2220 #undef MISSING_PARAMETER
2222 /* DO NOT USE lp_parm_string ANYMORE!!!!
2223 * use lp_parm_const_string or lp_parm_talloc_string
2225 * lp_parm_string is only used to let old modules find this symbol
2227 #undef lp_parm_string
2228 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2230 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2233 /* Return parametric option from a given service. Type is a part of option before ':' */
2234 /* Parametric option has following syntax: 'Type: option = value' */
2235 /* the returned value is talloced in lp_talloc */
2236 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2238 param_opt_struct *data = get_parametrics(snum, type, option);
2240 if (data == NULL||data->value==NULL) {
2241 if (def) {
2242 return lp_string(def);
2243 } else {
2244 return NULL;
2248 return lp_string(data->value);
2251 /* Return parametric option from a given service. Type is a part of option before ':' */
2252 /* Parametric option has following syntax: 'Type: option = value' */
2253 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2255 param_opt_struct *data = get_parametrics(snum, type, option);
2257 if (data == NULL||data->value==NULL)
2258 return def;
2260 return data->value;
2263 /* Return parametric option from a given service. Type is a part of option before ':' */
2264 /* Parametric option has following syntax: 'Type: option = value' */
2266 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2268 param_opt_struct *data = get_parametrics(snum, type, option);
2270 if (data == NULL||data->value==NULL)
2271 return (const char **)def;
2273 if (data->list==NULL) {
2274 data->list = str_list_make(data->value, NULL);
2277 return (const char **)data->list;
2280 /* Return parametric option from a given service. Type is a part of option before ':' */
2281 /* Parametric option has following syntax: 'Type: option = value' */
2283 int lp_parm_int(int snum, const char *type, const char *option, int def)
2285 param_opt_struct *data = get_parametrics(snum, type, option);
2287 if (data && data->value && *data->value)
2288 return lp_int(data->value);
2290 return def;
2293 /* Return parametric option from a given service. Type is a part of option before ':' */
2294 /* Parametric option has following syntax: 'Type: option = value' */
2296 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2298 param_opt_struct *data = get_parametrics(snum, type, option);
2300 if (data && data->value && *data->value)
2301 return lp_ulong(data->value);
2303 return def;
2306 /* Return parametric option from a given service. Type is a part of option before ':' */
2307 /* Parametric option has following syntax: 'Type: option = value' */
2309 BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2311 param_opt_struct *data = get_parametrics(snum, type, option);
2313 if (data && data->value && *data->value)
2314 return lp_bool(data->value);
2316 return def;
2319 /* Return parametric option from a given service. Type is a part of option before ':' */
2320 /* Parametric option has following syntax: 'Type: option = value' */
2322 int lp_parm_enum(int snum, const char *type, const char *option,
2323 const struct enum_list *_enum, int def)
2325 param_opt_struct *data = get_parametrics(snum, type, option);
2327 if (data && data->value && *data->value && _enum)
2328 return lp_enum(data->value, _enum);
2330 return def;
2334 /***************************************************************************
2335 Initialise a service to the defaults.
2336 ***************************************************************************/
2338 static void init_service(service * pservice)
2340 memset((char *)pservice, '\0', sizeof(service));
2341 copy_service(pservice, &sDefault, NULL);
2344 /***************************************************************************
2345 Free the dynamically allocated parts of a service struct.
2346 ***************************************************************************/
2348 static void free_service(service *pservice)
2350 int i;
2351 param_opt_struct *data, *pdata;
2352 if (!pservice)
2353 return;
2355 if (pservice->szService)
2356 DEBUG(5, ("free_service: Freeing service %s\n",
2357 pservice->szService));
2359 string_free(&pservice->szService);
2360 SAFE_FREE(pservice->copymap);
2362 for (i = 0; parm_table[i].label; i++) {
2363 if ((parm_table[i].type == P_STRING ||
2364 parm_table[i].type == P_USTRING) &&
2365 parm_table[i].p_class == P_LOCAL)
2366 string_free((char **)
2367 (((char *)pservice) +
2368 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2369 else if (parm_table[i].type == P_LIST &&
2370 parm_table[i].p_class == P_LOCAL)
2371 str_list_free((char ***)
2372 (((char *)pservice) +
2373 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2376 data = pservice->param_opt;
2377 if (data)
2378 DEBUG(5,("Freeing parametrics:\n"));
2379 while (data) {
2380 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2381 string_free(&data->key);
2382 string_free(&data->value);
2383 str_list_free(&data->list);
2384 pdata = data->next;
2385 SAFE_FREE(data);
2386 data = pdata;
2389 ZERO_STRUCTP(pservice);
2393 /***************************************************************************
2394 remove a service indexed in the ServicePtrs array from the ServiceHash
2395 and free the dynamically allocated parts
2396 ***************************************************************************/
2398 static void free_service_byindex(int idx)
2400 if ( !LP_SNUM_OK(idx) )
2401 return;
2403 ServicePtrs[idx]->valid = False;
2404 invalid_services[num_invalid_services++] = idx;
2406 /* we have to cleanup the hash record */
2408 if (ServicePtrs[idx]->szService) {
2409 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2411 tdb_delete_bystring(ServiceHash, canon_name );
2414 free_service(ServicePtrs[idx]);
2417 /***************************************************************************
2418 Add a new service to the services array initialising it with the given
2419 service.
2420 ***************************************************************************/
2422 static int add_a_service(const service *pservice, const char *name)
2424 int i;
2425 service tservice;
2426 int num_to_alloc = iNumServices + 1;
2427 param_opt_struct *data, *pdata;
2429 tservice = *pservice;
2431 /* it might already exist */
2432 if (name) {
2433 i = getservicebyname(name, NULL);
2434 if (i >= 0) {
2435 /* Clean all parametric options for service */
2436 /* They will be added during parsing again */
2437 data = ServicePtrs[i]->param_opt;
2438 while (data) {
2439 string_free(&data->key);
2440 string_free(&data->value);
2441 str_list_free(&data->list);
2442 pdata = data->next;
2443 SAFE_FREE(data);
2444 data = pdata;
2446 ServicePtrs[i]->param_opt = NULL;
2447 return (i);
2451 /* find an invalid one */
2452 i = iNumServices;
2453 if (num_invalid_services > 0) {
2454 i = invalid_services[--num_invalid_services];
2457 /* if not, then create one */
2458 if (i == iNumServices) {
2459 service **tsp;
2460 int *tinvalid;
2462 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2463 if (tsp == NULL) {
2464 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2465 return (-1);
2467 ServicePtrs = tsp;
2468 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2469 if (!ServicePtrs[iNumServices]) {
2470 DEBUG(0,("add_a_service: out of memory!\n"));
2471 return (-1);
2473 iNumServices++;
2475 /* enlarge invalid_services here for now... */
2476 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2477 num_to_alloc);
2478 if (tinvalid == NULL) {
2479 DEBUG(0,("add_a_service: failed to enlarge "
2480 "invalid_services!\n"));
2481 return (-1);
2483 invalid_services = tinvalid;
2484 } else {
2485 free_service_byindex(i);
2488 ServicePtrs[i]->valid = True;
2490 init_service(ServicePtrs[i]);
2491 copy_service(ServicePtrs[i], &tservice, NULL);
2492 if (name)
2493 string_set(&ServicePtrs[i]->szService, name);
2495 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2496 i, ServicePtrs[i]->szService));
2498 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2499 return (-1);
2502 return (i);
2505 /***************************************************************************
2506 Convert a string to uppercase and remove whitespaces.
2507 ***************************************************************************/
2509 static char *canonicalize_servicename(const char *src)
2511 static fstring canon; /* is fstring large enough? */
2513 if ( !src ) {
2514 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2515 return NULL;
2518 fstrcpy( canon, src );
2519 strlower_m( canon );
2521 return canon;
2524 /***************************************************************************
2525 Add a name/index pair for the services array to the hash table.
2526 ***************************************************************************/
2528 static BOOL hash_a_service(const char *name, int idx)
2530 char *canon_name;
2532 if ( !ServiceHash ) {
2533 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2534 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2535 (O_RDWR|O_CREAT), 0600);
2536 if ( !ServiceHash ) {
2537 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2538 return False;
2542 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2543 idx, name));
2545 if ( !(canon_name = canonicalize_servicename( name )) )
2546 return False;
2548 tdb_store_int32(ServiceHash, canon_name, idx);
2550 return True;
2553 /***************************************************************************
2554 Add a new home service, with the specified home directory, defaults coming
2555 from service ifrom.
2556 ***************************************************************************/
2558 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
2559 const char *user, const char *pszHomedir)
2561 int i;
2562 pstring newHomedir;
2564 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2566 if (i < 0)
2567 return (False);
2569 if (!(*(ServicePtrs[iDefaultService]->szPath))
2570 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2571 pstrcpy(newHomedir, pszHomedir);
2572 string_set(&ServicePtrs[i]->szPath, newHomedir);
2575 if (!(*(ServicePtrs[i]->comment))) {
2576 pstring comment;
2577 slprintf(comment, sizeof(comment) - 1,
2578 "Home directory of %s", user);
2579 string_set(&ServicePtrs[i]->comment, comment);
2582 /* set the browseable flag from the global default */
2584 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2586 ServicePtrs[i]->autoloaded = True;
2588 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2589 user, ServicePtrs[i]->szPath ));
2591 return (True);
2594 /***************************************************************************
2595 Add a new service, based on an old one.
2596 ***************************************************************************/
2598 int lp_add_service(const char *pszService, int iDefaultService)
2600 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2603 /***************************************************************************
2604 Add the IPC service.
2605 ***************************************************************************/
2607 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2609 pstring comment;
2610 int i = add_a_service(&sDefault, ipc_name);
2612 if (i < 0)
2613 return (False);
2615 slprintf(comment, sizeof(comment) - 1,
2616 "IPC Service (%s)", Globals.szServerString);
2618 string_set(&ServicePtrs[i]->szPath, tmpdir());
2619 string_set(&ServicePtrs[i]->szUsername, "");
2620 string_set(&ServicePtrs[i]->comment, comment);
2621 string_set(&ServicePtrs[i]->fstype, "IPC");
2622 ServicePtrs[i]->iMaxConnections = 0;
2623 ServicePtrs[i]->bAvailable = True;
2624 ServicePtrs[i]->bRead_only = True;
2625 ServicePtrs[i]->bGuest_only = False;
2626 ServicePtrs[i]->bGuest_ok = guest_ok;
2627 ServicePtrs[i]->bPrint_ok = False;
2628 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2630 DEBUG(3, ("adding IPC service\n"));
2632 return (True);
2635 /***************************************************************************
2636 Add a new printer service, with defaults coming from service iFrom.
2637 ***************************************************************************/
2639 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2641 const char *comment = "From Printcap";
2642 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2644 if (i < 0)
2645 return (False);
2647 /* note that we do NOT default the availability flag to True - */
2648 /* we take it from the default service passed. This allows all */
2649 /* dynamic printers to be disabled by disabling the [printers] */
2650 /* entry (if/when the 'available' keyword is implemented!). */
2652 /* the printer name is set to the service name. */
2653 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2654 string_set(&ServicePtrs[i]->comment, comment);
2656 /* set the browseable flag from the gloabl default */
2657 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2659 /* Printers cannot be read_only. */
2660 ServicePtrs[i]->bRead_only = False;
2661 /* No share modes on printer services. */
2662 ServicePtrs[i]->bShareModes = False;
2663 /* No oplocks on printer services. */
2664 ServicePtrs[i]->bOpLocks = False;
2665 /* Printer services must be printable. */
2666 ServicePtrs[i]->bPrint_ok = True;
2668 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2670 return (True);
2673 /***************************************************************************
2674 Map a parameter's string representation to something we can use.
2675 Returns False if the parameter string is not recognised, else TRUE.
2676 ***************************************************************************/
2678 static int map_parameter(const char *pszParmName)
2680 int iIndex;
2682 if (*pszParmName == '-')
2683 return (-1);
2685 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2686 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2687 return (iIndex);
2689 /* Warn only if it isn't parametric option */
2690 if (strchr(pszParmName, ':') == NULL)
2691 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2692 /* We do return 'fail' for parametric options as well because they are
2693 stored in different storage
2695 return (-1);
2698 /***************************************************************************
2699 Show all parameter's name, type, [values,] and flags.
2700 ***************************************************************************/
2702 void show_parameter_list(void)
2704 int classIndex, parmIndex, enumIndex, flagIndex;
2705 BOOL hadFlag;
2706 const char *section_names[] = { "local", "global", NULL};
2707 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2708 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2709 "P_UGSTRING", "P_ENUM", "P_SEP"};
2710 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2711 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2712 FLAG_HIDE, FLAG_DOS_STRING};
2713 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2714 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2715 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2717 for ( classIndex=0; section_names[classIndex]; classIndex++) {
2718 printf("[%s]\n", section_names[classIndex]);
2719 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2720 if (parm_table[parmIndex].p_class == classIndex) {
2721 printf("%s=%s",
2722 parm_table[parmIndex].label,
2723 type[parm_table[parmIndex].type]);
2724 switch (parm_table[parmIndex].type) {
2725 case P_ENUM:
2726 printf(",");
2727 for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2728 printf("%s%s",
2729 enumIndex ? "|" : "",
2730 parm_table[parmIndex].enum_list[enumIndex].name);
2731 break;
2732 default:
2733 break;
2735 printf(",");
2736 hadFlag = False;
2737 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2738 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2739 printf("%s%s",
2740 hadFlag ? "|" : "",
2741 flag_names[flagIndex]);
2742 hadFlag = True;
2745 printf("\n");
2751 /***************************************************************************
2752 Set a boolean variable from the text value stored in the passed string.
2753 Returns True in success, False if the passed string does not correctly
2754 represent a boolean.
2755 ***************************************************************************/
2757 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2759 BOOL bRetval;
2761 bRetval = True;
2762 if (strwicmp(pszParmValue, "yes") == 0 ||
2763 strwicmp(pszParmValue, "true") == 0 ||
2764 strwicmp(pszParmValue, "1") == 0)
2765 *pb = True;
2766 else if (strwicmp(pszParmValue, "no") == 0 ||
2767 strwicmp(pszParmValue, "False") == 0 ||
2768 strwicmp(pszParmValue, "0") == 0)
2769 *pb = False;
2770 else {
2771 DEBUG(0,
2772 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2773 pszParmValue));
2774 bRetval = False;
2776 return (bRetval);
2779 /***************************************************************************
2780 Find a service by name. Otherwise works like get_service.
2781 ***************************************************************************/
2783 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2785 int iService = -1;
2786 char *canon_name;
2788 if (ServiceHash != NULL) {
2789 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2790 return -1;
2792 iService = tdb_fetch_int32(ServiceHash, canon_name );
2794 if (LP_SNUM_OK(iService)) {
2795 if (pserviceDest != NULL) {
2796 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2798 } else {
2799 iService = -1;
2803 return (iService);
2806 /***************************************************************************
2807 Copy a service structure to another.
2808 If pcopymapDest is NULL then copy all fields
2809 ***************************************************************************/
2811 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2813 int i;
2814 BOOL bcopyall = (pcopymapDest == NULL);
2815 param_opt_struct *data, *pdata, *paramo;
2816 BOOL not_added;
2818 for (i = 0; parm_table[i].label; i++)
2819 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2820 (bcopyall || pcopymapDest[i])) {
2821 void *def_ptr = parm_table[i].ptr;
2822 void *src_ptr =
2823 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2824 &sDefault);
2825 void *dest_ptr =
2826 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2827 &sDefault);
2829 switch (parm_table[i].type) {
2830 case P_BOOL:
2831 case P_BOOLREV:
2832 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2833 break;
2835 case P_INTEGER:
2836 case P_ENUM:
2837 case P_OCTAL:
2838 *(int *)dest_ptr = *(int *)src_ptr;
2839 break;
2841 case P_CHAR:
2842 *(char *)dest_ptr = *(char *)src_ptr;
2843 break;
2845 case P_STRING:
2846 string_set((char **)dest_ptr,
2847 *(char **)src_ptr);
2848 break;
2850 case P_USTRING:
2851 string_set((char **)dest_ptr,
2852 *(char **)src_ptr);
2853 strupper_m(*(char **)dest_ptr);
2854 break;
2855 case P_LIST:
2856 str_list_free((char ***)dest_ptr);
2857 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2858 break;
2859 default:
2860 break;
2864 if (bcopyall) {
2865 init_copymap(pserviceDest);
2866 if (pserviceSource->copymap)
2867 memcpy((void *)pserviceDest->copymap,
2868 (void *)pserviceSource->copymap,
2869 sizeof(BOOL) * NUMPARAMETERS);
2872 data = pserviceSource->param_opt;
2873 while (data) {
2874 not_added = True;
2875 pdata = pserviceDest->param_opt;
2876 /* Traverse destination */
2877 while (pdata) {
2878 /* If we already have same option, override it */
2879 if (strcmp(pdata->key, data->key) == 0) {
2880 string_free(&pdata->value);
2881 str_list_free(&data->list);
2882 pdata->value = SMB_STRDUP(data->value);
2883 not_added = False;
2884 break;
2886 pdata = pdata->next;
2888 if (not_added) {
2889 paramo = SMB_XMALLOC_P(param_opt_struct);
2890 paramo->key = SMB_STRDUP(data->key);
2891 paramo->value = SMB_STRDUP(data->value);
2892 paramo->list = NULL;
2893 DLIST_ADD(pserviceDest->param_opt, paramo);
2895 data = data->next;
2899 /***************************************************************************
2900 Check a service for consistency. Return False if the service is in any way
2901 incomplete or faulty, else True.
2902 ***************************************************************************/
2904 static BOOL service_ok(int iService)
2906 BOOL bRetval;
2908 bRetval = True;
2909 if (ServicePtrs[iService]->szService[0] == '\0') {
2910 DEBUG(0, ("The following message indicates an internal error:\n"));
2911 DEBUG(0, ("No service name in service entry.\n"));
2912 bRetval = False;
2915 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2916 /* I can't see why you'd want a non-printable printer service... */
2917 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2918 if (!ServicePtrs[iService]->bPrint_ok) {
2919 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2920 ServicePtrs[iService]->szService));
2921 ServicePtrs[iService]->bPrint_ok = True;
2923 /* [printers] service must also be non-browsable. */
2924 if (ServicePtrs[iService]->bBrowseable)
2925 ServicePtrs[iService]->bBrowseable = False;
2928 if (ServicePtrs[iService]->szPath[0] == '\0' &&
2929 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2930 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
2932 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2933 ServicePtrs[iService]->szService));
2934 ServicePtrs[iService]->bAvailable = False;
2937 /* If a service is flagged unavailable, log the fact at level 0. */
2938 if (!ServicePtrs[iService]->bAvailable)
2939 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2940 ServicePtrs[iService]->szService));
2942 return (bRetval);
2945 static struct file_lists {
2946 struct file_lists *next;
2947 char *name;
2948 char *subfname;
2949 time_t modtime;
2950 } *file_lists = NULL;
2952 /*******************************************************************
2953 Keep a linked list of all config files so we know when one has changed
2954 it's date and needs to be reloaded.
2955 ********************************************************************/
2957 static void add_to_file_list(const char *fname, const char *subfname)
2959 struct file_lists *f = file_lists;
2961 while (f) {
2962 if (f->name && !strcmp(f->name, fname))
2963 break;
2964 f = f->next;
2967 if (!f) {
2968 f = SMB_MALLOC_P(struct file_lists);
2969 if (!f)
2970 return;
2971 f->next = file_lists;
2972 f->name = SMB_STRDUP(fname);
2973 if (!f->name) {
2974 SAFE_FREE(f);
2975 return;
2977 f->subfname = SMB_STRDUP(subfname);
2978 if (!f->subfname) {
2979 SAFE_FREE(f);
2980 return;
2982 file_lists = f;
2983 f->modtime = file_modtime(subfname);
2984 } else {
2985 time_t t = file_modtime(subfname);
2986 if (t)
2987 f->modtime = t;
2991 /*******************************************************************
2992 Check if a config file has changed date.
2993 ********************************************************************/
2995 BOOL lp_file_list_changed(void)
2997 struct file_lists *f = file_lists;
2999 DEBUG(6, ("lp_file_list_changed()\n"));
3001 while (f) {
3002 pstring n2;
3003 time_t mod_time;
3005 pstrcpy(n2, f->name);
3006 standard_sub_basic( get_current_username(), n2, sizeof(n2) );
3008 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3009 f->name, n2, ctime(&f->modtime)));
3011 mod_time = file_modtime(n2);
3013 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3014 DEBUGADD(6,
3015 ("file %s modified: %s\n", n2,
3016 ctime(&mod_time)));
3017 f->modtime = mod_time;
3018 SAFE_FREE(f->subfname);
3019 f->subfname = SMB_STRDUP(n2);
3020 return (True);
3022 f = f->next;
3024 return (False);
3027 /***************************************************************************
3028 Run standard_sub_basic on netbios name... needed because global_myname
3029 is not accessed through any lp_ macro.
3030 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3031 ***************************************************************************/
3033 static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3035 BOOL ret;
3036 pstring netbios_name;
3038 pstrcpy(netbios_name, pszParmValue);
3040 standard_sub_basic(get_current_username(), netbios_name,sizeof(netbios_name));
3042 ret = set_global_myname(netbios_name);
3043 string_set(&Globals.szNetbiosName,global_myname());
3045 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3046 global_myname()));
3048 return ret;
3051 static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3053 if (strcmp(*ptr, pszParmValue) != 0) {
3054 string_set(ptr, pszParmValue);
3055 init_iconv();
3057 return True;
3062 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3064 BOOL ret;
3066 ret = set_global_myworkgroup(pszParmValue);
3067 string_set(&Globals.szWorkgroup,lp_workgroup());
3069 return ret;
3072 static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3074 BOOL ret;
3076 ret = set_global_scope(pszParmValue);
3077 string_set(&Globals.szNetbiosScope,global_scope());
3079 return ret;
3082 static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3084 str_list_free(&Globals.szNetbiosAliases);
3085 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3086 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3089 /***************************************************************************
3090 Handle the include operation.
3091 ***************************************************************************/
3093 static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3095 pstring fname;
3096 pstrcpy(fname, pszParmValue);
3098 standard_sub_basic(get_current_username(), fname,sizeof(fname));
3100 add_to_file_list(pszParmValue, fname);
3102 string_set(ptr, fname);
3104 if (file_exist(fname, NULL))
3105 return (pm_process(fname, do_section, do_parameter));
3107 DEBUG(2, ("Can't find include file %s\n", fname));
3109 return (False);
3112 /***************************************************************************
3113 Handle the interpretation of the copy parameter.
3114 ***************************************************************************/
3116 static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3118 BOOL bRetval;
3119 int iTemp;
3120 service serviceTemp;
3122 string_set(ptr, pszParmValue);
3124 init_service(&serviceTemp);
3126 bRetval = False;
3128 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3130 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3131 if (iTemp == iServiceIndex) {
3132 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3133 } else {
3134 copy_service(ServicePtrs[iServiceIndex],
3135 &serviceTemp,
3136 ServicePtrs[iServiceIndex]->copymap);
3137 bRetval = True;
3139 } else {
3140 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3141 bRetval = False;
3144 free_service(&serviceTemp);
3145 return (bRetval);
3148 /***************************************************************************
3149 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3150 parameters is:
3152 [global]
3154 idmap uid = 1000-1999
3155 idmap gid = 700-899
3157 We only do simple parsing checks here. The strings are parsed into useful
3158 structures in the idmap daemon code.
3160 ***************************************************************************/
3162 /* Some lp_ routines to return idmap [ug]id information */
3164 static uid_t idmap_uid_low, idmap_uid_high;
3165 static gid_t idmap_gid_low, idmap_gid_high;
3167 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3169 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3170 return False;
3172 if (low)
3173 *low = idmap_uid_low;
3175 if (high)
3176 *high = idmap_uid_high;
3178 return True;
3181 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3183 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3184 return False;
3186 if (low)
3187 *low = idmap_gid_low;
3189 if (high)
3190 *high = idmap_gid_high;
3192 return True;
3195 /* Do some simple checks on "idmap [ug]id" parameter values */
3197 static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3199 uint32 low, high;
3201 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3202 return False;
3204 /* Parse OK */
3206 string_set(ptr, pszParmValue);
3208 idmap_uid_low = low;
3209 idmap_uid_high = high;
3211 return True;
3214 static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3216 uint32 low, high;
3218 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3219 return False;
3221 /* Parse OK */
3223 string_set(ptr, pszParmValue);
3225 idmap_gid_low = low;
3226 idmap_gid_high = high;
3228 return True;
3231 /***************************************************************************
3232 Handle the DEBUG level list.
3233 ***************************************************************************/
3235 static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3237 pstring pszParmValue;
3239 pstrcpy(pszParmValue, pszParmValueIn);
3240 string_set(ptr, pszParmValueIn);
3241 return debug_parse_levels( pszParmValue );
3244 /***************************************************************************
3245 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3246 ***************************************************************************/
3248 static char* append_ldap_suffix( const char *str )
3250 char *suffix_string;
3253 if (!lp_talloc)
3254 lp_talloc = talloc_init("lp_talloc");
3256 suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3257 if ( !suffix_string ) {
3258 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3259 return NULL;
3262 return suffix_string;
3265 char *lp_ldap_machine_suffix(void)
3267 if (Globals.szLdapMachineSuffix[0])
3268 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3270 return lp_string(Globals.szLdapSuffix);
3273 char *lp_ldap_user_suffix(void)
3275 if (Globals.szLdapUserSuffix[0])
3276 return append_ldap_suffix(Globals.szLdapUserSuffix);
3278 return lp_string(Globals.szLdapSuffix);
3281 char *lp_ldap_group_suffix(void)
3283 if (Globals.szLdapGroupSuffix[0])
3284 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3286 return lp_string(Globals.szLdapSuffix);
3289 char *lp_ldap_idmap_suffix(void)
3291 if (Globals.szLdapIdmapSuffix[0])
3292 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3294 return lp_string(Globals.szLdapSuffix);
3297 /****************************************************************************
3298 set the value for a P_ENUM
3299 ***************************************************************************/
3301 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3302 int *ptr )
3304 int i;
3306 for (i = 0; parm->enum_list[i].name; i++) {
3307 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3308 *ptr = parm->enum_list[i].value;
3309 break;
3314 /***************************************************************************
3315 ***************************************************************************/
3317 static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3319 static int parm_num = -1;
3320 service *s;
3322 if ( parm_num == -1 )
3323 parm_num = map_parameter( "printing" );
3325 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3327 if ( snum < 0 )
3328 s = &sDefault;
3329 else
3330 s = ServicePtrs[snum];
3332 init_printer_values( s );
3334 return True;
3338 /***************************************************************************
3339 Initialise a copymap.
3340 ***************************************************************************/
3342 static void init_copymap(service * pservice)
3344 int i;
3345 SAFE_FREE(pservice->copymap);
3346 pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3347 if (!pservice->copymap)
3348 DEBUG(0,
3349 ("Couldn't allocate copymap!! (size %d)\n",
3350 (int)NUMPARAMETERS));
3351 else
3352 for (i = 0; i < NUMPARAMETERS; i++)
3353 pservice->copymap[i] = True;
3356 /***************************************************************************
3357 Return the local pointer to a parameter given the service number and the
3358 pointer into the default structure.
3359 ***************************************************************************/
3361 void *lp_local_ptr(int snum, void *ptr)
3363 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3366 /***************************************************************************
3367 Process a parameter for a particular service number. If snum < 0
3368 then assume we are in the globals.
3369 ***************************************************************************/
3371 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3373 int parmnum, i, slen;
3374 void *parm_ptr = NULL; /* where we are going to store the result */
3375 void *def_ptr = NULL;
3376 pstring param_key;
3377 char *sep;
3378 param_opt_struct *paramo, *data;
3379 BOOL not_added;
3381 parmnum = map_parameter(pszParmName);
3383 if (parmnum < 0) {
3384 if ((sep=strchr(pszParmName, ':')) != NULL) {
3385 *sep = '\0';
3386 ZERO_STRUCT(param_key);
3387 pstr_sprintf(param_key, "%s:", pszParmName);
3388 slen = strlen(param_key);
3389 pstrcat(param_key, sep+1);
3390 trim_char(param_key+slen, ' ', ' ');
3391 not_added = True;
3392 data = (snum < 0) ? Globals.param_opt :
3393 ServicePtrs[snum]->param_opt;
3394 /* Traverse destination */
3395 while (data) {
3396 /* If we already have same option, override it */
3397 if (strcmp(data->key, param_key) == 0) {
3398 string_free(&data->value);
3399 str_list_free(&data->list);
3400 data->value = SMB_STRDUP(pszParmValue);
3401 not_added = False;
3402 break;
3404 data = data->next;
3406 if (not_added) {
3407 paramo = SMB_XMALLOC_P(param_opt_struct);
3408 paramo->key = SMB_STRDUP(param_key);
3409 paramo->value = SMB_STRDUP(pszParmValue);
3410 paramo->list = NULL;
3411 if (snum < 0) {
3412 DLIST_ADD(Globals.param_opt, paramo);
3413 } else {
3414 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3418 *sep = ':';
3419 return (True);
3421 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3422 return (True);
3425 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3426 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3427 pszParmName));
3430 def_ptr = parm_table[parmnum].ptr;
3432 /* we might point at a service, the default service or a global */
3433 if (snum < 0) {
3434 parm_ptr = def_ptr;
3435 } else {
3436 if (parm_table[parmnum].p_class == P_GLOBAL) {
3437 DEBUG(0,
3438 ("Global parameter %s found in service section!\n",
3439 pszParmName));
3440 return (True);
3442 parm_ptr =
3443 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3444 &sDefault);
3447 if (snum >= 0) {
3448 if (!ServicePtrs[snum]->copymap)
3449 init_copymap(ServicePtrs[snum]);
3451 /* this handles the aliases - set the copymap for other entries with
3452 the same data pointer */
3453 for (i = 0; parm_table[i].label; i++)
3454 if (parm_table[i].ptr == parm_table[parmnum].ptr)
3455 ServicePtrs[snum]->copymap[i] = False;
3458 /* if it is a special case then go ahead */
3459 if (parm_table[parmnum].special) {
3460 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3461 return (True);
3464 /* now switch on the type of variable it is */
3465 switch (parm_table[parmnum].type)
3467 case P_BOOL:
3468 *(BOOL *)parm_ptr = lp_bool(pszParmValue);
3469 break;
3471 case P_BOOLREV:
3472 *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
3473 break;
3475 case P_INTEGER:
3476 *(int *)parm_ptr = lp_int(pszParmValue);
3477 break;
3479 case P_CHAR:
3480 *(char *)parm_ptr = *pszParmValue;
3481 break;
3483 case P_OCTAL:
3484 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3485 if ( i != 1 ) {
3486 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3488 break;
3490 case P_LIST:
3491 str_list_free((char ***)parm_ptr);
3492 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3493 break;
3495 case P_STRING:
3496 string_set((char **)parm_ptr, pszParmValue);
3497 break;
3499 case P_USTRING:
3500 string_set((char **)parm_ptr, pszParmValue);
3501 strupper_m(*(char **)parm_ptr);
3502 break;
3504 case P_GSTRING:
3505 pstrcpy((char *)parm_ptr, pszParmValue);
3506 break;
3508 case P_UGSTRING:
3509 pstrcpy((char *)parm_ptr, pszParmValue);
3510 strupper_m((char *)parm_ptr);
3511 break;
3513 case P_ENUM:
3514 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3515 break;
3516 case P_SEP:
3517 break;
3520 return (True);
3523 /***************************************************************************
3524 Process a parameter.
3525 ***************************************************************************/
3527 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3529 if (!bInGlobalSection && bGlobalOnly)
3530 return (True);
3532 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3534 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3535 pszParmName, pszParmValue));
3538 /***************************************************************************
3539 Print a parameter of the specified type.
3540 ***************************************************************************/
3542 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3544 int i;
3545 switch (p->type)
3547 case P_ENUM:
3548 for (i = 0; p->enum_list[i].name; i++) {
3549 if (*(int *)ptr == p->enum_list[i].value) {
3550 fprintf(f, "%s",
3551 p->enum_list[i].name);
3552 break;
3555 break;
3557 case P_BOOL:
3558 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3559 break;
3561 case P_BOOLREV:
3562 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3563 break;
3565 case P_INTEGER:
3566 fprintf(f, "%d", *(int *)ptr);
3567 break;
3569 case P_CHAR:
3570 fprintf(f, "%c", *(char *)ptr);
3571 break;
3573 case P_OCTAL:
3574 fprintf(f, "%s", octal_string(*(int *)ptr));
3575 break;
3577 case P_LIST:
3578 if ((char ***)ptr && *(char ***)ptr) {
3579 char **list = *(char ***)ptr;
3581 for (; *list; list++) {
3582 /* surround strings with whitespace in double quotes */
3583 if ( strchr_m( *list, ' ' ) )
3584 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3585 else
3586 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3589 break;
3591 case P_GSTRING:
3592 case P_UGSTRING:
3593 if ((char *)ptr) {
3594 fprintf(f, "%s", (char *)ptr);
3596 break;
3598 case P_STRING:
3599 case P_USTRING:
3600 if (*(char **)ptr) {
3601 fprintf(f, "%s", *(char **)ptr);
3603 break;
3604 case P_SEP:
3605 break;
3609 /***************************************************************************
3610 Check if two parameters are equal.
3611 ***************************************************************************/
3613 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3615 switch (type) {
3616 case P_BOOL:
3617 case P_BOOLREV:
3618 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3620 case P_INTEGER:
3621 case P_ENUM:
3622 case P_OCTAL:
3623 return (*((int *)ptr1) == *((int *)ptr2));
3625 case P_CHAR:
3626 return (*((char *)ptr1) == *((char *)ptr2));
3628 case P_LIST:
3629 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3631 case P_GSTRING:
3632 case P_UGSTRING:
3634 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3635 if (p1 && !*p1)
3636 p1 = NULL;
3637 if (p2 && !*p2)
3638 p2 = NULL;
3639 return (p1 == p2 || strequal(p1, p2));
3641 case P_STRING:
3642 case P_USTRING:
3644 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3645 if (p1 && !*p1)
3646 p1 = NULL;
3647 if (p2 && !*p2)
3648 p2 = NULL;
3649 return (p1 == p2 || strequal(p1, p2));
3651 case P_SEP:
3652 break;
3654 return (False);
3657 /***************************************************************************
3658 Initialize any local varients in the sDefault table.
3659 ***************************************************************************/
3661 void init_locals(void)
3663 /* None as yet. */
3666 /***************************************************************************
3667 Process a new section (service). At this stage all sections are services.
3668 Later we'll have special sections that permit server parameters to be set.
3669 Returns True on success, False on failure.
3670 ***************************************************************************/
3672 static BOOL do_section(const char *pszSectionName)
3674 BOOL bRetval;
3675 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3676 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3677 bRetval = False;
3679 /* if we were in a global section then do the local inits */
3680 if (bInGlobalSection && !isglobal)
3681 init_locals();
3683 /* if we've just struck a global section, note the fact. */
3684 bInGlobalSection = isglobal;
3686 /* check for multiple global sections */
3687 if (bInGlobalSection) {
3688 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3689 return (True);
3692 if (!bInGlobalSection && bGlobalOnly)
3693 return (True);
3695 /* if we have a current service, tidy it up before moving on */
3696 bRetval = True;
3698 if (iServiceIndex >= 0)
3699 bRetval = service_ok(iServiceIndex);
3701 /* if all is still well, move to the next record in the services array */
3702 if (bRetval) {
3703 /* We put this here to avoid an odd message order if messages are */
3704 /* issued by the post-processing of a previous section. */
3705 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3707 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3708 < 0) {
3709 DEBUG(0, ("Failed to add a new service\n"));
3710 return (False);
3714 return (bRetval);
3718 /***************************************************************************
3719 Determine if a partcular base parameter is currentl set to the default value.
3720 ***************************************************************************/
3722 static BOOL is_default(int i)
3724 if (!defaults_saved)
3725 return False;
3726 switch (parm_table[i].type) {
3727 case P_LIST:
3728 return str_list_compare (parm_table[i].def.lvalue,
3729 *(char ***)parm_table[i].ptr);
3730 case P_STRING:
3731 case P_USTRING:
3732 return strequal(parm_table[i].def.svalue,
3733 *(char **)parm_table[i].ptr);
3734 case P_GSTRING:
3735 case P_UGSTRING:
3736 return strequal(parm_table[i].def.svalue,
3737 (char *)parm_table[i].ptr);
3738 case P_BOOL:
3739 case P_BOOLREV:
3740 return parm_table[i].def.bvalue ==
3741 *(BOOL *)parm_table[i].ptr;
3742 case P_CHAR:
3743 return parm_table[i].def.cvalue ==
3744 *(char *)parm_table[i].ptr;
3745 case P_INTEGER:
3746 case P_OCTAL:
3747 case P_ENUM:
3748 return parm_table[i].def.ivalue ==
3749 *(int *)parm_table[i].ptr;
3750 case P_SEP:
3751 break;
3753 return False;
3756 /***************************************************************************
3757 Display the contents of the global structure.
3758 ***************************************************************************/
3760 static void dump_globals(FILE *f)
3762 int i;
3763 param_opt_struct *data;
3765 fprintf(f, "[global]\n");
3767 for (i = 0; parm_table[i].label; i++)
3768 if (parm_table[i].p_class == P_GLOBAL &&
3769 parm_table[i].ptr &&
3770 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3771 if (defaults_saved && is_default(i))
3772 continue;
3773 fprintf(f, "\t%s = ", parm_table[i].label);
3774 print_parameter(&parm_table[i], parm_table[i].ptr, f);
3775 fprintf(f, "\n");
3777 if (Globals.param_opt != NULL) {
3778 data = Globals.param_opt;
3779 while(data) {
3780 fprintf(f, "\t%s = %s\n", data->key, data->value);
3781 data = data->next;
3787 /***************************************************************************
3788 Return True if a local parameter is currently set to the global default.
3789 ***************************************************************************/
3791 BOOL lp_is_default(int snum, struct parm_struct *parm)
3793 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3795 return equal_parameter(parm->type,
3796 ((char *)ServicePtrs[snum]) + pdiff,
3797 ((char *)&sDefault) + pdiff);
3800 /***************************************************************************
3801 Display the contents of a single services record.
3802 ***************************************************************************/
3804 static void dump_a_service(service * pService, FILE * f)
3806 int i;
3807 param_opt_struct *data;
3809 if (pService != &sDefault)
3810 fprintf(f, "[%s]\n", pService->szService);
3812 for (i = 0; parm_table[i].label; i++) {
3814 if (parm_table[i].p_class == P_LOCAL &&
3815 parm_table[i].ptr &&
3816 (*parm_table[i].label != '-') &&
3817 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3820 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3822 if (pService == &sDefault) {
3823 if (defaults_saved && is_default(i))
3824 continue;
3825 } else {
3826 if (equal_parameter(parm_table[i].type,
3827 ((char *)pService) +
3828 pdiff,
3829 ((char *)&sDefault) +
3830 pdiff))
3831 continue;
3834 fprintf(f, "\t%s = ", parm_table[i].label);
3835 print_parameter(&parm_table[i],
3836 ((char *)pService) + pdiff, f);
3837 fprintf(f, "\n");
3841 if (pService->param_opt != NULL) {
3842 data = pService->param_opt;
3843 while(data) {
3844 fprintf(f, "\t%s = %s\n", data->key, data->value);
3845 data = data->next;
3850 /***************************************************************************
3851 Display the contents of a parameter of a single services record.
3852 ***************************************************************************/
3854 BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
3856 service * pService = ServicePtrs[snum];
3857 int i;
3858 BOOL result = False;
3859 parm_class p_class;
3860 unsigned flag = 0;
3861 fstring local_parm_name;
3862 char *parm_opt;
3863 const char *parm_opt_value;
3865 /* check for parametrical option */
3866 fstrcpy( local_parm_name, parm_name);
3867 parm_opt = strchr( local_parm_name, ':');
3869 if (parm_opt) {
3870 *parm_opt = '\0';
3871 parm_opt++;
3872 if (strlen(parm_opt)) {
3873 parm_opt_value = lp_parm_const_string( snum,
3874 local_parm_name, parm_opt, NULL);
3875 if (parm_opt_value) {
3876 printf( "%s\n", parm_opt_value);
3877 result = True;
3880 return result;
3883 /* check for a key and print the value */
3884 if (isGlobal) {
3885 p_class = P_GLOBAL;
3886 flag = FLAG_GLOBAL;
3887 } else
3888 p_class = P_LOCAL;
3890 for (i = 0; parm_table[i].label; i++) {
3891 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3892 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3893 parm_table[i].ptr &&
3894 (*parm_table[i].label != '-') &&
3895 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3897 void *ptr;
3899 if (isGlobal)
3900 ptr = parm_table[i].ptr;
3901 else
3902 ptr = ((char *)pService) +
3903 PTR_DIFF(parm_table[i].ptr, &sDefault);
3905 print_parameter(&parm_table[i],
3906 ptr, f);
3907 fprintf(f, "\n");
3908 result = True;
3909 break;
3913 return result;
3916 /***************************************************************************
3917 Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
3918 Return NULL when out of parameters.
3919 ***************************************************************************/
3921 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3923 if (snum < 0) {
3924 /* do the globals */
3925 for (; parm_table[*i].label; (*i)++) {
3926 if (parm_table[*i].p_class == P_SEPARATOR)
3927 return &parm_table[(*i)++];
3929 if (!parm_table[*i].ptr
3930 || (*parm_table[*i].label == '-'))
3931 continue;
3933 if ((*i) > 0
3934 && (parm_table[*i].ptr ==
3935 parm_table[(*i) - 1].ptr))
3936 continue;
3938 return &parm_table[(*i)++];
3940 } else {
3941 service *pService = ServicePtrs[snum];
3943 for (; parm_table[*i].label; (*i)++) {
3944 if (parm_table[*i].p_class == P_SEPARATOR)
3945 return &parm_table[(*i)++];
3947 if (parm_table[*i].p_class == P_LOCAL &&
3948 parm_table[*i].ptr &&
3949 (*parm_table[*i].label != '-') &&
3950 ((*i) == 0 ||
3951 (parm_table[*i].ptr !=
3952 parm_table[(*i) - 1].ptr)))
3954 int pdiff =
3955 PTR_DIFF(parm_table[*i].ptr,
3956 &sDefault);
3958 if (allparameters ||
3959 !equal_parameter(parm_table[*i].type,
3960 ((char *)pService) +
3961 pdiff,
3962 ((char *)&sDefault) +
3963 pdiff))
3965 return &parm_table[(*i)++];
3971 return NULL;
3975 #if 0
3976 /***************************************************************************
3977 Display the contents of a single copy structure.
3978 ***************************************************************************/
3979 static void dump_copy_map(BOOL *pcopymap)
3981 int i;
3982 if (!pcopymap)
3983 return;
3985 printf("\n\tNon-Copied parameters:\n");
3987 for (i = 0; parm_table[i].label; i++)
3988 if (parm_table[i].p_class == P_LOCAL &&
3989 parm_table[i].ptr && !pcopymap[i] &&
3990 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3992 printf("\t\t%s\n", parm_table[i].label);
3995 #endif
3997 /***************************************************************************
3998 Return TRUE if the passed service number is within range.
3999 ***************************************************************************/
4001 BOOL lp_snum_ok(int iService)
4003 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4006 /***************************************************************************
4007 Auto-load some home services.
4008 ***************************************************************************/
4010 static void lp_add_auto_services(char *str)
4012 char *s;
4013 char *p;
4014 int homes;
4016 if (!str)
4017 return;
4019 s = SMB_STRDUP(str);
4020 if (!s)
4021 return;
4023 homes = lp_servicenumber(HOMES_NAME);
4025 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4026 char *home = get_user_home_dir(p);
4028 if (lp_servicenumber(p) >= 0)
4029 continue;
4031 if (home && homes >= 0)
4032 lp_add_home(p, homes, p, home);
4034 SAFE_FREE(s);
4037 /***************************************************************************
4038 Auto-load one printer.
4039 ***************************************************************************/
4041 void lp_add_one_printer(char *name, char *comment)
4043 int printers = lp_servicenumber(PRINTERS_NAME);
4044 int i;
4046 if (lp_servicenumber(name) < 0) {
4047 lp_add_printer(name, printers);
4048 if ((i = lp_servicenumber(name)) >= 0) {
4049 string_set(&ServicePtrs[i]->comment, comment);
4050 ServicePtrs[i]->autoloaded = True;
4055 /***************************************************************************
4056 Have we loaded a services file yet?
4057 ***************************************************************************/
4059 BOOL lp_loaded(void)
4061 return (bLoaded);
4064 /***************************************************************************
4065 Unload unused services.
4066 ***************************************************************************/
4068 void lp_killunused(BOOL (*snumused) (int))
4070 int i;
4071 for (i = 0; i < iNumServices; i++) {
4072 if (!VALID(i))
4073 continue;
4075 /* don't kill autoloaded or usershare services */
4076 if ( ServicePtrs[i]->autoloaded ||
4077 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4078 continue;
4081 if (!snumused || !snumused(i)) {
4082 free_service_byindex(i);
4087 /***************************************************************************
4088 Unload a service.
4089 ***************************************************************************/
4091 void lp_killservice(int iServiceIn)
4093 if (VALID(iServiceIn)) {
4094 free_service_byindex(iServiceIn);
4098 /***************************************************************************
4099 Save the curent values of all global and sDefault parameters into the
4100 defaults union. This allows swat and testparm to show only the
4101 changed (ie. non-default) parameters.
4102 ***************************************************************************/
4104 static void lp_save_defaults(void)
4106 int i;
4107 for (i = 0; parm_table[i].label; i++) {
4108 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4109 continue;
4110 switch (parm_table[i].type) {
4111 case P_LIST:
4112 str_list_copy(&(parm_table[i].def.lvalue),
4113 *(const char ***)parm_table[i].ptr);
4114 break;
4115 case P_STRING:
4116 case P_USTRING:
4117 if (parm_table[i].ptr) {
4118 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4119 } else {
4120 parm_table[i].def.svalue = NULL;
4122 break;
4123 case P_GSTRING:
4124 case P_UGSTRING:
4125 if (parm_table[i].ptr) {
4126 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4127 } else {
4128 parm_table[i].def.svalue = NULL;
4130 break;
4131 case P_BOOL:
4132 case P_BOOLREV:
4133 parm_table[i].def.bvalue =
4134 *(BOOL *)parm_table[i].ptr;
4135 break;
4136 case P_CHAR:
4137 parm_table[i].def.cvalue =
4138 *(char *)parm_table[i].ptr;
4139 break;
4140 case P_INTEGER:
4141 case P_OCTAL:
4142 case P_ENUM:
4143 parm_table[i].def.ivalue =
4144 *(int *)parm_table[i].ptr;
4145 break;
4146 case P_SEP:
4147 break;
4150 defaults_saved = True;
4153 /*******************************************************************
4154 Set the server type we will announce as via nmbd.
4155 ********************************************************************/
4157 static const struct srv_role_tab {
4158 uint32 role;
4159 const char *role_str;
4160 } srv_role_tab [] = {
4161 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4162 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4163 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4164 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4165 { 0, NULL }
4168 const char* server_role_str(uint32 role)
4170 int i = 0;
4171 for (i=0; srv_role_tab[i].role_str; i++) {
4172 if (role == srv_role_tab[i].role) {
4173 return srv_role_tab[i].role_str;
4176 return NULL;
4179 static void set_server_role(void)
4181 server_role = ROLE_STANDALONE;
4183 switch (lp_security()) {
4184 case SEC_SHARE:
4185 if (lp_domain_logons())
4186 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4187 break;
4188 case SEC_SERVER:
4189 if (lp_domain_logons())
4190 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4191 server_role = ROLE_DOMAIN_MEMBER;
4192 break;
4193 case SEC_DOMAIN:
4194 if (lp_domain_logons()) {
4195 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4196 server_role = ROLE_DOMAIN_BDC;
4197 break;
4199 server_role = ROLE_DOMAIN_MEMBER;
4200 break;
4201 case SEC_ADS:
4202 if (lp_domain_logons()) {
4203 server_role = ROLE_DOMAIN_PDC;
4204 break;
4206 server_role = ROLE_DOMAIN_MEMBER;
4207 break;
4208 case SEC_USER:
4209 if (lp_domain_logons()) {
4211 if (Globals.bDomainMaster) /* auto or yes */
4212 server_role = ROLE_DOMAIN_PDC;
4213 else
4214 server_role = ROLE_DOMAIN_BDC;
4216 break;
4217 default:
4218 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4219 break;
4222 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4225 /***********************************************************
4226 If we should send plaintext/LANMAN passwords in the clinet
4227 ************************************************************/
4229 static void set_allowed_client_auth(void)
4231 if (Globals.bClientNTLMv2Auth) {
4232 Globals.bClientLanManAuth = False;
4234 if (!Globals.bClientLanManAuth) {
4235 Globals.bClientPlaintextAuth = False;
4239 /***************************************************************************
4240 JRA.
4241 The following code allows smbd to read a user defined share file.
4242 Yes, this is my intent. Yes, I'm comfortable with that...
4244 THE FOLLOWING IS SECURITY CRITICAL CODE.
4246 It washes your clothes, it cleans your house, it guards you while you sleep...
4247 Do not f%^k with it....
4248 ***************************************************************************/
4250 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4252 /***************************************************************************
4253 Check allowed stat state of a usershare file.
4254 Ensure we print out who is dicking with us so the admin can
4255 get their sorry ass fired.
4256 ***************************************************************************/
4258 static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4260 if (!S_ISREG(psbuf->st_mode)) {
4261 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4262 "not a regular file\n",
4263 fname, (unsigned int)psbuf->st_uid ));
4264 return False;
4267 /* Ensure this doesn't have the other write bit set. */
4268 if (psbuf->st_mode & S_IWOTH) {
4269 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4270 "public write. Refusing to allow as a usershare file.\n",
4271 fname, (unsigned int)psbuf->st_uid ));
4272 return False;
4275 /* Should be 10k or less. */
4276 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4277 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4278 "too large (%u) to be a user share file.\n",
4279 fname, (unsigned int)psbuf->st_uid,
4280 (unsigned int)psbuf->st_size ));
4281 return False;
4284 return True;
4287 /***************************************************************************
4288 Parse the contents of a usershare file.
4289 ***************************************************************************/
4291 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4292 SMB_STRUCT_STAT *psbuf,
4293 const char *servicename,
4294 int snum,
4295 char **lines,
4296 int numlines,
4297 pstring sharepath,
4298 pstring comment,
4299 SEC_DESC **ppsd,
4300 BOOL *pallow_guest)
4302 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4303 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4304 int us_vers;
4305 SMB_STRUCT_DIR *dp;
4306 SMB_STRUCT_STAT sbuf;
4308 *pallow_guest = False;
4310 if (numlines < 4) {
4311 return USERSHARE_MALFORMED_FILE;
4314 if (strcmp(lines[0], "#VERSION 1") == 0) {
4315 us_vers = 1;
4316 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4317 us_vers = 2;
4318 if (numlines < 5) {
4319 return USERSHARE_MALFORMED_FILE;
4321 } else {
4322 return USERSHARE_BAD_VERSION;
4325 if (strncmp(lines[1], "path=", 5) != 0) {
4326 return USERSHARE_MALFORMED_PATH;
4329 pstrcpy(sharepath, &lines[1][5]);
4330 trim_string(sharepath, " ", " ");
4332 if (strncmp(lines[2], "comment=", 8) != 0) {
4333 return USERSHARE_MALFORMED_COMMENT_DEF;
4336 pstrcpy(comment, &lines[2][8]);
4337 trim_string(comment, " ", " ");
4338 trim_char(comment, '"', '"');
4340 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4341 return USERSHARE_MALFORMED_ACL_DEF;
4344 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4345 return USERSHARE_ACL_ERR;
4348 if (us_vers == 2) {
4349 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4350 return USERSHARE_MALFORMED_ACL_DEF;
4352 if (lines[4][9] == 'y') {
4353 *pallow_guest = True;
4357 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4358 /* Path didn't change, no checks needed. */
4359 return USERSHARE_OK;
4362 /* The path *must* be absolute. */
4363 if (sharepath[0] != '/') {
4364 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4365 servicename, sharepath));
4366 return USERSHARE_PATH_NOT_ABSOLUTE;
4369 /* If there is a usershare prefix deny list ensure one of these paths
4370 doesn't match the start of the user given path. */
4371 if (prefixdenylist) {
4372 int i;
4373 for ( i=0; prefixdenylist[i]; i++ ) {
4374 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4375 servicename, i, prefixdenylist[i], sharepath ));
4376 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4377 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4378 "usershare prefix deny list entries.\n",
4379 servicename, sharepath));
4380 return USERSHARE_PATH_IS_DENIED;
4385 /* If there is a usershare prefix allow list ensure one of these paths
4386 does match the start of the user given path. */
4388 if (prefixallowlist) {
4389 int i;
4390 for ( i=0; prefixallowlist[i]; i++ ) {
4391 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4392 servicename, i, prefixallowlist[i], sharepath ));
4393 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4394 break;
4397 if (prefixallowlist[i] == NULL) {
4398 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4399 "usershare prefix allow list entries.\n",
4400 servicename, sharepath));
4401 return USERSHARE_PATH_NOT_ALLOWED;
4405 /* Ensure this is pointing to a directory. */
4406 dp = sys_opendir(sharepath);
4408 if (!dp) {
4409 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4410 servicename, sharepath));
4411 return USERSHARE_PATH_NOT_DIRECTORY;
4414 /* Ensure the owner of the usershare file has permission to share
4415 this directory. */
4417 if (sys_stat(sharepath, &sbuf) == -1) {
4418 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4419 servicename, sharepath, strerror(errno) ));
4420 sys_closedir(dp);
4421 return USERSHARE_POSIX_ERR;
4424 sys_closedir(dp);
4426 if (!S_ISDIR(sbuf.st_mode)) {
4427 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4428 servicename, sharepath ));
4429 return USERSHARE_PATH_NOT_DIRECTORY;
4432 /* Check if sharing is restricted to owner-only. */
4433 /* psbuf is the stat of the usershare definition file,
4434 sbuf is the stat of the target directory to be shared. */
4436 if (lp_usershare_owner_only()) {
4437 /* root can share anything. */
4438 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4439 return USERSHARE_PATH_NOT_ALLOWED;
4443 return USERSHARE_OK;
4446 /***************************************************************************
4447 Deal with a usershare file.
4448 Returns:
4449 >= 0 - snum
4450 -1 - Bad name, invalid contents.
4451 - service name already existed and not a usershare, problem
4452 with permissions to share directory etc.
4453 ***************************************************************************/
4455 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4457 SMB_STRUCT_STAT sbuf;
4458 SMB_STRUCT_STAT lsbuf;
4459 pstring fname;
4460 pstring sharepath;
4461 pstring comment;
4462 fstring service_name;
4463 char **lines = NULL;
4464 int numlines = 0;
4465 int fd = -1;
4466 int iService = -1;
4467 TALLOC_CTX *ctx = NULL;
4468 SEC_DESC *psd = NULL;
4469 BOOL guest_ok = False;
4471 /* Ensure share name doesn't contain invalid characters. */
4472 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4473 DEBUG(0,("process_usershare_file: share name %s contains "
4474 "invalid characters (any of %s)\n",
4475 file_name, INVALID_SHARENAME_CHARS ));
4476 return -1;
4479 fstrcpy(service_name, file_name);
4481 pstrcpy(fname, dir_name);
4482 pstrcat(fname, "/");
4483 pstrcat(fname, file_name);
4485 /* Minimize the race condition by doing an lstat before we
4486 open and fstat. Ensure this isn't a symlink link. */
4488 if (sys_lstat(fname, &lsbuf) != 0) {
4489 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4490 fname, strerror(errno) ));
4491 return -1;
4494 /* This must be a regular file, not a symlink, directory or
4495 other strange filetype. */
4496 if (!check_usershare_stat(fname, &lsbuf)) {
4497 return -1;
4500 /* See if there is already a servicenum for this name. */
4501 /* tdb_fetch_int32 returns -1 if not found. */
4502 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4504 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4505 /* Nothing changed - Mark valid and return. */
4506 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4507 service_name ));
4508 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4509 return iService;
4512 /* Try and open the file read only - no symlinks allowed. */
4513 #ifdef O_NOFOLLOW
4514 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4515 #else
4516 fd = sys_open(fname, O_RDONLY, 0);
4517 #endif
4519 if (fd == -1) {
4520 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4521 fname, strerror(errno) ));
4522 return -1;
4525 /* Now fstat to be *SURE* it's a regular file. */
4526 if (sys_fstat(fd, &sbuf) != 0) {
4527 close(fd);
4528 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4529 fname, strerror(errno) ));
4530 return -1;
4533 /* Is it the same dev/inode as was lstated ? */
4534 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4535 close(fd);
4536 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4537 "Symlink spoofing going on ?\n", fname ));
4538 return -1;
4541 /* This must be a regular file, not a symlink, directory or
4542 other strange filetype. */
4543 if (!check_usershare_stat(fname, &sbuf)) {
4544 return -1;
4547 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4549 close(fd);
4550 if (lines == NULL) {
4551 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4552 fname, (unsigned int)sbuf.st_uid ));
4553 return -1;
4556 /* Should we allow printers to be shared... ? */
4557 ctx = talloc_init("usershare_sd_xctx");
4558 if (!ctx) {
4559 SAFE_FREE(lines);
4560 return 1;
4563 if (parse_usershare_file(ctx, &sbuf, service_name,
4564 iService, lines, numlines, sharepath,
4565 comment, &psd, &guest_ok) != USERSHARE_OK) {
4566 talloc_destroy(ctx);
4567 SAFE_FREE(lines);
4568 return -1;
4571 SAFE_FREE(lines);
4573 /* Everything ok - add the service possibly using a template. */
4574 if (iService < 0) {
4575 const service *sp = &sDefault;
4576 if (snum_template != -1) {
4577 sp = ServicePtrs[snum_template];
4580 if ((iService = add_a_service(sp, service_name)) < 0) {
4581 DEBUG(0, ("process_usershare_file: Failed to add "
4582 "new service %s\n", service_name));
4583 talloc_destroy(ctx);
4584 return -1;
4587 /* Read only is controlled by usershare ACL below. */
4588 ServicePtrs[iService]->bRead_only = False;
4591 /* Write the ACL of the new/modified share. */
4592 if (!set_share_security(ctx, service_name, psd)) {
4593 DEBUG(0, ("process_usershare_file: Failed to set share "
4594 "security for user share %s\n",
4595 service_name ));
4596 lp_remove_service(iService);
4597 talloc_destroy(ctx);
4598 return -1;
4601 talloc_destroy(ctx);
4603 /* If from a template it may be marked invalid. */
4604 ServicePtrs[iService]->valid = True;
4606 /* Set the service as a valid usershare. */
4607 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4609 /* Set guest access. */
4610 if (lp_usershare_allow_guests()) {
4611 ServicePtrs[iService]->bGuest_ok = guest_ok;
4614 /* And note when it was loaded. */
4615 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4616 string_set(&ServicePtrs[iService]->szPath, sharepath);
4617 string_set(&ServicePtrs[iService]->comment, comment);
4619 return iService;
4622 /***************************************************************************
4623 Checks if a usershare entry has been modified since last load.
4624 ***************************************************************************/
4626 static BOOL usershare_exists(int iService, time_t *last_mod)
4628 SMB_STRUCT_STAT lsbuf;
4629 const char *usersharepath = Globals.szUsersharePath;
4630 pstring fname;
4632 pstrcpy(fname, usersharepath);
4633 pstrcat(fname, "/");
4634 pstrcat(fname, ServicePtrs[iService]->szService);
4636 if (sys_lstat(fname, &lsbuf) != 0) {
4637 return False;
4640 if (!S_ISREG(lsbuf.st_mode)) {
4641 return False;
4644 *last_mod = lsbuf.st_mtime;
4645 return True;
4648 /***************************************************************************
4649 Load a usershare service by name. Returns a valid servicenumber or -1.
4650 ***************************************************************************/
4652 int load_usershare_service(const char *servicename)
4654 SMB_STRUCT_STAT sbuf;
4655 const char *usersharepath = Globals.szUsersharePath;
4656 int max_user_shares = Globals.iUsershareMaxShares;
4657 int snum_template = -1;
4659 if (*usersharepath == 0 || max_user_shares == 0) {
4660 return -1;
4663 if (sys_stat(usersharepath, &sbuf) != 0) {
4664 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4665 usersharepath, strerror(errno) ));
4666 return -1;
4669 if (!S_ISDIR(sbuf.st_mode)) {
4670 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4671 usersharepath ));
4672 return -1;
4676 * This directory must be owned by root, and have the 't' bit set.
4677 * It also must not be writable by "other".
4680 #ifdef S_ISVTX
4681 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4682 #else
4683 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4684 #endif
4685 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4686 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4687 usersharepath ));
4688 return -1;
4691 /* Ensure the template share exists if it's set. */
4692 if (Globals.szUsershareTemplateShare[0]) {
4693 /* We can't use lp_servicenumber here as we are recommending that
4694 template shares have -valid=False set. */
4695 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4696 if (ServicePtrs[snum_template]->szService &&
4697 strequal(ServicePtrs[snum_template]->szService,
4698 Globals.szUsershareTemplateShare)) {
4699 break;
4703 if (snum_template == -1) {
4704 DEBUG(0,("load_usershare_service: usershare template share %s "
4705 "does not exist.\n",
4706 Globals.szUsershareTemplateShare ));
4707 return -1;
4711 return process_usershare_file(usersharepath, servicename, snum_template);
4714 /***************************************************************************
4715 Load all user defined shares from the user share directory.
4716 We only do this if we're enumerating the share list.
4717 This is the function that can delete usershares that have
4718 been removed.
4719 ***************************************************************************/
4721 int load_usershare_shares(void)
4723 SMB_STRUCT_DIR *dp;
4724 SMB_STRUCT_STAT sbuf;
4725 SMB_STRUCT_DIRENT *de;
4726 int num_usershares = 0;
4727 int max_user_shares = Globals.iUsershareMaxShares;
4728 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4729 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4730 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4731 int iService;
4732 int snum_template = -1;
4733 const char *usersharepath = Globals.szUsersharePath;
4734 int ret = lp_numservices();
4736 if (max_user_shares == 0 || *usersharepath == '\0') {
4737 return lp_numservices();
4740 if (sys_stat(usersharepath, &sbuf) != 0) {
4741 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4742 usersharepath, strerror(errno) ));
4743 return ret;
4747 * This directory must be owned by root, and have the 't' bit set.
4748 * It also must not be writable by "other".
4751 #ifdef S_ISVTX
4752 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4753 #else
4754 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4755 #endif
4756 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4757 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4758 usersharepath ));
4759 return ret;
4762 /* Ensure the template share exists if it's set. */
4763 if (Globals.szUsershareTemplateShare[0]) {
4764 /* We can't use lp_servicenumber here as we are recommending that
4765 template shares have -valid=False set. */
4766 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4767 if (ServicePtrs[snum_template]->szService &&
4768 strequal(ServicePtrs[snum_template]->szService,
4769 Globals.szUsershareTemplateShare)) {
4770 break;
4774 if (snum_template == -1) {
4775 DEBUG(0,("load_usershare_shares: usershare template share %s "
4776 "does not exist.\n",
4777 Globals.szUsershareTemplateShare ));
4778 return ret;
4782 /* Mark all existing usershares as pending delete. */
4783 for (iService = iNumServices - 1; iService >= 0; iService--) {
4784 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4785 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4789 dp = sys_opendir(usersharepath);
4790 if (!dp) {
4791 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4792 usersharepath, strerror(errno) ));
4793 return ret;
4796 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4797 (de = sys_readdir(dp));
4798 num_dir_entries++ ) {
4799 int r;
4800 const char *n = de->d_name;
4802 /* Ignore . and .. */
4803 if (*n == '.') {
4804 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4805 continue;
4809 if (n[0] == ':') {
4810 /* Temporary file used when creating a share. */
4811 num_tmp_dir_entries++;
4814 /* Allow 20% tmp entries. */
4815 if (num_tmp_dir_entries > allowed_tmp_entries) {
4816 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4817 "in directory %s\n",
4818 num_tmp_dir_entries, usersharepath));
4819 break;
4822 r = process_usershare_file(usersharepath, n, snum_template);
4823 if (r == 0) {
4824 /* Update the services count. */
4825 num_usershares++;
4826 if (num_usershares >= max_user_shares) {
4827 DEBUG(0,("load_usershare_shares: max user shares reached "
4828 "on file %s in directory %s\n",
4829 n, usersharepath ));
4830 break;
4832 } else if (r == -1) {
4833 num_bad_dir_entries++;
4836 /* Allow 20% bad entries. */
4837 if (num_bad_dir_entries > allowed_bad_entries) {
4838 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4839 "in directory %s\n",
4840 num_bad_dir_entries, usersharepath));
4841 break;
4844 /* Allow 20% bad entries. */
4845 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4846 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4847 "in directory %s\n",
4848 num_dir_entries, usersharepath));
4849 break;
4853 sys_closedir(dp);
4855 /* Sweep through and delete any non-refreshed usershares that are
4856 not currently in use. */
4857 for (iService = iNumServices - 1; iService >= 0; iService--) {
4858 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4859 if (conn_snum_used(iService)) {
4860 continue;
4862 /* Remove from the share ACL db. */
4863 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4864 lp_servicename(iService) ));
4865 delete_share_security(iService);
4866 free_service_byindex(iService);
4870 return lp_numservices();
4873 /********************************************************
4874 Destroy global resources allocated in this file
4875 ********************************************************/
4877 void gfree_loadparm(void)
4879 struct file_lists *f;
4880 struct file_lists *next;
4881 int i;
4883 lp_TALLOC_FREE();
4885 /* Free the file lists */
4887 f = file_lists;
4888 while( f ) {
4889 next = f->next;
4890 SAFE_FREE( f->name );
4891 SAFE_FREE( f->subfname );
4892 SAFE_FREE( f );
4893 f = next;
4896 /* Free resources allocated to services */
4898 for ( i = 0; i < iNumServices; i++ ) {
4899 if ( VALID(i) ) {
4900 free_service_byindex(i);
4904 SAFE_FREE( ServicePtrs );
4905 iNumServices = 0;
4907 /* Now release all resources allocated to global
4908 parameters and the default service */
4910 for (i = 0; parm_table[i].label; i++)
4912 if ( parm_table[i].type == P_STRING
4913 || parm_table[i].type == P_USTRING )
4915 string_free( (char**)parm_table[i].ptr );
4917 else if (parm_table[i].type == P_LIST) {
4918 str_list_free( (char***)parm_table[i].ptr );
4923 /***************************************************************************
4924 Load the services array from the services file. Return True on success,
4925 False on failure.
4926 ***************************************************************************/
4928 BOOL lp_load(const char *pszFname,
4929 BOOL global_only,
4930 BOOL save_defaults,
4931 BOOL add_ipc,
4932 BOOL initialize_globals)
4934 pstring n2;
4935 BOOL bRetval;
4936 param_opt_struct *data, *pdata;
4938 pstrcpy(n2, pszFname);
4940 standard_sub_basic( get_current_username(), n2,sizeof(n2) );
4942 add_to_file_list(pszFname, n2);
4944 bRetval = False;
4946 DEBUG(3, ("lp_load: refreshing parameters\n"));
4948 bInGlobalSection = True;
4949 bGlobalOnly = global_only;
4951 init_globals(! initialize_globals);
4952 debug_init();
4954 if (save_defaults) {
4955 init_locals();
4956 lp_save_defaults();
4959 if (Globals.param_opt != NULL) {
4960 data = Globals.param_opt;
4961 while (data) {
4962 string_free(&data->key);
4963 string_free(&data->value);
4964 str_list_free(&data->list);
4965 pdata = data->next;
4966 SAFE_FREE(data);
4967 data = pdata;
4969 Globals.param_opt = NULL;
4972 /* We get sections first, so have to start 'behind' to make up */
4973 iServiceIndex = -1;
4974 bRetval = pm_process(n2, do_section, do_parameter);
4976 /* finish up the last section */
4977 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4978 if (bRetval)
4979 if (iServiceIndex >= 0)
4980 bRetval = service_ok(iServiceIndex);
4982 lp_add_auto_services(lp_auto_services());
4984 if (add_ipc) {
4985 /* When 'restrict anonymous = 2' guest connections to ipc$
4986 are denied */
4987 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4988 if ( lp_enable_asu_support() )
4989 lp_add_ipc("ADMIN$", False);
4992 set_server_role();
4993 set_default_server_announce_type();
4994 set_allowed_client_auth();
4996 bLoaded = True;
4998 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
4999 /* if bWINSsupport is true and we are in the client */
5000 if (in_client && Globals.bWINSsupport) {
5001 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5004 init_iconv();
5006 return (bRetval);
5009 /***************************************************************************
5010 Reset the max number of services.
5011 ***************************************************************************/
5013 void lp_resetnumservices(void)
5015 iNumServices = 0;
5018 /***************************************************************************
5019 Return the max number of services.
5020 ***************************************************************************/
5022 int lp_numservices(void)
5024 return (iNumServices);
5027 /***************************************************************************
5028 Display the contents of the services array in human-readable form.
5029 ***************************************************************************/
5031 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
5033 int iService;
5035 if (show_defaults)
5036 defaults_saved = False;
5038 dump_globals(f);
5040 dump_a_service(&sDefault, f);
5042 for (iService = 0; iService < maxtoprint; iService++) {
5043 fprintf(f,"\n");
5044 lp_dump_one(f, show_defaults, iService);
5048 /***************************************************************************
5049 Display the contents of one service in human-readable form.
5050 ***************************************************************************/
5052 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
5054 if (VALID(snum)) {
5055 if (ServicePtrs[snum]->szService[0] == '\0')
5056 return;
5057 dump_a_service(ServicePtrs[snum], f);
5061 /***************************************************************************
5062 Return the number of the service with the given name, or -1 if it doesn't
5063 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5064 getservicebyname()! This works ONLY if all services have been loaded, and
5065 does not copy the found service.
5066 ***************************************************************************/
5068 int lp_servicenumber(const char *pszServiceName)
5070 int iService;
5071 fstring serviceName;
5073 if (!pszServiceName) {
5074 return GLOBAL_SECTION_SNUM;
5077 for (iService = iNumServices - 1; iService >= 0; iService--) {
5078 if (VALID(iService) && ServicePtrs[iService]->szService) {
5080 * The substitution here is used to support %U is
5081 * service names
5083 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5084 standard_sub_basic(get_current_username(), serviceName,sizeof(serviceName));
5085 if (strequal(serviceName, pszServiceName)) {
5086 break;
5091 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5092 time_t last_mod;
5094 if (!usershare_exists(iService, &last_mod)) {
5095 /* Remove the share security tdb entry for it. */
5096 delete_share_security(iService);
5097 /* Remove it from the array. */
5098 free_service_byindex(iService);
5099 /* Doesn't exist anymore. */
5100 return GLOBAL_SECTION_SNUM;
5103 /* Has it been modified ? If so delete and reload. */
5104 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5105 /* Remove it from the array. */
5106 free_service_byindex(iService);
5107 /* and now reload it. */
5108 iService = load_usershare_service(pszServiceName);
5112 if (iService < 0) {
5113 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5114 return GLOBAL_SECTION_SNUM;
5117 return (iService);
5120 /*******************************************************************
5121 A useful volume label function.
5122 ********************************************************************/
5124 char *volume_label(int snum)
5126 char *ret = lp_volume(snum);
5127 if (!*ret)
5128 return lp_servicename(snum);
5129 return (ret);
5133 /*******************************************************************
5134 Set the server type we will announce as via nmbd.
5135 ********************************************************************/
5137 static void set_default_server_announce_type(void)
5139 default_server_announce = 0;
5140 default_server_announce |= SV_TYPE_WORKSTATION;
5141 default_server_announce |= SV_TYPE_SERVER;
5142 default_server_announce |= SV_TYPE_SERVER_UNIX;
5144 /* note that the flag should be set only if we have a
5145 printer service but nmbd doesn't actually load the
5146 services so we can't tell --jerry */
5148 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5150 switch (lp_announce_as()) {
5151 case ANNOUNCE_AS_NT_SERVER:
5152 default_server_announce |= SV_TYPE_SERVER_NT;
5153 /* fall through... */
5154 case ANNOUNCE_AS_NT_WORKSTATION:
5155 default_server_announce |= SV_TYPE_NT;
5156 break;
5157 case ANNOUNCE_AS_WIN95:
5158 default_server_announce |= SV_TYPE_WIN95_PLUS;
5159 break;
5160 case ANNOUNCE_AS_WFW:
5161 default_server_announce |= SV_TYPE_WFW;
5162 break;
5163 default:
5164 break;
5167 switch (lp_server_role()) {
5168 case ROLE_DOMAIN_MEMBER:
5169 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5170 break;
5171 case ROLE_DOMAIN_PDC:
5172 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5173 break;
5174 case ROLE_DOMAIN_BDC:
5175 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5176 break;
5177 case ROLE_STANDALONE:
5178 default:
5179 break;
5181 if (lp_time_server())
5182 default_server_announce |= SV_TYPE_TIME_SOURCE;
5184 if (lp_host_msdfs())
5185 default_server_announce |= SV_TYPE_DFS_SERVER;
5188 /***********************************************************
5189 returns role of Samba server
5190 ************************************************************/
5192 int lp_server_role(void)
5194 return server_role;
5197 /***********************************************************
5198 If we are PDC then prefer us as DMB
5199 ************************************************************/
5201 BOOL lp_domain_master(void)
5203 if (Globals.bDomainMaster == Auto)
5204 return (lp_server_role() == ROLE_DOMAIN_PDC);
5206 return Globals.bDomainMaster;
5209 /***********************************************************
5210 If we are DMB then prefer us as LMB
5211 ************************************************************/
5213 BOOL lp_preferred_master(void)
5215 if (Globals.bPreferredMaster == Auto)
5216 return (lp_local_master() && lp_domain_master());
5218 return Globals.bPreferredMaster;
5221 /*******************************************************************
5222 Remove a service.
5223 ********************************************************************/
5225 void lp_remove_service(int snum)
5227 ServicePtrs[snum]->valid = False;
5228 invalid_services[num_invalid_services++] = snum;
5231 /*******************************************************************
5232 Copy a service.
5233 ********************************************************************/
5235 void lp_copy_service(int snum, const char *new_name)
5237 do_section(new_name);
5238 if (snum >= 0) {
5239 snum = lp_servicenumber(new_name);
5240 if (snum >= 0)
5241 lp_do_parameter(snum, "copy", lp_servicename(snum));
5246 /*******************************************************************
5247 Get the default server type we will announce as via nmbd.
5248 ********************************************************************/
5250 int lp_default_server_announce(void)
5252 return default_server_announce;
5255 /*******************************************************************
5256 Split the announce version into major and minor numbers.
5257 ********************************************************************/
5259 int lp_major_announce_version(void)
5261 static BOOL got_major = False;
5262 static int major_version = DEFAULT_MAJOR_VERSION;
5263 char *vers;
5264 char *p;
5266 if (got_major)
5267 return major_version;
5269 got_major = True;
5270 if ((vers = lp_announce_version()) == NULL)
5271 return major_version;
5273 if ((p = strchr_m(vers, '.')) == 0)
5274 return major_version;
5276 *p = '\0';
5277 major_version = atoi(vers);
5278 return major_version;
5281 int lp_minor_announce_version(void)
5283 static BOOL got_minor = False;
5284 static int minor_version = DEFAULT_MINOR_VERSION;
5285 char *vers;
5286 char *p;
5288 if (got_minor)
5289 return minor_version;
5291 got_minor = True;
5292 if ((vers = lp_announce_version()) == NULL)
5293 return minor_version;
5295 if ((p = strchr_m(vers, '.')) == 0)
5296 return minor_version;
5298 p++;
5299 minor_version = atoi(p);
5300 return minor_version;
5303 /***********************************************************
5304 Set the global name resolution order (used in smbclient).
5305 ************************************************************/
5307 void lp_set_name_resolve_order(const char *new_order)
5309 string_set(&Globals.szNameResolveOrder, new_order);
5312 const char *lp_printername(int snum)
5314 const char *ret = _lp_printername(snum);
5315 if (ret == NULL || (ret != NULL && *ret == '\0'))
5316 ret = lp_const_servicename(snum);
5318 return ret;
5322 /***********************************************************
5323 Allow daemons such as winbindd to fix their logfile name.
5324 ************************************************************/
5326 void lp_set_logfile(const char *name)
5328 string_set(&Globals.szLogFile, name);
5329 pstrcpy(debugf, name);
5332 /*******************************************************************
5333 Return the max print jobs per queue.
5334 ********************************************************************/
5336 int lp_maxprintjobs(int snum)
5338 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5339 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5340 maxjobs = PRINT_MAX_JOBID - 1;
5342 return maxjobs;
5345 const char *lp_printcapname(void)
5347 if ((Globals.szPrintcapname != NULL) &&
5348 (Globals.szPrintcapname[0] != '\0'))
5349 return Globals.szPrintcapname;
5351 if (sDefault.iPrinting == PRINT_CUPS) {
5352 #ifdef HAVE_CUPS
5353 return "cups";
5354 #else
5355 return "lpstat";
5356 #endif
5359 if (sDefault.iPrinting == PRINT_BSD)
5360 return "/etc/printcap";
5362 return PRINTCAP_NAME;
5365 /*******************************************************************
5366 Ensure we don't use sendfile if server smb signing is active.
5367 ********************************************************************/
5369 static uint32 spoolss_state;
5371 BOOL lp_disable_spoolss( void )
5373 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5374 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5376 return spoolss_state == SVCCTL_STOPPED ? True : False;
5379 void lp_set_spoolss_state( uint32 state )
5381 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5383 spoolss_state = state;
5386 uint32 lp_get_spoolss_state( void )
5388 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5391 /*******************************************************************
5392 Ensure we don't use sendfile if server smb signing is active.
5393 ********************************************************************/
5395 BOOL lp_use_sendfile(int snum)
5397 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5398 if (Protocol < PROTOCOL_NT1) {
5399 return False;
5401 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5404 /*******************************************************************
5405 Turn off sendfile if we find the underlying OS doesn't support it.
5406 ********************************************************************/
5408 void set_use_sendfile(int snum, BOOL val)
5410 if (LP_SNUM_OK(snum))
5411 ServicePtrs[snum]->bUseSendfile = val;
5412 else
5413 sDefault.bUseSendfile = val;
5416 /*******************************************************************
5417 Turn off storing DOS attributes if this share doesn't support it.
5418 ********************************************************************/
5420 void set_store_dos_attributes(int snum, BOOL val)
5422 if (!LP_SNUM_OK(snum))
5423 return;
5424 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5427 void lp_set_mangling_method(const char *new_method)
5429 string_set(&Globals.szManglingMethod, new_method);
5432 /*******************************************************************
5433 Global state for POSIX pathname processing.
5434 ********************************************************************/
5436 static BOOL posix_pathnames;
5438 BOOL lp_posix_pathnames(void)
5440 return posix_pathnames;
5443 /*******************************************************************
5444 Change everything needed to ensure POSIX pathname processing (currently
5445 not much).
5446 ********************************************************************/
5448 void lp_set_posix_pathnames(void)
5450 posix_pathnames = True;
5453 /*******************************************************************
5454 Global state for POSIX lock processing - CIFS unix extensions.
5455 ********************************************************************/
5457 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5459 enum brl_flavour lp_posix_cifsu_locktype(void)
5461 return posix_cifsx_locktype;
5464 /*******************************************************************
5465 ********************************************************************/
5467 void lp_set_posix_cifsx_locktype(enum brl_flavour val)
5469 posix_cifsx_locktype = val;