Samba 3: added Samba 3.0.24 sources
[tomato.git] / release / src / router / samba3 / source / param / loadparm.c
blobb6c027f8714143456a922ea4bd69834901cb3cc4
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 int iAclCompat;
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_ENUM, P_GLOBAL, &Globals.iAclCompat, 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.szCupsServer, "");
1615 string_set(&Globals.szIPrintServer, "");
1617 Globals.winbind_cache_time = 300; /* 5 minutes */
1618 Globals.bWinbindEnumUsers = False;
1619 Globals.bWinbindEnumGroups = False;
1620 Globals.bWinbindUseDefaultDomain = False;
1621 Globals.bWinbindTrustedDomainsOnly = False;
1622 Globals.bWinbindNestedGroups = True;
1623 Globals.szWinbindNssInfo = str_list_make("template", NULL);
1624 Globals.bWinbindRefreshTickets = False;
1625 Globals.bWinbindOfflineLogon = False;
1627 Globals.bPassdbExpandExplicit = False;
1629 Globals.name_cache_timeout = 660; /* In seconds */
1631 Globals.bUseSpnego = True;
1632 Globals.bClientUseSpnego = True;
1634 Globals.client_signing = Auto;
1635 Globals.server_signing = False;
1637 Globals.bDeferSharingViolations = True;
1638 string_set(&Globals.smb_ports, SMB_PORTS);
1640 Globals.bEnablePrivileges = True;
1641 Globals.bHostMSDfs = True;
1642 Globals.bASUSupport = False;
1644 /* User defined shares. */
1645 pstrcpy(s, dyn_LOCKDIR);
1646 pstrcat(s, "/usershares");
1647 string_set(&Globals.szUsersharePath, s);
1648 string_set(&Globals.szUsershareTemplateShare, "");
1649 Globals.iUsershareMaxShares = 0;
1650 /* By default disallow sharing of directories not owned by the sharer. */
1651 Globals.bUsershareOwnerOnly = True;
1652 /* By default disallow guest access to usershares. */
1653 Globals.bUsershareAllowGuests = False;
1656 static TALLOC_CTX *lp_talloc;
1658 /******************************************************************* a
1659 Free up temporary memory - called from the main loop.
1660 ********************************************************************/
1662 void lp_TALLOC_FREE(void)
1664 if (!lp_talloc)
1665 return;
1666 TALLOC_FREE(lp_talloc);
1667 lp_talloc = NULL;
1670 TALLOC_CTX *tmp_talloc_ctx(void)
1672 if (lp_talloc == NULL) {
1673 lp_talloc = talloc_init("tmp_talloc_ctx");
1676 if (lp_talloc == NULL) {
1677 smb_panic("Could not create temporary talloc context\n");
1680 return lp_talloc;
1683 /*******************************************************************
1684 Convenience routine to grab string parameters into temporary memory
1685 and run standard_sub_basic on them. The buffers can be written to by
1686 callers without affecting the source string.
1687 ********************************************************************/
1689 static char *lp_string(const char *s)
1691 char *ret, *tmpstr;
1693 /* The follow debug is useful for tracking down memory problems
1694 especially if you have an inner loop that is calling a lp_*()
1695 function that returns a string. Perhaps this debug should be
1696 present all the time? */
1698 #if 0
1699 DEBUG(10, ("lp_string(%s)\n", s));
1700 #endif
1702 if (!lp_talloc)
1703 lp_talloc = talloc_init("lp_talloc");
1705 tmpstr = alloc_sub_basic(get_current_username(), s);
1706 if (trim_char(tmpstr, '\"', '\"')) {
1707 if (strchr(tmpstr,'\"') != NULL) {
1708 SAFE_FREE(tmpstr);
1709 tmpstr = alloc_sub_basic(get_current_username(),s);
1712 ret = talloc_strdup(lp_talloc, tmpstr);
1713 SAFE_FREE(tmpstr);
1715 return (ret);
1719 In this section all the functions that are used to access the
1720 parameters from the rest of the program are defined
1723 #define FN_GLOBAL_STRING(fn_name,ptr) \
1724 char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
1725 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
1726 const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
1727 #define FN_GLOBAL_LIST(fn_name,ptr) \
1728 const char **fn_name(void) {return(*(const char ***)(ptr));}
1729 #define FN_GLOBAL_BOOL(fn_name,ptr) \
1730 BOOL fn_name(void) {return(*(BOOL *)(ptr));}
1731 #define FN_GLOBAL_CHAR(fn_name,ptr) \
1732 char fn_name(void) {return(*(char *)(ptr));}
1733 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
1734 int fn_name(void) {return(*(int *)(ptr));}
1736 #define FN_LOCAL_STRING(fn_name,val) \
1737 char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
1738 #define FN_LOCAL_CONST_STRING(fn_name,val) \
1739 const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
1740 #define FN_LOCAL_LIST(fn_name,val) \
1741 const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1742 #define FN_LOCAL_BOOL(fn_name,val) \
1743 BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1744 #define FN_LOCAL_CHAR(fn_name,val) \
1745 char fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1746 #define FN_LOCAL_INTEGER(fn_name,val) \
1747 int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
1749 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
1750 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
1751 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
1752 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
1753 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
1754 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
1755 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
1756 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
1757 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
1758 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
1759 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
1760 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
1761 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
1762 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
1763 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
1764 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
1765 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
1766 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
1767 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
1768 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
1769 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
1770 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
1771 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
1772 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
1773 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
1774 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
1775 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
1776 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
1777 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
1778 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
1779 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
1780 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
1781 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
1782 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
1783 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
1784 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
1785 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
1786 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
1787 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
1788 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
1789 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
1790 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
1791 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
1792 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
1793 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
1794 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
1795 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
1796 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
1797 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
1798 FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
1799 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
1800 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
1801 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
1802 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
1803 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
1805 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
1806 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
1807 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
1808 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
1809 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
1810 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
1812 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
1814 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
1815 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
1816 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
1818 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
1820 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
1821 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
1822 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
1823 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
1824 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
1825 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
1826 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
1827 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
1828 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
1829 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
1830 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
1831 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
1833 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend)
1834 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
1836 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
1837 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
1838 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
1839 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
1840 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
1841 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
1842 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
1843 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
1844 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
1845 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
1846 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
1847 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
1848 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
1849 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
1851 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
1853 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
1854 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
1855 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
1856 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
1857 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
1858 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
1859 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
1860 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
1861 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
1862 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
1863 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
1864 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
1865 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
1866 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
1867 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
1868 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
1869 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
1870 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
1871 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
1872 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
1873 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
1874 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
1875 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
1876 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
1877 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
1878 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
1879 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
1880 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
1881 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
1882 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
1883 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
1884 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
1885 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
1886 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
1887 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
1888 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
1889 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
1890 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
1891 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
1892 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
1893 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
1894 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
1895 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
1896 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
1897 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
1898 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
1899 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
1900 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
1901 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
1902 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
1903 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
1904 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
1905 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
1906 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
1907 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
1908 FN_GLOBAL_BOOL(lp_kernel_change_notify, &Globals.bKernelChangeNotify)
1909 FN_GLOBAL_BOOL(lp_fam_change_notify, &Globals.bFamChangeNotify)
1910 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
1911 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
1912 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
1913 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
1914 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
1915 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
1916 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
1917 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
1918 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
1919 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
1920 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
1921 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
1922 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
1923 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
1924 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
1925 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
1926 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
1927 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
1928 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
1929 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
1930 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
1931 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
1932 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
1933 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
1934 FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
1935 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
1936 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
1937 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
1938 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
1939 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
1940 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
1941 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
1942 FN_GLOBAL_INTEGER(lp_lock_spin_count, &Globals.iLockSpinCount)
1943 FN_GLOBAL_INTEGER(lp_lock_sleep_time, &Globals.iLockSpinTime)
1944 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
1946 FN_LOCAL_STRING(lp_preexec, szPreExec)
1947 FN_LOCAL_STRING(lp_postexec, szPostExec)
1948 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
1949 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
1950 FN_LOCAL_STRING(lp_servicename, szService)
1951 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
1952 FN_LOCAL_STRING(lp_pathname, szPath)
1953 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
1954 FN_LOCAL_STRING(lp_username, szUsername)
1955 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
1956 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
1957 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
1958 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
1959 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
1960 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
1961 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
1962 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
1963 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
1964 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
1965 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
1966 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
1967 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
1968 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
1969 static FN_LOCAL_STRING(_lp_printername, szPrintername)
1970 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
1971 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
1972 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
1973 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
1974 FN_LOCAL_STRING(lp_comment, comment)
1975 FN_LOCAL_STRING(lp_force_user, force_user)
1976 FN_LOCAL_STRING(lp_force_group, force_group)
1977 FN_LOCAL_LIST(lp_readlist, readlist)
1978 FN_LOCAL_LIST(lp_writelist, writelist)
1979 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
1980 FN_LOCAL_STRING(lp_fstype, fstype)
1981 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
1982 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
1983 static FN_LOCAL_STRING(lp_volume, volume)
1984 FN_LOCAL_STRING(lp_mangled_map, szMangledMap)
1985 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
1986 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
1987 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
1988 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
1989 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
1990 FN_LOCAL_STRING(lp_dfree_command, szDfree)
1991 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
1992 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
1993 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
1994 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
1995 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
1996 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
1997 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
1998 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
1999 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
2000 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
2001 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
2002 FN_LOCAL_BOOL(lp_readonly, bRead_only)
2003 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
2004 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
2005 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
2006 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
2007 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
2008 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
2009 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
2010 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
2011 FN_LOCAL_BOOL(lp_locking, bLocking)
2012 FN_LOCAL_INTEGER(lp_strict_locking, iStrictLocking)
2013 FN_LOCAL_BOOL(lp_posix_locking, bPosixLocking)
2014 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
2015 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
2016 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
2017 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
2018 FN_LOCAL_BOOL(lp_manglednames, bMangledNames)
2019 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
2020 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
2021 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
2022 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
2023 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
2024 FN_LOCAL_BOOL(lp_map_system, bMap_system)
2025 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
2026 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
2027 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
2028 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
2029 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
2030 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
2031 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
2032 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
2033 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
2034 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
2035 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
2036 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
2037 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
2038 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
2039 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
2040 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
2041 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
2042 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
2043 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
2044 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
2045 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
2046 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
2047 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
2048 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
2049 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
2050 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
2051 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
2052 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
2053 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
2054 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
2055 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
2056 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
2057 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
2058 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
2059 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
2060 FN_LOCAL_INTEGER(lp_printing, iPrinting)
2061 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
2062 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
2063 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
2064 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
2065 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
2066 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
2067 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
2068 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
2069 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
2070 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
2071 FN_LOCAL_INTEGER(lp_change_notify_timeout, ichange_notify_timeout)
2072 FN_LOCAL_CHAR(lp_magicchar, magic_char)
2073 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
2074 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
2075 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
2076 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
2077 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
2078 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
2080 /* local prototypes */
2082 static int map_parameter(const char *pszParmName);
2083 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
2084 static int getservicebyname(const char *pszServiceName,
2085 service * pserviceDest);
2086 static void copy_service(service * pserviceDest,
2087 service * pserviceSource, BOOL *pcopymapDest);
2088 static BOOL service_ok(int iService);
2089 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
2090 static BOOL do_section(const char *pszSectionName);
2091 static void init_copymap(service * pservice);
2092 static BOOL hash_a_service(const char *name, int number);
2093 static void free_service_byindex(int iService);
2094 static char * canonicalize_servicename(const char *name);
2096 /* This is a helper function for parametrical options support. */
2097 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
2098 /* Actual parametrical functions are quite simple */
2099 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
2101 BOOL global_section = False;
2102 char* param_key;
2103 param_opt_struct *data;
2105 if (snum >= iNumServices) return NULL;
2107 if (snum < 0) {
2108 data = Globals.param_opt;
2109 global_section = True;
2110 } else {
2111 data = ServicePtrs[snum]->param_opt;
2114 asprintf(&param_key, "%s:%s", type, option);
2115 if (!param_key) {
2116 DEBUG(0,("asprintf failed!\n"));
2117 return NULL;
2120 while (data) {
2121 if (strcmp(data->key, param_key) == 0) {
2122 string_free(&param_key);
2123 return data;
2125 data = data->next;
2128 if (!global_section) {
2129 /* Try to fetch the same option but from globals */
2130 /* but only if we are not already working with Globals */
2131 data = Globals.param_opt;
2132 while (data) {
2133 if (strcmp(data->key, param_key) == 0) {
2134 string_free(&param_key);
2135 return data;
2137 data = data->next;
2141 string_free(&param_key);
2143 return NULL;
2147 #define MISSING_PARAMETER(name) \
2148 DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
2150 /*******************************************************************
2151 convenience routine to return int parameters.
2152 ********************************************************************/
2153 static int lp_int(const char *s)
2156 if (!s || !*s) {
2157 MISSING_PARAMETER(lp_int);
2158 return (-1);
2161 return atoi(s);
2164 /*******************************************************************
2165 convenience routine to return unsigned long parameters.
2166 ********************************************************************/
2167 static unsigned long lp_ulong(const char *s)
2170 if (!s || !*s) {
2171 MISSING_PARAMETER(lp_ulong);
2172 return (0);
2175 return strtoul(s, NULL, 10);
2178 /*******************************************************************
2179 convenience routine to return boolean parameters.
2180 ********************************************************************/
2181 static BOOL lp_bool(const char *s)
2183 BOOL ret = False;
2185 if (!s || !*s) {
2186 MISSING_PARAMETER(lp_bool);
2187 return False;
2190 if (!set_boolean(&ret,s)) {
2191 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
2192 return False;
2195 return ret;
2198 /*******************************************************************
2199 convenience routine to return enum parameters.
2200 ********************************************************************/
2201 static int lp_enum(const char *s,const struct enum_list *_enum)
2203 int i;
2205 if (!s || !*s || !_enum) {
2206 MISSING_PARAMETER(lp_enum);
2207 return (-1);
2210 for (i=0; _enum[i].name; i++) {
2211 if (strequal(_enum[i].name,s))
2212 return _enum[i].value;
2215 DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
2216 return (-1);
2219 #undef MISSING_PARAMETER
2221 /* DO NOT USE lp_parm_string ANYMORE!!!!
2222 * use lp_parm_const_string or lp_parm_talloc_string
2224 * lp_parm_string is only used to let old modules find this symbol
2226 #undef lp_parm_string
2227 char *lp_parm_string(const char *servicename, const char *type, const char *option)
2229 return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
2232 /* Return parametric option from a given service. Type is a part of option before ':' */
2233 /* Parametric option has following syntax: 'Type: option = value' */
2234 /* the returned value is talloced in lp_talloc */
2235 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
2237 param_opt_struct *data = get_parametrics(snum, type, option);
2239 if (data == NULL||data->value==NULL) {
2240 if (def) {
2241 return lp_string(def);
2242 } else {
2243 return NULL;
2247 return lp_string(data->value);
2250 /* Return parametric option from a given service. Type is a part of option before ':' */
2251 /* Parametric option has following syntax: 'Type: option = value' */
2252 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
2254 param_opt_struct *data = get_parametrics(snum, type, option);
2256 if (data == NULL||data->value==NULL)
2257 return def;
2259 return data->value;
2262 /* Return parametric option from a given service. Type is a part of option before ':' */
2263 /* Parametric option has following syntax: 'Type: option = value' */
2265 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
2267 param_opt_struct *data = get_parametrics(snum, type, option);
2269 if (data == NULL||data->value==NULL)
2270 return (const char **)def;
2272 if (data->list==NULL) {
2273 data->list = str_list_make(data->value, NULL);
2276 return (const char **)data->list;
2279 /* Return parametric option from a given service. Type is a part of option before ':' */
2280 /* Parametric option has following syntax: 'Type: option = value' */
2282 int lp_parm_int(int snum, const char *type, const char *option, int def)
2284 param_opt_struct *data = get_parametrics(snum, type, option);
2286 if (data && data->value && *data->value)
2287 return lp_int(data->value);
2289 return def;
2292 /* Return parametric option from a given service. Type is a part of option before ':' */
2293 /* Parametric option has following syntax: 'Type: option = value' */
2295 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
2297 param_opt_struct *data = get_parametrics(snum, type, option);
2299 if (data && data->value && *data->value)
2300 return lp_ulong(data->value);
2302 return def;
2305 /* Return parametric option from a given service. Type is a part of option before ':' */
2306 /* Parametric option has following syntax: 'Type: option = value' */
2308 BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
2310 param_opt_struct *data = get_parametrics(snum, type, option);
2312 if (data && data->value && *data->value)
2313 return lp_bool(data->value);
2315 return def;
2318 /* Return parametric option from a given service. Type is a part of option before ':' */
2319 /* Parametric option has following syntax: 'Type: option = value' */
2321 int lp_parm_enum(int snum, const char *type, const char *option,
2322 const struct enum_list *_enum, int def)
2324 param_opt_struct *data = get_parametrics(snum, type, option);
2326 if (data && data->value && *data->value && _enum)
2327 return lp_enum(data->value, _enum);
2329 return def;
2333 /***************************************************************************
2334 Initialise a service to the defaults.
2335 ***************************************************************************/
2337 static void init_service(service * pservice)
2339 memset((char *)pservice, '\0', sizeof(service));
2340 copy_service(pservice, &sDefault, NULL);
2343 /***************************************************************************
2344 Free the dynamically allocated parts of a service struct.
2345 ***************************************************************************/
2347 static void free_service(service *pservice)
2349 int i;
2350 param_opt_struct *data, *pdata;
2351 if (!pservice)
2352 return;
2354 if (pservice->szService)
2355 DEBUG(5, ("free_service: Freeing service %s\n",
2356 pservice->szService));
2358 string_free(&pservice->szService);
2359 SAFE_FREE(pservice->copymap);
2361 for (i = 0; parm_table[i].label; i++) {
2362 if ((parm_table[i].type == P_STRING ||
2363 parm_table[i].type == P_USTRING) &&
2364 parm_table[i].p_class == P_LOCAL)
2365 string_free((char **)
2366 (((char *)pservice) +
2367 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2368 else if (parm_table[i].type == P_LIST &&
2369 parm_table[i].p_class == P_LOCAL)
2370 str_list_free((char ***)
2371 (((char *)pservice) +
2372 PTR_DIFF(parm_table[i].ptr, &sDefault)));
2375 data = pservice->param_opt;
2376 if (data)
2377 DEBUG(5,("Freeing parametrics:\n"));
2378 while (data) {
2379 DEBUG(5,("[%s = %s]\n", data->key, data->value));
2380 string_free(&data->key);
2381 string_free(&data->value);
2382 str_list_free(&data->list);
2383 pdata = data->next;
2384 SAFE_FREE(data);
2385 data = pdata;
2388 ZERO_STRUCTP(pservice);
2392 /***************************************************************************
2393 remove a service indexed in the ServicePtrs array from the ServiceHash
2394 and free the dynamically allocated parts
2395 ***************************************************************************/
2397 static void free_service_byindex(int idx)
2399 if ( !LP_SNUM_OK(idx) )
2400 return;
2402 ServicePtrs[idx]->valid = False;
2403 invalid_services[num_invalid_services++] = idx;
2405 /* we have to cleanup the hash record */
2407 if (ServicePtrs[idx]->szService) {
2408 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
2410 tdb_delete_bystring(ServiceHash, canon_name );
2413 free_service(ServicePtrs[idx]);
2416 /***************************************************************************
2417 Add a new service to the services array initialising it with the given
2418 service.
2419 ***************************************************************************/
2421 static int add_a_service(const service *pservice, const char *name)
2423 int i;
2424 service tservice;
2425 int num_to_alloc = iNumServices + 1;
2426 param_opt_struct *data, *pdata;
2428 tservice = *pservice;
2430 /* it might already exist */
2431 if (name) {
2432 i = getservicebyname(name, NULL);
2433 if (i >= 0) {
2434 /* Clean all parametric options for service */
2435 /* They will be added during parsing again */
2436 data = ServicePtrs[i]->param_opt;
2437 while (data) {
2438 string_free(&data->key);
2439 string_free(&data->value);
2440 str_list_free(&data->list);
2441 pdata = data->next;
2442 SAFE_FREE(data);
2443 data = pdata;
2445 ServicePtrs[i]->param_opt = NULL;
2446 return (i);
2450 /* find an invalid one */
2451 i = iNumServices;
2452 if (num_invalid_services > 0) {
2453 i = invalid_services[--num_invalid_services];
2456 /* if not, then create one */
2457 if (i == iNumServices) {
2458 service **tsp;
2459 int *tinvalid;
2461 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
2462 if (tsp == NULL) {
2463 DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
2464 return (-1);
2466 ServicePtrs = tsp;
2467 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
2468 if (!ServicePtrs[iNumServices]) {
2469 DEBUG(0,("add_a_service: out of memory!\n"));
2470 return (-1);
2472 iNumServices++;
2474 /* enlarge invalid_services here for now... */
2475 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
2476 num_to_alloc);
2477 if (tinvalid == NULL) {
2478 DEBUG(0,("add_a_service: failed to enlarge "
2479 "invalid_services!\n"));
2480 return (-1);
2482 invalid_services = tinvalid;
2483 } else {
2484 free_service_byindex(i);
2487 ServicePtrs[i]->valid = True;
2489 init_service(ServicePtrs[i]);
2490 copy_service(ServicePtrs[i], &tservice, NULL);
2491 if (name)
2492 string_set(&ServicePtrs[i]->szService, name);
2494 DEBUG(8,("add_a_service: Creating snum = %d for %s\n",
2495 i, ServicePtrs[i]->szService));
2497 if (!hash_a_service(ServicePtrs[i]->szService, i)) {
2498 return (-1);
2501 return (i);
2504 /***************************************************************************
2505 Convert a string to uppercase and remove whitespaces.
2506 ***************************************************************************/
2508 static char *canonicalize_servicename(const char *src)
2510 static fstring canon; /* is fstring large enough? */
2512 if ( !src ) {
2513 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
2514 return NULL;
2517 fstrcpy( canon, src );
2518 strlower_m( canon );
2520 return canon;
2523 /***************************************************************************
2524 Add a name/index pair for the services array to the hash table.
2525 ***************************************************************************/
2527 static BOOL hash_a_service(const char *name, int idx)
2529 char *canon_name;
2531 if ( !ServiceHash ) {
2532 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
2533 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL,
2534 (O_RDWR|O_CREAT), 0600);
2535 if ( !ServiceHash ) {
2536 DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
2537 return False;
2541 DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
2542 idx, name));
2544 if ( !(canon_name = canonicalize_servicename( name )) )
2545 return False;
2547 tdb_store_int32(ServiceHash, canon_name, idx);
2549 return True;
2552 /***************************************************************************
2553 Add a new home service, with the specified home directory, defaults coming
2554 from service ifrom.
2555 ***************************************************************************/
2557 BOOL lp_add_home(const char *pszHomename, int iDefaultService,
2558 const char *user, const char *pszHomedir)
2560 int i;
2561 pstring newHomedir;
2563 i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
2565 if (i < 0)
2566 return (False);
2568 if (!(*(ServicePtrs[iDefaultService]->szPath))
2569 || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
2570 pstrcpy(newHomedir, pszHomedir);
2571 string_set(&ServicePtrs[i]->szPath, newHomedir);
2574 if (!(*(ServicePtrs[i]->comment))) {
2575 pstring comment;
2576 slprintf(comment, sizeof(comment) - 1,
2577 "Home directory of %s", user);
2578 string_set(&ServicePtrs[i]->comment, comment);
2581 /* set the browseable flag from the global default */
2583 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2585 ServicePtrs[i]->autoloaded = True;
2587 DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename,
2588 user, ServicePtrs[i]->szPath ));
2590 return (True);
2593 /***************************************************************************
2594 Add a new service, based on an old one.
2595 ***************************************************************************/
2597 int lp_add_service(const char *pszService, int iDefaultService)
2599 return (add_a_service(ServicePtrs[iDefaultService], pszService));
2602 /***************************************************************************
2603 Add the IPC service.
2604 ***************************************************************************/
2606 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
2608 pstring comment;
2609 int i = add_a_service(&sDefault, ipc_name);
2611 if (i < 0)
2612 return (False);
2614 slprintf(comment, sizeof(comment) - 1,
2615 "IPC Service (%s)", Globals.szServerString);
2617 string_set(&ServicePtrs[i]->szPath, tmpdir());
2618 string_set(&ServicePtrs[i]->szUsername, "");
2619 string_set(&ServicePtrs[i]->comment, comment);
2620 string_set(&ServicePtrs[i]->fstype, "IPC");
2621 ServicePtrs[i]->iMaxConnections = 0;
2622 ServicePtrs[i]->bAvailable = True;
2623 ServicePtrs[i]->bRead_only = True;
2624 ServicePtrs[i]->bGuest_only = False;
2625 ServicePtrs[i]->bGuest_ok = guest_ok;
2626 ServicePtrs[i]->bPrint_ok = False;
2627 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2629 DEBUG(3, ("adding IPC service\n"));
2631 return (True);
2634 /***************************************************************************
2635 Add a new printer service, with defaults coming from service iFrom.
2636 ***************************************************************************/
2638 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
2640 const char *comment = "From Printcap";
2641 int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
2643 if (i < 0)
2644 return (False);
2646 /* note that we do NOT default the availability flag to True - */
2647 /* we take it from the default service passed. This allows all */
2648 /* dynamic printers to be disabled by disabling the [printers] */
2649 /* entry (if/when the 'available' keyword is implemented!). */
2651 /* the printer name is set to the service name. */
2652 string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
2653 string_set(&ServicePtrs[i]->comment, comment);
2655 /* set the browseable flag from the gloabl default */
2656 ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
2658 /* Printers cannot be read_only. */
2659 ServicePtrs[i]->bRead_only = False;
2660 /* No share modes on printer services. */
2661 ServicePtrs[i]->bShareModes = False;
2662 /* No oplocks on printer services. */
2663 ServicePtrs[i]->bOpLocks = False;
2664 /* Printer services must be printable. */
2665 ServicePtrs[i]->bPrint_ok = True;
2667 DEBUG(3, ("adding printer service %s\n", pszPrintername));
2669 return (True);
2672 /***************************************************************************
2673 Map a parameter's string representation to something we can use.
2674 Returns False if the parameter string is not recognised, else TRUE.
2675 ***************************************************************************/
2677 static int map_parameter(const char *pszParmName)
2679 int iIndex;
2681 if (*pszParmName == '-')
2682 return (-1);
2684 for (iIndex = 0; parm_table[iIndex].label; iIndex++)
2685 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
2686 return (iIndex);
2688 /* Warn only if it isn't parametric option */
2689 if (strchr(pszParmName, ':') == NULL)
2690 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
2691 /* We do return 'fail' for parametric options as well because they are
2692 stored in different storage
2694 return (-1);
2697 /***************************************************************************
2698 Show all parameter's name, type, [values,] and flags.
2699 ***************************************************************************/
2701 void show_parameter_list(void)
2703 int classIndex, parmIndex, enumIndex, flagIndex;
2704 BOOL hadFlag;
2705 const char *section_names[] = { "local", "global", NULL};
2706 const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
2707 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
2708 "P_UGSTRING", "P_ENUM", "P_SEP"};
2709 unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
2710 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
2711 FLAG_HIDE, FLAG_DOS_STRING};
2712 const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
2713 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
2714 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
2716 for ( classIndex=0; section_names[classIndex]; classIndex++) {
2717 printf("[%s]\n", section_names[classIndex]);
2718 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
2719 if (parm_table[parmIndex].p_class == classIndex) {
2720 printf("%s=%s",
2721 parm_table[parmIndex].label,
2722 type[parm_table[parmIndex].type]);
2723 switch (parm_table[parmIndex].type) {
2724 case P_ENUM:
2725 printf(",");
2726 for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
2727 printf("%s%s",
2728 enumIndex ? "|" : "",
2729 parm_table[parmIndex].enum_list[enumIndex].name);
2730 break;
2731 default:
2732 break;
2734 printf(",");
2735 hadFlag = False;
2736 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
2737 if (parm_table[parmIndex].flags & flags[flagIndex]) {
2738 printf("%s%s",
2739 hadFlag ? "|" : "",
2740 flag_names[flagIndex]);
2741 hadFlag = True;
2744 printf("\n");
2750 /***************************************************************************
2751 Set a boolean variable from the text value stored in the passed string.
2752 Returns True in success, False if the passed string does not correctly
2753 represent a boolean.
2754 ***************************************************************************/
2756 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
2758 BOOL bRetval;
2760 bRetval = True;
2761 if (strwicmp(pszParmValue, "yes") == 0 ||
2762 strwicmp(pszParmValue, "true") == 0 ||
2763 strwicmp(pszParmValue, "1") == 0)
2764 *pb = True;
2765 else if (strwicmp(pszParmValue, "no") == 0 ||
2766 strwicmp(pszParmValue, "False") == 0 ||
2767 strwicmp(pszParmValue, "0") == 0)
2768 *pb = False;
2769 else {
2770 DEBUG(0,
2771 ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
2772 pszParmValue));
2773 bRetval = False;
2775 return (bRetval);
2778 /***************************************************************************
2779 Find a service by name. Otherwise works like get_service.
2780 ***************************************************************************/
2782 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
2784 int iService = -1;
2785 char *canon_name;
2787 if (ServiceHash != NULL) {
2788 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
2789 return -1;
2791 iService = tdb_fetch_int32(ServiceHash, canon_name );
2793 if (LP_SNUM_OK(iService)) {
2794 if (pserviceDest != NULL) {
2795 copy_service(pserviceDest, ServicePtrs[iService], NULL);
2797 } else {
2798 iService = -1;
2802 return (iService);
2805 /***************************************************************************
2806 Copy a service structure to another.
2807 If pcopymapDest is NULL then copy all fields
2808 ***************************************************************************/
2810 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
2812 int i;
2813 BOOL bcopyall = (pcopymapDest == NULL);
2814 param_opt_struct *data, *pdata, *paramo;
2815 BOOL not_added;
2817 for (i = 0; parm_table[i].label; i++)
2818 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
2819 (bcopyall || pcopymapDest[i])) {
2820 void *def_ptr = parm_table[i].ptr;
2821 void *src_ptr =
2822 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
2823 &sDefault);
2824 void *dest_ptr =
2825 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
2826 &sDefault);
2828 switch (parm_table[i].type) {
2829 case P_BOOL:
2830 case P_BOOLREV:
2831 *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
2832 break;
2834 case P_INTEGER:
2835 case P_ENUM:
2836 case P_OCTAL:
2837 *(int *)dest_ptr = *(int *)src_ptr;
2838 break;
2840 case P_CHAR:
2841 *(char *)dest_ptr = *(char *)src_ptr;
2842 break;
2844 case P_STRING:
2845 string_set((char **)dest_ptr,
2846 *(char **)src_ptr);
2847 break;
2849 case P_USTRING:
2850 string_set((char **)dest_ptr,
2851 *(char **)src_ptr);
2852 strupper_m(*(char **)dest_ptr);
2853 break;
2854 case P_LIST:
2855 str_list_free((char ***)dest_ptr);
2856 str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
2857 break;
2858 default:
2859 break;
2863 if (bcopyall) {
2864 init_copymap(pserviceDest);
2865 if (pserviceSource->copymap)
2866 memcpy((void *)pserviceDest->copymap,
2867 (void *)pserviceSource->copymap,
2868 sizeof(BOOL) * NUMPARAMETERS);
2871 data = pserviceSource->param_opt;
2872 while (data) {
2873 not_added = True;
2874 pdata = pserviceDest->param_opt;
2875 /* Traverse destination */
2876 while (pdata) {
2877 /* If we already have same option, override it */
2878 if (strcmp(pdata->key, data->key) == 0) {
2879 string_free(&pdata->value);
2880 str_list_free(&data->list);
2881 pdata->value = SMB_STRDUP(data->value);
2882 not_added = False;
2883 break;
2885 pdata = pdata->next;
2887 if (not_added) {
2888 paramo = SMB_XMALLOC_P(param_opt_struct);
2889 paramo->key = SMB_STRDUP(data->key);
2890 paramo->value = SMB_STRDUP(data->value);
2891 paramo->list = NULL;
2892 DLIST_ADD(pserviceDest->param_opt, paramo);
2894 data = data->next;
2898 /***************************************************************************
2899 Check a service for consistency. Return False if the service is in any way
2900 incomplete or faulty, else True.
2901 ***************************************************************************/
2903 static BOOL service_ok(int iService)
2905 BOOL bRetval;
2907 bRetval = True;
2908 if (ServicePtrs[iService]->szService[0] == '\0') {
2909 DEBUG(0, ("The following message indicates an internal error:\n"));
2910 DEBUG(0, ("No service name in service entry.\n"));
2911 bRetval = False;
2914 /* The [printers] entry MUST be printable. I'm all for flexibility, but */
2915 /* I can't see why you'd want a non-printable printer service... */
2916 if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
2917 if (!ServicePtrs[iService]->bPrint_ok) {
2918 DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
2919 ServicePtrs[iService]->szService));
2920 ServicePtrs[iService]->bPrint_ok = True;
2922 /* [printers] service must also be non-browsable. */
2923 if (ServicePtrs[iService]->bBrowseable)
2924 ServicePtrs[iService]->bBrowseable = False;
2927 if (ServicePtrs[iService]->szPath[0] == '\0' &&
2928 strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
2929 ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
2931 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
2932 ServicePtrs[iService]->szService));
2933 ServicePtrs[iService]->bAvailable = False;
2936 /* If a service is flagged unavailable, log the fact at level 0. */
2937 if (!ServicePtrs[iService]->bAvailable)
2938 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
2939 ServicePtrs[iService]->szService));
2941 return (bRetval);
2944 static struct file_lists {
2945 struct file_lists *next;
2946 char *name;
2947 char *subfname;
2948 time_t modtime;
2949 } *file_lists = NULL;
2951 /*******************************************************************
2952 Keep a linked list of all config files so we know when one has changed
2953 it's date and needs to be reloaded.
2954 ********************************************************************/
2956 static void add_to_file_list(const char *fname, const char *subfname)
2958 struct file_lists *f = file_lists;
2960 while (f) {
2961 if (f->name && !strcmp(f->name, fname))
2962 break;
2963 f = f->next;
2966 if (!f) {
2967 f = SMB_MALLOC_P(struct file_lists);
2968 if (!f)
2969 return;
2970 f->next = file_lists;
2971 f->name = SMB_STRDUP(fname);
2972 if (!f->name) {
2973 SAFE_FREE(f);
2974 return;
2976 f->subfname = SMB_STRDUP(subfname);
2977 if (!f->subfname) {
2978 SAFE_FREE(f);
2979 return;
2981 file_lists = f;
2982 f->modtime = file_modtime(subfname);
2983 } else {
2984 time_t t = file_modtime(subfname);
2985 if (t)
2986 f->modtime = t;
2990 /*******************************************************************
2991 Check if a config file has changed date.
2992 ********************************************************************/
2994 BOOL lp_file_list_changed(void)
2996 struct file_lists *f = file_lists;
2998 DEBUG(6, ("lp_file_list_changed()\n"));
3000 while (f) {
3001 pstring n2;
3002 time_t mod_time;
3004 pstrcpy(n2, f->name);
3005 standard_sub_basic( get_current_username(), n2, sizeof(n2) );
3007 DEBUGADD(6, ("file %s -> %s last mod_time: %s\n",
3008 f->name, n2, ctime(&f->modtime)));
3010 mod_time = file_modtime(n2);
3012 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
3013 DEBUGADD(6,
3014 ("file %s modified: %s\n", n2,
3015 ctime(&mod_time)));
3016 f->modtime = mod_time;
3017 SAFE_FREE(f->subfname);
3018 f->subfname = SMB_STRDUP(n2);
3019 return (True);
3021 f = f->next;
3023 return (False);
3026 /***************************************************************************
3027 Run standard_sub_basic on netbios name... needed because global_myname
3028 is not accessed through any lp_ macro.
3029 Note: We must *NOT* use string_set() here as ptr points to global_myname.
3030 ***************************************************************************/
3032 static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
3034 BOOL ret;
3035 pstring netbios_name;
3037 pstrcpy(netbios_name, pszParmValue);
3039 standard_sub_basic(get_current_username(), netbios_name,sizeof(netbios_name));
3041 ret = set_global_myname(netbios_name);
3042 string_set(&Globals.szNetbiosName,global_myname());
3044 DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
3045 global_myname()));
3047 return ret;
3050 static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
3052 if (strcmp(*ptr, pszParmValue) != 0) {
3053 string_set(ptr, pszParmValue);
3054 init_iconv();
3056 return True;
3061 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
3063 BOOL ret;
3065 ret = set_global_myworkgroup(pszParmValue);
3066 string_set(&Globals.szWorkgroup,lp_workgroup());
3068 return ret;
3071 static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
3073 BOOL ret;
3075 ret = set_global_scope(pszParmValue);
3076 string_set(&Globals.szNetbiosScope,global_scope());
3078 return ret;
3081 static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
3083 str_list_free(&Globals.szNetbiosAliases);
3084 Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
3085 return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
3088 /***************************************************************************
3089 Handle the include operation.
3090 ***************************************************************************/
3092 static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
3094 pstring fname;
3095 pstrcpy(fname, pszParmValue);
3097 standard_sub_basic(get_current_username(), fname,sizeof(fname));
3099 add_to_file_list(pszParmValue, fname);
3101 string_set(ptr, fname);
3103 if (file_exist(fname, NULL))
3104 return (pm_process(fname, do_section, do_parameter));
3106 DEBUG(2, ("Can't find include file %s\n", fname));
3108 return (False);
3111 /***************************************************************************
3112 Handle the interpretation of the copy parameter.
3113 ***************************************************************************/
3115 static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
3117 BOOL bRetval;
3118 int iTemp;
3119 service serviceTemp;
3121 string_set(ptr, pszParmValue);
3123 init_service(&serviceTemp);
3125 bRetval = False;
3127 DEBUG(3, ("Copying service from service %s\n", pszParmValue));
3129 if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
3130 if (iTemp == iServiceIndex) {
3131 DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
3132 } else {
3133 copy_service(ServicePtrs[iServiceIndex],
3134 &serviceTemp,
3135 ServicePtrs[iServiceIndex]->copymap);
3136 bRetval = True;
3138 } else {
3139 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
3140 bRetval = False;
3143 free_service(&serviceTemp);
3144 return (bRetval);
3147 /***************************************************************************
3148 Handle idmap/non unix account uid and gid allocation parameters. The format of these
3149 parameters is:
3151 [global]
3153 idmap uid = 1000-1999
3154 idmap gid = 700-899
3156 We only do simple parsing checks here. The strings are parsed into useful
3157 structures in the idmap daemon code.
3159 ***************************************************************************/
3161 /* Some lp_ routines to return idmap [ug]id information */
3163 static uid_t idmap_uid_low, idmap_uid_high;
3164 static gid_t idmap_gid_low, idmap_gid_high;
3166 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
3168 if (idmap_uid_low == 0 || idmap_uid_high == 0)
3169 return False;
3171 if (low)
3172 *low = idmap_uid_low;
3174 if (high)
3175 *high = idmap_uid_high;
3177 return True;
3180 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
3182 if (idmap_gid_low == 0 || idmap_gid_high == 0)
3183 return False;
3185 if (low)
3186 *low = idmap_gid_low;
3188 if (high)
3189 *high = idmap_gid_high;
3191 return True;
3194 /* Do some simple checks on "idmap [ug]id" parameter values */
3196 static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
3198 uint32 low, high;
3200 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3201 return False;
3203 /* Parse OK */
3205 string_set(ptr, pszParmValue);
3207 idmap_uid_low = low;
3208 idmap_uid_high = high;
3210 return True;
3213 static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
3215 uint32 low, high;
3217 if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
3218 return False;
3220 /* Parse OK */
3222 string_set(ptr, pszParmValue);
3224 idmap_gid_low = low;
3225 idmap_gid_high = high;
3227 return True;
3230 /***************************************************************************
3231 Handle the DEBUG level list.
3232 ***************************************************************************/
3234 static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
3236 pstring pszParmValue;
3238 pstrcpy(pszParmValue, pszParmValueIn);
3239 string_set(ptr, pszParmValueIn);
3240 return debug_parse_levels( pszParmValue );
3243 /***************************************************************************
3244 Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
3245 ***************************************************************************/
3247 static const char *append_ldap_suffix( const char *str )
3249 const char *suffix_string;
3252 if (!lp_talloc)
3253 lp_talloc = talloc_init("lp_talloc");
3255 suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
3256 if ( !suffix_string ) {
3257 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
3258 return "";
3261 return suffix_string;
3264 const char *lp_ldap_machine_suffix(void)
3266 if (Globals.szLdapMachineSuffix[0])
3267 return append_ldap_suffix(Globals.szLdapMachineSuffix);
3269 return lp_string(Globals.szLdapSuffix);
3272 const char *lp_ldap_user_suffix(void)
3274 if (Globals.szLdapUserSuffix[0])
3275 return append_ldap_suffix(Globals.szLdapUserSuffix);
3277 return lp_string(Globals.szLdapSuffix);
3280 const char *lp_ldap_group_suffix(void)
3282 if (Globals.szLdapGroupSuffix[0])
3283 return append_ldap_suffix(Globals.szLdapGroupSuffix);
3285 return lp_string(Globals.szLdapSuffix);
3288 const char *lp_ldap_idmap_suffix(void)
3290 if (Globals.szLdapIdmapSuffix[0])
3291 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
3293 return lp_string(Globals.szLdapSuffix);
3296 /****************************************************************************
3297 set the value for a P_ENUM
3298 ***************************************************************************/
3300 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
3301 int *ptr )
3303 int i;
3305 for (i = 0; parm->enum_list[i].name; i++) {
3306 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
3307 *ptr = parm->enum_list[i].value;
3308 break;
3313 /***************************************************************************
3314 ***************************************************************************/
3316 static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
3318 static int parm_num = -1;
3319 service *s;
3321 if ( parm_num == -1 )
3322 parm_num = map_parameter( "printing" );
3324 lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
3326 if ( snum < 0 )
3327 s = &sDefault;
3328 else
3329 s = ServicePtrs[snum];
3331 init_printer_values( s );
3333 return True;
3337 /***************************************************************************
3338 Initialise a copymap.
3339 ***************************************************************************/
3341 static void init_copymap(service * pservice)
3343 int i;
3344 SAFE_FREE(pservice->copymap);
3345 pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
3346 if (!pservice->copymap)
3347 DEBUG(0,
3348 ("Couldn't allocate copymap!! (size %d)\n",
3349 (int)NUMPARAMETERS));
3350 else
3351 for (i = 0; i < NUMPARAMETERS; i++)
3352 pservice->copymap[i] = True;
3355 /***************************************************************************
3356 Return the local pointer to a parameter given the service number and the
3357 pointer into the default structure.
3358 ***************************************************************************/
3360 void *lp_local_ptr(int snum, void *ptr)
3362 return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
3365 /***************************************************************************
3366 Process a parameter for a particular service number. If snum < 0
3367 then assume we are in the globals.
3368 ***************************************************************************/
3370 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
3372 int parmnum, i, slen;
3373 void *parm_ptr = NULL; /* where we are going to store the result */
3374 void *def_ptr = NULL;
3375 pstring param_key;
3376 char *sep;
3377 param_opt_struct *paramo, *data;
3378 BOOL not_added;
3380 parmnum = map_parameter(pszParmName);
3382 if (parmnum < 0) {
3383 if ((sep=strchr(pszParmName, ':')) != NULL) {
3384 *sep = '\0';
3385 ZERO_STRUCT(param_key);
3386 pstr_sprintf(param_key, "%s:", pszParmName);
3387 slen = strlen(param_key);
3388 pstrcat(param_key, sep+1);
3389 trim_char(param_key+slen, ' ', ' ');
3390 not_added = True;
3391 data = (snum < 0) ? Globals.param_opt :
3392 ServicePtrs[snum]->param_opt;
3393 /* Traverse destination */
3394 while (data) {
3395 /* If we already have same option, override it */
3396 if (strcmp(data->key, param_key) == 0) {
3397 string_free(&data->value);
3398 str_list_free(&data->list);
3399 data->value = SMB_STRDUP(pszParmValue);
3400 not_added = False;
3401 break;
3403 data = data->next;
3405 if (not_added) {
3406 paramo = SMB_XMALLOC_P(param_opt_struct);
3407 paramo->key = SMB_STRDUP(param_key);
3408 paramo->value = SMB_STRDUP(pszParmValue);
3409 paramo->list = NULL;
3410 if (snum < 0) {
3411 DLIST_ADD(Globals.param_opt, paramo);
3412 } else {
3413 DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
3417 *sep = ':';
3418 return (True);
3420 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
3421 return (True);
3424 if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
3425 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
3426 pszParmName));
3429 def_ptr = parm_table[parmnum].ptr;
3431 /* we might point at a service, the default service or a global */
3432 if (snum < 0) {
3433 parm_ptr = def_ptr;
3434 } else {
3435 if (parm_table[parmnum].p_class == P_GLOBAL) {
3436 DEBUG(0,
3437 ("Global parameter %s found in service section!\n",
3438 pszParmName));
3439 return (True);
3441 parm_ptr =
3442 ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
3443 &sDefault);
3446 if (snum >= 0) {
3447 if (!ServicePtrs[snum]->copymap)
3448 init_copymap(ServicePtrs[snum]);
3450 /* this handles the aliases - set the copymap for other entries with
3451 the same data pointer */
3452 for (i = 0; parm_table[i].label; i++)
3453 if (parm_table[i].ptr == parm_table[parmnum].ptr)
3454 ServicePtrs[snum]->copymap[i] = False;
3457 /* if it is a special case then go ahead */
3458 if (parm_table[parmnum].special) {
3459 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
3460 return (True);
3463 /* now switch on the type of variable it is */
3464 switch (parm_table[parmnum].type)
3466 case P_BOOL:
3467 *(BOOL *)parm_ptr = lp_bool(pszParmValue);
3468 break;
3470 case P_BOOLREV:
3471 *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
3472 break;
3474 case P_INTEGER:
3475 *(int *)parm_ptr = lp_int(pszParmValue);
3476 break;
3478 case P_CHAR:
3479 *(char *)parm_ptr = *pszParmValue;
3480 break;
3482 case P_OCTAL:
3483 i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
3484 if ( i != 1 ) {
3485 DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
3487 break;
3489 case P_LIST:
3490 str_list_free((char ***)parm_ptr);
3491 *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
3492 break;
3494 case P_STRING:
3495 string_set((char **)parm_ptr, pszParmValue);
3496 break;
3498 case P_USTRING:
3499 string_set((char **)parm_ptr, pszParmValue);
3500 strupper_m(*(char **)parm_ptr);
3501 break;
3503 case P_GSTRING:
3504 pstrcpy((char *)parm_ptr, pszParmValue);
3505 break;
3507 case P_UGSTRING:
3508 pstrcpy((char *)parm_ptr, pszParmValue);
3509 strupper_m((char *)parm_ptr);
3510 break;
3512 case P_ENUM:
3513 lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
3514 break;
3515 case P_SEP:
3516 break;
3519 return (True);
3522 /***************************************************************************
3523 Process a parameter.
3524 ***************************************************************************/
3526 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
3528 if (!bInGlobalSection && bGlobalOnly)
3529 return (True);
3531 DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
3533 return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
3534 pszParmName, pszParmValue));
3537 /***************************************************************************
3538 Print a parameter of the specified type.
3539 ***************************************************************************/
3541 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
3543 int i;
3544 switch (p->type)
3546 case P_ENUM:
3547 for (i = 0; p->enum_list[i].name; i++) {
3548 if (*(int *)ptr == p->enum_list[i].value) {
3549 fprintf(f, "%s",
3550 p->enum_list[i].name);
3551 break;
3554 break;
3556 case P_BOOL:
3557 fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
3558 break;
3560 case P_BOOLREV:
3561 fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
3562 break;
3564 case P_INTEGER:
3565 fprintf(f, "%d", *(int *)ptr);
3566 break;
3568 case P_CHAR:
3569 fprintf(f, "%c", *(char *)ptr);
3570 break;
3572 case P_OCTAL:
3573 fprintf(f, "%s", octal_string(*(int *)ptr));
3574 break;
3576 case P_LIST:
3577 if ((char ***)ptr && *(char ***)ptr) {
3578 char **list = *(char ***)ptr;
3580 for (; *list; list++) {
3581 /* surround strings with whitespace in double quotes */
3582 if ( strchr_m( *list, ' ' ) )
3583 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
3584 else
3585 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
3588 break;
3590 case P_GSTRING:
3591 case P_UGSTRING:
3592 if ((char *)ptr) {
3593 fprintf(f, "%s", (char *)ptr);
3595 break;
3597 case P_STRING:
3598 case P_USTRING:
3599 if (*(char **)ptr) {
3600 fprintf(f, "%s", *(char **)ptr);
3602 break;
3603 case P_SEP:
3604 break;
3608 /***************************************************************************
3609 Check if two parameters are equal.
3610 ***************************************************************************/
3612 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
3614 switch (type) {
3615 case P_BOOL:
3616 case P_BOOLREV:
3617 return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
3619 case P_INTEGER:
3620 case P_ENUM:
3621 case P_OCTAL:
3622 return (*((int *)ptr1) == *((int *)ptr2));
3624 case P_CHAR:
3625 return (*((char *)ptr1) == *((char *)ptr2));
3627 case P_LIST:
3628 return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
3630 case P_GSTRING:
3631 case P_UGSTRING:
3633 char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
3634 if (p1 && !*p1)
3635 p1 = NULL;
3636 if (p2 && !*p2)
3637 p2 = NULL;
3638 return (p1 == p2 || strequal(p1, p2));
3640 case P_STRING:
3641 case P_USTRING:
3643 char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
3644 if (p1 && !*p1)
3645 p1 = NULL;
3646 if (p2 && !*p2)
3647 p2 = NULL;
3648 return (p1 == p2 || strequal(p1, p2));
3650 case P_SEP:
3651 break;
3653 return (False);
3656 /***************************************************************************
3657 Initialize any local varients in the sDefault table.
3658 ***************************************************************************/
3660 void init_locals(void)
3662 /* None as yet. */
3665 /***************************************************************************
3666 Process a new section (service). At this stage all sections are services.
3667 Later we'll have special sections that permit server parameters to be set.
3668 Returns True on success, False on failure.
3669 ***************************************************************************/
3671 static BOOL do_section(const char *pszSectionName)
3673 BOOL bRetval;
3674 BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
3675 (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
3676 bRetval = False;
3678 /* if we were in a global section then do the local inits */
3679 if (bInGlobalSection && !isglobal)
3680 init_locals();
3682 /* if we've just struck a global section, note the fact. */
3683 bInGlobalSection = isglobal;
3685 /* check for multiple global sections */
3686 if (bInGlobalSection) {
3687 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
3688 return (True);
3691 if (!bInGlobalSection && bGlobalOnly)
3692 return (True);
3694 /* if we have a current service, tidy it up before moving on */
3695 bRetval = True;
3697 if (iServiceIndex >= 0)
3698 bRetval = service_ok(iServiceIndex);
3700 /* if all is still well, move to the next record in the services array */
3701 if (bRetval) {
3702 /* We put this here to avoid an odd message order if messages are */
3703 /* issued by the post-processing of a previous section. */
3704 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
3706 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
3707 < 0) {
3708 DEBUG(0, ("Failed to add a new service\n"));
3709 return (False);
3713 return (bRetval);
3717 /***************************************************************************
3718 Determine if a partcular base parameter is currentl set to the default value.
3719 ***************************************************************************/
3721 static BOOL is_default(int i)
3723 if (!defaults_saved)
3724 return False;
3725 switch (parm_table[i].type) {
3726 case P_LIST:
3727 return str_list_compare (parm_table[i].def.lvalue,
3728 *(char ***)parm_table[i].ptr);
3729 case P_STRING:
3730 case P_USTRING:
3731 return strequal(parm_table[i].def.svalue,
3732 *(char **)parm_table[i].ptr);
3733 case P_GSTRING:
3734 case P_UGSTRING:
3735 return strequal(parm_table[i].def.svalue,
3736 (char *)parm_table[i].ptr);
3737 case P_BOOL:
3738 case P_BOOLREV:
3739 return parm_table[i].def.bvalue ==
3740 *(BOOL *)parm_table[i].ptr;
3741 case P_CHAR:
3742 return parm_table[i].def.cvalue ==
3743 *(char *)parm_table[i].ptr;
3744 case P_INTEGER:
3745 case P_OCTAL:
3746 case P_ENUM:
3747 return parm_table[i].def.ivalue ==
3748 *(int *)parm_table[i].ptr;
3749 case P_SEP:
3750 break;
3752 return False;
3755 /***************************************************************************
3756 Display the contents of the global structure.
3757 ***************************************************************************/
3759 static void dump_globals(FILE *f)
3761 int i;
3762 param_opt_struct *data;
3764 fprintf(f, "[global]\n");
3766 for (i = 0; parm_table[i].label; i++)
3767 if (parm_table[i].p_class == P_GLOBAL &&
3768 parm_table[i].ptr &&
3769 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
3770 if (defaults_saved && is_default(i))
3771 continue;
3772 fprintf(f, "\t%s = ", parm_table[i].label);
3773 print_parameter(&parm_table[i], parm_table[i].ptr, f);
3774 fprintf(f, "\n");
3776 if (Globals.param_opt != NULL) {
3777 data = Globals.param_opt;
3778 while(data) {
3779 fprintf(f, "\t%s = %s\n", data->key, data->value);
3780 data = data->next;
3786 /***************************************************************************
3787 Return True if a local parameter is currently set to the global default.
3788 ***************************************************************************/
3790 BOOL lp_is_default(int snum, struct parm_struct *parm)
3792 int pdiff = PTR_DIFF(parm->ptr, &sDefault);
3794 return equal_parameter(parm->type,
3795 ((char *)ServicePtrs[snum]) + pdiff,
3796 ((char *)&sDefault) + pdiff);
3799 /***************************************************************************
3800 Display the contents of a single services record.
3801 ***************************************************************************/
3803 static void dump_a_service(service * pService, FILE * f)
3805 int i;
3806 param_opt_struct *data;
3808 if (pService != &sDefault)
3809 fprintf(f, "[%s]\n", pService->szService);
3811 for (i = 0; parm_table[i].label; i++) {
3813 if (parm_table[i].p_class == P_LOCAL &&
3814 parm_table[i].ptr &&
3815 (*parm_table[i].label != '-') &&
3816 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3819 int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
3821 if (pService == &sDefault) {
3822 if (defaults_saved && is_default(i))
3823 continue;
3824 } else {
3825 if (equal_parameter(parm_table[i].type,
3826 ((char *)pService) +
3827 pdiff,
3828 ((char *)&sDefault) +
3829 pdiff))
3830 continue;
3833 fprintf(f, "\t%s = ", parm_table[i].label);
3834 print_parameter(&parm_table[i],
3835 ((char *)pService) + pdiff, f);
3836 fprintf(f, "\n");
3840 if (pService->param_opt != NULL) {
3841 data = pService->param_opt;
3842 while(data) {
3843 fprintf(f, "\t%s = %s\n", data->key, data->value);
3844 data = data->next;
3849 /***************************************************************************
3850 Display the contents of a parameter of a single services record.
3851 ***************************************************************************/
3853 BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
3855 service * pService = ServicePtrs[snum];
3856 int i;
3857 BOOL result = False;
3858 parm_class p_class;
3859 unsigned flag = 0;
3860 fstring local_parm_name;
3861 char *parm_opt;
3862 const char *parm_opt_value;
3864 /* check for parametrical option */
3865 fstrcpy( local_parm_name, parm_name);
3866 parm_opt = strchr( local_parm_name, ':');
3868 if (parm_opt) {
3869 *parm_opt = '\0';
3870 parm_opt++;
3871 if (strlen(parm_opt)) {
3872 parm_opt_value = lp_parm_const_string( snum,
3873 local_parm_name, parm_opt, NULL);
3874 if (parm_opt_value) {
3875 printf( "%s\n", parm_opt_value);
3876 result = True;
3879 return result;
3882 /* check for a key and print the value */
3883 if (isGlobal) {
3884 p_class = P_GLOBAL;
3885 flag = FLAG_GLOBAL;
3886 } else
3887 p_class = P_LOCAL;
3889 for (i = 0; parm_table[i].label; i++) {
3890 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
3891 (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
3892 parm_table[i].ptr &&
3893 (*parm_table[i].label != '-') &&
3894 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3896 void *ptr;
3898 if (isGlobal)
3899 ptr = parm_table[i].ptr;
3900 else
3901 ptr = ((char *)pService) +
3902 PTR_DIFF(parm_table[i].ptr, &sDefault);
3904 print_parameter(&parm_table[i],
3905 ptr, f);
3906 fprintf(f, "\n");
3907 result = True;
3908 break;
3912 return result;
3915 /***************************************************************************
3916 Return info about the next service in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
3917 Return NULL when out of parameters.
3918 ***************************************************************************/
3920 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
3922 if (snum < 0) {
3923 /* do the globals */
3924 for (; parm_table[*i].label; (*i)++) {
3925 if (parm_table[*i].p_class == P_SEPARATOR)
3926 return &parm_table[(*i)++];
3928 if (!parm_table[*i].ptr
3929 || (*parm_table[*i].label == '-'))
3930 continue;
3932 if ((*i) > 0
3933 && (parm_table[*i].ptr ==
3934 parm_table[(*i) - 1].ptr))
3935 continue;
3937 return &parm_table[(*i)++];
3939 } else {
3940 service *pService = ServicePtrs[snum];
3942 for (; parm_table[*i].label; (*i)++) {
3943 if (parm_table[*i].p_class == P_SEPARATOR)
3944 return &parm_table[(*i)++];
3946 if (parm_table[*i].p_class == P_LOCAL &&
3947 parm_table[*i].ptr &&
3948 (*parm_table[*i].label != '-') &&
3949 ((*i) == 0 ||
3950 (parm_table[*i].ptr !=
3951 parm_table[(*i) - 1].ptr)))
3953 int pdiff =
3954 PTR_DIFF(parm_table[*i].ptr,
3955 &sDefault);
3957 if (allparameters ||
3958 !equal_parameter(parm_table[*i].type,
3959 ((char *)pService) +
3960 pdiff,
3961 ((char *)&sDefault) +
3962 pdiff))
3964 return &parm_table[(*i)++];
3970 return NULL;
3974 #if 0
3975 /***************************************************************************
3976 Display the contents of a single copy structure.
3977 ***************************************************************************/
3978 static void dump_copy_map(BOOL *pcopymap)
3980 int i;
3981 if (!pcopymap)
3982 return;
3984 printf("\n\tNon-Copied parameters:\n");
3986 for (i = 0; parm_table[i].label; i++)
3987 if (parm_table[i].p_class == P_LOCAL &&
3988 parm_table[i].ptr && !pcopymap[i] &&
3989 (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
3991 printf("\t\t%s\n", parm_table[i].label);
3994 #endif
3996 /***************************************************************************
3997 Return TRUE if the passed service number is within range.
3998 ***************************************************************************/
4000 BOOL lp_snum_ok(int iService)
4002 return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
4005 /***************************************************************************
4006 Auto-load some home services.
4007 ***************************************************************************/
4009 static void lp_add_auto_services(char *str)
4011 char *s;
4012 char *p;
4013 int homes;
4015 if (!str)
4016 return;
4018 s = SMB_STRDUP(str);
4019 if (!s)
4020 return;
4022 homes = lp_servicenumber(HOMES_NAME);
4024 for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
4025 char *home = get_user_home_dir(p);
4027 if (lp_servicenumber(p) >= 0)
4028 continue;
4030 if (home && homes >= 0)
4031 lp_add_home(p, homes, p, home);
4033 SAFE_FREE(s);
4036 /***************************************************************************
4037 Auto-load one printer.
4038 ***************************************************************************/
4040 void lp_add_one_printer(char *name, char *comment)
4042 int printers = lp_servicenumber(PRINTERS_NAME);
4043 int i;
4045 if (lp_servicenumber(name) < 0) {
4046 lp_add_printer(name, printers);
4047 if ((i = lp_servicenumber(name)) >= 0) {
4048 string_set(&ServicePtrs[i]->comment, comment);
4049 ServicePtrs[i]->autoloaded = True;
4054 /***************************************************************************
4055 Have we loaded a services file yet?
4056 ***************************************************************************/
4058 BOOL lp_loaded(void)
4060 return (bLoaded);
4063 /***************************************************************************
4064 Unload unused services.
4065 ***************************************************************************/
4067 void lp_killunused(BOOL (*snumused) (int))
4069 int i;
4070 for (i = 0; i < iNumServices; i++) {
4071 if (!VALID(i))
4072 continue;
4074 /* don't kill autoloaded or usershare services */
4075 if ( ServicePtrs[i]->autoloaded ||
4076 ServicePtrs[i]->usershare == USERSHARE_VALID) {
4077 continue;
4080 if (!snumused || !snumused(i)) {
4081 free_service_byindex(i);
4086 /***************************************************************************
4087 Unload a service.
4088 ***************************************************************************/
4090 void lp_killservice(int iServiceIn)
4092 if (VALID(iServiceIn)) {
4093 free_service_byindex(iServiceIn);
4097 /***************************************************************************
4098 Save the curent values of all global and sDefault parameters into the
4099 defaults union. This allows swat and testparm to show only the
4100 changed (ie. non-default) parameters.
4101 ***************************************************************************/
4103 static void lp_save_defaults(void)
4105 int i;
4106 for (i = 0; parm_table[i].label; i++) {
4107 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
4108 continue;
4109 switch (parm_table[i].type) {
4110 case P_LIST:
4111 str_list_copy(&(parm_table[i].def.lvalue),
4112 *(const char ***)parm_table[i].ptr);
4113 break;
4114 case P_STRING:
4115 case P_USTRING:
4116 if (parm_table[i].ptr) {
4117 parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
4118 } else {
4119 parm_table[i].def.svalue = NULL;
4121 break;
4122 case P_GSTRING:
4123 case P_UGSTRING:
4124 if (parm_table[i].ptr) {
4125 parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
4126 } else {
4127 parm_table[i].def.svalue = NULL;
4129 break;
4130 case P_BOOL:
4131 case P_BOOLREV:
4132 parm_table[i].def.bvalue =
4133 *(BOOL *)parm_table[i].ptr;
4134 break;
4135 case P_CHAR:
4136 parm_table[i].def.cvalue =
4137 *(char *)parm_table[i].ptr;
4138 break;
4139 case P_INTEGER:
4140 case P_OCTAL:
4141 case P_ENUM:
4142 parm_table[i].def.ivalue =
4143 *(int *)parm_table[i].ptr;
4144 break;
4145 case P_SEP:
4146 break;
4149 defaults_saved = True;
4152 /*******************************************************************
4153 Set the server type we will announce as via nmbd.
4154 ********************************************************************/
4156 static const struct srv_role_tab {
4157 uint32 role;
4158 const char *role_str;
4159 } srv_role_tab [] = {
4160 { ROLE_STANDALONE, "ROLE_STANDALONE" },
4161 { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
4162 { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
4163 { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
4164 { 0, NULL }
4167 const char* server_role_str(uint32 role)
4169 int i = 0;
4170 for (i=0; srv_role_tab[i].role_str; i++) {
4171 if (role == srv_role_tab[i].role) {
4172 return srv_role_tab[i].role_str;
4175 return NULL;
4178 static void set_server_role(void)
4180 server_role = ROLE_STANDALONE;
4182 switch (lp_security()) {
4183 case SEC_SHARE:
4184 if (lp_domain_logons())
4185 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
4186 break;
4187 case SEC_SERVER:
4188 if (lp_domain_logons())
4189 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
4190 server_role = ROLE_DOMAIN_MEMBER;
4191 break;
4192 case SEC_DOMAIN:
4193 if (lp_domain_logons()) {
4194 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
4195 server_role = ROLE_DOMAIN_BDC;
4196 break;
4198 server_role = ROLE_DOMAIN_MEMBER;
4199 break;
4200 case SEC_ADS:
4201 if (lp_domain_logons()) {
4202 server_role = ROLE_DOMAIN_PDC;
4203 break;
4205 server_role = ROLE_DOMAIN_MEMBER;
4206 break;
4207 case SEC_USER:
4208 if (lp_domain_logons()) {
4210 if (Globals.bDomainMaster) /* auto or yes */
4211 server_role = ROLE_DOMAIN_PDC;
4212 else
4213 server_role = ROLE_DOMAIN_BDC;
4215 break;
4216 default:
4217 DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
4218 break;
4221 DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
4224 /***********************************************************
4225 If we should send plaintext/LANMAN passwords in the clinet
4226 ************************************************************/
4228 static void set_allowed_client_auth(void)
4230 if (Globals.bClientNTLMv2Auth) {
4231 Globals.bClientLanManAuth = False;
4233 if (!Globals.bClientLanManAuth) {
4234 Globals.bClientPlaintextAuth = False;
4238 /***************************************************************************
4239 JRA.
4240 The following code allows smbd to read a user defined share file.
4241 Yes, this is my intent. Yes, I'm comfortable with that...
4243 THE FOLLOWING IS SECURITY CRITICAL CODE.
4245 It washes your clothes, it cleans your house, it guards you while you sleep...
4246 Do not f%^k with it....
4247 ***************************************************************************/
4249 #define MAX_USERSHARE_FILE_SIZE (10*1024)
4251 /***************************************************************************
4252 Check allowed stat state of a usershare file.
4253 Ensure we print out who is dicking with us so the admin can
4254 get their sorry ass fired.
4255 ***************************************************************************/
4257 static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
4259 if (!S_ISREG(psbuf->st_mode)) {
4260 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4261 "not a regular file\n",
4262 fname, (unsigned int)psbuf->st_uid ));
4263 return False;
4266 /* Ensure this doesn't have the other write bit set. */
4267 if (psbuf->st_mode & S_IWOTH) {
4268 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
4269 "public write. Refusing to allow as a usershare file.\n",
4270 fname, (unsigned int)psbuf->st_uid ));
4271 return False;
4274 /* Should be 10k or less. */
4275 if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
4276 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
4277 "too large (%u) to be a user share file.\n",
4278 fname, (unsigned int)psbuf->st_uid,
4279 (unsigned int)psbuf->st_size ));
4280 return False;
4283 return True;
4286 /***************************************************************************
4287 Parse the contents of a usershare file.
4288 ***************************************************************************/
4290 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx,
4291 SMB_STRUCT_STAT *psbuf,
4292 const char *servicename,
4293 int snum,
4294 char **lines,
4295 int numlines,
4296 pstring sharepath,
4297 pstring comment,
4298 SEC_DESC **ppsd,
4299 BOOL *pallow_guest)
4301 const char **prefixallowlist = lp_usershare_prefix_allow_list();
4302 const char **prefixdenylist = lp_usershare_prefix_deny_list();
4303 int us_vers;
4304 SMB_STRUCT_DIR *dp;
4305 SMB_STRUCT_STAT sbuf;
4307 *pallow_guest = False;
4309 if (numlines < 4) {
4310 return USERSHARE_MALFORMED_FILE;
4313 if (strcmp(lines[0], "#VERSION 1") == 0) {
4314 us_vers = 1;
4315 } else if (strcmp(lines[0], "#VERSION 2") == 0) {
4316 us_vers = 2;
4317 if (numlines < 5) {
4318 return USERSHARE_MALFORMED_FILE;
4320 } else {
4321 return USERSHARE_BAD_VERSION;
4324 if (strncmp(lines[1], "path=", 5) != 0) {
4325 return USERSHARE_MALFORMED_PATH;
4328 pstrcpy(sharepath, &lines[1][5]);
4329 trim_string(sharepath, " ", " ");
4331 if (strncmp(lines[2], "comment=", 8) != 0) {
4332 return USERSHARE_MALFORMED_COMMENT_DEF;
4335 pstrcpy(comment, &lines[2][8]);
4336 trim_string(comment, " ", " ");
4337 trim_char(comment, '"', '"');
4339 if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
4340 return USERSHARE_MALFORMED_ACL_DEF;
4343 if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
4344 return USERSHARE_ACL_ERR;
4347 if (us_vers == 2) {
4348 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
4349 return USERSHARE_MALFORMED_ACL_DEF;
4351 if (lines[4][9] == 'y') {
4352 *pallow_guest = True;
4356 if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
4357 /* Path didn't change, no checks needed. */
4358 return USERSHARE_OK;
4361 /* The path *must* be absolute. */
4362 if (sharepath[0] != '/') {
4363 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
4364 servicename, sharepath));
4365 return USERSHARE_PATH_NOT_ABSOLUTE;
4368 /* If there is a usershare prefix deny list ensure one of these paths
4369 doesn't match the start of the user given path. */
4370 if (prefixdenylist) {
4371 int i;
4372 for ( i=0; prefixdenylist[i]; i++ ) {
4373 DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
4374 servicename, i, prefixdenylist[i], sharepath ));
4375 if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
4376 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
4377 "usershare prefix deny list entries.\n",
4378 servicename, sharepath));
4379 return USERSHARE_PATH_IS_DENIED;
4384 /* If there is a usershare prefix allow list ensure one of these paths
4385 does match the start of the user given path. */
4387 if (prefixallowlist) {
4388 int i;
4389 for ( i=0; prefixallowlist[i]; i++ ) {
4390 DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
4391 servicename, i, prefixallowlist[i], sharepath ));
4392 if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
4393 break;
4396 if (prefixallowlist[i] == NULL) {
4397 DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
4398 "usershare prefix allow list entries.\n",
4399 servicename, sharepath));
4400 return USERSHARE_PATH_NOT_ALLOWED;
4404 /* Ensure this is pointing to a directory. */
4405 dp = sys_opendir(sharepath);
4407 if (!dp) {
4408 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4409 servicename, sharepath));
4410 return USERSHARE_PATH_NOT_DIRECTORY;
4413 /* Ensure the owner of the usershare file has permission to share
4414 this directory. */
4416 if (sys_stat(sharepath, &sbuf) == -1) {
4417 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
4418 servicename, sharepath, strerror(errno) ));
4419 sys_closedir(dp);
4420 return USERSHARE_POSIX_ERR;
4423 sys_closedir(dp);
4425 if (!S_ISDIR(sbuf.st_mode)) {
4426 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
4427 servicename, sharepath ));
4428 return USERSHARE_PATH_NOT_DIRECTORY;
4431 /* Check if sharing is restricted to owner-only. */
4432 /* psbuf is the stat of the usershare definition file,
4433 sbuf is the stat of the target directory to be shared. */
4435 if (lp_usershare_owner_only()) {
4436 /* root can share anything. */
4437 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
4438 return USERSHARE_PATH_NOT_ALLOWED;
4442 return USERSHARE_OK;
4445 /***************************************************************************
4446 Deal with a usershare file.
4447 Returns:
4448 >= 0 - snum
4449 -1 - Bad name, invalid contents.
4450 - service name already existed and not a usershare, problem
4451 with permissions to share directory etc.
4452 ***************************************************************************/
4454 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
4456 SMB_STRUCT_STAT sbuf;
4457 SMB_STRUCT_STAT lsbuf;
4458 pstring fname;
4459 pstring sharepath;
4460 pstring comment;
4461 fstring service_name;
4462 char **lines = NULL;
4463 int numlines = 0;
4464 int fd = -1;
4465 int iService = -1;
4466 TALLOC_CTX *ctx = NULL;
4467 SEC_DESC *psd = NULL;
4468 BOOL guest_ok = False;
4470 /* Ensure share name doesn't contain invalid characters. */
4471 if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
4472 DEBUG(0,("process_usershare_file: share name %s contains "
4473 "invalid characters (any of %s)\n",
4474 file_name, INVALID_SHARENAME_CHARS ));
4475 return -1;
4478 fstrcpy(service_name, file_name);
4480 pstrcpy(fname, dir_name);
4481 pstrcat(fname, "/");
4482 pstrcat(fname, file_name);
4484 /* Minimize the race condition by doing an lstat before we
4485 open and fstat. Ensure this isn't a symlink link. */
4487 if (sys_lstat(fname, &lsbuf) != 0) {
4488 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
4489 fname, strerror(errno) ));
4490 return -1;
4493 /* This must be a regular file, not a symlink, directory or
4494 other strange filetype. */
4495 if (!check_usershare_stat(fname, &lsbuf)) {
4496 return -1;
4499 /* See if there is already a servicenum for this name. */
4500 /* tdb_fetch_int32 returns -1 if not found. */
4501 iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
4503 if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
4504 /* Nothing changed - Mark valid and return. */
4505 DEBUG(10,("process_usershare_file: service %s not changed.\n",
4506 service_name ));
4507 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4508 return iService;
4511 /* Try and open the file read only - no symlinks allowed. */
4512 #ifdef O_NOFOLLOW
4513 fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
4514 #else
4515 fd = sys_open(fname, O_RDONLY, 0);
4516 #endif
4518 if (fd == -1) {
4519 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
4520 fname, strerror(errno) ));
4521 return -1;
4524 /* Now fstat to be *SURE* it's a regular file. */
4525 if (sys_fstat(fd, &sbuf) != 0) {
4526 close(fd);
4527 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
4528 fname, strerror(errno) ));
4529 return -1;
4532 /* Is it the same dev/inode as was lstated ? */
4533 if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
4534 close(fd);
4535 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
4536 "Symlink spoofing going on ?\n", fname ));
4537 return -1;
4540 /* This must be a regular file, not a symlink, directory or
4541 other strange filetype. */
4542 if (!check_usershare_stat(fname, &sbuf)) {
4543 return -1;
4546 lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
4548 close(fd);
4549 if (lines == NULL) {
4550 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
4551 fname, (unsigned int)sbuf.st_uid ));
4552 return -1;
4555 /* Should we allow printers to be shared... ? */
4556 ctx = talloc_init("usershare_sd_xctx");
4557 if (!ctx) {
4558 SAFE_FREE(lines);
4559 return 1;
4562 if (parse_usershare_file(ctx, &sbuf, service_name,
4563 iService, lines, numlines, sharepath,
4564 comment, &psd, &guest_ok) != USERSHARE_OK) {
4565 talloc_destroy(ctx);
4566 SAFE_FREE(lines);
4567 return -1;
4570 SAFE_FREE(lines);
4572 /* Everything ok - add the service possibly using a template. */
4573 if (iService < 0) {
4574 const service *sp = &sDefault;
4575 if (snum_template != -1) {
4576 sp = ServicePtrs[snum_template];
4579 if ((iService = add_a_service(sp, service_name)) < 0) {
4580 DEBUG(0, ("process_usershare_file: Failed to add "
4581 "new service %s\n", service_name));
4582 talloc_destroy(ctx);
4583 return -1;
4586 /* Read only is controlled by usershare ACL below. */
4587 ServicePtrs[iService]->bRead_only = False;
4590 /* Write the ACL of the new/modified share. */
4591 if (!set_share_security(ctx, service_name, psd)) {
4592 DEBUG(0, ("process_usershare_file: Failed to set share "
4593 "security for user share %s\n",
4594 service_name ));
4595 lp_remove_service(iService);
4596 talloc_destroy(ctx);
4597 return -1;
4600 talloc_destroy(ctx);
4602 /* If from a template it may be marked invalid. */
4603 ServicePtrs[iService]->valid = True;
4605 /* Set the service as a valid usershare. */
4606 ServicePtrs[iService]->usershare = USERSHARE_VALID;
4608 /* Set guest access. */
4609 if (lp_usershare_allow_guests()) {
4610 ServicePtrs[iService]->bGuest_ok = guest_ok;
4613 /* And note when it was loaded. */
4614 ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
4615 string_set(&ServicePtrs[iService]->szPath, sharepath);
4616 string_set(&ServicePtrs[iService]->comment, comment);
4618 return iService;
4621 /***************************************************************************
4622 Checks if a usershare entry has been modified since last load.
4623 ***************************************************************************/
4625 static BOOL usershare_exists(int iService, time_t *last_mod)
4627 SMB_STRUCT_STAT lsbuf;
4628 const char *usersharepath = Globals.szUsersharePath;
4629 pstring fname;
4631 pstrcpy(fname, usersharepath);
4632 pstrcat(fname, "/");
4633 pstrcat(fname, ServicePtrs[iService]->szService);
4635 if (sys_lstat(fname, &lsbuf) != 0) {
4636 return False;
4639 if (!S_ISREG(lsbuf.st_mode)) {
4640 return False;
4643 *last_mod = lsbuf.st_mtime;
4644 return True;
4647 /***************************************************************************
4648 Load a usershare service by name. Returns a valid servicenumber or -1.
4649 ***************************************************************************/
4651 int load_usershare_service(const char *servicename)
4653 SMB_STRUCT_STAT sbuf;
4654 const char *usersharepath = Globals.szUsersharePath;
4655 int max_user_shares = Globals.iUsershareMaxShares;
4656 int snum_template = -1;
4658 if (*usersharepath == 0 || max_user_shares == 0) {
4659 return -1;
4662 if (sys_stat(usersharepath, &sbuf) != 0) {
4663 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
4664 usersharepath, strerror(errno) ));
4665 return -1;
4668 if (!S_ISDIR(sbuf.st_mode)) {
4669 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
4670 usersharepath ));
4671 return -1;
4675 * This directory must be owned by root, and have the 't' bit set.
4676 * It also must not be writable by "other".
4679 #ifdef S_ISVTX
4680 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4681 #else
4682 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4683 #endif
4684 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
4685 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4686 usersharepath ));
4687 return -1;
4690 /* Ensure the template share exists if it's set. */
4691 if (Globals.szUsershareTemplateShare[0]) {
4692 /* We can't use lp_servicenumber here as we are recommending that
4693 template shares have -valid=False set. */
4694 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4695 if (ServicePtrs[snum_template]->szService &&
4696 strequal(ServicePtrs[snum_template]->szService,
4697 Globals.szUsershareTemplateShare)) {
4698 break;
4702 if (snum_template == -1) {
4703 DEBUG(0,("load_usershare_service: usershare template share %s "
4704 "does not exist.\n",
4705 Globals.szUsershareTemplateShare ));
4706 return -1;
4710 return process_usershare_file(usersharepath, servicename, snum_template);
4713 /***************************************************************************
4714 Load all user defined shares from the user share directory.
4715 We only do this if we're enumerating the share list.
4716 This is the function that can delete usershares that have
4717 been removed.
4718 ***************************************************************************/
4720 int load_usershare_shares(void)
4722 SMB_STRUCT_DIR *dp;
4723 SMB_STRUCT_STAT sbuf;
4724 SMB_STRUCT_DIRENT *de;
4725 int num_usershares = 0;
4726 int max_user_shares = Globals.iUsershareMaxShares;
4727 unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
4728 unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
4729 unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
4730 int iService;
4731 int snum_template = -1;
4732 const char *usersharepath = Globals.szUsersharePath;
4733 int ret = lp_numservices();
4735 if (max_user_shares == 0 || *usersharepath == '\0') {
4736 return lp_numservices();
4739 if (sys_stat(usersharepath, &sbuf) != 0) {
4740 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
4741 usersharepath, strerror(errno) ));
4742 return ret;
4746 * This directory must be owned by root, and have the 't' bit set.
4747 * It also must not be writable by "other".
4750 #ifdef S_ISVTX
4751 if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
4752 #else
4753 if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
4754 #endif
4755 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
4756 "or does not have the sticky bit 't' set or is writable by anyone.\n",
4757 usersharepath ));
4758 return ret;
4761 /* Ensure the template share exists if it's set. */
4762 if (Globals.szUsershareTemplateShare[0]) {
4763 /* We can't use lp_servicenumber here as we are recommending that
4764 template shares have -valid=False set. */
4765 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
4766 if (ServicePtrs[snum_template]->szService &&
4767 strequal(ServicePtrs[snum_template]->szService,
4768 Globals.szUsershareTemplateShare)) {
4769 break;
4773 if (snum_template == -1) {
4774 DEBUG(0,("load_usershare_shares: usershare template share %s "
4775 "does not exist.\n",
4776 Globals.szUsershareTemplateShare ));
4777 return ret;
4781 /* Mark all existing usershares as pending delete. */
4782 for (iService = iNumServices - 1; iService >= 0; iService--) {
4783 if (VALID(iService) && ServicePtrs[iService]->usershare) {
4784 ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
4788 dp = sys_opendir(usersharepath);
4789 if (!dp) {
4790 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
4791 usersharepath, strerror(errno) ));
4792 return ret;
4795 for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
4796 (de = sys_readdir(dp));
4797 num_dir_entries++ ) {
4798 int r;
4799 const char *n = de->d_name;
4801 /* Ignore . and .. */
4802 if (*n == '.') {
4803 if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
4804 continue;
4808 if (n[0] == ':') {
4809 /* Temporary file used when creating a share. */
4810 num_tmp_dir_entries++;
4813 /* Allow 20% tmp entries. */
4814 if (num_tmp_dir_entries > allowed_tmp_entries) {
4815 DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
4816 "in directory %s\n",
4817 num_tmp_dir_entries, usersharepath));
4818 break;
4821 r = process_usershare_file(usersharepath, n, snum_template);
4822 if (r == 0) {
4823 /* Update the services count. */
4824 num_usershares++;
4825 if (num_usershares >= max_user_shares) {
4826 DEBUG(0,("load_usershare_shares: max user shares reached "
4827 "on file %s in directory %s\n",
4828 n, usersharepath ));
4829 break;
4831 } else if (r == -1) {
4832 num_bad_dir_entries++;
4835 /* Allow 20% bad entries. */
4836 if (num_bad_dir_entries > allowed_bad_entries) {
4837 DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
4838 "in directory %s\n",
4839 num_bad_dir_entries, usersharepath));
4840 break;
4843 /* Allow 20% bad entries. */
4844 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
4845 DEBUG(0,("load_usershare_shares: too many total entries (%u) "
4846 "in directory %s\n",
4847 num_dir_entries, usersharepath));
4848 break;
4852 sys_closedir(dp);
4854 /* Sweep through and delete any non-refreshed usershares that are
4855 not currently in use. */
4856 for (iService = iNumServices - 1; iService >= 0; iService--) {
4857 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
4858 if (conn_snum_used(iService)) {
4859 continue;
4861 /* Remove from the share ACL db. */
4862 DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
4863 lp_servicename(iService) ));
4864 delete_share_security(iService);
4865 free_service_byindex(iService);
4869 return lp_numservices();
4872 /********************************************************
4873 Destroy global resources allocated in this file
4874 ********************************************************/
4876 void gfree_loadparm(void)
4878 struct file_lists *f;
4879 struct file_lists *next;
4880 int i;
4882 lp_TALLOC_FREE();
4884 /* Free the file lists */
4886 f = file_lists;
4887 while( f ) {
4888 next = f->next;
4889 SAFE_FREE( f->name );
4890 SAFE_FREE( f->subfname );
4891 SAFE_FREE( f );
4892 f = next;
4895 /* Free resources allocated to services */
4897 for ( i = 0; i < iNumServices; i++ ) {
4898 if ( VALID(i) ) {
4899 free_service_byindex(i);
4903 SAFE_FREE( ServicePtrs );
4904 iNumServices = 0;
4906 /* Now release all resources allocated to global
4907 parameters and the default service */
4909 for (i = 0; parm_table[i].label; i++)
4911 if ( parm_table[i].type == P_STRING
4912 || parm_table[i].type == P_USTRING )
4914 string_free( (char**)parm_table[i].ptr );
4916 else if (parm_table[i].type == P_LIST) {
4917 str_list_free( (char***)parm_table[i].ptr );
4922 /***************************************************************************
4923 Load the services array from the services file. Return True on success,
4924 False on failure.
4925 ***************************************************************************/
4927 BOOL lp_load(const char *pszFname,
4928 BOOL global_only,
4929 BOOL save_defaults,
4930 BOOL add_ipc,
4931 BOOL initialize_globals)
4933 pstring n2;
4934 BOOL bRetval;
4935 param_opt_struct *data, *pdata;
4937 pstrcpy(n2, pszFname);
4939 standard_sub_basic( get_current_username(), n2,sizeof(n2) );
4941 add_to_file_list(pszFname, n2);
4943 bRetval = False;
4945 DEBUG(3, ("lp_load: refreshing parameters\n"));
4947 bInGlobalSection = True;
4948 bGlobalOnly = global_only;
4950 init_globals(! initialize_globals);
4951 debug_init();
4953 if (save_defaults) {
4954 init_locals();
4955 lp_save_defaults();
4958 if (Globals.param_opt != NULL) {
4959 data = Globals.param_opt;
4960 while (data) {
4961 string_free(&data->key);
4962 string_free(&data->value);
4963 str_list_free(&data->list);
4964 pdata = data->next;
4965 SAFE_FREE(data);
4966 data = pdata;
4968 Globals.param_opt = NULL;
4971 /* We get sections first, so have to start 'behind' to make up */
4972 iServiceIndex = -1;
4973 bRetval = pm_process(n2, do_section, do_parameter);
4975 /* finish up the last section */
4976 DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
4977 if (bRetval)
4978 if (iServiceIndex >= 0)
4979 bRetval = service_ok(iServiceIndex);
4981 lp_add_auto_services(lp_auto_services());
4983 if (add_ipc) {
4984 /* When 'restrict anonymous = 2' guest connections to ipc$
4985 are denied */
4986 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
4987 if ( lp_enable_asu_support() )
4988 lp_add_ipc("ADMIN$", False);
4991 set_server_role();
4992 set_default_server_announce_type();
4993 set_allowed_client_auth();
4995 bLoaded = True;
4997 /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
4998 /* if bWINSsupport is true and we are in the client */
4999 if (in_client && Globals.bWINSsupport) {
5000 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
5003 init_iconv();
5005 return (bRetval);
5008 /***************************************************************************
5009 Reset the max number of services.
5010 ***************************************************************************/
5012 void lp_resetnumservices(void)
5014 iNumServices = 0;
5017 /***************************************************************************
5018 Return the max number of services.
5019 ***************************************************************************/
5021 int lp_numservices(void)
5023 return (iNumServices);
5026 /***************************************************************************
5027 Display the contents of the services array in human-readable form.
5028 ***************************************************************************/
5030 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
5032 int iService;
5034 if (show_defaults)
5035 defaults_saved = False;
5037 dump_globals(f);
5039 dump_a_service(&sDefault, f);
5041 for (iService = 0; iService < maxtoprint; iService++) {
5042 fprintf(f,"\n");
5043 lp_dump_one(f, show_defaults, iService);
5047 /***************************************************************************
5048 Display the contents of one service in human-readable form.
5049 ***************************************************************************/
5051 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
5053 if (VALID(snum)) {
5054 if (ServicePtrs[snum]->szService[0] == '\0')
5055 return;
5056 dump_a_service(ServicePtrs[snum], f);
5060 /***************************************************************************
5061 Return the number of the service with the given name, or -1 if it doesn't
5062 exist. Note that this is a DIFFERENT ANIMAL from the internal function
5063 getservicebyname()! This works ONLY if all services have been loaded, and
5064 does not copy the found service.
5065 ***************************************************************************/
5067 int lp_servicenumber(const char *pszServiceName)
5069 int iService;
5070 fstring serviceName;
5072 if (!pszServiceName) {
5073 return GLOBAL_SECTION_SNUM;
5076 for (iService = iNumServices - 1; iService >= 0; iService--) {
5077 if (VALID(iService) && ServicePtrs[iService]->szService) {
5079 * The substitution here is used to support %U is
5080 * service names
5082 fstrcpy(serviceName, ServicePtrs[iService]->szService);
5083 standard_sub_basic(get_current_username(), serviceName,sizeof(serviceName));
5084 if (strequal(serviceName, pszServiceName)) {
5085 break;
5090 if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
5091 time_t last_mod;
5093 if (!usershare_exists(iService, &last_mod)) {
5094 /* Remove the share security tdb entry for it. */
5095 delete_share_security(iService);
5096 /* Remove it from the array. */
5097 free_service_byindex(iService);
5098 /* Doesn't exist anymore. */
5099 return GLOBAL_SECTION_SNUM;
5102 /* Has it been modified ? If so delete and reload. */
5103 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
5104 /* Remove it from the array. */
5105 free_service_byindex(iService);
5106 /* and now reload it. */
5107 iService = load_usershare_service(pszServiceName);
5111 if (iService < 0) {
5112 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
5113 return GLOBAL_SECTION_SNUM;
5116 return (iService);
5119 /*******************************************************************
5120 A useful volume label function.
5121 ********************************************************************/
5123 char *volume_label(int snum)
5125 char *ret = lp_volume(snum);
5126 if (!*ret)
5127 return lp_servicename(snum);
5128 return (ret);
5132 /*******************************************************************
5133 Set the server type we will announce as via nmbd.
5134 ********************************************************************/
5136 static void set_default_server_announce_type(void)
5138 default_server_announce = 0;
5139 default_server_announce |= SV_TYPE_WORKSTATION;
5140 default_server_announce |= SV_TYPE_SERVER;
5141 default_server_announce |= SV_TYPE_SERVER_UNIX;
5143 /* note that the flag should be set only if we have a
5144 printer service but nmbd doesn't actually load the
5145 services so we can't tell --jerry */
5147 default_server_announce |= SV_TYPE_PRINTQ_SERVER;
5149 switch (lp_announce_as()) {
5150 case ANNOUNCE_AS_NT_SERVER:
5151 default_server_announce |= SV_TYPE_SERVER_NT;
5152 /* fall through... */
5153 case ANNOUNCE_AS_NT_WORKSTATION:
5154 default_server_announce |= SV_TYPE_NT;
5155 break;
5156 case ANNOUNCE_AS_WIN95:
5157 default_server_announce |= SV_TYPE_WIN95_PLUS;
5158 break;
5159 case ANNOUNCE_AS_WFW:
5160 default_server_announce |= SV_TYPE_WFW;
5161 break;
5162 default:
5163 break;
5166 switch (lp_server_role()) {
5167 case ROLE_DOMAIN_MEMBER:
5168 default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
5169 break;
5170 case ROLE_DOMAIN_PDC:
5171 default_server_announce |= SV_TYPE_DOMAIN_CTRL;
5172 break;
5173 case ROLE_DOMAIN_BDC:
5174 default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
5175 break;
5176 case ROLE_STANDALONE:
5177 default:
5178 break;
5180 if (lp_time_server())
5181 default_server_announce |= SV_TYPE_TIME_SOURCE;
5183 if (lp_host_msdfs())
5184 default_server_announce |= SV_TYPE_DFS_SERVER;
5187 /***********************************************************
5188 returns role of Samba server
5189 ************************************************************/
5191 int lp_server_role(void)
5193 return server_role;
5196 /***********************************************************
5197 If we are PDC then prefer us as DMB
5198 ************************************************************/
5200 BOOL lp_domain_master(void)
5202 if (Globals.bDomainMaster == Auto)
5203 return (lp_server_role() == ROLE_DOMAIN_PDC);
5205 return Globals.bDomainMaster;
5208 /***********************************************************
5209 If we are DMB then prefer us as LMB
5210 ************************************************************/
5212 BOOL lp_preferred_master(void)
5214 if (Globals.bPreferredMaster == Auto)
5215 return (lp_local_master() && lp_domain_master());
5217 return Globals.bPreferredMaster;
5220 /*******************************************************************
5221 Remove a service.
5222 ********************************************************************/
5224 void lp_remove_service(int snum)
5226 ServicePtrs[snum]->valid = False;
5227 invalid_services[num_invalid_services++] = snum;
5230 /*******************************************************************
5231 Copy a service.
5232 ********************************************************************/
5234 void lp_copy_service(int snum, const char *new_name)
5236 do_section(new_name);
5237 if (snum >= 0) {
5238 snum = lp_servicenumber(new_name);
5239 if (snum >= 0)
5240 lp_do_parameter(snum, "copy", lp_servicename(snum));
5245 /*******************************************************************
5246 Get the default server type we will announce as via nmbd.
5247 ********************************************************************/
5249 int lp_default_server_announce(void)
5251 return default_server_announce;
5254 /*******************************************************************
5255 Split the announce version into major and minor numbers.
5256 ********************************************************************/
5258 int lp_major_announce_version(void)
5260 static BOOL got_major = False;
5261 static int major_version = DEFAULT_MAJOR_VERSION;
5262 char *vers;
5263 char *p;
5265 if (got_major)
5266 return major_version;
5268 got_major = True;
5269 if ((vers = lp_announce_version()) == NULL)
5270 return major_version;
5272 if ((p = strchr_m(vers, '.')) == 0)
5273 return major_version;
5275 *p = '\0';
5276 major_version = atoi(vers);
5277 return major_version;
5280 int lp_minor_announce_version(void)
5282 static BOOL got_minor = False;
5283 static int minor_version = DEFAULT_MINOR_VERSION;
5284 char *vers;
5285 char *p;
5287 if (got_minor)
5288 return minor_version;
5290 got_minor = True;
5291 if ((vers = lp_announce_version()) == NULL)
5292 return minor_version;
5294 if ((p = strchr_m(vers, '.')) == 0)
5295 return minor_version;
5297 p++;
5298 minor_version = atoi(p);
5299 return minor_version;
5302 /***********************************************************
5303 Set the global name resolution order (used in smbclient).
5304 ************************************************************/
5306 void lp_set_name_resolve_order(const char *new_order)
5308 string_set(&Globals.szNameResolveOrder, new_order);
5311 const char *lp_printername(int snum)
5313 const char *ret = _lp_printername(snum);
5314 if (ret == NULL || (ret != NULL && *ret == '\0'))
5315 ret = lp_const_servicename(snum);
5317 return ret;
5321 /***********************************************************
5322 Allow daemons such as winbindd to fix their logfile name.
5323 ************************************************************/
5325 void lp_set_logfile(const char *name)
5327 string_set(&Globals.szLogFile, name);
5328 pstrcpy(debugf, name);
5331 /*******************************************************************
5332 Return the max print jobs per queue.
5333 ********************************************************************/
5335 int lp_maxprintjobs(int snum)
5337 int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
5338 if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
5339 maxjobs = PRINT_MAX_JOBID - 1;
5341 return maxjobs;
5344 const char *lp_printcapname(void)
5346 if ((Globals.szPrintcapname != NULL) &&
5347 (Globals.szPrintcapname[0] != '\0'))
5348 return Globals.szPrintcapname;
5350 if (sDefault.iPrinting == PRINT_CUPS) {
5351 #ifdef HAVE_CUPS
5352 return "cups";
5353 #else
5354 return "lpstat";
5355 #endif
5358 if (sDefault.iPrinting == PRINT_BSD)
5359 return "/etc/printcap";
5361 return PRINTCAP_NAME;
5364 /*******************************************************************
5365 Ensure we don't use sendfile if server smb signing is active.
5366 ********************************************************************/
5368 static uint32 spoolss_state;
5370 BOOL lp_disable_spoolss( void )
5372 if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
5373 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5375 return spoolss_state == SVCCTL_STOPPED ? True : False;
5378 void lp_set_spoolss_state( uint32 state )
5380 SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
5382 spoolss_state = state;
5385 uint32 lp_get_spoolss_state( void )
5387 return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
5390 /*******************************************************************
5391 Ensure we don't use sendfile if server smb signing is active.
5392 ********************************************************************/
5394 BOOL lp_use_sendfile(int snum)
5396 /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
5397 if (Protocol < PROTOCOL_NT1) {
5398 return False;
5400 return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
5403 /*******************************************************************
5404 Turn off sendfile if we find the underlying OS doesn't support it.
5405 ********************************************************************/
5407 void set_use_sendfile(int snum, BOOL val)
5409 if (LP_SNUM_OK(snum))
5410 ServicePtrs[snum]->bUseSendfile = val;
5411 else
5412 sDefault.bUseSendfile = val;
5415 /*******************************************************************
5416 Turn off storing DOS attributes if this share doesn't support it.
5417 ********************************************************************/
5419 void set_store_dos_attributes(int snum, BOOL val)
5421 if (!LP_SNUM_OK(snum))
5422 return;
5423 ServicePtrs[(snum)]->bStoreDosAttributes = val;
5426 void lp_set_mangling_method(const char *new_method)
5428 string_set(&Globals.szManglingMethod, new_method);
5431 /*******************************************************************
5432 Global state for POSIX pathname processing.
5433 ********************************************************************/
5435 static BOOL posix_pathnames;
5437 BOOL lp_posix_pathnames(void)
5439 return posix_pathnames;
5442 /*******************************************************************
5443 Change everything needed to ensure POSIX pathname processing (currently
5444 not much).
5445 ********************************************************************/
5447 void lp_set_posix_pathnames(void)
5449 posix_pathnames = True;
5452 /*******************************************************************
5453 Global state for POSIX lock processing - CIFS unix extensions.
5454 ********************************************************************/
5456 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
5458 enum brl_flavour lp_posix_cifsu_locktype(void)
5460 return posix_cifsx_locktype;
5463 /*******************************************************************
5464 ********************************************************************/
5466 void lp_set_posix_cifsx_locktype(enum brl_flavour val)
5468 posix_cifsx_locktype = val;