param/loadparm.c

説明を見る。
00001 /* 
00002    Unix SMB/CIFS implementation.
00003    Parameter loading functions
00004    Copyright (C) Karl Auer 1993-1998
00005 
00006    Largely re-written by Andrew Tridgell, September 1994
00007 
00008    Copyright (C) Simo Sorce 2001
00009    Copyright (C) Alexander Bokovoy 2002
00010    Copyright (C) Stefan (metze) Metzmacher 2002
00011    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
00012    
00013    This program is free software; you can redistribute it and/or modify
00014    it under the terms of the GNU General Public License as published by
00015    the Free Software Foundation; either version 2 of the License, or
00016    (at your option) any later version.
00017    
00018    This program is distributed in the hope that it will be useful,
00019    but WITHOUT ANY WARRANTY; without even the implied warranty of
00020    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021    GNU General Public License for more details.
00022    
00023    You should have received a copy of the GNU General Public License
00024    along with this program; if not, write to the Free Software
00025    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00026 */
00027 
00028 /*
00029  *  Load parameters.
00030  *
00031  *  This module provides suitable callback functions for the params
00032  *  module. It builds the internal table of service details which is
00033  *  then used by the rest of the server.
00034  *
00035  * To add a parameter:
00036  *
00037  * 1) add it to the global or service structure definition
00038  * 2) add it to the parm_table
00039  * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
00040  * 4) If it's a global then initialise it in init_globals. If a local
00041  *    (ie. service) parameter then initialise it in the sDefault structure
00042  *  
00043  *
00044  * Notes:
00045  *   The configuration file is processed sequentially for speed. It is NOT
00046  *   accessed randomly as happens in 'real' Windows. For this reason, there
00047  *   is a fair bit of sequence-dependent code here - ie., code which assumes
00048  *   that certain things happen before others. In particular, the code which
00049  *   happens at the boundary between sections is delicately poised, so be
00050  *   careful!
00051  *
00052  */
00053 
00054 #include "includes.h"
00055 
00056 BOOL in_client = False;         /* Not in the client by default */
00057 BOOL bLoaded = False;
00058 
00059 extern pstring user_socket_options;
00060 extern enum protocol_types Protocol;
00061 extern userdom_struct current_user_info;
00062 
00063 #ifndef GLOBAL_NAME
00064 #define GLOBAL_NAME "global"
00065 #endif
00066 
00067 #ifndef PRINTERS_NAME
00068 #define PRINTERS_NAME "printers"
00069 #endif
00070 
00071 #ifndef HOMES_NAME
00072 #define HOMES_NAME "homes"
00073 #endif
00074 
00075 /* some helpful bits */
00076 #define LP_SNUM_OK(i) (((i) >= 0) && ((i) < iNumServices) && (ServicePtrs != NULL) && ServicePtrs[(i)]->valid)
00077 #define VALID(i) (ServicePtrs != NULL && ServicePtrs[i]->valid)
00078 
00079 #define USERSHARE_VALID 1
00080 #define USERSHARE_PENDING_DELETE 2
00081 
00082 int keepalive = DEFAULT_KEEPALIVE;
00083 BOOL use_getwd_cache = True;
00084 
00085 extern int extra_time_offset;
00086 
00087 static BOOL defaults_saved = False;
00088 
00089 typedef struct _param_opt_struct param_opt_struct;
00090 struct _param_opt_struct {
00091         param_opt_struct *prev, *next;
00092         char *key;
00093         char *value;
00094         char **list;
00095 };
00096 
00097 /* 
00098  * This structure describes global (ie., server-wide) parameters.
00099  */
00100 typedef struct {
00101         char *smb_ports;
00102         char *dos_charset;
00103         char *unix_charset;
00104         char *display_charset;
00105         char *szPrintcapname;
00106         char *szAddPortCommand;
00107         char *szEnumPortsCommand;
00108         char *szAddPrinterCommand;
00109         char *szDeletePrinterCommand;
00110         char *szOs2DriverMap;
00111         char *szLockDir;
00112         char *szPidDir;
00113         char *szRootdir;
00114         char *szDefaultService;
00115         char *szGetQuota;
00116         char *szSetQuota;
00117         char *szMsgCommand;
00118         char *szServerString;
00119         char *szAutoServices;
00120         char *szPasswdProgram;
00121         char *szPasswdChat;
00122         char *szLogFile;
00123         char *szConfigFile;
00124         char *szSMBPasswdFile;
00125         char *szPrivateDir;
00126         char *szPassdbBackend;
00127         char **szPreloadModules;
00128         char *szPasswordServer;
00129         char *szSocketOptions;
00130         char *szRealm;
00131         char *szAfsUsernameMap;
00132         int iAfsTokenLifetime;
00133         char *szLogNtTokenCommand;
00134         char *szUsernameMap;
00135         char *szLogonScript;
00136         char *szLogonPath;
00137         char *szLogonDrive;
00138         char *szLogonHome;
00139         char **szWINSservers;
00140         char **szInterfaces;
00141         char *szRemoteAnnounce;
00142         char *szRemoteBrowseSync;
00143         char *szSocketAddress;
00144         char *szNISHomeMapName;
00145         char *szAnnounceVersion;        /* This is initialised in init_globals */
00146         char *szWorkgroup;
00147         char *szNetbiosName;
00148         char **szNetbiosAliases;
00149         char *szNetbiosScope;
00150         char *szNameResolveOrder;
00151         char *szPanicAction;
00152         char *szAddUserScript;
00153         char *szRenameUserScript;
00154         char *szDelUserScript;
00155         char *szAddGroupScript;
00156         char *szDelGroupScript;
00157         char *szAddUserToGroupScript;
00158         char *szDelUserFromGroupScript;
00159         char *szSetPrimaryGroupScript;
00160         char *szAddMachineScript;
00161         char *szShutdownScript;
00162         char *szAbortShutdownScript;
00163         char *szUsernameMapScript;
00164         char *szCheckPasswordScript;
00165         char *szWINSHook;
00166         char *szUtmpDir;
00167         char *szWtmpDir;
00168         BOOL bUtmp;
00169         char *szIdmapUID;
00170         char *szIdmapGID;
00171         BOOL bPassdbExpandExplicit;
00172         int AlgorithmicRidBase;
00173         char *szTemplateHomedir;
00174         char *szTemplateShell;
00175         char *szWinbindSeparator;
00176         BOOL bWinbindEnumUsers;
00177         BOOL bWinbindEnumGroups;
00178         BOOL bWinbindUseDefaultDomain;
00179         BOOL bWinbindTrustedDomainsOnly;
00180         BOOL bWinbindNestedGroups;
00181         BOOL bWinbindRefreshTickets;
00182         BOOL bWinbindOfflineLogon;
00183         BOOL bWinbindNormalizeNames;
00184         char **szIdmapDomains;
00185         char **szIdmapBackend; /* deprecated */
00186         char *szIdmapAllocBackend;
00187         char *szAddShareCommand;
00188         char *szChangeShareCommand;
00189         char *szDeleteShareCommand;
00190         char **szEventLogs;
00191         char *szGuestaccount;
00192         char *szManglingMethod;
00193         char **szServicesList;
00194         char *szUsersharePath;
00195         char *szUsershareTemplateShare;
00196         char **szUsersharePrefixAllowList;
00197         char **szUsersharePrefixDenyList;
00198         int mangle_prefix;
00199         int max_log_size;
00200         char *szLogLevel;
00201         int max_xmit;
00202         int max_mux;
00203         int max_open_files;
00204         int open_files_db_hash_size;
00205         int pwordlevel;
00206         int unamelevel;
00207         int deadtime;
00208         int maxprotocol;
00209         int minprotocol;
00210         int security;
00211         char **AuthMethods;
00212         BOOL paranoid_server_security;
00213         int maxdisksize;
00214         int lpqcachetime;
00215         int iMaxSmbdProcesses;
00216         BOOL bDisableSpoolss;
00217         int syslog;
00218         int os_level;
00219         int enhanced_browsing;
00220         int max_ttl;
00221         int max_wins_ttl;
00222         int min_wins_ttl;
00223         int lm_announce;
00224         int lm_interval;
00225         int announce_as;        /* This is initialised in init_globals */
00226         int machine_password_timeout;
00227         int map_to_guest;
00228         int oplock_break_wait_time;
00229         int winbind_cache_time;
00230         int winbind_max_idle_children;
00231         char **szWinbindNssInfo;
00232         int iLockSpinTime;
00233         char *szLdapMachineSuffix;
00234         char *szLdapUserSuffix;
00235         char *szLdapIdmapSuffix;
00236         char *szLdapGroupSuffix;
00237         int ldap_ssl;
00238         char *szLdapSuffix;
00239         char *szLdapAdminDn;
00240         int ldap_debug_level;
00241         int ldap_debug_threshold;
00242         int iAclCompat;
00243         char *szCupsServer;
00244         char *szIPrintServer;
00245         int ldap_passwd_sync; 
00246         int ldap_replication_sleep;
00247         int ldap_timeout; /* This is initialised in init_globals */
00248         int ldap_page_size;
00249         BOOL ldap_delete_dn;
00250         BOOL bMsAddPrinterWizard;
00251         BOOL bDNSproxy;
00252         BOOL bWINSsupport;
00253         BOOL bWINSproxy;
00254         BOOL bLocalMaster;
00255         BOOL bPreferredMaster;
00256         BOOL bDomainMaster;
00257         BOOL bDomainLogons;
00258         BOOL bEncryptPasswords;
00259         BOOL bUpdateEncrypt;
00260         int  clientSchannel;
00261         int  serverSchannel;
00262         BOOL bNullPasswords;
00263         BOOL bObeyPamRestrictions;
00264         BOOL bLoadPrinters;
00265         int PrintcapCacheTime;
00266         BOOL bLargeReadwrite;
00267         BOOL bReadRaw;
00268         BOOL bWriteRaw;
00269         BOOL bReadbmpx;
00270         BOOL bSyslogOnly;
00271         BOOL bBrowseList;
00272         BOOL bNISHomeMap;
00273         BOOL bTimeServer;
00274         BOOL bBindInterfacesOnly;
00275         BOOL bPamPasswordChange;
00276         BOOL bUnixPasswdSync;
00277         BOOL bPasswdChatDebug;
00278         int iPasswdChatTimeout;
00279         BOOL bTimestampLogs;
00280         BOOL bNTSmbSupport;
00281         BOOL bNTPipeSupport;
00282         BOOL bNTStatusSupport;
00283         BOOL bStatCache;
00284         int iMaxStatCacheSize;
00285         BOOL bKernelOplocks;
00286         BOOL bAllowTrustedDomains;
00287         BOOL bLanmanAuth;
00288         BOOL bNTLMAuth;
00289         BOOL bUseSpnego;
00290         BOOL bClientLanManAuth;
00291         BOOL bClientNTLMv2Auth;
00292         BOOL bClientPlaintextAuth;
00293         BOOL bClientUseSpnego;
00294         BOOL bDebugPrefixTimestamp;
00295         BOOL bDebugHiresTimestamp;
00296         BOOL bDebugPid;
00297         BOOL bDebugUid;
00298         BOOL bEnableCoreFiles;
00299         BOOL bHostMSDfs;
00300         BOOL bUseMmap;
00301         BOOL bHostnameLookups;
00302         BOOL bUnixExtensions;
00303         BOOL bDisableNetbios;
00304         BOOL bUseKerberosKeytab;
00305         BOOL bDeferSharingViolations;
00306         BOOL bEnablePrivileges;
00307         BOOL bASUSupport;
00308         BOOL bUsershareOwnerOnly;
00309         BOOL bUsershareAllowGuests;
00310         int restrict_anonymous;
00311         int name_cache_timeout;
00312         int client_signing;
00313         int server_signing;
00314         int iUsershareMaxShares;
00315         int iIdmapCacheTime;
00316         int iIdmapNegativeCacheTime;
00317 
00318         BOOL bResetOnZeroVC;
00319         param_opt_struct *param_opt;
00320 } global;
00321 
00322 static global Globals;
00323 
00324 /* 
00325  * This structure describes a single service. 
00326  */
00327 typedef struct {
00328         BOOL valid;
00329         BOOL autoloaded;
00330         int usershare;
00331         time_t usershare_last_mod;
00332         char *szService;
00333         char *szPath;
00334         char *szUsername;
00335         char **szInvalidUsers;
00336         char **szValidUsers;
00337         char **szAdminUsers;
00338         char *szCopy;
00339         char *szInclude;
00340         char *szPreExec;
00341         char *szPostExec;
00342         char *szRootPreExec;
00343         char *szRootPostExec;
00344         char *szCupsOptions;
00345         char *szPrintcommand;
00346         char *szLpqcommand;
00347         char *szLprmcommand;
00348         char *szLppausecommand;
00349         char *szLpresumecommand;
00350         char *szQueuepausecommand;
00351         char *szQueueresumecommand;
00352         char *szPrintername;
00353         char *szPrintjobUsername;
00354         char *szDontdescend;
00355         char **szHostsallow;
00356         char **szHostsdeny;
00357         char *szMagicScript;
00358         char *szMagicOutput;
00359         char *szMangledMap;
00360         char *szVetoFiles;
00361         char *szHideFiles;
00362         char *szVetoOplockFiles;
00363         char *comment;
00364         char *force_user;
00365         char *force_group;
00366         char **readlist;
00367         char **writelist;
00368         char **printer_admin;
00369         char *volume;
00370         char *fstype;
00371         char **szVfsObjects;
00372         char *szMSDfsProxy;
00373         char *szAioWriteBehind;
00374         char *szDfree;
00375         int iMinPrintSpace;
00376         int iMaxPrintJobs;
00377         int iMaxReportedPrintJobs;
00378         int iWriteCacheSize;
00379         int iCreate_mask;
00380         int iCreate_force_mode;
00381         int iSecurity_mask;
00382         int iSecurity_force_mode;
00383         int iDir_mask;
00384         int iDir_force_mode;
00385         int iDir_Security_mask;
00386         int iDir_Security_force_mode;
00387         int iMaxConnections;
00388         int iDefaultCase;
00389         int iPrinting;
00390         int iOplockContentionLimit;
00391         int iCSCPolicy;
00392         int iBlock_size;
00393         int iDfreeCacheTime;
00394         BOOL bPreexecClose;
00395         BOOL bRootpreexecClose;
00396         int  iCaseSensitive;
00397         BOOL bCasePreserve;
00398         BOOL bShortCasePreserve;
00399         BOOL bHideDotFiles;
00400         BOOL bHideSpecialFiles;
00401         BOOL bHideUnReadable;
00402         BOOL bHideUnWriteableFiles;
00403         BOOL bBrowseable;
00404         BOOL bAvailable;
00405         BOOL bRead_only;
00406         BOOL bNo_set_dir;
00407         BOOL bGuest_only;
00408         BOOL bAdministrative_share;
00409         BOOL bGuest_ok;
00410         BOOL bPrint_ok;
00411         BOOL bMap_system;
00412         BOOL bMap_hidden;
00413         BOOL bMap_archive;
00414         BOOL bStoreDosAttributes;
00415         BOOL bDmapiSupport;
00416         BOOL bLocking;
00417         int iStrictLocking;
00418         BOOL bPosixLocking;
00419         BOOL bShareModes;
00420         BOOL bOpLocks;
00421         BOOL bLevel2OpLocks;
00422         BOOL bOnlyUser;
00423         BOOL bMangledNames;
00424         BOOL bWidelinks;
00425         BOOL bSymlinks;
00426         BOOL bSyncAlways;
00427         BOOL bStrictAllocate;
00428         BOOL bStrictSync;
00429         char magic_char;
00430         BOOL *copymap;
00431         BOOL bDeleteReadonly;
00432         BOOL bFakeOplocks;
00433         BOOL bDeleteVetoFiles;
00434         BOOL bDosFilemode;
00435         BOOL bDosFiletimes;
00436         BOOL bDosFiletimeResolution;
00437         BOOL bFakeDirCreateTimes;
00438         BOOL bBlockingLocks;
00439         BOOL bInheritPerms;
00440         BOOL bInheritACLS;
00441         BOOL bInheritOwner;
00442         BOOL bMSDfsRoot;
00443         BOOL bUseClientDriver;
00444         BOOL bDefaultDevmode;
00445         BOOL bForcePrintername;
00446         BOOL bNTAclSupport;
00447         BOOL bForceUnknownAclUser;
00448         BOOL bUseSendfile;
00449         BOOL bProfileAcls;
00450         BOOL bMap_acl_inherit;
00451         BOOL bAfs_Share;
00452         BOOL bEASupport;
00453         BOOL bAclCheckPermissions;
00454         BOOL bAclMapFullControl;
00455         BOOL bAclGroupControl;
00456         BOOL bChangeNotify;
00457         BOOL bKernelChangeNotify;
00458         int iallocation_roundup_size;
00459         int iAioReadSize;
00460         int iAioWriteSize;
00461         int iMap_readonly;
00462         int iDirectoryNameCacheSize;
00463         param_opt_struct *param_opt;
00464 
00465         char dummy[3];          /* for alignment */
00466 } service;
00467 
00468 
00469 /* This is a default service used to prime a services structure */
00470 static service sDefault = {
00471         True,                   /* valid */
00472         False,                  /* not autoloaded */
00473         0,                      /* not a usershare */
00474         (time_t)0,              /* No last mod time */
00475         NULL,                   /* szService */
00476         NULL,                   /* szPath */
00477         NULL,                   /* szUsername */
00478         NULL,                   /* szInvalidUsers */
00479         NULL,                   /* szValidUsers */
00480         NULL,                   /* szAdminUsers */
00481         NULL,                   /* szCopy */
00482         NULL,                   /* szInclude */
00483         NULL,                   /* szPreExec */
00484         NULL,                   /* szPostExec */
00485         NULL,                   /* szRootPreExec */
00486         NULL,                   /* szRootPostExec */
00487         NULL,                   /* szCupsOptions */
00488         NULL,                   /* szPrintcommand */
00489         NULL,                   /* szLpqcommand */
00490         NULL,                   /* szLprmcommand */
00491         NULL,                   /* szLppausecommand */
00492         NULL,                   /* szLpresumecommand */
00493         NULL,                   /* szQueuepausecommand */
00494         NULL,                   /* szQueueresumecommand */
00495         NULL,                   /* szPrintername */
00496         NULL,                   /* szPrintjobUsername */
00497         NULL,                   /* szDontdescend */
00498         NULL,                   /* szHostsallow */
00499         NULL,                   /* szHostsdeny */
00500         NULL,                   /* szMagicScript */
00501         NULL,                   /* szMagicOutput */
00502         NULL,                   /* szMangledMap */
00503         NULL,                   /* szVetoFiles */
00504         NULL,                   /* szHideFiles */
00505         NULL,                   /* szVetoOplockFiles */
00506         NULL,                   /* comment */
00507         NULL,                   /* force user */
00508         NULL,                   /* force group */
00509         NULL,                   /* readlist */
00510         NULL,                   /* writelist */
00511         NULL,                   /* printer admin */
00512         NULL,                   /* volume */
00513         NULL,                   /* fstype */
00514         NULL,                   /* vfs objects */
00515         NULL,                   /* szMSDfsProxy */
00516         NULL,                   /* szAioWriteBehind */
00517         NULL,                   /* szDfree */
00518         0,                      /* iMinPrintSpace */
00519         1000,                   /* iMaxPrintJobs */
00520         0,                      /* iMaxReportedPrintJobs */
00521         0,                      /* iWriteCacheSize */
00522         0744,                   /* iCreate_mask */
00523         0000,                   /* iCreate_force_mode */
00524         0777,                   /* iSecurity_mask */
00525         0,                      /* iSecurity_force_mode */
00526         0755,                   /* iDir_mask */
00527         0000,                   /* iDir_force_mode */
00528         0777,                   /* iDir_Security_mask */
00529         0,                      /* iDir_Security_force_mode */
00530         0,                      /* iMaxConnections */
00531         CASE_LOWER,             /* iDefaultCase */
00532         DEFAULT_PRINTING,       /* iPrinting */
00533         2,                      /* iOplockContentionLimit */
00534         0,                      /* iCSCPolicy */
00535         1024,                   /* iBlock_size */
00536         0,                      /* iDfreeCacheTime */
00537         False,                  /* bPreexecClose */
00538         False,                  /* bRootpreexecClose */
00539         Auto,                   /* case sensitive */
00540         True,                   /* case preserve */
00541         True,                   /* short case preserve */
00542         True,                   /* bHideDotFiles */
00543         False,                  /* bHideSpecialFiles */
00544         False,                  /* bHideUnReadable */
00545         False,                  /* bHideUnWriteableFiles */
00546         True,                   /* bBrowseable */
00547         True,                   /* bAvailable */
00548         True,                   /* bRead_only */
00549         True,                   /* bNo_set_dir */
00550         False,                  /* bGuest_only */
00551         False,                  /* bAdministrative_share */
00552         False,                  /* bGuest_ok */
00553         False,                  /* bPrint_ok */
00554         False,                  /* bMap_system */
00555         False,                  /* bMap_hidden */
00556         True,                   /* bMap_archive */
00557         False,                  /* bStoreDosAttributes */
00558         False,                  /* bDmapiSupport */
00559         True,                   /* bLocking */
00560         Auto,                   /* iStrictLocking */
00561         True,                   /* bPosixLocking */
00562         True,                   /* bShareModes */
00563         True,                   /* bOpLocks */
00564         True,                   /* bLevel2OpLocks */
00565         False,                  /* bOnlyUser */
00566         True,                   /* bMangledNames */
00567         True,                   /* bWidelinks */
00568         True,                   /* bSymlinks */
00569         False,                  /* bSyncAlways */
00570         False,                  /* bStrictAllocate */
00571         False,                  /* bStrictSync */
00572         '~',                    /* magic char */
00573         NULL,                   /* copymap */
00574         False,                  /* bDeleteReadonly */
00575         False,                  /* bFakeOplocks */
00576         False,                  /* bDeleteVetoFiles */
00577         False,                  /* bDosFilemode */
00578         True,                   /* bDosFiletimes */
00579         False,                  /* bDosFiletimeResolution */
00580         False,                  /* bFakeDirCreateTimes */
00581         True,                   /* bBlockingLocks */
00582         False,                  /* bInheritPerms */
00583         False,                  /* bInheritACLS */
00584         False,                  /* bInheritOwner */
00585         False,                  /* bMSDfsRoot */
00586         False,                  /* bUseClientDriver */
00587         True,                   /* bDefaultDevmode */
00588         False,                  /* bForcePrintername */
00589         True,                   /* bNTAclSupport */
00590         False,                  /* bForceUnknownAclUser */
00591         False,                  /* bUseSendfile */
00592         False,                  /* bProfileAcls */
00593         False,                  /* bMap_acl_inherit */
00594         False,                  /* bAfs_Share */
00595         False,                  /* bEASupport */
00596         True,                   /* bAclCheckPermissions */
00597         True,                   /* bAclMapFullControl */
00598         False,                  /* bAclGroupControl */
00599         True,                   /* bChangeNotify */
00600         True,                   /* bKernelChangeNotify */
00601         SMB_ROUNDUP_ALLOCATION_SIZE,            /* iallocation_roundup_size */
00602         0,                      /* iAioReadSize */
00603         0,                      /* iAioWriteSize */
00604         MAP_READONLY_YES,       /* iMap_readonly */
00605 #ifdef BROKEN_DIRECTORY_HANDLING
00606         0,                      /* iDirectoryNameCacheSize */
00607 #else
00608         100,                    /* iDirectoryNameCacheSize */
00609 #endif
00610         NULL,                   /* Parametric options */
00611 
00612         ""                      /* dummy */
00613 };
00614 
00615 /* local variables */
00616 static service **ServicePtrs = NULL;
00617 static int iNumServices = 0;
00618 static int iServiceIndex = 0;
00619 static TDB_CONTEXT *ServiceHash;
00620 static int *invalid_services = NULL;
00621 static int num_invalid_services = 0;
00622 static BOOL bInGlobalSection = True;
00623 static BOOL bGlobalOnly = False;
00624 static int server_role;
00625 static int default_server_announce;
00626 
00627 #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
00628 
00629 /* prototypes for the special type handlers */
00630 static BOOL handle_include( int snum, const char *pszParmValue, char **ptr);
00631 static BOOL handle_copy( int snum, const char *pszParmValue, char **ptr);
00632 static BOOL handle_netbios_name( int snum, const char *pszParmValue, char **ptr);
00633 static BOOL handle_idmap_uid( int snum, const char *pszParmValue, char **ptr);
00634 static BOOL handle_idmap_gid( int snum, const char *pszParmValue, char **ptr);
00635 static BOOL handle_debug_list( int snum, const char *pszParmValue, char **ptr );
00636 static BOOL handle_workgroup( int snum, const char *pszParmValue, char **ptr );
00637 static BOOL handle_netbios_aliases( int snum, const char *pszParmValue, char **ptr );
00638 static BOOL handle_netbios_scope( int snum, const char *pszParmValue, char **ptr );
00639 static BOOL handle_charset( int snum, const char *pszParmValue, char **ptr );
00640 static BOOL handle_printing( int snum, const char *pszParmValue, char **ptr);
00641 static BOOL handle_ldap_debug_level( int snum, const char *pszParmValue, char **ptr);
00642 
00643 static void set_server_role(void);
00644 static void set_default_server_announce_type(void);
00645 static void set_allowed_client_auth(void);
00646 
00647 static const struct enum_list enum_protocol[] = {
00648         {PROTOCOL_NT1, "NT1"},
00649         {PROTOCOL_LANMAN2, "LANMAN2"},
00650         {PROTOCOL_LANMAN1, "LANMAN1"},
00651         {PROTOCOL_CORE, "CORE"},
00652         {PROTOCOL_COREPLUS, "COREPLUS"},
00653         {PROTOCOL_COREPLUS, "CORE+"},
00654         {-1, NULL}
00655 };
00656 
00657 static const struct enum_list enum_security[] = {
00658         {SEC_SHARE, "SHARE"},
00659         {SEC_USER, "USER"},
00660         {SEC_SERVER, "SERVER"},
00661         {SEC_DOMAIN, "DOMAIN"},
00662 #ifdef HAVE_ADS
00663         {SEC_ADS, "ADS"},
00664 #endif
00665         {-1, NULL}
00666 };
00667 
00668 static const struct enum_list enum_printing[] = {
00669         {PRINT_SYSV, "sysv"},
00670         {PRINT_AIX, "aix"},
00671         {PRINT_HPUX, "hpux"},
00672         {PRINT_BSD, "bsd"},
00673         {PRINT_QNX, "qnx"},
00674         {PRINT_PLP, "plp"},
00675         {PRINT_LPRNG, "lprng"},
00676         {PRINT_CUPS, "cups"},
00677         {PRINT_IPRINT, "iprint"},
00678         {PRINT_LPRNT, "nt"},
00679         {PRINT_LPROS2, "os2"},
00680 #ifdef DEVELOPER
00681         {PRINT_TEST, "test"},
00682         {PRINT_VLP, "vlp"},
00683 #endif /* DEVELOPER */
00684         {-1, NULL}
00685 };
00686 
00687 static const struct enum_list enum_ldap_ssl[] = {
00688         {LDAP_SSL_OFF, "no"},
00689         {LDAP_SSL_OFF, "No"},
00690         {LDAP_SSL_OFF, "off"},
00691         {LDAP_SSL_OFF, "Off"},
00692         {LDAP_SSL_START_TLS, "start tls"},
00693         {LDAP_SSL_START_TLS, "Start_tls"},
00694         {-1, NULL}
00695 };
00696 
00697 static const struct enum_list enum_ldap_passwd_sync[] = {
00698         {LDAP_PASSWD_SYNC_OFF, "no"},
00699         {LDAP_PASSWD_SYNC_OFF, "No"},
00700         {LDAP_PASSWD_SYNC_OFF, "off"},
00701         {LDAP_PASSWD_SYNC_OFF, "Off"},
00702         {LDAP_PASSWD_SYNC_ON, "Yes"},
00703         {LDAP_PASSWD_SYNC_ON, "yes"},
00704         {LDAP_PASSWD_SYNC_ON, "on"},
00705         {LDAP_PASSWD_SYNC_ON, "On"},
00706         {LDAP_PASSWD_SYNC_ONLY, "Only"},
00707         {LDAP_PASSWD_SYNC_ONLY, "only"},
00708         {-1, NULL}
00709 };
00710 
00711 /* Types of machine we can announce as. */
00712 #define ANNOUNCE_AS_NT_SERVER 1
00713 #define ANNOUNCE_AS_WIN95 2
00714 #define ANNOUNCE_AS_WFW 3
00715 #define ANNOUNCE_AS_NT_WORKSTATION 4
00716 
00717 static const struct enum_list enum_announce_as[] = {
00718         {ANNOUNCE_AS_NT_SERVER, "NT"},
00719         {ANNOUNCE_AS_NT_SERVER, "NT Server"},
00720         {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"},
00721         {ANNOUNCE_AS_WIN95, "win95"},
00722         {ANNOUNCE_AS_WFW, "WfW"},
00723         {-1, NULL}
00724 };
00725 
00726 static const struct enum_list enum_map_readonly[] = {
00727         {MAP_READONLY_NO, "no"},
00728         {MAP_READONLY_NO, "false"},
00729         {MAP_READONLY_NO, "0"},
00730         {MAP_READONLY_YES, "yes"},
00731         {MAP_READONLY_YES, "true"},
00732         {MAP_READONLY_YES, "1"},
00733         {MAP_READONLY_PERMISSIONS, "permissions"},
00734         {MAP_READONLY_PERMISSIONS, "perms"},
00735         {-1, NULL}
00736 };
00737 
00738 static const struct enum_list enum_case[] = {
00739         {CASE_LOWER, "lower"},
00740         {CASE_UPPER, "upper"},
00741         {-1, NULL}
00742 };
00743 
00744 static const struct enum_list enum_bool_auto[] = {
00745         {False, "No"},
00746         {False, "False"},
00747         {False, "0"},
00748         {True, "Yes"},
00749         {True, "True"},
00750         {True, "1"},
00751         {Auto, "Auto"},
00752         {-1, NULL}
00753 };
00754 
00755 /* Client-side offline caching policy types */
00756 #define CSC_POLICY_MANUAL 0
00757 #define CSC_POLICY_DOCUMENTS 1
00758 #define CSC_POLICY_PROGRAMS 2
00759 #define CSC_POLICY_DISABLE 3
00760 
00761 static const struct enum_list enum_csc_policy[] = {
00762         {CSC_POLICY_MANUAL, "manual"},
00763         {CSC_POLICY_DOCUMENTS, "documents"},
00764         {CSC_POLICY_PROGRAMS, "programs"},
00765         {CSC_POLICY_DISABLE, "disable"},
00766         {-1, NULL}
00767 };
00768 
00769 /* SMB signing types. */
00770 static const struct enum_list enum_smb_signing_vals[] = {
00771         {False, "No"},
00772         {False, "False"},
00773         {False, "0"},
00774         {False, "Off"},
00775         {False, "disabled"},
00776         {True, "Yes"},
00777         {True, "True"},
00778         {True, "1"},
00779         {True, "On"},
00780         {True, "enabled"},
00781         {Auto, "auto"},
00782         {Required, "required"},
00783         {Required, "mandatory"},
00784         {Required, "force"},
00785         {Required, "forced"},
00786         {Required, "enforced"},
00787         {-1, NULL}
00788 };
00789 
00790 /* ACL compatibility options. */
00791 static const struct enum_list enum_acl_compat_vals[] = {
00792     { ACL_COMPAT_AUTO, "auto" },
00793     { ACL_COMPAT_WINNT, "winnt" },
00794     { ACL_COMPAT_WIN2K, "win2k" },
00795     { -1, NULL}
00796 };
00797 
00798 /* 
00799    Do you want session setups at user level security with a invalid
00800    password to be rejected or allowed in as guest? WinNT rejects them
00801    but it can be a pain as it means "net view" needs to use a password
00802 
00803    You have 3 choices in the setting of map_to_guest:
00804 
00805    "Never" means session setups with an invalid password
00806    are rejected. This is the default.
00807 
00808    "Bad User" means session setups with an invalid password
00809    are rejected, unless the username does not exist, in which case it
00810    is treated as a guest login
00811 
00812    "Bad Password" means session setups with an invalid password
00813    are treated as a guest login
00814 
00815    Note that map_to_guest only has an effect in user or server
00816    level security.
00817 */
00818 
00819 static const struct enum_list enum_map_to_guest[] = {
00820         {NEVER_MAP_TO_GUEST, "Never"},
00821         {MAP_TO_GUEST_ON_BAD_USER, "Bad User"},
00822         {MAP_TO_GUEST_ON_BAD_PASSWORD, "Bad Password"},
00823         {MAP_TO_GUEST_ON_BAD_UID, "Bad Uid"},
00824         {-1, NULL}
00825 };
00826 
00827 /* Note: We do not initialise the defaults union - it is not allowed in ANSI C
00828  *
00829  * The FLAG_HIDE is explicit. Paramters set this way do NOT appear in any edit
00830  * screen in SWAT. This is used to exclude parameters as well as to squash all
00831  * parameters that have been duplicated by pseudonyms.
00832  *
00833  * NOTE: To display a parameter in BASIC view set FLAG_BASIC
00834  *       Any parameter that does NOT have FLAG_ADVANCED will not disply at all
00835  *       Set FLAG_SHARE and FLAG_PRINT to specifically display parameters in
00836  *        respective views.
00837  *
00838  * NOTE2: Handling of duplicated (synonym) paramters:
00839  *      Only the first occurance of a parameter should be enabled by FLAG_BASIC
00840  *      and/or FLAG_ADVANCED. All duplicates following the first mention should be
00841  *      set to FLAG_HIDE. ie: Make you must place the parameter that has the preferred
00842  *      name first, and all synonyms must follow it with the FLAG_HIDE attribute.
00843  */
00844 
00845 static struct parm_struct parm_table[] = {
00846         {N_("Base Options"), P_SEP, P_SEPARATOR}, 
00847 
00848         {"dos charset", P_STRING, P_GLOBAL, &Globals.dos_charset, handle_charset, NULL, FLAG_ADVANCED}, 
00849         {"unix charset", P_STRING, P_GLOBAL, &Globals.unix_charset, handle_charset, NULL, FLAG_ADVANCED}, 
00850         {"display charset", P_STRING, P_GLOBAL, &Globals.display_charset, handle_charset, NULL, FLAG_ADVANCED}, 
00851         {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
00852         {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
00853         {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_HIDE}, 
00854         {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkgroup, handle_workgroup, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
00855 #ifdef WITH_ADS
00856         {"realm", P_USTRING, P_GLOBAL, &Globals.szRealm, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
00857 #endif
00858         {"netbios name", P_USTRING, P_GLOBAL, &Globals.szNetbiosName, handle_netbios_name, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
00859         {"netbios aliases", P_LIST, P_GLOBAL, &Globals.szNetbiosAliases, handle_netbios_aliases,  NULL, FLAG_ADVANCED}, 
00860         {"netbios scope", P_USTRING, P_GLOBAL, &Globals.szNetbiosScope, handle_netbios_scope,  NULL, FLAG_ADVANCED}, 
00861         {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED }, 
00862         {"interfaces", P_LIST, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
00863         {"bind interfaces only", P_BOOL, P_GLOBAL, &Globals.bBindInterfacesOnly, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
00864 
00865         {N_("Security Options"), P_SEP, P_SEPARATOR}, 
00866 
00867         {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
00868         {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_ADVANCED}, 
00869         {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
00870         {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_ADVANCED}, 
00871         {"client schannel", P_ENUM, P_GLOBAL, &Globals.clientSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
00872         {"server schannel", P_ENUM, P_GLOBAL, &Globals.serverSchannel, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
00873         {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, FLAG_ADVANCED}, 
00874         {"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, FLAG_ADVANCED}, 
00875         {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, FLAG_ADVANCED}, 
00876         {"obey pam restrictions", P_BOOL, P_GLOBAL, &Globals.bObeyPamRestrictions, NULL, NULL, FLAG_ADVANCED}, 
00877         {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
00878         {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED}, 
00879         {"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED}, 
00880         {"passdb backend", P_STRING, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
00881         {"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED}, 
00882         {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED}, 
00883         {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE}, 
00884         {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_HIDE}, 
00885         {"guest account", P_STRING, P_GLOBAL, &Globals.szGuestaccount, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, 
00886         {"enable privileges", P_BOOL, P_GLOBAL, &Globals.bEnablePrivileges, NULL, NULL, FLAG_ADVANCED}, 
00887 
00888         {"pam password change", P_BOOL, P_GLOBAL, &Globals.bPamPasswordChange, NULL, NULL, FLAG_ADVANCED}, 
00889         {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL, NULL, FLAG_ADVANCED}, 
00890         {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL, NULL, FLAG_ADVANCED}, 
00891         {"passwd chat debug", P_BOOL, P_GLOBAL, &Globals.bPasswdChatDebug, NULL, NULL, FLAG_ADVANCED}, 
00892         {"passwd chat timeout", P_INTEGER, P_GLOBAL, &Globals.iPasswdChatTimeout, NULL, NULL, FLAG_ADVANCED}, 
00893         {"check password script", P_STRING, P_GLOBAL, &Globals.szCheckPasswordScript, NULL, NULL, FLAG_ADVANCED}, 
00894         {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL, NULL, FLAG_ADVANCED}, 
00895         {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, FLAG_ADVANCED}, 
00896         {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, FLAG_ADVANCED}, 
00897         {"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, FLAG_ADVANCED}, 
00898         {"restrict anonymous", P_INTEGER, P_GLOBAL, &Globals.restrict_anonymous, NULL, NULL, FLAG_ADVANCED}, 
00899         {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, FLAG_ADVANCED}, 
00900         {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, FLAG_ADVANCED}, 
00901         {"client NTLMv2 auth", P_BOOL, P_GLOBAL, &Globals.bClientNTLMv2Auth, NULL, NULL, FLAG_ADVANCED}, 
00902         {"client lanman auth", P_BOOL, P_GLOBAL, &Globals.bClientLanManAuth, NULL, NULL, FLAG_ADVANCED}, 
00903         {"client plaintext auth", P_BOOL, P_GLOBAL, &Globals.bClientPlaintextAuth, NULL, NULL, FLAG_ADVANCED}, 
00904 
00905         {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00906         {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, 
00907         {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_HIDE}, 
00908 
00909         {"invalid users", P_LIST, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00910         {"valid users", P_LIST, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00911         {"admin users", P_LIST, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00912         {"read list", P_LIST, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00913         {"write list", P_LIST, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00914         {"printer admin", P_LIST, P_LOCAL, &sDefault.printer_admin, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_PRINT | FLAG_DEPRECATED }, 
00915         {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
00916         {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
00917         {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_ADVANCED}, 
00918 
00919         {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE}, 
00920         {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
00921         {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
00922         {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_HIDE}, 
00923 
00924         {"acl check permissions", P_BOOL, P_LOCAL, &sDefault.bAclCheckPermissions, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
00925         {"acl group control", P_BOOL, P_LOCAL, &sDefault.bAclGroupControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE },
00926         {"acl map full control", P_BOOL, P_LOCAL, &sDefault.bAclMapFullControl, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
00927         {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00928         {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_HIDE}, 
00929         {"force create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00930         {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00931         {"force security mode", P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00932         {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00933         {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
00934         {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00935         {"directory security mask", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_mask, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00936         {"force directory security mode", P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00937         {"force unknown acl user", P_BOOL, P_LOCAL, &sDefault.bForceUnknownAclUser, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE},
00938         {"inherit permissions", P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
00939         {"inherit acls", P_BOOL, P_LOCAL, &sDefault.bInheritACLS, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
00940         {"inherit owner", P_BOOL, P_LOCAL, &sDefault.bInheritOwner, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
00941         {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
00942         {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_HIDE}, 
00943         {"administrative share", P_BOOL, P_LOCAL, &sDefault.bAdministrative_share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT},
00944 
00945         {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
00946         {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_HIDE}, 
00947 
00948         {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED}, 
00949         {"hosts allow", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
00950         {"allow hosts", P_LIST, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_HIDE}, 
00951         {"hosts deny", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL | FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
00952         {"deny hosts", P_LIST, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_HIDE}, 
00953         {"preload modules", P_LIST, P_GLOBAL, &Globals.szPreloadModules, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
00954         {"use kerberos keytab", P_BOOL, P_GLOBAL, &Globals.bUseKerberosKeytab, NULL, NULL, FLAG_ADVANCED}, 
00955 
00956         {N_("Logging Options"), P_SEP, P_SEPARATOR}, 
00957 
00958         {"log level", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_ADVANCED}, 
00959         {"debuglevel", P_STRING, P_GLOBAL, &Globals.szLogLevel, handle_debug_list, NULL, FLAG_HIDE}, 
00960         {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, FLAG_ADVANCED}, 
00961         {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, FLAG_ADVANCED}, 
00962         {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, FLAG_ADVANCED}, 
00963 
00964         {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, FLAG_ADVANCED}, 
00965         {"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED}, 
00966         {"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, FLAG_ADVANCED}, 
00967         {"debug prefix timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugPrefixTimestamp, NULL, NULL, FLAG_ADVANCED}, 
00968         {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, FLAG_ADVANCED}, 
00969         {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, FLAG_ADVANCED}, 
00970         {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, FLAG_ADVANCED}, 
00971         {"enable core files", P_BOOL, P_GLOBAL, &Globals.bEnableCoreFiles, NULL, NULL, FLAG_ADVANCED},
00972 
00973         {N_("Protocol Options"), P_SEP, P_SEPARATOR}, 
00974 
00975         {"allocation roundup size", P_INTEGER, P_LOCAL, &sDefault.iallocation_roundup_size, NULL, NULL, FLAG_ADVANCED}, 
00976         {"aio read size", P_INTEGER, P_LOCAL, &sDefault.iAioReadSize, NULL, NULL, FLAG_ADVANCED}, 
00977         {"aio write size", P_INTEGER, P_LOCAL, &sDefault.iAioWriteSize, NULL, NULL, FLAG_ADVANCED}, 
00978         {"aio write behind", P_STRING, P_LOCAL, &sDefault.szAioWriteBehind, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
00979         {"smb ports", P_STRING, P_GLOBAL, &Globals.smb_ports, NULL, NULL, FLAG_ADVANCED}, 
00980         {"large readwrite", P_BOOL, P_GLOBAL, &Globals.bLargeReadwrite, NULL, NULL, FLAG_ADVANCED}, 
00981         {"max protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, 
00982         {"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, FLAG_ADVANCED}, 
00983         {"min protocol", P_ENUM, P_GLOBAL, &Globals.minprotocol, NULL, enum_protocol, FLAG_ADVANCED}, 
00984         {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, FLAG_ADVANCED}, 
00985         {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, FLAG_ADVANCED}, 
00986         {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, FLAG_ADVANCED}, 
00987         {"disable netbios", P_BOOL, P_GLOBAL, &Globals.bDisableNetbios, NULL, NULL, FLAG_ADVANCED}, 
00988         {"reset on zero vc", P_BOOL, P_GLOBAL, &Globals.bResetOnZeroVC, NULL, NULL, FLAG_ADVANCED}, 
00989 
00990         {"acl compatibility", P_ENUM, P_GLOBAL, &Globals.iAclCompat, NULL,  enum_acl_compat_vals, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
00991         {"defer sharing violations", P_BOOL, P_GLOBAL, &Globals.bDeferSharingViolations, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL},
00992         {"ea support", P_BOOL, P_LOCAL, &sDefault.bEASupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
00993         {"nt acl support", P_BOOL, P_LOCAL, &sDefault.bNTAclSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
00994         {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, FLAG_ADVANCED}, 
00995         {"nt status support", P_BOOL, P_GLOBAL, &Globals.bNTStatusSupport, NULL, NULL, FLAG_ADVANCED}, 
00996         {"profile acls", P_BOOL, P_LOCAL, &sDefault.bProfileAcls, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
00997 
00998         {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, FLAG_ADVANCED}, 
00999         {"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as,  FLAG_ADVANCED}, 
01000         {"map acl inherit", P_BOOL, P_LOCAL, &sDefault.bMap_acl_inherit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01001         {"afs share", P_BOOL, P_LOCAL, &sDefault.bAfs_Share, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
01002         {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, FLAG_ADVANCED}, 
01003         {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, FLAG_ADVANCED}, 
01004 
01005         {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
01006         {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, FLAG_ADVANCED}, 
01007         {"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, FLAG_ADVANCED}, 
01008         {"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, FLAG_ADVANCED}, 
01009         {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, FLAG_ADVANCED}, 
01010         {"unix extensions", P_BOOL, P_GLOBAL, &Globals.bUnixExtensions, NULL, NULL, FLAG_ADVANCED}, 
01011         {"use spnego", P_BOOL, P_GLOBAL, &Globals.bUseSpnego, NULL, NULL, FLAG_ADVANCED}, 
01012         {"client signing", P_ENUM, P_GLOBAL, &Globals.client_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, 
01013         {"server signing", P_ENUM, P_GLOBAL, &Globals.server_signing, NULL, enum_smb_signing_vals, FLAG_ADVANCED}, 
01014         {"client use spnego", P_BOOL, P_GLOBAL, &Globals.bClientUseSpnego, NULL, NULL, FLAG_ADVANCED}, 
01015 
01016         {"enable asu support", P_BOOL, P_GLOBAL, &Globals.bASUSupport, NULL, NULL, FLAG_ADVANCED}, 
01017         {"svcctl list", P_LIST, P_GLOBAL, &Globals.szServicesList, NULL, NULL, FLAG_ADVANCED},
01018 
01019         {N_("Tuning Options"), P_SEP, P_SEPARATOR}, 
01020 
01021         {"block size", P_INTEGER, P_LOCAL, &sDefault.iBlock_size, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01022         {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, FLAG_ADVANCED}, 
01023         {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED}, 
01024         {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, FLAG_ADVANCED}, 
01025         {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
01026         {"directory name cache size", P_INTEGER, P_LOCAL, &sDefault.iDirectoryNameCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
01027         {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE },
01028 
01029         {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED}, 
01030         {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, FLAG_ADVANCED}, 
01031         {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01032         {"paranoid server security", P_BOOL, P_GLOBAL, &Globals.paranoid_server_security, NULL, NULL, FLAG_ADVANCED}, 
01033         {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, FLAG_ADVANCED}, 
01034         {"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, FLAG_ADVANCED}, 
01035         {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01036         {"open files database hash size", P_INTEGER, P_GLOBAL, &Globals.open_files_db_hash_size, NULL, NULL, FLAG_ADVANCED}, 
01037 
01038         {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, FLAG_ADVANCED}, 
01039         {"strict allocate", P_BOOL, P_LOCAL, &sDefault.bStrictAllocate, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01040         {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01041         {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01042         {"use mmap", P_BOOL, P_GLOBAL, &Globals.bUseMmap, NULL, NULL, FLAG_ADVANCED}, 
01043         {"use sendfile", P_BOOL, P_LOCAL, &sDefault.bUseSendfile, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01044         {"hostname lookups", P_BOOL, P_GLOBAL, &Globals.bHostnameLookups, NULL, NULL, FLAG_ADVANCED}, 
01045         {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_DEPRECATED}, 
01046 
01047         {"name cache timeout", P_INTEGER, P_GLOBAL, &Globals.name_cache_timeout, NULL, NULL, FLAG_ADVANCED}, 
01048 
01049         {N_("Printing Options"), P_SEP, P_SEPARATOR}, 
01050 
01051         {"max reported print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxReportedPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01052         {"max print jobs", P_INTEGER, P_LOCAL, &sDefault.iMaxPrintJobs, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01053         {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01054         {"printcap cache time", P_INTEGER, P_GLOBAL, &Globals.PrintcapCacheTime, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01055         {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01056         {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_HIDE}, 
01057         {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01058         {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_HIDE}, 
01059         {"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, handle_printing, enum_printing, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01060         {"cups options", P_STRING, P_LOCAL, &sDefault.szCupsOptions, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01061         {"cups server", P_STRING, P_GLOBAL, &Globals.szCupsServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01062         {"iprint server", P_STRING, P_GLOBAL, &Globals.szIPrintServer, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01063         {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01064         {"disable spoolss", P_BOOL, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01065         {"enable spoolss", P_BOOLREV, P_GLOBAL, &Globals.bDisableSpoolss, NULL, NULL, FLAG_HIDE}, 
01066         {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01067         {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01068         {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01069         {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01070         {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01071         {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT | FLAG_GLOBAL}, 
01072 
01073         {"addport command", P_STRING, P_GLOBAL, &Globals.szAddPortCommand, NULL, NULL, FLAG_ADVANCED}, 
01074         {"enumports command", P_STRING, P_GLOBAL, &Globals.szEnumPortsCommand, NULL, NULL, FLAG_ADVANCED}, 
01075         {"addprinter command", P_STRING, P_GLOBAL, &Globals.szAddPrinterCommand, NULL, NULL, FLAG_ADVANCED}, 
01076         {"deleteprinter command", P_STRING, P_GLOBAL, &Globals.szDeletePrinterCommand, NULL, NULL, FLAG_ADVANCED}, 
01077         {"show add printer wizard", P_BOOL, P_GLOBAL, &Globals.bMsAddPrinterWizard, NULL, NULL, FLAG_ADVANCED}, 
01078         {"os2 driver map", P_STRING, P_GLOBAL, &Globals.szOs2DriverMap, NULL, NULL, FLAG_ADVANCED}, 
01079 
01080         {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01081         {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_HIDE}, 
01082         {"use client driver", P_BOOL, P_LOCAL, &sDefault.bUseClientDriver, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01083         {"default devmode", P_BOOL, P_LOCAL, &sDefault.bDefaultDevmode, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01084         {"force printername", P_BOOL, P_LOCAL, &sDefault.bForcePrintername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT}, 
01085         {"printjob username", P_STRING, P_LOCAL, &sDefault.szPrintjobUsername, NULL, NULL, FLAG_ADVANCED | FLAG_PRINT},
01086 
01087         {N_("Filename Handling"), P_SEP, P_SEPARATOR}, 
01088         {"mangling method", P_STRING, P_GLOBAL, &Globals.szManglingMethod, NULL, NULL, FLAG_ADVANCED}, 
01089         {"mangle prefix", P_INTEGER, P_GLOBAL, &Globals.mangle_prefix, NULL, NULL, FLAG_ADVANCED}, 
01090 
01091         {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_ADVANCED | FLAG_SHARE}, 
01092         {"case sensitive", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01093         {"casesignames", P_ENUM, P_LOCAL, &sDefault.iCaseSensitive, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_HIDE}, 
01094         {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01095         {"short preserve case", P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01096         {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01097         {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01098         {"hide special files", P_BOOL, P_LOCAL, &sDefault.bHideSpecialFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01099         {"hide unreadable", P_BOOL, P_LOCAL, &sDefault.bHideUnReadable, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01100         {"hide unwriteable files", P_BOOL, P_LOCAL, &sDefault.bHideUnWriteableFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01101         {"delete veto files", P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01102         {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
01103         {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
01104         {"veto oplock files", P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL }, 
01105         {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01106         {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01107         {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01108         {"map readonly", P_ENUM, P_LOCAL, &sDefault.iMap_readonly, NULL, enum_map_readonly, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01109         {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01110         {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL | FLAG_DEPRECATED }, 
01111         {"max stat cache size", P_INTEGER, P_GLOBAL, &Globals.iMaxStatCacheSize, NULL, NULL, FLAG_ADVANCED}, 
01112         {"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, FLAG_ADVANCED}, 
01113         {"store dos attributes", P_BOOL, P_LOCAL, &sDefault.bStoreDosAttributes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01114         {"dmapi support", P_BOOL, P_LOCAL, &sDefault.bDmapiSupport, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL},
01115 
01116 
01117         {N_("Domain Options"), P_SEP, P_SEPARATOR}, 
01118 
01119         {"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD}, 
01120 
01121         {N_("Logon Options"), P_SEP, P_SEPARATOR}, 
01122 
01123         {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, FLAG_ADVANCED}, 
01124         {"rename user script", P_STRING, P_GLOBAL, &Globals.szRenameUserScript, NULL, NULL, FLAG_ADVANCED},
01125         {"delete user script", P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, FLAG_ADVANCED}, 
01126         {"add group script", P_STRING, P_GLOBAL, &Globals.szAddGroupScript, NULL, NULL, FLAG_ADVANCED}, 
01127         {"delete group script", P_STRING, P_GLOBAL, &Globals.szDelGroupScript, NULL, NULL, FLAG_ADVANCED}, 
01128         {"add user to group script", P_STRING, P_GLOBAL, &Globals.szAddUserToGroupScript, NULL, NULL, FLAG_ADVANCED}, 
01129         {"delete user from group script", P_STRING, P_GLOBAL, &Globals.szDelUserFromGroupScript, NULL, NULL, FLAG_ADVANCED}, 
01130         {"set primary group script", P_STRING, P_GLOBAL, &Globals.szSetPrimaryGroupScript, NULL, NULL, FLAG_ADVANCED}, 
01131         {"add machine script", P_STRING, P_GLOBAL, &Globals.szAddMachineScript, NULL, NULL, FLAG_ADVANCED}, 
01132         {"shutdown script", P_STRING, P_GLOBAL, &Globals.szShutdownScript, NULL, NULL, FLAG_ADVANCED}, 
01133         {"abort shutdown script", P_STRING, P_GLOBAL, &Globals.szAbortShutdownScript, NULL, NULL, FLAG_ADVANCED}, 
01134         {"username map script", P_STRING, P_GLOBAL, &Globals.szUsernameMapScript, NULL, NULL, FLAG_ADVANCED}, 
01135 
01136         {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_ADVANCED}, 
01137         {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_ADVANCED}, 
01138         {"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, FLAG_ADVANCED}, 
01139         {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_ADVANCED}, 
01140         {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, FLAG_ADVANCED}, 
01141 
01142         {N_("Browse Options"), P_SEP, P_SEPARATOR}, 
01143 
01144         {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, 
01145         {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, FLAG_ADVANCED}, 
01146         {"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, FLAG_ADVANCED}, 
01147         {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
01148         {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE}, 
01149         {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED}, 
01150         {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC | FLAG_ADVANCED}, 
01151         {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, FLAG_ADVANCED}, 
01152         {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
01153         {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_HIDE}, 
01154         {"enhanced browsing", P_BOOL, P_GLOBAL, &Globals.enhanced_browsing, NULL, NULL, FLAG_ADVANCED}, 
01155 
01156         {N_("WINS Options"), P_SEP, P_SEPARATOR}, 
01157 
01158         {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, FLAG_ADVANCED}, 
01159         {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, FLAG_ADVANCED}, 
01160 
01161         {"wins server", P_LIST, P_GLOBAL, &Globals.szWINSservers, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
01162         {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_WIZARD}, 
01163         {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, FLAG_ADVANCED}, 
01164 
01165         {N_("Locking Options"), P_SEP, P_SEPARATOR}, 
01166 
01167         {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01168         {"csc policy", P_ENUM, P_LOCAL, &sDefault.iCSCPolicy, NULL, enum_csc_policy, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01169         {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01170         {"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
01171         {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01172         {"lock spin time", P_INTEGER, P_GLOBAL, &Globals.iLockSpinTime, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
01173 
01174         {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01175         {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01176         {"oplock break wait time", P_INTEGER, P_GLOBAL, &Globals.oplock_break_wait_time, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL}, 
01177         {"oplock contention limit", P_INTEGER, P_LOCAL, &sDefault.iOplockContentionLimit, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01178         {"posix locking", P_BOOL, P_LOCAL, &sDefault.bPosixLocking, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01179         {"strict locking", P_ENUM, P_LOCAL, &sDefault.iStrictLocking, NULL, enum_bool_auto, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01180         {"share modes", P_BOOL, P_LOCAL,  &sDefault.bShareModes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01181 
01182         {N_("Ldap Options"), P_SEP, P_SEPARATOR}, 
01183 
01184         {"ldap admin dn", P_STRING, P_GLOBAL, &Globals.szLdapAdminDn, NULL, NULL, FLAG_ADVANCED}, 
01185         {"ldap delete dn", P_BOOL, P_GLOBAL, &Globals.ldap_delete_dn, NULL, NULL, FLAG_ADVANCED}, 
01186         {"ldap group suffix", P_STRING, P_GLOBAL, &Globals.szLdapGroupSuffix, NULL, NULL, FLAG_ADVANCED}, 
01187         {"ldap idmap suffix", P_STRING, P_GLOBAL, &Globals.szLdapIdmapSuffix, NULL, NULL, FLAG_ADVANCED}, 
01188         {"ldap machine suffix", P_STRING, P_GLOBAL, &Globals.szLdapMachineSuffix, NULL, NULL, FLAG_ADVANCED}, 
01189         {"ldap passwd sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_ADVANCED}, 
01190         {"ldap password sync", P_ENUM, P_GLOBAL, &Globals.ldap_passwd_sync, NULL, enum_ldap_passwd_sync, FLAG_HIDE}, 
01191         {"ldap replication sleep", P_INTEGER, P_GLOBAL, &Globals.ldap_replication_sleep, NULL, NULL, FLAG_ADVANCED},
01192         {"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, FLAG_ADVANCED}, 
01193         {"ldap ssl", P_ENUM, P_GLOBAL, &Globals.ldap_ssl, NULL, enum_ldap_ssl, FLAG_ADVANCED}, 
01194         {"ldap timeout", P_INTEGER, P_GLOBAL, &Globals.ldap_timeout, NULL, NULL, FLAG_ADVANCED},
01195         {"ldap page size", P_INTEGER, P_GLOBAL, &Globals.ldap_page_size, NULL, NULL, FLAG_ADVANCED},
01196         {"ldap user suffix", P_STRING, P_GLOBAL, &Globals.szLdapUserSuffix, NULL, NULL, FLAG_ADVANCED}, 
01197 
01198         {"ldap debug level", P_INTEGER, P_GLOBAL, &Globals.ldap_debug_level, handle_ldap_debug_level, NULL, FLAG_ADVANCED},
01199         {"ldap debug threshold", P_INTEGER, P_GLOBAL, &Globals.ldap_debug_threshold, NULL, NULL, FLAG_ADVANCED},
01200 
01201 
01202         {N_("Miscellaneous Options"), P_SEP, P_SEPARATOR}, 
01203         {"add share command", P_STRING, P_GLOBAL, &Globals.szAddShareCommand, NULL, NULL, FLAG_ADVANCED}, 
01204         {"change share command", P_STRING, P_GLOBAL, &Globals.szChangeShareCommand, NULL, NULL, FLAG_ADVANCED}, 
01205         {"delete share command", P_STRING, P_GLOBAL, &Globals.szDeleteShareCommand, NULL, NULL, FLAG_ADVANCED}, 
01206 
01207         {N_("EventLog Options"), P_SEP, P_SEPARATOR}, 
01208         {"eventlog list",  P_LIST, P_GLOBAL, &Globals.szEventLogs, NULL, NULL, FLAG_ADVANCED | FLAG_GLOBAL | FLAG_SHARE}, 
01209         
01210         {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE}, 
01211         {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED}, 
01212         {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, FLAG_ADVANCED}, 
01213         {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_ADVANCED}, 
01214         {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, FLAG_HIDE}, 
01215         {"pid directory", P_STRING, P_GLOBAL, &Globals.szPidDir, NULL, NULL, FLAG_ADVANCED}, 
01216 #ifdef WITH_UTMP
01217         {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, FLAG_ADVANCED}, 
01218         {"wtmp directory", P_STRING, P_GLOBAL, &Globals.szWtmpDir, NULL, NULL, FLAG_ADVANCED}, 
01219         {"utmp", P_BOOL, P_GLOBAL, &Globals.bUtmp, NULL, NULL, FLAG_ADVANCED}, 
01220 #endif
01221 
01222         {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED}, 
01223         {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, FLAG_ADVANCED}, 
01224         {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, FLAG_ADVANCED}, 
01225         {"dfree cache time", P_INTEGER, P_LOCAL, &sDefault.iDfreeCacheTime, NULL, NULL, FLAG_ADVANCED}, 
01226         {"dfree command", P_STRING, P_LOCAL, &sDefault.szDfree, NULL, NULL, FLAG_ADVANCED}, 
01227         {"get quota command", P_STRING, P_GLOBAL, &Globals.szGetQuota, NULL, NULL, FLAG_ADVANCED}, 
01228         {"set quota command", P_STRING, P_GLOBAL, &Globals.szSetQuota, NULL, NULL, FLAG_ADVANCED}, 
01229         {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL, NULL, FLAG_ADVANCED}, 
01230         {"remote browse sync", P_STRING, P_GLOBAL, &Globals.szRemoteBrowseSync, NULL, NULL, FLAG_ADVANCED}, 
01231         {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL, NULL, FLAG_ADVANCED}, 
01232         {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL, NULL, FLAG_ADVANCED}, 
01233         {"afs username map", P_STRING, P_GLOBAL, &Globals.szAfsUsernameMap, NULL, NULL, FLAG_ADVANCED}, 
01234         {"afs token lifetime", P_INTEGER, P_GLOBAL, &Globals.iAfsTokenLifetime, NULL, NULL, FLAG_ADVANCED},
01235         {"log nt token command", P_STRING, P_GLOBAL, &Globals.szLogNtTokenCommand, NULL, NULL, FLAG_ADVANCED},
01236         {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL, NULL, FLAG_ADVANCED}, 
01237         {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL, NULL, FLAG_ADVANCED}, 
01238         {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE}, 
01239 
01240         {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE}, 
01241         {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE}, 
01242         {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
01243         {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_ADVANCED}, 
01244 
01245         {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01246         {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
01247         {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
01248         {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01249         {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
01250         {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC | FLAG_ADVANCED | FLAG_SHARE | FLAG_PRINT}, 
01251         {"usershare allow guests", P_BOOL, P_GLOBAL, &Globals.bUsershareAllowGuests, NULL, NULL, FLAG_ADVANCED},
01252         {"usershare max shares", P_INTEGER, P_GLOBAL, &Globals.iUsershareMaxShares, NULL, NULL, FLAG_ADVANCED},
01253         {"usershare owner only", P_BOOL, P_GLOBAL, &Globals.bUsershareOwnerOnly, NULL, NULL, FLAG_ADVANCED}, 
01254         {"usershare path", P_STRING, P_GLOBAL, &Globals.szUsersharePath, NULL, NULL, FLAG_ADVANCED},
01255         {"usershare prefix allow list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixAllowList, NULL, NULL, FLAG_ADVANCED}, 
01256         {"usershare prefix deny list", P_LIST, P_GLOBAL, &Globals.szUsersharePrefixDenyList, NULL, NULL, FLAG_ADVANCED}, 
01257         {"usershare template share", P_STRING, P_GLOBAL, &Globals.szUsershareTemplateShare, NULL, NULL, FLAG_ADVANCED},
01258         {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE }, 
01259         {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01260         {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01261         {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01262         {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01263         {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01264         {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01265         {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01266         {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01267         {"dos filemode", P_BOOL, P_LOCAL, &sDefault.bDosFilemode, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01268         {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01269         {"dos filetime resolution", P_BOOL, P_LOCAL, &sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01270 
01271         {"fake directory create times", P_BOOL, P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL}, 
01272         {"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, FLAG_ADVANCED}, 
01273 
01274         {N_("VFS module options"), P_SEP, P_SEPARATOR}, 
01275 
01276         {"vfs objects", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01277         {"vfs object", P_LIST, P_LOCAL, &sDefault.szVfsObjects, NULL, NULL, FLAG_HIDE}, 
01278 
01279 
01280         {"msdfs root", P_BOOL, P_LOCAL, &sDefault.bMSDfsRoot, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01281         {"msdfs proxy", P_STRING, P_LOCAL, &sDefault.szMSDfsProxy, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE}, 
01282         {"host msdfs", P_BOOL, P_GLOBAL, &Globals.bHostMSDfs, NULL, NULL, FLAG_ADVANCED}, 
01283 
01284         {N_("Winbind options"), P_SEP, P_SEPARATOR}, 
01285 
01286         {"passdb expand explicit", P_BOOL, P_GLOBAL, &Globals.bPassdbExpandExplicit, NULL, NULL, FLAG_ADVANCED},
01287         {"idmap domains", P_LIST, P_GLOBAL, &Globals.szIdmapDomains, NULL, NULL, FLAG_ADVANCED}, 
01288         {"idmap backend", P_LIST, P_GLOBAL, &Globals.szIdmapBackend, NULL, NULL, FLAG_ADVANCED }, 
01289         {"idmap alloc backend", P_STRING, P_GLOBAL, &Globals.szIdmapAllocBackend, NULL, NULL, FLAG_ADVANCED}, 
01290         {"idmap cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapCacheTime, NULL, NULL, FLAG_ADVANCED}, 
01291         {"idmap negative cache time", P_INTEGER, P_GLOBAL, &Globals.iIdmapNegativeCacheTime, NULL, NULL, FLAG_ADVANCED}, 
01292         {"idmap uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_ADVANCED }, 
01293         {"winbind uid", P_STRING, P_GLOBAL, &Globals.szIdmapUID, handle_idmap_uid, NULL, FLAG_HIDE }, 
01294         {"idmap gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_ADVANCED }, 
01295         {"winbind gid", P_STRING, P_GLOBAL, &Globals.szIdmapGID, handle_idmap_gid, NULL, FLAG_HIDE }, 
01296         {"template homedir", P_STRING, P_GLOBAL, &Globals.szTemplateHomedir, NULL, NULL, FLAG_ADVANCED}, 
01297         {"template shell", P_STRING, P_GLOBAL, &Globals.szTemplateShell, NULL, NULL, FLAG_ADVANCED}, 
01298         {"winbind separator", P_STRING, P_GLOBAL, &Globals.szWinbindSeparator, NULL, NULL, FLAG_ADVANCED}, 
01299         {"winbind cache time", P_INTEGER, P_GLOBAL, &Globals.winbind_cache_time, NULL, NULL, FLAG_ADVANCED}, 
01300         {"winbind enum users", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumUsers, NULL, NULL, FLAG_ADVANCED}, 
01301         {"winbind enum groups", P_BOOL, P_GLOBAL, &Globals.bWinbindEnumGroups, NULL, NULL, FLAG_ADVANCED}, 
01302         {"winbind use default domain", P_BOOL, P_GLOBAL, &Globals.bWinbindUseDefaultDomain, NULL, NULL, FLAG_ADVANCED}, 
01303         {"winbind trusted domains only", P_BOOL, P_GLOBAL, &Globals.bWinbindTrustedDomainsOnly, NULL, NULL, FLAG_ADVANCED}, 
01304         {"winbind nested groups", P_BOOL, P_GLOBAL, &Globals.bWinbindNestedGroups, NULL, NULL, FLAG_ADVANCED}, 
01305         {"winbind nss info", P_LIST, P_GLOBAL, &Globals.szWinbindNssInfo, NULL, NULL, FLAG_ADVANCED}, 
01306         {"winbind refresh tickets", P_BOOL, P_GLOBAL, &Globals.bWinbindRefreshTickets, NULL, NULL, FLAG_ADVANCED}, 
01307         {"winbind offline logon", P_BOOL, P_GLOBAL, &Globals.bWinbindOfflineLogon, NULL, NULL, FLAG_ADVANCED},
01308         {"winbind normalize names", P_BOOL, P_GLOBAL, &Globals.bWinbindNormalizeNames, NULL, NULL, FLAG_ADVANCED},
01309 
01310         {NULL,  P_BOOL,  P_NONE,  NULL,  NULL,  NULL,  0}
01311 };
01312 
01313 /***************************************************************************
01314  Initialise the sDefault parameter structure for the printer values.
01315 ***************************************************************************/
01316 
01317 static void init_printer_values(service *pService)
01318 {
01319         /* choose defaults depending on the type of printing */
01320         switch (pService->iPrinting) {
01321                 case PRINT_BSD:
01322                 case PRINT_AIX:
01323                 case PRINT_LPRNT:
01324                 case PRINT_LPROS2:
01325                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
01326                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
01327                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
01328                         break;
01329 
01330                 case PRINT_LPRNG:
01331                 case PRINT_PLP:
01332                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
01333                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
01334                         string_set(&pService->szPrintcommand, "lpr -r -P'%p' %s");
01335                         string_set(&pService->szQueuepausecommand, "lpc stop '%p'");
01336                         string_set(&pService->szQueueresumecommand, "lpc start '%p'");
01337                         string_set(&pService->szLppausecommand, "lpc hold '%p' %j");
01338                         string_set(&pService->szLpresumecommand, "lpc release '%p' %j");
01339                         break;
01340 
01341                 case PRINT_CUPS:
01342                 case PRINT_IPRINT:
01343 #ifdef HAVE_CUPS
01344                         /* set the lpq command to contain the destination printer
01345                            name only.  This is used by cups_queue_get() */
01346                         string_set(&pService->szLpqcommand, "%p");
01347                         string_set(&pService->szLprmcommand, "");
01348                         string_set(&pService->szPrintcommand, "");
01349                         string_set(&pService->szLppausecommand, "");
01350                         string_set(&pService->szLpresumecommand, "");
01351                         string_set(&pService->szQueuepausecommand, "");
01352                         string_set(&pService->szQueueresumecommand, "");
01353 #else
01354                         string_set(&pService->szLpqcommand, "lpq -P'%p'");
01355                         string_set(&pService->szLprmcommand, "lprm -P'%p' %j");
01356                         string_set(&pService->szPrintcommand, "lpr -P'%p' %s; rm %s");
01357                         string_set(&pService->szLppausecommand, "lp -i '%p-%j' -H hold");
01358                         string_set(&pService->szLpresumecommand, "lp -i '%p-%j' -H resume");
01359                         string_set(&pService->szQueuepausecommand, "disable '%p'");
01360                         string_set(&pService->szQueueresumecommand, "enable '%p'");
01361 #endif /* HAVE_CUPS */
01362                         break;
01363 
01364                 case PRINT_SYSV:
01365                 case PRINT_HPUX:
01366                         string_set(&pService->szLpqcommand, "lpstat -o%p");
01367                         string_set(&pService->szLprmcommand, "cancel %p-%j");
01368                         string_set(&pService->szPrintcommand, "lp -c -d%p %s; rm %s");
01369                         string_set(&pService->szQueuepausecommand, "disable %p");
01370                         string_set(&pService->szQueueresumecommand, "enable %p");
01371 #ifndef HPUX
01372                         string_set(&pService->szLppausecommand, "lp -i %p-%j -H hold");
01373                         string_set(&pService->szLpresumecommand, "lp -i %p-%j -H resume");
01374 #endif /* HPUX */
01375                         break;
01376 
01377                 case PRINT_QNX:
01378                         string_set(&pService->szLpqcommand, "lpq -P%p");
01379                         string_set(&pService->szLprmcommand, "lprm -P%p %j");
01380                         string_set(&pService->szPrintcommand, "lp -r -P%p %s");
01381                         break;
01382 
01383 #ifdef DEVELOPER
01384         case PRINT_TEST:
01385         case PRINT_VLP:
01386                 string_set(&pService->szPrintcommand, "vlp print %p %s");
01387                 string_set(&pService->szLpqcommand, "vlp lpq %p");
01388                 string_set(&pService->szLprmcommand, "vlp lprm %p %j");
01389                 string_set(&pService->szLppausecommand, "vlp lppause %p %j");
01390                 string_set(&pService->szLpresumecommand, "vlp lpresum %p %j");
01391                 string_set(&pService->szQueuepausecommand, "vlp queuepause %p");
01392                 string_set(&pService->szQueueresumecommand, "vlp queueresume %p");
01393                 break;
01394 #endif /* DEVELOPER */
01395 
01396         }
01397 }
01398 
01399 /***************************************************************************
01400  Initialise the global parameter structure.
01401 ***************************************************************************/
01402 
01403 static void init_globals(BOOL first_time_only)
01404 {
01405         static BOOL done_init = False;
01406         pstring s;
01407 
01408         /* If requested to initialize only once and we've already done it... */
01409         if (first_time_only && done_init) {
01410                 /* ... then we have nothing more to do */
01411                 return;
01412         }
01413 
01414         if (!done_init) {
01415                 int i;
01416 
01417                 /* The logfile can be set before this is invoked. Free it if so. */
01418                 if (Globals.szLogFile != NULL) {
01419                         string_free(&Globals.szLogFile);
01420                         Globals.szLogFile = NULL;
01421                 }
01422 
01423                 memset((void *)&Globals, '\0', sizeof(Globals));
01424 
01425                 for (i = 0; parm_table[i].label; i++)
01426                         if ((parm_table[i].type == P_STRING ||
01427                              parm_table[i].type == P_USTRING) &&
01428                             parm_table[i].ptr)
01429                                 string_set((char **)parm_table[i].ptr, "");
01430 
01431                 string_set(&sDefault.fstype, FSTYPE_STRING);
01432                 string_set(&sDefault.szPrintjobUsername, "%U");
01433 
01434                 init_printer_values(&sDefault);
01435 
01436                 done_init = True;
01437         }
01438 
01439 
01440         DEBUG(3, ("Initialising global parameters\n"));
01441 
01442         string_set(&Globals.szSMBPasswdFile, dyn_SMB_PASSWD_FILE);
01443         string_set(&Globals.szPrivateDir, dyn_PRIVATE_DIR);
01444 
01445         /* use the new 'hash2' method by default, with a prefix of 1 */
01446         string_set(&Globals.szManglingMethod, "hash2");
01447         Globals.mangle_prefix = 1;
01448 
01449         string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
01450 
01451         /* using UTF8 by default allows us to support all chars */
01452         string_set(&Globals.unix_charset, DEFAULT_UNIX_CHARSET);
01453 
01454 #if defined(HAVE_NL_LANGINFO) && defined(CODESET)
01455         /* If the system supports nl_langinfo(), try to grab the value
01456            from the user's locale */
01457         string_set(&Globals.display_charset, "LOCALE");
01458 #else
01459         string_set(&Globals.display_charset, DEFAULT_DISPLAY_CHARSET);
01460 #endif
01461 
01462         /* Use codepage 850 as a default for the dos character set */
01463         string_set(&Globals.dos_charset, DEFAULT_DOS_CHARSET);
01464 
01465         /*
01466          * Allow the default PASSWD_CHAT to be overridden in local.h.
01467          */
01468         string_set(&Globals.szPasswdChat, DEFAULT_PASSWD_CHAT);
01469         
01470         if (!global_myname_override())
01471                 set_global_myname(myhostname());
01472         else
01473                 set_global_myname(global_myname_override());
01474         string_set(&Globals.szNetbiosName,global_myname());
01475 
01476         set_global_myworkgroup(WORKGROUP);
01477         string_set(&Globals.szWorkgroup, lp_workgroup());
01478         
01479         string_set(&Globals.szPasswdProgram, "");
01480         string_set(&Globals.szPidDir, dyn_PIDDIR);
01481         string_set(&Globals.szLockDir, dyn_LOCKDIR);
01482         string_set(&Globals.szSocketAddress, "0.0.0.0");
01483         pstrcpy(s, "Samba ");
01484         pstrcat(s, SAMBA_VERSION_STRING);
01485         string_set(&Globals.szServerString, s);
01486         slprintf(s, sizeof(s) - 1, "%d.%d", DEFAULT_MAJOR_VERSION,
01487                  DEFAULT_MINOR_VERSION);
01488         string_set(&Globals.szAnnounceVersion, s);
01489 #ifdef DEVELOPER
01490         string_set(&Globals.szPanicAction, "/bin/sleep 999999999");
01491 #endif
01492 
01493         pstrcpy(user_socket_options, DEFAULT_SOCKET_OPTIONS);
01494 
01495         string_set(&Globals.szLogonDrive, "");
01496         /* %N is the NIS auto.home server if -DAUTOHOME is used, else same as %L */
01497         string_set(&Globals.szLogonHome, "\\\\%N\\%U");
01498         string_set(&Globals.szLogonPath, "\\\\%N\\%U\\profile");
01499 
01500         string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
01501         string_set(&Globals.szPasswordServer, "*");
01502 
01503         Globals.AlgorithmicRidBase = BASE_RID;
01504 
01505         Globals.bLoadPrinters = True;
01506         Globals.PrintcapCacheTime = 750;        /* 12.5 minutes */
01507 
01508         /* Was 65535 (0xFFFF). 0x4101 matches W2K and causes major speed improvements... */
01509         /* Discovered by 2 days of pain by Don McCall @ HP :-). */
01510         Globals.max_xmit = 0x4104;
01511         Globals.max_mux = 50;   /* This is *needed* for profile support. */
01512         Globals.lpqcachetime = 30;      /* changed to handle large print servers better -- jerry */
01513         Globals.bDisableSpoolss = False;
01514         Globals.iMaxSmbdProcesses = 0;/* no limit specified */
01515         Globals.pwordlevel = 0;
01516         Globals.unamelevel = 0;
01517         Globals.deadtime = 0;
01518         Globals.bLargeReadwrite = True;
01519         Globals.max_log_size = 5000;
01520         Globals.max_open_files = MAX_OPEN_FILES;
01521         Globals.open_files_db_hash_size = SMB_OPEN_DATABASE_TDB_HASH_SIZE;
01522         Globals.maxprotocol = PROTOCOL_NT1;
01523         Globals.minprotocol = PROTOCOL_CORE;
01524         Globals.security = SEC_USER;
01525         Globals.paranoid_server_security = True;
01526         Globals.bEncryptPasswords = True;
01527         Globals.bUpdateEncrypt = False;
01528         Globals.clientSchannel = Auto;
01529         Globals.serverSchannel = Auto;
01530         Globals.bReadRaw = True;
01531         Globals.bWriteRaw = True;
01532         Globals.bReadbmpx = False;
01533         Globals.bNullPasswords = False;
01534         Globals.bObeyPamRestrictions = False;
01535         Globals.syslog = 1;
01536         Globals.bSyslogOnly = False;
01537         Globals.bTimestampLogs = True;
01538         string_set(&Globals.szLogLevel, "0");
01539         Globals.bDebugPrefixTimestamp = False;
01540         Globals.bDebugHiresTimestamp = False;
01541         Globals.bDebugPid = False;
01542         Globals.bDebugUid = False;
01543         Globals.bEnableCoreFiles = True;
01544         Globals.max_ttl = 60 * 60 * 24 * 3;     /* 3 days default. */
01545         Globals.max_wins_ttl = 60 * 60 * 24 * 6;        /* 6 days default. */
01546         Globals.min_wins_ttl = 60 * 60 * 6;     /* 6 hours default. */
01547         Globals.machine_password_timeout = 60 * 60 * 24 * 7;    /* 7 days default. */
01548         Globals.lm_announce = 2;        /* = Auto: send only if LM clients found */
01549         Globals.lm_interval = 60;
01550         Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
01551 #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
01552         Globals.bNISHomeMap = False;
01553 #ifdef WITH_NISPLUS_HOME
01554         string_set(&Globals.szNISHomeMapName, "auto_home.org_dir");
01555 #else
01556         string_set(&Globals.szNISHomeMapName, "auto.home");
01557 #endif
01558 #endif
01559         Globals.bTimeServer = False;
01560         Globals.bBindInterfacesOnly = False;
01561         Globals.bUnixPasswdSync = False;
01562         Globals.bPamPasswordChange = False;
01563         Globals.bPasswdChatDebug = False;
01564         Globals.iPasswdChatTimeout = 2; /* 2 second default. */
01565         Globals.bNTPipeSupport = True;  /* Do NT pipes by default. */
01566         Globals.bNTStatusSupport = True; /* Use NT status by default. */
01567         Globals.bStatCache = True;      /* use stat cache by default */
01568         Globals.iMaxStatCacheSize = 1024; /* one Meg by default. */
01569         Globals.restrict_anonymous = 0;
01570         Globals.bClientLanManAuth = True;       /* Do use the LanMan hash if it is available */
01571         Globals.bClientPlaintextAuth = True;    /* Do use a plaintext password if is requested by the server */
01572         Globals.bLanmanAuth = True;     /* Do use the LanMan hash if it is available */
01573         Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
01574         Globals.bClientNTLMv2Auth = False; /* Client should not use NTLMv2, as we can't tell that the server supports it. */
01575         /* Note, that we will use NTLM2 session security (which is different), if it is available */
01576 
01577         Globals.map_to_guest = 0;       /* By Default, "Never" */
01578         Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
01579         Globals.enhanced_browsing = True; 
01580         Globals.iLockSpinTime = WINDOWS_MINIMUM_LOCK_TIMEOUT_MS; /* msec. */
01581 #ifdef MMAP_BLACKLIST
01582         Globals.bUseMmap = False;
01583 #else
01584         Globals.bUseMmap = True;
01585 #endif
01586         Globals.bUnixExtensions = True;
01587         Globals.bResetOnZeroVC = False;
01588 
01589         /* hostname lookups can be very expensive and are broken on
01590            a large number of sites (tridge) */
01591         Globals.bHostnameLookups = False;
01592 
01593         string_set(&Globals.szPassdbBackend, "smbpasswd");
01594         string_set(&Globals.szLdapSuffix, "");
01595         string_set(&Globals.szLdapMachineSuffix, "");
01596         string_set(&Globals.szLdapUserSuffix, "");
01597         string_set(&Globals.szLdapGroupSuffix, "");
01598         string_set(&Globals.szLdapIdmapSuffix, "");
01599 
01600         string_set(&Globals.szLdapAdminDn, "");
01601         Globals.ldap_ssl = LDAP_SSL_ON;
01602         Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
01603         Globals.ldap_delete_dn = False;
01604         Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
01605         Globals.ldap_timeout = LDAP_CONNECT_DEFAULT_TIMEOUT;
01606         Globals.ldap_page_size = LDAP_PAGE_SIZE;
01607 
01608         Globals.ldap_debug_level = 0;
01609         Globals.ldap_debug_threshold = 10;
01610 
01611         /* This is what we tell the afs client. in reality we set the token 
01612          * to never expire, though, when this runs out the afs client will 
01613          * forget the token. Set to 0 to get NEVERDATE.*/
01614         Globals.iAfsTokenLifetime = 604800;
01615 
01616 /* these parameters are set to defaults that are more appropriate
01617    for the increasing samba install base:
01618 
01619    as a member of the workgroup, that will possibly become a
01620    _local_ master browser (lm = True).  this is opposed to a forced
01621    local master browser startup (pm = True).
01622 
01623    doesn't provide WINS server service by default (wsupp = False),
01624    and doesn't provide domain master browser services by default, either.
01625 
01626 */
01627 
01628         Globals.bMsAddPrinterWizard = True;
01629         Globals.bPreferredMaster = Auto;        /* depending on bDomainMaster */
01630         Globals.os_level = 20;
01631         Globals.bLocalMaster = True;
01632         Globals.bDomainMaster = Auto;   /* depending on bDomainLogons */
01633         Globals.bDomainLogons = False;
01634         Globals.bBrowseList = True;
01635         Globals.bWINSsupport = False;
01636         Globals.bWINSproxy = False;
01637 
01638         Globals.bDNSproxy = True;
01639 
01640         /* this just means to use them if they exist */
01641         Globals.bKernelOplocks = True;
01642 
01643         Globals.bAllowTrustedDomains = True;
01644 
01645         string_set(&Globals.szTemplateShell, "/bin/false");
01646         string_set(&Globals.szTemplateHomedir, "/home/%D/%U");
01647         string_set(&Globals.szWinbindSeparator, "\\");
01648 
01649         string_set(&Globals.szCupsServer, "");
01650         string_set(&Globals.szIPrintServer, "");
01651 
01652         Globals.winbind_cache_time = 300;       /* 5 minutes */
01653         Globals.bWinbindEnumUsers = False;
01654         Globals.bWinbindEnumGroups = False;
01655         Globals.bWinbindUseDefaultDomain = False;
01656         Globals.bWinbindTrustedDomainsOnly = False;
01657         Globals.bWinbindNestedGroups = True;
01658         Globals.szWinbindNssInfo = str_list_make("template", NULL);
01659         Globals.bWinbindRefreshTickets = False;
01660         Globals.bWinbindOfflineLogon = False;
01661 
01662         Globals.iIdmapCacheTime = 900; /* 15 minutes by default */
01663         Globals.iIdmapNegativeCacheTime = 120; /* 2 minutes by default */
01664 
01665         Globals.bPassdbExpandExplicit = False;
01666 
01667         Globals.name_cache_timeout = 660; /* In seconds */
01668 
01669         Globals.bUseSpnego = True;
01670         Globals.bClientUseSpnego = True;
01671 
01672         Globals.client_signing = Auto;
01673         Globals.server_signing = False;
01674 
01675         Globals.bDeferSharingViolations = True;
01676         string_set(&Globals.smb_ports, SMB_PORTS);
01677 
01678         Globals.bEnablePrivileges = True;
01679         Globals.bHostMSDfs        = True;
01680         Globals.bASUSupport       = False;
01681         
01682         /* User defined shares. */
01683         pstrcpy(s, dyn_LOCKDIR);
01684         pstrcat(s, "/usershares");
01685         string_set(&Globals.szUsersharePath, s);
01686         string_set(&Globals.szUsershareTemplateShare, "");
01687         Globals.iUsershareMaxShares = 0;
01688         /* By default disallow sharing of directories not owned by the sharer. */
01689         Globals.bUsershareOwnerOnly = True;
01690         /* By default disallow guest access to usershares. */
01691         Globals.bUsershareAllowGuests = False;
01692 }
01693 
01694 static TALLOC_CTX *lp_talloc;
01695 
01696 /******************************************************************* a
01697  Free up temporary memory - called from the main loop.
01698 ********************************************************************/
01699 
01700 void lp_TALLOC_FREE(void)
01701 {
01702         if (!lp_talloc)
01703                 return;
01704         TALLOC_FREE(lp_talloc);
01705         lp_talloc = NULL;
01706 }
01707 
01708 TALLOC_CTX *tmp_talloc_ctx(void)
01709 {
01710         if (lp_talloc == NULL) {
01711                 lp_talloc = talloc_init("tmp_talloc_ctx");
01712         }
01713 
01714         if (lp_talloc == NULL) {
01715                 smb_panic("Could not create temporary talloc context\n");
01716         }
01717 
01718         return lp_talloc;
01719 }
01720 
01721 /*******************************************************************
01722  Convenience routine to grab string parameters into temporary memory
01723  and run standard_sub_basic on them. The buffers can be written to by
01724  callers without affecting the source string.
01725 ********************************************************************/
01726 
01727 static char *lp_string(const char *s)
01728 {
01729         char *ret, *tmpstr;
01730 
01731         /* The follow debug is useful for tracking down memory problems
01732            especially if you have an inner loop that is calling a lp_*()
01733            function that returns a string.  Perhaps this debug should be
01734            present all the time? */
01735 
01736 #if 0
01737         DEBUG(10, ("lp_string(%s)\n", s));
01738 #endif
01739 
01740         if (!lp_talloc)
01741                 lp_talloc = talloc_init("lp_talloc");
01742 
01743         tmpstr = alloc_sub_basic(get_current_username(),
01744                                  current_user_info.domain, s);
01745         if (trim_char(tmpstr, '\"', '\"')) {
01746                 if (strchr(tmpstr,'\"') != NULL) {
01747                         SAFE_FREE(tmpstr);
01748                         tmpstr = alloc_sub_basic(get_current_username(),
01749                                                  current_user_info.domain, s);
01750                 }
01751         }
01752         ret = talloc_strdup(lp_talloc, tmpstr);
01753         SAFE_FREE(tmpstr);
01754                         
01755         return (ret);
01756 }
01757 
01758 /*
01759    In this section all the functions that are used to access the 
01760    parameters from the rest of the program are defined 
01761 */
01762 
01763 #define FN_GLOBAL_STRING(fn_name,ptr) \
01764  char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
01765 #define FN_GLOBAL_CONST_STRING(fn_name,ptr) \
01766  const char *fn_name(void) {return(*(const char **)(ptr) ? *(const char **)(ptr) : "");}
01767 #define FN_GLOBAL_LIST(fn_name,ptr) \
01768  const char **fn_name(void) {return(*(const char ***)(ptr));}
01769 #define FN_GLOBAL_BOOL(fn_name,ptr) \
01770  BOOL fn_name(void) {return(*(BOOL *)(ptr));}
01771 #define FN_GLOBAL_CHAR(fn_name,ptr) \
01772  char fn_name(void) {return(*(char *)(ptr));}
01773 #define FN_GLOBAL_INTEGER(fn_name,ptr) \
01774  int fn_name(void) {return(*(int *)(ptr));}
01775 
01776 #define FN_LOCAL_STRING(fn_name,val) \
01777  char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val));}
01778 #define FN_LOCAL_CONST_STRING(fn_name,val) \
01779  const char *fn_name(int i) {return (const char *)((LP_SNUM_OK(i) && ServicePtrs[(i)]->val) ? ServicePtrs[(i)]->val : sDefault.val);}
01780 #define FN_LOCAL_LIST(fn_name,val) \
01781  const char **fn_name(int i) {return(const char **)(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
01782 #define FN_LOCAL_BOOL(fn_name,val) \
01783  BOOL fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
01784 #define FN_LOCAL_INTEGER(fn_name,val) \
01785  int fn_name(int i) {return(LP_SNUM_OK(i)? ServicePtrs[(i)]->val : sDefault.val);}
01786 
01787 #define FN_LOCAL_PARM_BOOL(fn_name,val) \
01788  BOOL fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
01789 #define FN_LOCAL_PARM_INTEGER(fn_name,val) \
01790  int fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
01791 #define FN_LOCAL_PARM_STRING(fn_name,val) \
01792  char *fn_name(const struct share_params *p) {return(lp_string((LP_SNUM_OK(p->service) && ServicePtrs[(p->service)]->val) ? ServicePtrs[(p->service)]->val : sDefault.val));}
01793 #define FN_LOCAL_CHAR(fn_name,val) \
01794  char fn_name(const struct share_params *p) {return(LP_SNUM_OK(p->service)? ServicePtrs[(p->service)]->val : sDefault.val);}
01795 
01796 FN_GLOBAL_STRING(lp_smb_ports, &Globals.smb_ports)
01797 FN_GLOBAL_STRING(lp_dos_charset, &Globals.dos_charset)
01798 FN_GLOBAL_STRING(lp_unix_charset, &Globals.unix_charset)
01799 FN_GLOBAL_STRING(lp_display_charset, &Globals.display_charset)
01800 FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
01801 FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
01802 FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
01803 FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
01804 FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
01805 FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
01806 FN_GLOBAL_STRING(lp_addport_cmd, &Globals.szAddPortCommand)
01807 FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
01808 FN_GLOBAL_STRING(lp_addprinter_cmd, &Globals.szAddPrinterCommand)
01809 FN_GLOBAL_STRING(lp_deleteprinter_cmd, &Globals.szDeletePrinterCommand)
01810 FN_GLOBAL_STRING(lp_os2_driver_map, &Globals.szOs2DriverMap)
01811 FN_GLOBAL_STRING(lp_lockdir, &Globals.szLockDir)
01812 FN_GLOBAL_STRING(lp_piddir, &Globals.szPidDir)
01813 FN_GLOBAL_STRING(lp_mangling_method, &Globals.szManglingMethod)
01814 FN_GLOBAL_INTEGER(lp_mangle_prefix, &Globals.mangle_prefix)
01815 FN_GLOBAL_STRING(lp_utmpdir, &Globals.szUtmpDir)
01816 FN_GLOBAL_STRING(lp_wtmpdir, &Globals.szWtmpDir)
01817 FN_GLOBAL_BOOL(lp_utmp, &Globals.bUtmp)
01818 FN_GLOBAL_STRING(lp_rootdir, &Globals.szRootdir)
01819 FN_GLOBAL_STRING(lp_defaultservice, &Globals.szDefaultService)
01820 FN_GLOBAL_STRING(lp_msg_command, &Globals.szMsgCommand)
01821 FN_GLOBAL_STRING(lp_get_quota_command, &Globals.szGetQuota)
01822 FN_GLOBAL_STRING(lp_set_quota_command, &Globals.szSetQuota)
01823 FN_GLOBAL_STRING(lp_auto_services, &Globals.szAutoServices)
01824 FN_GLOBAL_STRING(lp_passwd_program, &Globals.szPasswdProgram)
01825 FN_GLOBAL_STRING(lp_passwd_chat, &Globals.szPasswdChat)
01826 FN_GLOBAL_STRING(lp_passwordserver, &Globals.szPasswordServer)
01827 FN_GLOBAL_STRING(lp_name_resolve_order, &Globals.szNameResolveOrder)
01828 FN_GLOBAL_STRING(lp_realm, &Globals.szRealm)
01829 FN_GLOBAL_CONST_STRING(lp_afs_username_map, &Globals.szAfsUsernameMap)
01830 FN_GLOBAL_INTEGER(lp_afs_token_lifetime, &Globals.iAfsTokenLifetime)
01831 FN_GLOBAL_STRING(lp_log_nt_token_command, &Globals.szLogNtTokenCommand)
01832 FN_GLOBAL_STRING(lp_username_map, &Globals.szUsernameMap)
01833 FN_GLOBAL_CONST_STRING(lp_logon_script, &Globals.szLogonScript)
01834 FN_GLOBAL_CONST_STRING(lp_logon_path, &Globals.szLogonPath)
01835 FN_GLOBAL_CONST_STRING(lp_logon_drive, &Globals.szLogonDrive)
01836 FN_GLOBAL_CONST_STRING(lp_logon_home, &Globals.szLogonHome)
01837 FN_GLOBAL_STRING(lp_remote_announce, &Globals.szRemoteAnnounce)
01838 FN_GLOBAL_STRING(lp_remote_browse_sync, &Globals.szRemoteBrowseSync)
01839 FN_GLOBAL_LIST(lp_wins_server_list, &Globals.szWINSservers)
01840 FN_GLOBAL_LIST(lp_interfaces, &Globals.szInterfaces)
01841 FN_GLOBAL_STRING(lp_socket_address, &Globals.szSocketAddress)
01842 FN_GLOBAL_STRING(lp_nis_home_map_name, &Globals.szNISHomeMapName)
01843 static FN_GLOBAL_STRING(lp_announce_version, &Globals.szAnnounceVersion)
01844 FN_GLOBAL_LIST(lp_netbios_aliases, &Globals.szNetbiosAliases)
01845 /* FN_GLOBAL_STRING(lp_passdb_backend, &Globals.szPassdbBackend)
01846  * lp_passdb_backend() should be replace by the this macro again after
01847  * some releases.
01848  * */
01849 const char *lp_passdb_backend(void)
01850 {
01851         char *delim, *quote;
01852 
01853         delim = strchr( Globals.szPassdbBackend, ' ');
01854         /* no space at all */
01855         if (delim == NULL) {
01856                 goto out;
01857         }
01858 
01859         quote = strchr(Globals.szPassdbBackend, '"');
01860         /* no quote char or non in the first part */
01861         if (quote == NULL || quote > delim) {
01862                 *delim = '\0';
01863                 goto warn;
01864         }
01865 
01866         quote = strchr(quote+1, '"');
01867         if (quote == NULL) {
01868                 DEBUG(0, ("WARNING: Your 'passdb backend' configuration is invalid due to a missing second \" char.\n"));
01869                 goto out;
01870         } else if (*(quote+1) == '\0') {
01871                 /* space, fitting quote char, and one backend only */
01872                 goto out;
01873         } else {
01874                 /* terminate string after the fitting quote char */
01875                 *(quote+1) = '\0';
01876         }
01877 
01878 warn:
01879         DEBUG(0, ("WARNING: Your 'passdb backend' configuration includes multiple backends.  This\n"
01880                 "is deprecated since Samba 3.0.23.  Please check WHATSNEW.txt or the section 'Passdb\n"
01881                 "Changes' from the ChangeNotes as part of the Samba HOWTO collection.  Only the first\n"
01882                 "backend (%s) is used.  The rest is ignored.\n", Globals.szPassdbBackend));
01883 
01884 out:
01885         return Globals.szPassdbBackend;
01886 }
01887 FN_GLOBAL_LIST(lp_preload_modules, &Globals.szPreloadModules)
01888 FN_GLOBAL_STRING(lp_panic_action, &Globals.szPanicAction)
01889 FN_GLOBAL_STRING(lp_adduser_script, &Globals.szAddUserScript)
01890 FN_GLOBAL_STRING(lp_renameuser_script, &Globals.szRenameUserScript)
01891 FN_GLOBAL_STRING(lp_deluser_script, &Globals.szDelUserScript)
01892 
01893 FN_GLOBAL_CONST_STRING(lp_guestaccount, &Globals.szGuestaccount)
01894 FN_GLOBAL_STRING(lp_addgroup_script, &Globals.szAddGroupScript)
01895 FN_GLOBAL_STRING(lp_delgroup_script, &Globals.szDelGroupScript)
01896 FN_GLOBAL_STRING(lp_addusertogroup_script, &Globals.szAddUserToGroupScript)
01897 FN_GLOBAL_STRING(lp_deluserfromgroup_script, &Globals.szDelUserFromGroupScript)
01898 FN_GLOBAL_STRING(lp_setprimarygroup_script, &Globals.szSetPrimaryGroupScript)
01899 
01900 FN_GLOBAL_STRING(lp_addmachine_script, &Globals.szAddMachineScript)
01901 
01902 FN_GLOBAL_STRING(lp_shutdown_script, &Globals.szShutdownScript)
01903 FN_GLOBAL_STRING(lp_abort_shutdown_script, &Globals.szAbortShutdownScript)
01904 FN_GLOBAL_STRING(lp_username_map_script, &Globals.szUsernameMapScript)
01905 
01906 FN_GLOBAL_STRING(lp_check_password_script, &Globals.szCheckPasswordScript)
01907 
01908 FN_GLOBAL_STRING(lp_wins_hook, &Globals.szWINSHook)
01909 FN_GLOBAL_CONST_STRING(lp_template_homedir, &Globals.szTemplateHomedir)
01910 FN_GLOBAL_CONST_STRING(lp_template_shell, &Globals.szTemplateShell)
01911 FN_GLOBAL_CONST_STRING(lp_winbind_separator, &Globals.szWinbindSeparator)
01912 FN_GLOBAL_INTEGER(lp_acl_compatibility, &Globals.iAclCompat)
01913 FN_GLOBAL_BOOL(lp_winbind_enum_users, &Globals.bWinbindEnumUsers)
01914 FN_GLOBAL_BOOL(lp_winbind_enum_groups, &Globals.bWinbindEnumGroups)
01915 FN_GLOBAL_BOOL(lp_winbind_use_default_domain, &Globals.bWinbindUseDefaultDomain)
01916 FN_GLOBAL_BOOL(lp_winbind_trusted_domains_only, &Globals.bWinbindTrustedDomainsOnly)
01917 FN_GLOBAL_BOOL(lp_winbind_nested_groups, &Globals.bWinbindNestedGroups)
01918 FN_GLOBAL_BOOL(lp_winbind_refresh_tickets, &Globals.bWinbindRefreshTickets)
01919 FN_GLOBAL_BOOL(lp_winbind_offline_logon, &Globals.bWinbindOfflineLogon)
01920 FN_GLOBAL_BOOL(lp_winbind_normalize_names, &Globals.bWinbindNormalizeNames)
01921 
01922 FN_GLOBAL_LIST(lp_idmap_domains, &Globals.szIdmapDomains)
01923 FN_GLOBAL_LIST(lp_idmap_backend, &Globals.szIdmapBackend) /* deprecated */
01924 FN_GLOBAL_STRING(lp_idmap_alloc_backend, &Globals.szIdmapAllocBackend)
01925 FN_GLOBAL_INTEGER(lp_idmap_cache_time, &Globals.iIdmapCacheTime)
01926 FN_GLOBAL_INTEGER(lp_idmap_negative_cache_time, &Globals.iIdmapNegativeCacheTime)
01927 FN_GLOBAL_BOOL(lp_passdb_expand_explicit, &Globals.bPassdbExpandExplicit)
01928 
01929 FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
01930 FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
01931 FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
01932 FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
01933 FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
01934 FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
01935 FN_GLOBAL_INTEGER(lp_ldap_timeout, &Globals.ldap_timeout)
01936 FN_GLOBAL_INTEGER(lp_ldap_page_size, &Globals.ldap_page_size)
01937 FN_GLOBAL_INTEGER(lp_ldap_debug_level, &Globals.ldap_debug_level)
01938 FN_GLOBAL_INTEGER(lp_ldap_debug_threshold, &Globals.ldap_debug_threshold)
01939 FN_GLOBAL_STRING(lp_add_share_cmd, &Globals.szAddShareCommand)
01940 FN_GLOBAL_STRING(lp_change_share_cmd, &Globals.szChangeShareCommand)
01941 FN_GLOBAL_STRING(lp_delete_share_cmd, &Globals.szDeleteShareCommand)
01942 FN_GLOBAL_STRING(lp_usershare_path, &Globals.szUsersharePath)
01943 FN_GLOBAL_LIST(lp_usershare_prefix_allow_list, &Globals.szUsersharePrefixAllowList)
01944 FN_GLOBAL_LIST(lp_usershare_prefix_deny_list, &Globals.szUsersharePrefixDenyList)
01945 
01946 FN_GLOBAL_LIST(lp_eventlog_list, &Globals.szEventLogs)
01947 
01948 FN_GLOBAL_BOOL(lp_usershare_allow_guests, &Globals.bUsershareAllowGuests)
01949 FN_GLOBAL_BOOL(lp_usershare_owner_only, &Globals.bUsershareOwnerOnly)
01950 FN_GLOBAL_BOOL(lp_disable_netbios, &Globals.bDisableNetbios)
01951 FN_GLOBAL_BOOL(lp_reset_on_zero_vc, &Globals.bResetOnZeroVC)
01952 FN_GLOBAL_BOOL(lp_ms_add_printer_wizard, &Globals.bMsAddPrinterWizard)
01953 FN_GLOBAL_BOOL(lp_dns_proxy, &Globals.bDNSproxy)
01954 FN_GLOBAL_BOOL(lp_wins_support, &Globals.bWINSsupport)
01955 FN_GLOBAL_BOOL(lp_we_are_a_wins_server, &Globals.bWINSsupport)
01956 FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
01957 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
01958 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
01959 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
01960 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
01961 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
01962 FN_GLOBAL_BOOL(lp_large_readwrite, &Globals.bLargeReadwrite)
01963 FN_GLOBAL_BOOL(lp_writeraw, &Globals.bWriteRaw)
01964 FN_GLOBAL_BOOL(lp_null_passwords, &Globals.bNullPasswords)
01965 FN_GLOBAL_BOOL(lp_obey_pam_restrictions, &Globals.bObeyPamRestrictions)
01966 FN_GLOBAL_BOOL(lp_encrypted_passwords, &Globals.bEncryptPasswords)
01967 FN_GLOBAL_BOOL(lp_update_encrypted, &Globals.bUpdateEncrypt)
01968 FN_GLOBAL_INTEGER(lp_client_schannel, &Globals.clientSchannel)
01969 FN_GLOBAL_INTEGER(lp_server_schannel, &Globals.serverSchannel)
01970 FN_GLOBAL_BOOL(lp_syslog_only, &Globals.bSyslogOnly)
01971 FN_GLOBAL_BOOL(lp_timestamp_logs, &Globals.bTimestampLogs)
01972 FN_GLOBAL_BOOL(lp_debug_prefix_timestamp, &Globals.bDebugPrefixTimestamp)
01973 FN_GLOBAL_BOOL(lp_debug_hires_timestamp, &Globals.bDebugHiresTimestamp)
01974 FN_GLOBAL_BOOL(lp_debug_pid, &Globals.bDebugPid)
01975 FN_GLOBAL_BOOL(lp_debug_uid, &Globals.bDebugUid)
01976 FN_GLOBAL_BOOL(lp_enable_core_files, &Globals.bEnableCoreFiles)
01977 FN_GLOBAL_BOOL(lp_browse_list, &Globals.bBrowseList)
01978 FN_GLOBAL_BOOL(lp_nis_home_map, &Globals.bNISHomeMap)
01979 static FN_GLOBAL_BOOL(lp_time_server, &Globals.bTimeServer)
01980 FN_GLOBAL_BOOL(lp_bind_interfaces_only, &Globals.bBindInterfacesOnly)
01981 FN_GLOBAL_BOOL(lp_pam_password_change, &Globals.bPamPasswordChange)
01982 FN_GLOBAL_BOOL(lp_unix_password_sync, &Globals.bUnixPasswdSync)
01983 FN_GLOBAL_BOOL(lp_passwd_chat_debug, &Globals.bPasswdChatDebug)
01984 FN_GLOBAL_INTEGER(lp_passwd_chat_timeout, &Globals.iPasswdChatTimeout)
01985 FN_GLOBAL_BOOL(lp_nt_pipe_support, &Globals.bNTPipeSupport)
01986 FN_GLOBAL_BOOL(lp_nt_status_support, &Globals.bNTStatusSupport)
01987 FN_GLOBAL_BOOL(lp_stat_cache, &Globals.bStatCache)
01988 FN_GLOBAL_INTEGER(lp_max_stat_cache_size, &Globals.iMaxStatCacheSize)
01989 FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
01990 FN_GLOBAL_INTEGER(lp_restrict_anonymous, &Globals.restrict_anonymous)
01991 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
01992 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
01993 FN_GLOBAL_BOOL(lp_client_plaintext_auth, &Globals.bClientPlaintextAuth)
01994 FN_GLOBAL_BOOL(lp_client_lanman_auth, &Globals.bClientLanManAuth)
01995 FN_GLOBAL_BOOL(lp_client_ntlmv2_auth, &Globals.bClientNTLMv2Auth)
01996 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
01997 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
01998 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
01999 FN_GLOBAL_BOOL(lp_use_mmap, &Globals.bUseMmap)
02000 FN_GLOBAL_BOOL(lp_unix_extensions, &Globals.bUnixExtensions)
02001 FN_GLOBAL_BOOL(lp_use_spnego, &Globals.bUseSpnego)
02002 FN_GLOBAL_BOOL(lp_client_use_spnego, &Globals.bClientUseSpnego)
02003 FN_GLOBAL_BOOL(lp_hostname_lookups, &Globals.bHostnameLookups)
02004 FN_LOCAL_PARM_BOOL(lp_change_notify, bChangeNotify)
02005 FN_LOCAL_PARM_BOOL(lp_kernel_change_notify, bKernelChangeNotify)
02006 FN_GLOBAL_BOOL(lp_use_kerberos_keytab, &Globals.bUseKerberosKeytab)
02007 FN_GLOBAL_BOOL(lp_defer_sharing_violations, &Globals.bDeferSharingViolations)
02008 FN_GLOBAL_BOOL(lp_enable_privileges, &Globals.bEnablePrivileges)
02009 FN_GLOBAL_BOOL(lp_enable_asu_support, &Globals.bASUSupport)
02010 FN_GLOBAL_INTEGER(lp_os_level, &Globals.os_level)
02011 FN_GLOBAL_INTEGER(lp_max_ttl, &Globals.max_ttl)
02012 FN_GLOBAL_INTEGER(lp_max_wins_ttl, &Globals.max_wins_ttl)
02013 FN_GLOBAL_INTEGER(lp_min_wins_ttl, &Globals.min_wins_ttl)
02014 FN_GLOBAL_INTEGER(lp_max_log_size, &Globals.max_log_size)
02015 FN_GLOBAL_INTEGER(lp_max_open_files, &Globals.max_open_files)
02016 FN_GLOBAL_INTEGER(lp_open_files_db_hash_size, &Globals.open_files_db_hash_size)
02017 FN_GLOBAL_INTEGER(lp_maxxmit, &Globals.max_xmit)
02018 FN_GLOBAL_INTEGER(lp_maxmux, &Globals.max_mux)
02019 FN_GLOBAL_INTEGER(lp_passwordlevel, &Globals.pwordlevel)
02020 FN_GLOBAL_INTEGER(lp_usernamelevel, &Globals.unamelevel)
02021 FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
02022 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
02023 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
02024 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
02025 FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
02026 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
02027 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
02028 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
02029 FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
02030 FN_GLOBAL_INTEGER(_lp_disable_spoolss, &Globals.bDisableSpoolss)
02031 FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
02032 static FN_GLOBAL_INTEGER(lp_announce_as, &Globals.announce_as)
02033 FN_GLOBAL_INTEGER(lp_lm_announce, &Globals.lm_announce)
02034 FN_GLOBAL_INTEGER(lp_lm_interval, &Globals.lm_interval)
02035 FN_GLOBAL_INTEGER(lp_machine_password_timeout, &Globals.machine_password_timeout)
02036 FN_GLOBAL_INTEGER(lp_map_to_guest, &Globals.map_to_guest)
02037 FN_GLOBAL_INTEGER(lp_oplock_break_wait_time, &Globals.oplock_break_wait_time)
02038 FN_GLOBAL_INTEGER(lp_lock_spin_time, &Globals.iLockSpinTime)
02039 FN_GLOBAL_INTEGER(lp_usershare_max_shares, &Globals.iUsershareMaxShares)
02040 
02041 FN_LOCAL_STRING(lp_preexec, szPreExec)
02042 FN_LOCAL_STRING(lp_postexec, szPostExec)
02043 FN_LOCAL_STRING(lp_rootpreexec, szRootPreExec)
02044 FN_LOCAL_STRING(lp_rootpostexec, szRootPostExec)
02045 FN_LOCAL_STRING(lp_servicename, szService)
02046 FN_LOCAL_CONST_STRING(lp_const_servicename, szService)
02047 FN_LOCAL_STRING(lp_pathname, szPath)
02048 FN_LOCAL_STRING(lp_dontdescend, szDontdescend)
02049 FN_LOCAL_STRING(lp_username, szUsername)
02050 FN_LOCAL_LIST(lp_invalid_users, szInvalidUsers)
02051 FN_LOCAL_LIST(lp_valid_users, szValidUsers)
02052 FN_LOCAL_LIST(lp_admin_users, szAdminUsers)
02053 FN_GLOBAL_LIST(lp_svcctl_list, &Globals.szServicesList)
02054 FN_LOCAL_STRING(lp_cups_options, szCupsOptions)
02055 FN_GLOBAL_STRING(lp_cups_server, &Globals.szCupsServer)
02056 FN_GLOBAL_STRING(lp_iprint_server, &Globals.szIPrintServer)
02057 FN_LOCAL_STRING(lp_printcommand, szPrintcommand)
02058 FN_LOCAL_STRING(lp_lpqcommand, szLpqcommand)
02059 FN_LOCAL_STRING(lp_lprmcommand, szLprmcommand)
02060 FN_LOCAL_STRING(lp_lppausecommand, szLppausecommand)
02061 FN_LOCAL_STRING(lp_lpresumecommand, szLpresumecommand)
02062 FN_LOCAL_STRING(lp_queuepausecommand, szQueuepausecommand)
02063 FN_LOCAL_STRING(lp_queueresumecommand, szQueueresumecommand)
02064 static FN_LOCAL_STRING(_lp_printername, szPrintername)
02065 FN_LOCAL_CONST_STRING(lp_printjob_username, szPrintjobUsername)
02066 FN_LOCAL_LIST(lp_hostsallow, szHostsallow)
02067 FN_LOCAL_LIST(lp_hostsdeny, szHostsdeny)
02068 FN_LOCAL_STRING(lp_magicscript, szMagicScript)
02069 FN_LOCAL_STRING(lp_magicoutput, szMagicOutput)
02070 FN_LOCAL_STRING(lp_comment, comment)
02071 FN_LOCAL_STRING(lp_force_user, force_user)
02072 FN_LOCAL_STRING(lp_force_group, force_group)
02073 FN_LOCAL_LIST(lp_readlist, readlist)
02074 FN_LOCAL_LIST(lp_writelist, writelist)
02075 FN_LOCAL_LIST(lp_printer_admin, printer_admin)
02076 FN_LOCAL_STRING(lp_fstype, fstype)
02077 FN_LOCAL_LIST(lp_vfs_objects, szVfsObjects)
02078 FN_LOCAL_STRING(lp_msdfs_proxy, szMSDfsProxy)
02079 static FN_LOCAL_STRING(lp_volume, volume)
02080 FN_LOCAL_PARM_STRING(lp_mangled_map, szMangledMap)
02081 FN_LOCAL_STRING(lp_veto_files, szVetoFiles)
02082 FN_LOCAL_STRING(lp_hide_files, szHideFiles)
02083 FN_LOCAL_STRING(lp_veto_oplocks, szVetoOplockFiles)
02084 FN_LOCAL_BOOL(lp_msdfs_root, bMSDfsRoot)
02085 FN_LOCAL_STRING(lp_aio_write_behind, szAioWriteBehind)
02086 FN_LOCAL_STRING(lp_dfree_command, szDfree)
02087 FN_LOCAL_BOOL(lp_autoloaded, autoloaded)
02088 FN_LOCAL_BOOL(lp_preexec_close, bPreexecClose)
02089 FN_LOCAL_BOOL(lp_rootpreexec_close, bRootpreexecClose)
02090 FN_LOCAL_INTEGER(lp_casesensitive, iCaseSensitive)
02091 FN_LOCAL_BOOL(lp_preservecase, bCasePreserve)
02092 FN_LOCAL_BOOL(lp_shortpreservecase, bShortCasePreserve)
02093 FN_LOCAL_BOOL(lp_hide_dot_files, bHideDotFiles)
02094 FN_LOCAL_BOOL(lp_hide_special_files, bHideSpecialFiles)
02095 FN_LOCAL_BOOL(lp_hideunreadable, bHideUnReadable)
02096 FN_LOCAL_BOOL(lp_hideunwriteable_files, bHideUnWriteableFiles)
02097 FN_LOCAL_BOOL(lp_browseable, bBrowseable)
02098 FN_LOCAL_BOOL(lp_readonly, bRead_only)
02099 FN_LOCAL_BOOL(lp_no_set_dir, bNo_set_dir)
02100 FN_LOCAL_BOOL(lp_guest_ok, bGuest_ok)
02101 FN_LOCAL_BOOL(lp_guest_only, bGuest_only)
02102 FN_LOCAL_BOOL(lp_administrative_share, bAdministrative_share)
02103 FN_LOCAL_BOOL(lp_print_ok, bPrint_ok)
02104 FN_LOCAL_BOOL(lp_map_hidden, bMap_hidden)
02105 FN_LOCAL_BOOL(lp_map_archive, bMap_archive)
02106 FN_LOCAL_BOOL(lp_store_dos_attributes, bStoreDosAttributes)
02107 FN_LOCAL_BOOL(lp_dmapi_support, bDmapiSupport)
02108 FN_LOCAL_PARM_BOOL(lp_locking, bLocking)
02109 FN_LOCAL_PARM_INTEGER(lp_strict_locking, iStrictLocking)
02110 FN_LOCAL_PARM_BOOL(lp_posix_locking, bPosixLocking)
02111 FN_LOCAL_BOOL(lp_share_modes, bShareModes)
02112 FN_LOCAL_BOOL(lp_oplocks, bOpLocks)
02113 FN_LOCAL_BOOL(lp_level2_oplocks, bLevel2OpLocks)
02114 FN_LOCAL_BOOL(lp_onlyuser, bOnlyUser)
02115 FN_LOCAL_PARM_BOOL(lp_manglednames, bMangledNames)
02116 FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
02117 FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
02118 FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
02119 FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
02120 FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
02121 FN_LOCAL_BOOL(lp_map_system, bMap_system)
02122 FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
02123 FN_LOCAL_BOOL(lp_fake_oplocks, bFakeOplocks)
02124 FN_LOCAL_BOOL(lp_recursive_veto_delete, bDeleteVetoFiles)
02125 FN_LOCAL_BOOL(lp_dos_filemode, bDosFilemode)
02126 FN_LOCAL_BOOL(lp_dos_filetimes, bDosFiletimes)
02127 FN_LOCAL_BOOL(lp_dos_filetime_resolution, bDosFiletimeResolution)
02128 FN_LOCAL_BOOL(lp_fake_dir_create_times, bFakeDirCreateTimes)
02129 FN_LOCAL_BOOL(lp_blocking_locks, bBlockingLocks)
02130 FN_LOCAL_BOOL(lp_inherit_perms, bInheritPerms)
02131 FN_LOCAL_BOOL(lp_inherit_acls, bInheritACLS)
02132 FN_LOCAL_BOOL(lp_inherit_owner, bInheritOwner)
02133 FN_LOCAL_BOOL(lp_use_client_driver, bUseClientDriver)
02134 FN_LOCAL_BOOL(lp_default_devmode, bDefaultDevmode)
02135 FN_LOCAL_BOOL(lp_force_printername, bForcePrintername)
02136 FN_LOCAL_BOOL(lp_nt_acl_support, bNTAclSupport)
02137 FN_LOCAL_BOOL(lp_force_unknown_acl_user, bForceUnknownAclUser)
02138 FN_LOCAL_BOOL(lp_ea_support, bEASupport)
02139 FN_LOCAL_BOOL(_lp_use_sendfile, bUseSendfile)
02140 FN_LOCAL_BOOL(lp_profile_acls, bProfileAcls)
02141 FN_LOCAL_BOOL(lp_map_acl_inherit, bMap_acl_inherit)
02142 FN_LOCAL_BOOL(lp_afs_share, bAfs_Share)
02143 FN_LOCAL_BOOL(lp_acl_check_permissions, bAclCheckPermissions)
02144 FN_LOCAL_BOOL(lp_acl_group_control, bAclGroupControl)
02145 FN_LOCAL_BOOL(lp_acl_map_full_control, bAclMapFullControl)
02146 FN_LOCAL_INTEGER(lp_create_mask, iCreate_mask)
02147 FN_LOCAL_INTEGER(lp_force_create_mode, iCreate_force_mode)
02148 FN_LOCAL_INTEGER(lp_security_mask, iSecurity_mask)
02149 FN_LOCAL_INTEGER(lp_force_security_mode, iSecurity_force_mode)
02150 FN_LOCAL_INTEGER(lp_dir_mask, iDir_mask)
02151 FN_LOCAL_INTEGER(lp_force_dir_mode, iDir_force_mode)
02152 FN_LOCAL_INTEGER(lp_dir_security_mask, iDir_Security_mask)
02153 FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
02154 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
02155 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
02156 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
02157 FN_LOCAL_INTEGER(lp_printing, iPrinting)
02158 FN_LOCAL_INTEGER(lp_max_reported_jobs, iMaxReportedPrintJobs)
02159 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
02160 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
02161 FN_LOCAL_INTEGER(lp_write_cache_size, iWriteCacheSize)
02162 FN_LOCAL_INTEGER(lp_block_size, iBlock_size)
02163 FN_LOCAL_INTEGER(lp_dfree_cache_time, iDfreeCacheTime)
02164 FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size)
02165 FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize)
02166 FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize)
02167 FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly)
02168 FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize)
02169 FN_LOCAL_CHAR(lp_magicchar, magic_char)
02170 FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time)
02171 FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo)
02172 FN_GLOBAL_INTEGER(lp_algorithmic_rid_base, &Globals.AlgorithmicRidBase)
02173 FN_GLOBAL_INTEGER(lp_name_cache_timeout, &Globals.name_cache_timeout)
02174 FN_GLOBAL_INTEGER(lp_client_signing, &Globals.client_signing)
02175 FN_GLOBAL_INTEGER(lp_server_signing, &Globals.server_signing)
02176 
02177 /* local prototypes */
02178 
02179 static int map_parameter(const char *pszParmName);
02180 static BOOL set_boolean(BOOL *pb, const char *pszParmValue);
02181 static int getservicebyname(const char *pszServiceName,
02182                             service * pserviceDest);
02183 static void copy_service(service * pserviceDest,
02184                          service * pserviceSource, BOOL *pcopymapDest);
02185 static BOOL service_ok(int iService);
02186 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue);
02187 static BOOL do_section(const char *pszSectionName);
02188 static void init_copymap(service * pservice);
02189 static BOOL hash_a_service(const char *name, int number);
02190 static void free_service_byindex(int iService);
02191 static char * canonicalize_servicename(const char *name);
02192 
02193 /* This is a helper function for parametrical options support. */
02194 /* It returns a pointer to parametrical option value if it exists or NULL otherwise */
02195 /* Actual parametrical functions are quite simple */
02196 static param_opt_struct *get_parametrics(int snum, const char *type, const char *option)
02197 {
02198         BOOL global_section = False;
02199         char* param_key;
02200         param_opt_struct *data;
02201         
02202         if (snum >= iNumServices) return NULL;
02203         
02204         if (snum < 0) { 
02205                 data = Globals.param_opt;
02206                 global_section = True;
02207         } else {
02208                 data = ServicePtrs[snum]->param_opt;
02209         }
02210     
02211         asprintf(&param_key, "%s:%s", type, option);
02212         if (!param_key) {
02213                 DEBUG(0,("asprintf failed!\n"));
02214                 return NULL;
02215         }
02216 
02217         while (data) {
02218                 if (strcmp(data->key, param_key) == 0) {
02219                         string_free(&param_key);
02220                         return data;
02221                 }
02222                 data = data->next;
02223         }
02224 
02225         if (!global_section) {
02226                 /* Try to fetch the same option but from globals */
02227                 /* but only if we are not already working with Globals */
02228                 data = Globals.param_opt;
02229                 while (data) {
02230                         if (strcmp(data->key, param_key) == 0) {
02231                                 string_free(&param_key);
02232                                 return data;
02233                         }
02234                         data = data->next;
02235                 }
02236         }
02237 
02238         string_free(&param_key);
02239         
02240         return NULL;
02241 }
02242 
02243 
02244 #define MISSING_PARAMETER(name) \
02245     DEBUG(0, ("%s(): value is NULL or empty!\n", #name))
02246 
02247 /*******************************************************************
02248 convenience routine to return int parameters.
02249 ********************************************************************/
02250 static int lp_int(const char *s)
02251 {
02252 
02253         if (!s || !*s) {
02254                 MISSING_PARAMETER(lp_int);
02255                 return (-1);
02256         }
02257 
02258         return (int)strtol(s, NULL, 0);
02259 }
02260 
02261 /*******************************************************************
02262 convenience routine to return unsigned long parameters.
02263 ********************************************************************/
02264 static unsigned long lp_ulong(const char *s)
02265 {
02266 
02267         if (!s || !*s) {
02268                 MISSING_PARAMETER(lp_ulong);
02269                 return (0);
02270         }
02271 
02272         return strtoul(s, NULL, 0);
02273 }
02274 
02275 /*******************************************************************
02276 convenience routine to return boolean parameters.
02277 ********************************************************************/
02278 static BOOL lp_bool(const char *s)
02279 {
02280         BOOL ret = False;
02281 
02282         if (!s || !*s) {
02283                 MISSING_PARAMETER(lp_bool);
02284                 return False;
02285         }
02286         
02287         if (!set_boolean(&ret,s)) {
02288                 DEBUG(0,("lp_bool(%s): value is not boolean!\n",s));
02289                 return False;
02290         }
02291 
02292         return ret;
02293 }
02294 
02295 /*******************************************************************
02296 convenience routine to return enum parameters.
02297 ********************************************************************/
02298 static int lp_enum(const char *s,const struct enum_list *_enum)
02299 {
02300         int i;
02301 
02302         if (!s || !*s || !_enum) {
02303                 MISSING_PARAMETER(lp_enum);
02304                 return (-1);
02305         }
02306         
02307         for (i=0; _enum[i].name; i++) {
02308                 if (strequal(_enum[i].name,s))
02309                         return _enum[i].value;
02310         }
02311 
02312         DEBUG(0,("lp_enum(%s,enum): value is not in enum_list!\n",s));
02313         return (-1);
02314 }
02315 
02316 #undef MISSING_PARAMETER
02317 
02318 /* DO NOT USE lp_parm_string ANYMORE!!!!
02319  * use lp_parm_const_string or lp_parm_talloc_string
02320  *
02321  * lp_parm_string is only used to let old modules find this symbol
02322  */
02323 #undef lp_parm_string
02324  char *lp_parm_string(const char *servicename, const char *type, const char *option);
02325  char *lp_parm_string(const char *servicename, const char *type, const char *option)
02326 {
02327         return lp_parm_talloc_string(lp_servicenumber(servicename), type, option, NULL);
02328 }
02329 
02330 /* Return parametric option from a given service. Type is a part of option before ':' */
02331 /* Parametric option has following syntax: 'Type: option = value' */
02332 /* the returned value is talloced in lp_talloc */
02333 char *lp_parm_talloc_string(int snum, const char *type, const char *option, const char *def)
02334 {
02335         param_opt_struct *data = get_parametrics(snum, type, option);
02336         
02337         if (data == NULL||data->value==NULL) {
02338                 if (def) {
02339                         return lp_string(def);
02340                 } else {
02341                         return NULL;
02342                 }
02343         }
02344 
02345         return lp_string(data->value);
02346 }
02347 
02348 /* Return parametric option from a given service. Type is a part of option before ':' */
02349 /* Parametric option has following syntax: 'Type: option = value' */
02350 const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def)
02351 {
02352         param_opt_struct *data = get_parametrics(snum, type, option);
02353         
02354         if (data == NULL||data->value==NULL)
02355                 return def;
02356                 
02357         return data->value;
02358 }
02359 
02360 /* Return parametric option from a given service. Type is a part of option before ':' */
02361 /* Parametric option has following syntax: 'Type: option = value' */
02362 
02363 const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def)
02364 {
02365         param_opt_struct *data = get_parametrics(snum, type, option);
02366 
02367         if (data == NULL||data->value==NULL)
02368                 return (const char **)def;
02369                 
02370         if (data->list==NULL) {
02371                 data->list = str_list_make(data->value, NULL);
02372         }
02373 
02374         return (const char **)data->list;
02375 }
02376 
02377 /* Return parametric option from a given service. Type is a part of option before ':' */
02378 /* Parametric option has following syntax: 'Type: option = value' */
02379 
02380 int lp_parm_int(int snum, const char *type, const char *option, int def)
02381 {
02382         param_opt_struct *data = get_parametrics(snum, type, option);
02383         
02384         if (data && data->value && *data->value)
02385                 return lp_int(data->value);
02386 
02387         return def;
02388 }
02389 
02390 /* Return parametric option from a given service. Type is a part of option before ':' */
02391 /* Parametric option has following syntax: 'Type: option = value' */
02392 
02393 unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def)
02394 {
02395         param_opt_struct *data = get_parametrics(snum, type, option);
02396         
02397         if (data && data->value && *data->value)
02398                 return lp_ulong(data->value);
02399 
02400         return def;
02401 }
02402 
02403 /* Return parametric option from a given service. Type is a part of option before ':' */
02404 /* Parametric option has following syntax: 'Type: option = value' */
02405 
02406 BOOL lp_parm_bool(int snum, const char *type, const char *option, BOOL def)
02407 {
02408         param_opt_struct *data = get_parametrics(snum, type, option);
02409         
02410         if (data && data->value && *data->value)
02411                 return lp_bool(data->value);
02412 
02413         return def;
02414 }
02415 
02416 /* Return parametric option from a given service. Type is a part of option before ':' */
02417 /* Parametric option has following syntax: 'Type: option = value' */
02418 
02419 int lp_parm_enum(int snum, const char *type, const char *option,
02420                  const struct enum_list *_enum, int def)
02421 {
02422         param_opt_struct *data = get_parametrics(snum, type, option);
02423         
02424         if (data && data->value && *data->value && _enum)
02425                 return lp_enum(data->value, _enum);
02426 
02427         return def;
02428 }
02429 
02430 
02431 /***************************************************************************
02432  Initialise a service to the defaults.
02433 ***************************************************************************/
02434 
02435 static void init_service(service * pservice)
02436 {
02437         memset((char *)pservice, '\0', sizeof(service));
02438         copy_service(pservice, &sDefault, NULL);
02439 }
02440 
02441 /***************************************************************************
02442  Free the dynamically allocated parts of a service struct.
02443 ***************************************************************************/
02444 
02445 static void free_service(service *pservice)
02446 {
02447         int i;
02448         param_opt_struct *data, *pdata;
02449         if (!pservice)
02450                 return;
02451 
02452         if (pservice->szService)
02453                 DEBUG(5, ("free_service: Freeing service %s\n",
02454                        pservice->szService));
02455 
02456         string_free(&pservice->szService);
02457         SAFE_FREE(pservice->copymap);
02458 
02459         for (i = 0; parm_table[i].label; i++) {
02460                 if ((parm_table[i].type == P_STRING ||
02461                      parm_table[i].type == P_USTRING) &&
02462                     parm_table[i].p_class == P_LOCAL)
02463                         string_free((char **)
02464                                     (((char *)pservice) +
02465                                      PTR_DIFF(parm_table[i].ptr, &sDefault)));
02466                 else if (parm_table[i].type == P_LIST &&
02467                          parm_table[i].p_class == P_LOCAL)
02468                              str_list_free((char ***)
02469                                             (((char *)pservice) +
02470                                              PTR_DIFF(parm_table[i].ptr, &sDefault)));
02471         }
02472 
02473         data = pservice->param_opt;
02474         if (data)
02475                 DEBUG(5,("Freeing parametrics:\n"));
02476         while (data) {
02477                 DEBUG(5,("[%s = %s]\n", data->key, data->value));
02478                 string_free(&data->key);
02479                 string_free(&data->value);
02480                 str_list_free(&data->list);
02481                 pdata = data->next;
02482                 SAFE_FREE(data);
02483                 data = pdata;
02484         }
02485 
02486         ZERO_STRUCTP(pservice);
02487 }
02488 
02489 
02490 /***************************************************************************
02491  remove a service indexed in the ServicePtrs array from the ServiceHash
02492  and free the dynamically allocated parts
02493 ***************************************************************************/
02494 
02495 static void free_service_byindex(int idx)
02496 {
02497         if ( !LP_SNUM_OK(idx) ) 
02498                 return;
02499 
02500         ServicePtrs[idx]->valid = False;
02501         invalid_services[num_invalid_services++] = idx;
02502 
02503         /* we have to cleanup the hash record */
02504 
02505         if (ServicePtrs[idx]->szService) {
02506                 char *canon_name = canonicalize_servicename( ServicePtrs[idx]->szService );
02507                 
02508                 tdb_delete_bystring(ServiceHash, canon_name );
02509         }
02510 
02511         free_service(ServicePtrs[idx]);
02512 }
02513 
02514 /***************************************************************************
02515  Add a new service to the services array initialising it with the given 
02516  service. 
02517 ***************************************************************************/
02518 
02519 static int add_a_service(const service *pservice, const char *name)
02520 {
02521         int i;
02522         service tservice;
02523         int num_to_alloc = iNumServices + 1;
02524         param_opt_struct *data, *pdata;
02525 
02526         tservice = *pservice;
02527 
02528         /* it might already exist */
02529         if (name) {
02530                 i = getservicebyname(name, NULL);
02531                 if (i >= 0) {
02532                         /* Clean all parametric options for service */
02533                         /* They will be added during parsing again */
02534                         data = ServicePtrs[i]->param_opt;
02535                         while (data) {
02536                                 string_free(&data->key);
02537                                 string_free(&data->value);
02538                                 str_list_free(&data->list);
02539                                 pdata = data->next;
02540                                 SAFE_FREE(data);
02541                                 data = pdata;
02542                         }
02543                         ServicePtrs[i]->param_opt = NULL;
02544                         return (i);
02545                 }
02546         }
02547 
02548         /* find an invalid one */
02549         i = iNumServices;
02550         if (num_invalid_services > 0) {
02551                 i = invalid_services[--num_invalid_services];
02552         }
02553 
02554         /* if not, then create one */
02555         if (i == iNumServices) {
02556                 service **tsp;
02557                 int *tinvalid;
02558                 
02559                 tsp = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(ServicePtrs, service *, num_to_alloc);
02560                 if (tsp == NULL) {
02561                         DEBUG(0,("add_a_service: failed to enlarge ServicePtrs!\n"));
02562                         return (-1);
02563                 }
02564                 ServicePtrs = tsp;
02565                 ServicePtrs[iNumServices] = SMB_MALLOC_P(service);
02566                 if (!ServicePtrs[iNumServices]) {
02567                         DEBUG(0,("add_a_service: out of memory!\n"));
02568                         return (-1);
02569                 }
02570                 iNumServices++;
02571 
02572                 /* enlarge invalid_services here for now... */
02573                 tinvalid = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(invalid_services, int,
02574                                              num_to_alloc);
02575                 if (tinvalid == NULL) {
02576                         DEBUG(0,("add_a_service: failed to enlarge "
02577                                  "invalid_services!\n"));
02578                         return (-1);
02579                 }
02580                 invalid_services = tinvalid;
02581         } else {
02582                 free_service_byindex(i);
02583         }
02584 
02585         ServicePtrs[i]->valid = True;
02586 
02587         init_service(ServicePtrs[i]);
02588         copy_service(ServicePtrs[i], &tservice, NULL);
02589         if (name)
02590                 string_set(&ServicePtrs[i]->szService, name);
02591                 
02592         DEBUG(8,("add_a_service: Creating snum = %d for %s\n", 
02593                 i, ServicePtrs[i]->szService));
02594 
02595         if (!hash_a_service(ServicePtrs[i]->szService, i)) {
02596                 return (-1);
02597         }
02598                 
02599         return (i);
02600 }
02601 
02602 /***************************************************************************
02603   Convert a string to uppercase and remove whitespaces.
02604 ***************************************************************************/
02605 
02606 static char *canonicalize_servicename(const char *src)
02607 {
02608         static fstring canon; /* is fstring large enough? */
02609 
02610         if ( !src ) {
02611                 DEBUG(0,("canonicalize_servicename: NULL source name!\n"));
02612                 return NULL;
02613         }
02614 
02615         fstrcpy( canon, src );
02616         strlower_m( canon );
02617 
02618         return canon;
02619 }
02620 
02621 /***************************************************************************
02622   Add a name/index pair for the services array to the hash table.
02623 ***************************************************************************/
02624 
02625 static BOOL hash_a_service(const char *name, int idx)
02626 {
02627         char *canon_name;
02628 
02629         if ( !ServiceHash ) {
02630                 DEBUG(10,("hash_a_service: creating tdb servicehash\n"));
02631                 ServiceHash = tdb_open("servicehash", 1031, TDB_INTERNAL, 
02632                                         (O_RDWR|O_CREAT), 0600);
02633                 if ( !ServiceHash ) {
02634                         DEBUG(0,("hash_a_service: open tdb servicehash failed!\n"));
02635                         return False;
02636                 }
02637         }
02638 
02639         DEBUG(10,("hash_a_service: hashing index %d for service name %s\n",
02640                 idx, name));
02641 
02642         if ( !(canon_name = canonicalize_servicename( name )) )
02643                 return False;
02644 
02645         tdb_store_int32(ServiceHash, canon_name, idx);
02646 
02647         return True;
02648 }
02649 
02650 /***************************************************************************
02651  Add a new home service, with the specified home directory, defaults coming 
02652  from service ifrom.
02653 ***************************************************************************/
02654 
02655 BOOL lp_add_home(const char *pszHomename, int iDefaultService, 
02656                  const char *user, const char *pszHomedir)
02657 {
02658         int i;
02659         pstring newHomedir;
02660 
02661         i = add_a_service(ServicePtrs[iDefaultService], pszHomename);
02662 
02663         if (i < 0)
02664                 return (False);
02665 
02666         if (!(*(ServicePtrs[iDefaultService]->szPath))
02667             || strequal(ServicePtrs[iDefaultService]->szPath, lp_pathname(GLOBAL_SECTION_SNUM))) {
02668                 pstrcpy(newHomedir, pszHomedir);
02669                 string_set(&ServicePtrs[i]->szPath, newHomedir);
02670         } 
02671 
02672         if (!(*(ServicePtrs[i]->comment))) {
02673                 pstring comment;
02674                 slprintf(comment, sizeof(comment) - 1,
02675                          "Home directory of %s", user);
02676                 string_set(&ServicePtrs[i]->comment, comment);
02677         }
02678 
02679         /* set the browseable flag from the global default */
02680 
02681         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
02682 
02683         ServicePtrs[i]->autoloaded = True;
02684 
02685         DEBUG(3, ("adding home's share [%s] for user '%s' at '%s'\n", pszHomename, 
02686                user, ServicePtrs[i]->szPath ));
02687         
02688         return (True);
02689 }
02690 
02691 /***************************************************************************
02692  Add a new service, based on an old one.
02693 ***************************************************************************/
02694 
02695 int lp_add_service(const char *pszService, int iDefaultService)
02696 {
02697         return (add_a_service(ServicePtrs[iDefaultService], pszService));
02698 }
02699 
02700 /***************************************************************************
02701  Add the IPC service.
02702 ***************************************************************************/
02703 
02704 static BOOL lp_add_ipc(const char *ipc_name, BOOL guest_ok)
02705 {
02706         pstring comment;
02707         int i = add_a_service(&sDefault, ipc_name);
02708 
02709         if (i < 0)
02710                 return (False);
02711 
02712         slprintf(comment, sizeof(comment) - 1,
02713                  "IPC Service (%s)", Globals.szServerString);
02714 
02715         string_set(&ServicePtrs[i]->szPath, tmpdir());
02716         string_set(&ServicePtrs[i]->szUsername, "");
02717         string_set(&ServicePtrs[i]->comment, comment);
02718         string_set(&ServicePtrs[i]->fstype, "IPC");
02719         ServicePtrs[i]->iMaxConnections = 0;
02720         ServicePtrs[i]->bAvailable = True;
02721         ServicePtrs[i]->bRead_only = True;
02722         ServicePtrs[i]->bGuest_only = False;
02723         ServicePtrs[i]->bAdministrative_share = True;
02724         ServicePtrs[i]->bGuest_ok = guest_ok;
02725         ServicePtrs[i]->bPrint_ok = False;
02726         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
02727 
02728         DEBUG(3, ("adding IPC service\n"));
02729 
02730         return (True);
02731 }
02732 
02733 /***************************************************************************
02734  Add a new printer service, with defaults coming from service iFrom.
02735 ***************************************************************************/
02736 
02737 BOOL lp_add_printer(const char *pszPrintername, int iDefaultService)
02738 {
02739         const char *comment = "From Printcap";
02740         int i = add_a_service(ServicePtrs[iDefaultService], pszPrintername);
02741 
02742         if (i < 0)
02743                 return (False);
02744 
02745         /* note that we do NOT default the availability flag to True - */
02746         /* we take it from the default service passed. This allows all */
02747         /* dynamic printers to be disabled by disabling the [printers] */
02748         /* entry (if/when the 'available' keyword is implemented!).    */
02749 
02750         /* the printer name is set to the service name. */
02751         string_set(&ServicePtrs[i]->szPrintername, pszPrintername);
02752         string_set(&ServicePtrs[i]->comment, comment);
02753 
02754         /* set the browseable flag from the gloabl default */
02755         ServicePtrs[i]->bBrowseable = sDefault.bBrowseable;
02756 
02757         /* Printers cannot be read_only. */
02758         ServicePtrs[i]->bRead_only = False;
02759         /* No share modes on printer services. */
02760         ServicePtrs[i]->bShareModes = False;
02761         /* No oplocks on printer services. */
02762         ServicePtrs[i]->bOpLocks = False;
02763         /* Printer services must be printable. */
02764         ServicePtrs[i]->bPrint_ok = True;
02765         
02766         DEBUG(3, ("adding printer service %s\n", pszPrintername));
02767 
02768         return (True);
02769 }
02770 
02771 /***************************************************************************
02772  Map a parameter's string representation to something we can use. 
02773  Returns False if the parameter string is not recognised, else TRUE.
02774 ***************************************************************************/
02775 
02776 static int map_parameter(const char *pszParmName)
02777 {
02778         int iIndex;
02779 
02780         if (*pszParmName == '-')
02781                 return (-1);
02782 
02783         for (iIndex = 0; parm_table[iIndex].label; iIndex++)
02784                 if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
02785                         return (iIndex);
02786 
02787         /* Warn only if it isn't parametric option */
02788         if (strchr(pszParmName, ':') == NULL)
02789                 DEBUG(0, ("Unknown parameter encountered: \"%s\"\n", pszParmName));
02790         /* We do return 'fail' for parametric options as well because they are
02791            stored in different storage
02792          */
02793         return (-1);
02794 }
02795 
02796 /***************************************************************************
02797  Show all parameter's name, type, [values,] and flags.
02798 ***************************************************************************/
02799 
02800 void show_parameter_list(void)
02801 {
02802         int classIndex, parmIndex, enumIndex, flagIndex;
02803         BOOL hadFlag;
02804         const char *section_names[] = { "local", "global", NULL};
02805         const char *type[] = { "P_BOOL", "P_BOOLREV", "P_CHAR", "P_INTEGER",
02806                 "P_OCTAL", "P_LIST", "P_STRING", "P_USTRING", "P_GSTRING",
02807                 "P_UGSTRING", "P_ENUM", "P_SEP"};
02808         unsigned flags[] = { FLAG_BASIC, FLAG_SHARE, FLAG_PRINT, FLAG_GLOBAL,
02809                 FLAG_WIZARD, FLAG_ADVANCED, FLAG_DEVELOPER, FLAG_DEPRECATED,
02810                 FLAG_HIDE, FLAG_DOS_STRING};
02811         const char *flag_names[] = { "FLAG_BASIC", "FLAG_SHARE", "FLAG_PRINT",
02812                 "FLAG_GLOBAL", "FLAG_WIZARD", "FLAG_ADVANCED", "FLAG_DEVELOPER",
02813                 "FLAG_DEPRECATED", "FLAG_HIDE", "FLAG_DOS_STRING", NULL};
02814 
02815         for ( classIndex=0; section_names[classIndex]; classIndex++) {
02816                 printf("[%s]\n", section_names[classIndex]);
02817                 for (parmIndex = 0; parm_table[parmIndex].label; parmIndex++) {
02818                         if (parm_table[parmIndex].p_class == classIndex) {
02819                                 printf("%s=%s", 
02820                                         parm_table[parmIndex].label,
02821                                         type[parm_table[parmIndex].type]);
02822                                 switch (parm_table[parmIndex].type) {
02823                                 case P_ENUM:
02824                                         printf(",");
02825                                         for (enumIndex=0; parm_table[parmIndex].enum_list[enumIndex].name; enumIndex++)
02826                                                 printf("%s%s",
02827                                                         enumIndex ? "|" : "",
02828                                                         parm_table[parmIndex].enum_list[enumIndex].name);
02829                                         break;
02830                                 default:
02831                                         break;
02832                                 }
02833                                 printf(",");
02834                                 hadFlag = False;
02835                                 for ( flagIndex=0; flag_names[flagIndex]; flagIndex++ ) {
02836                                         if (parm_table[parmIndex].flags & flags[flagIndex]) {
02837                                                 printf("%s%s",
02838                                                         hadFlag ? "|" : "",
02839                                                         flag_names[flagIndex]);
02840                                                 hadFlag = True;
02841                                         }
02842                                 }
02843                                 printf("\n");
02844                         }
02845                 }
02846         }
02847 }
02848 
02849 /***************************************************************************
02850  Set a boolean variable from the text value stored in the passed string.
02851  Returns True in success, False if the passed string does not correctly 
02852  represent a boolean.
02853 ***************************************************************************/
02854 
02855 static BOOL set_boolean(BOOL *pb, const char *pszParmValue)
02856 {
02857         BOOL bRetval;
02858 
02859         bRetval = True;
02860         if (strwicmp(pszParmValue, "yes") == 0 ||
02861             strwicmp(pszParmValue, "true") == 0 ||
02862             strwicmp(pszParmValue, "1") == 0)
02863                 *pb = True;
02864         else if (strwicmp(pszParmValue, "no") == 0 ||
02865                     strwicmp(pszParmValue, "False") == 0 ||
02866                     strwicmp(pszParmValue, "0") == 0)
02867                 *pb = False;
02868         else {
02869                 DEBUG(0,
02870                       ("ERROR: Badly formed boolean in configuration file: \"%s\".\n",
02871                        pszParmValue));
02872                 bRetval = False;
02873         }
02874         return (bRetval);
02875 }
02876 
02877 /***************************************************************************
02878 Find a service by name. Otherwise works like get_service.
02879 ***************************************************************************/
02880 
02881 static int getservicebyname(const char *pszServiceName, service * pserviceDest)
02882 {
02883         int iService = -1;
02884         char *canon_name;
02885 
02886         if (ServiceHash != NULL) {
02887                 if ( !(canon_name = canonicalize_servicename( pszServiceName )) )
02888                         return -1;
02889 
02890                 iService = tdb_fetch_int32(ServiceHash, canon_name );
02891 
02892                 if (LP_SNUM_OK(iService)) {
02893                         if (pserviceDest != NULL) {
02894                                 copy_service(pserviceDest, ServicePtrs[iService], NULL);
02895                         }
02896                 } else {
02897                         iService = -1;
02898                 }
02899         }
02900 
02901         return (iService);
02902 }
02903 
02904 /***************************************************************************
02905  Copy a service structure to another.
02906  If pcopymapDest is NULL then copy all fields
02907 ***************************************************************************/
02908 
02909 static void copy_service(service * pserviceDest, service * pserviceSource, BOOL *pcopymapDest)
02910 {
02911         int i;
02912         BOOL bcopyall = (pcopymapDest == NULL);
02913         param_opt_struct *data, *pdata, *paramo;
02914         BOOL not_added;
02915 
02916         for (i = 0; parm_table[i].label; i++)
02917                 if (parm_table[i].ptr && parm_table[i].p_class == P_LOCAL &&
02918                     (bcopyall || pcopymapDest[i])) {
02919                         void *def_ptr = parm_table[i].ptr;
02920                         void *src_ptr =
02921                                 ((char *)pserviceSource) + PTR_DIFF(def_ptr,
02922                                                                     &sDefault);
02923                         void *dest_ptr =
02924                                 ((char *)pserviceDest) + PTR_DIFF(def_ptr,
02925                                                                   &sDefault);
02926 
02927                         switch (parm_table[i].type) {
02928                                 case P_BOOL:
02929                                 case P_BOOLREV:
02930                                         *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
02931                                         break;
02932 
02933                                 case P_INTEGER:
02934                                 case P_ENUM:
02935                                 case P_OCTAL:
02936                                         *(int *)dest_ptr = *(int *)src_ptr;
02937                                         break;
02938 
02939                                 case P_CHAR:
02940                                         *(char *)dest_ptr = *(char *)src_ptr;
02941                                         break;
02942 
02943                                 case P_STRING:
02944                                         string_set((char **)dest_ptr,
02945                                                    *(char **)src_ptr);
02946                                         break;
02947 
02948                                 case P_USTRING:
02949                                         string_set((char **)dest_ptr,
02950                                                    *(char **)src_ptr);
02951                                         strupper_m(*(char **)dest_ptr);
02952                                         break;
02953                                 case P_LIST:
02954                                         str_list_free((char ***)dest_ptr);
02955                                         str_list_copy((char ***)dest_ptr, *(const char ***)src_ptr);
02956                                         break;
02957                                 default:
02958                                         break;
02959                         }
02960                 }
02961 
02962         if (bcopyall) {
02963                 init_copymap(pserviceDest);
02964                 if (pserviceSource->copymap)
02965                         memcpy((void *)pserviceDest->copymap,
02966                                (void *)pserviceSource->copymap,
02967                                sizeof(BOOL) * NUMPARAMETERS);
02968         }
02969         
02970         data = pserviceSource->param_opt;
02971         while (data) {
02972                 not_added = True;
02973                 pdata = pserviceDest->param_opt;
02974                 /* Traverse destination */
02975                 while (pdata) {
02976                         /* If we already have same option, override it */
02977                         if (strcmp(pdata->key, data->key) == 0) {
02978                                 string_free(&pdata->value);
02979                                 str_list_free(&data->list);
02980                                 pdata->value = SMB_STRDUP(data->value);
02981                                 not_added = False;
02982                                 break;
02983                         }
02984                         pdata = pdata->next;
02985                 }
02986                 if (not_added) {
02987                     paramo = SMB_XMALLOC_P(param_opt_struct);
02988                     paramo->key = SMB_STRDUP(data->key);
02989                     paramo->value = SMB_STRDUP(data->value);
02990                     paramo->list = NULL;
02991                     DLIST_ADD(pserviceDest->param_opt, paramo);
02992                 }
02993                 data = data->next;
02994         }
02995 }
02996 
02997 /***************************************************************************
02998 Check a service for consistency. Return False if the service is in any way
02999 incomplete or faulty, else True.
03000 ***************************************************************************/
03001 
03002 static BOOL service_ok(int iService)
03003 {
03004         BOOL bRetval;
03005 
03006         bRetval = True;
03007         if (ServicePtrs[iService]->szService[0] == '\0') {
03008                 DEBUG(0, ("The following message indicates an internal error:\n"));
03009                 DEBUG(0, ("No service name in service entry.\n"));
03010                 bRetval = False;
03011         }
03012 
03013         /* The [printers] entry MUST be printable. I'm all for flexibility, but */
03014         /* I can't see why you'd want a non-printable printer service...        */
03015         if (strwicmp(ServicePtrs[iService]->szService, PRINTERS_NAME) == 0) {
03016                 if (!ServicePtrs[iService]->bPrint_ok) {
03017                         DEBUG(0, ("WARNING: [%s] service MUST be printable!\n",
03018                                ServicePtrs[iService]->szService));
03019                         ServicePtrs[iService]->bPrint_ok = True;
03020                 }
03021                 /* [printers] service must also be non-browsable. */
03022                 if (ServicePtrs[iService]->bBrowseable)
03023                         ServicePtrs[iService]->bBrowseable = False;
03024         }
03025 
03026         if (ServicePtrs[iService]->szPath[0] == '\0' &&
03027             strwicmp(ServicePtrs[iService]->szService, HOMES_NAME) != 0 &&
03028             ServicePtrs[iService]->szMSDfsProxy[0] == '\0'
03029             ) {
03030                 DEBUG(0, ("WARNING: No path in service %s - making it unavailable!\n",
03031                         ServicePtrs[iService]->szService));
03032                 ServicePtrs[iService]->bAvailable = False;
03033         }
03034 
03035         /* If a service is flagged unavailable, log the fact at level 0. */
03036         if (!ServicePtrs[iService]->bAvailable)
03037                 DEBUG(1, ("NOTE: Service %s is flagged unavailable.\n",
03038                           ServicePtrs[iService]->szService));
03039 
03040         return (bRetval);
03041 }
03042 
03043 static struct file_lists {
03044         struct file_lists *next;
03045         char *name;
03046         char *subfname;
03047         time_t modtime;
03048 } *file_lists = NULL;
03049 
03050 /*******************************************************************
03051  Keep a linked list of all config files so we know when one has changed 
03052  it's date and needs to be reloaded.
03053 ********************************************************************/
03054 
03055 static void add_to_file_list(const char *fname, const char *subfname)
03056 {
03057         struct file_lists *f = file_lists;
03058 
03059         while (f) {
03060                 if (f->name && !strcmp(f->name, fname))
03061                         break;
03062                 f = f->next;
03063         }
03064 
03065         if (!f) {
03066                 f = SMB_MALLOC_P(struct file_lists);
03067                 if (!f)
03068                         return;
03069                 f->next = file_lists;
03070                 f->name = SMB_STRDUP(fname);
03071                 if (!f->name) {
03072                         SAFE_FREE(f);
03073                         return;
03074                 }
03075                 f->subfname = SMB_STRDUP(subfname);
03076                 if (!f->subfname) {
03077                         SAFE_FREE(f);
03078                         return;
03079                 }
03080                 file_lists = f;
03081                 f->modtime = file_modtime(subfname);
03082         } else {
03083                 time_t t = file_modtime(subfname);
03084                 if (t)
03085                         f->modtime = t;
03086         }
03087 }
03088 
03089 /*******************************************************************
03090  Check if a config file has changed date.
03091 ********************************************************************/
03092 
03093 BOOL lp_file_list_changed(void)
03094 {
03095         struct file_lists *f = file_lists;
03096 
03097         DEBUG(6, ("lp_file_list_changed()\n"));
03098 
03099         while (f) {
03100                 pstring n2;
03101                 time_t mod_time;
03102 
03103                 pstrcpy(n2, f->name);
03104                 standard_sub_basic( get_current_username(),
03105                                     current_user_info.domain,
03106                                     n2, sizeof(n2) );
03107 
03108                 DEBUGADD(6, ("file %s -> %s  last mod_time: %s\n",
03109                              f->name, n2, ctime(&f->modtime)));
03110 
03111                 mod_time = file_modtime(n2);
03112 
03113                 if (mod_time && ((f->modtime != mod_time) || (f->subfname == NULL) || (strcmp(n2, f->subfname) != 0))) {
03114                         DEBUGADD(6,
03115                                  ("file %s modified: %s\n", n2,
03116                                   ctime(&mod_time)));
03117                         f->modtime = mod_time;
03118                         SAFE_FREE(f->subfname);
03119                         f->subfname = SMB_STRDUP(n2);
03120                         return (True);
03121                 }
03122                 f = f->next;
03123         }
03124         return (False);
03125 }
03126 
03127 /***************************************************************************
03128  Run standard_sub_basic on netbios name... needed because global_myname
03129  is not accessed through any lp_ macro.
03130  Note: We must *NOT* use string_set() here as ptr points to global_myname.
03131 ***************************************************************************/
03132 
03133 static BOOL handle_netbios_name(int snum, const char *pszParmValue, char **ptr)
03134 {
03135         BOOL ret;
03136         pstring netbios_name;
03137 
03138         if (global_myname_override()) {
03139                 DEBUG(4, ("handle_netbios_name: ignoring netbios name "
03140                           "parameter"));
03141                 return True;
03142         }
03143 
03144         pstrcpy(netbios_name, pszParmValue);
03145 
03146         standard_sub_basic(get_current_username(), current_user_info.domain,
03147                            netbios_name, sizeof(netbios_name));
03148 
03149         ret = set_global_myname(netbios_name);
03150         string_set(&Globals.szNetbiosName,global_myname());
03151         
03152         DEBUG(4, ("handle_netbios_name: set global_myname to: %s\n",
03153                global_myname()));
03154 
03155         return ret;
03156 }
03157 
03158 static BOOL handle_charset(int snum, const char *pszParmValue, char **ptr)
03159 {
03160         if (strcmp(*ptr, pszParmValue) != 0) {
03161                 string_set(ptr, pszParmValue);
03162                 init_iconv();
03163         }
03164         return True;
03165 }
03166 
03167 
03168 
03169 static BOOL handle_workgroup(int snum, const char *pszParmValue, char **ptr)
03170 {
03171         BOOL ret;
03172         
03173         ret = set_global_myworkgroup(pszParmValue);
03174         string_set(&Globals.szWorkgroup,lp_workgroup());
03175         
03176         return ret;
03177 }
03178 
03179 static BOOL handle_netbios_scope(int snum, const char *pszParmValue, char **ptr)
03180 {
03181         BOOL ret;
03182         
03183         ret = set_global_scope(pszParmValue);
03184         string_set(&Globals.szNetbiosScope,global_scope());
03185 
03186         return ret;
03187 }
03188 
03189 static BOOL handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr)
03190 {
03191         str_list_free(&Globals.szNetbiosAliases);
03192         Globals.szNetbiosAliases = str_list_make(pszParmValue, NULL);
03193         return set_netbios_aliases((const char **)Globals.szNetbiosAliases);
03194 }
03195 
03196 /***************************************************************************
03197  Handle the include operation.
03198 ***************************************************************************/
03199 
03200 static BOOL handle_include(int snum, const char *pszParmValue, char **ptr)
03201 {
03202         pstring fname;
03203         pstrcpy(fname, pszParmValue);
03204 
03205         standard_sub_basic(get_current_username(), current_user_info.domain,
03206                            fname,sizeof(fname));
03207 
03208         add_to_file_list(pszParmValue, fname);
03209 
03210         string_set(ptr, fname);
03211 
03212         if (file_exist(fname, NULL))
03213                 return (pm_process(fname, do_section, do_parameter));
03214 
03215         DEBUG(2, ("Can't find include file %s\n", fname));
03216 
03217         return (False);
03218 }
03219 
03220 /***************************************************************************
03221  Handle the interpretation of the copy parameter.
03222 ***************************************************************************/
03223 
03224 static BOOL handle_copy(int snum, const char *pszParmValue, char **ptr)
03225 {
03226         BOOL bRetval;
03227         int iTemp;
03228         service serviceTemp;
03229 
03230         string_set(ptr, pszParmValue);
03231 
03232         init_service(&serviceTemp);
03233 
03234         bRetval = False;
03235 
03236         DEBUG(3, ("Copying service from service %s\n", pszParmValue));
03237 
03238         if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0) {
03239                 if (iTemp == iServiceIndex) {
03240                         DEBUG(0, ("Can't copy service %s - unable to copy self!\n", pszParmValue));
03241                 } else {
03242                         copy_service(ServicePtrs[iServiceIndex],
03243                                      &serviceTemp,
03244                                      ServicePtrs[iServiceIndex]->copymap);
03245                         bRetval = True;
03246                 }
03247         } else {
03248                 DEBUG(0, ("Unable to copy service - source not found: %s\n", pszParmValue));
03249                 bRetval = False;
03250         }
03251 
03252         free_service(&serviceTemp);
03253         return (bRetval);
03254 }
03255 
03256 static BOOL handle_ldap_debug_level(int snum, const char *pszParmValue, char **ptr)
03257 {
03258         Globals.ldap_debug_level = lp_int(pszParmValue);
03259         init_ldap_debugging();
03260         return True;
03261 }
03262 
03263 /***************************************************************************
03264  Handle idmap/non unix account uid and gid allocation parameters.  The format of these
03265  parameters is:
03266 
03267  [global]
03268 
03269         idmap uid = 1000-1999
03270         idmap gid = 700-899
03271 
03272  We only do simple parsing checks here.  The strings are parsed into useful
03273  structures in the idmap daemon code.
03274 
03275 ***************************************************************************/
03276 
03277 /* Some lp_ routines to return idmap [ug]id information */
03278 
03279 static uid_t idmap_uid_low, idmap_uid_high;
03280 static gid_t idmap_gid_low, idmap_gid_high;
03281 
03282 BOOL lp_idmap_uid(uid_t *low, uid_t *high)
03283 {
03284         if (idmap_uid_low == 0 || idmap_uid_high == 0)
03285                 return False;
03286 
03287         if (low)
03288                 *low = idmap_uid_low;
03289 
03290         if (high)
03291                 *high = idmap_uid_high;
03292 
03293         return True;
03294 }
03295 
03296 BOOL lp_idmap_gid(gid_t *low, gid_t *high)
03297 {
03298         if (idmap_gid_low == 0 || idmap_gid_high == 0)
03299                 return False;
03300 
03301         if (low)
03302                 *low = idmap_gid_low;
03303 
03304         if (high)
03305                 *high = idmap_gid_high;
03306 
03307         return True;
03308 }
03309 
03310 /* Do some simple checks on "idmap [ug]id" parameter values */
03311 
03312 static BOOL handle_idmap_uid(int snum, const char *pszParmValue, char **ptr)
03313 {
03314         uint32 low, high;
03315 
03316         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
03317                 return False;
03318 
03319         /* Parse OK */
03320 
03321         string_set(ptr, pszParmValue);
03322 
03323         idmap_uid_low = low;
03324         idmap_uid_high = high;
03325 
03326         return True;
03327 }
03328 
03329 static BOOL handle_idmap_gid(int snum, const char *pszParmValue, char **ptr)
03330 {
03331         uint32 low, high;
03332 
03333         if (sscanf(pszParmValue, "%u - %u", &low, &high) != 2 || high < low)
03334                 return False;
03335 
03336         /* Parse OK */
03337 
03338         string_set(ptr, pszParmValue);
03339 
03340         idmap_gid_low = low;
03341         idmap_gid_high = high;
03342 
03343         return True;
03344 }
03345 
03346 /***************************************************************************
03347  Handle the DEBUG level list.
03348 ***************************************************************************/
03349 
03350 static BOOL handle_debug_list( int snum, const char *pszParmValueIn, char **ptr )
03351 {
03352         pstring pszParmValue;
03353 
03354         pstrcpy(pszParmValue, pszParmValueIn);
03355         string_set(ptr, pszParmValueIn);
03356         return debug_parse_levels( pszParmValue );
03357 }
03358 
03359 /***************************************************************************
03360  Handle ldap suffixes - default to ldapsuffix if sub-suffixes are not defined.
03361 ***************************************************************************/
03362 
03363 static const char *append_ldap_suffix( const char *str )
03364 {
03365         const char *suffix_string;
03366 
03367 
03368         if (!lp_talloc)
03369                 lp_talloc = talloc_init("lp_talloc");
03370 
03371         suffix_string = talloc_asprintf( lp_talloc, "%s,%s", str, Globals.szLdapSuffix );
03372         if ( !suffix_string ) {
03373                 DEBUG(0,("append_ldap_suffix: talloc_asprintf() failed!\n"));
03374                 return "";
03375         }
03376 
03377         return suffix_string;
03378 }
03379 
03380 const char *lp_ldap_machine_suffix(void)
03381 {
03382         if (Globals.szLdapMachineSuffix[0])
03383                 return append_ldap_suffix(Globals.szLdapMachineSuffix);
03384 
03385         return lp_string(Globals.szLdapSuffix);
03386 }
03387 
03388 const char *lp_ldap_user_suffix(void)
03389 {
03390         if (Globals.szLdapUserSuffix[0])
03391                 return append_ldap_suffix(Globals.szLdapUserSuffix);
03392 
03393         return lp_string(Globals.szLdapSuffix);
03394 }
03395 
03396 const char *lp_ldap_group_suffix(void)
03397 {
03398         if (Globals.szLdapGroupSuffix[0])
03399                 return append_ldap_suffix(Globals.szLdapGroupSuffix);
03400 
03401         return lp_string(Globals.szLdapSuffix);
03402 }
03403 
03404 const char *lp_ldap_idmap_suffix(void)
03405 {
03406         if (Globals.szLdapIdmapSuffix[0])
03407                 return append_ldap_suffix(Globals.szLdapIdmapSuffix);
03408 
03409         return lp_string(Globals.szLdapSuffix);
03410 }
03411 
03412 /****************************************************************************
03413  set the value for a P_ENUM
03414  ***************************************************************************/
03415 
03416 static void lp_set_enum_parm( struct parm_struct *parm, const char *pszParmValue,
03417                               int *ptr )
03418 {
03419         int i;
03420 
03421         for (i = 0; parm->enum_list[i].name; i++) {
03422                 if ( strequal(pszParmValue, parm->enum_list[i].name)) {
03423                         *ptr = parm->enum_list[i].value;
03424                         break;
03425                 }
03426         }
03427 }
03428 
03429 /***************************************************************************
03430 ***************************************************************************/
03431 
03432 static BOOL handle_printing(int snum, const char *pszParmValue, char **ptr)
03433 {
03434         static int parm_num = -1;
03435         service *s;
03436 
03437         if ( parm_num == -1 )
03438                 parm_num = map_parameter( "printing" );
03439 
03440         lp_set_enum_parm( &parm_table[parm_num], pszParmValue, (int*)ptr );
03441 
03442         if ( snum < 0 )
03443                 s = &sDefault;
03444         else
03445                 s = ServicePtrs[snum];
03446 
03447         init_printer_values( s );
03448 
03449         return True;
03450 }
03451 
03452 
03453 /***************************************************************************
03454  Initialise a copymap.
03455 ***************************************************************************/
03456 
03457 static void init_copymap(service * pservice)
03458 {
03459         int i;
03460         SAFE_FREE(pservice->copymap);
03461         pservice->copymap = SMB_MALLOC_ARRAY(BOOL,NUMPARAMETERS);
03462         if (!pservice->copymap)
03463                 DEBUG(0,
03464                       ("Couldn't allocate copymap!! (size %d)\n",
03465                        (int)NUMPARAMETERS));
03466         else
03467                 for (i = 0; i < NUMPARAMETERS; i++)
03468                         pservice->copymap[i] = True;
03469 }
03470 
03471 /***************************************************************************
03472  Return the local pointer to a parameter given the service number and the 
03473  pointer into the default structure.
03474 ***************************************************************************/
03475 
03476 void *lp_local_ptr(int snum, void *ptr)
03477 {
03478         return (void *)(((char *)ServicePtrs[snum]) + PTR_DIFF(ptr, &sDefault));
03479 }
03480 
03481 /***************************************************************************
03482  Process a parameter for a particular service number. If snum < 0
03483  then assume we are in the globals.
03484 ***************************************************************************/
03485 
03486 BOOL lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue)
03487 {
03488         int parmnum, i, slen;
03489         void *parm_ptr = NULL;  /* where we are going to store the result */
03490         void *def_ptr = NULL;
03491         pstring param_key;
03492         char *sep;
03493         param_opt_struct *paramo, *data;
03494         BOOL not_added;
03495 
03496         parmnum = map_parameter(pszParmName);
03497 
03498         if (parmnum < 0) {
03499                 if ((sep=strchr(pszParmName, ':')) != NULL) {
03500                         *sep = '\0';
03501                         ZERO_STRUCT(param_key);
03502                         pstr_sprintf(param_key, "%s:", pszParmName);
03503                         slen = strlen(param_key);
03504                         pstrcat(param_key, sep+1);
03505                         trim_char(param_key+slen, ' ', ' ');
03506                         not_added = True;
03507                         data = (snum < 0) ? Globals.param_opt : 
03508                                 ServicePtrs[snum]->param_opt;
03509                         /* Traverse destination */
03510                         while (data) {
03511                                 /* If we already have same option, override it */
03512                                 if (strcmp(data->key, param_key) == 0) {
03513                                         string_free(&data->value);
03514                                         str_list_free(&data->list);
03515                                         data->value = SMB_STRDUP(pszParmValue);
03516                                         not_added = False;
03517                                         break;
03518                                 }
03519                                 data = data->next;
03520                         }
03521                         if (not_added) {
03522                                 paramo = SMB_XMALLOC_P(param_opt_struct);
03523                                 paramo->key = SMB_STRDUP(param_key);
03524                                 paramo->value = SMB_STRDUP(pszParmValue);
03525                                 paramo->list = NULL;
03526                                 if (snum < 0) {
03527                                         DLIST_ADD(Globals.param_opt, paramo);
03528                                 } else {
03529                                         DLIST_ADD(ServicePtrs[snum]->param_opt, paramo);
03530                                 }
03531                         }
03532 
03533                         *sep = ':';
03534                         return (True);
03535                 }
03536                 DEBUG(0, ("Ignoring unknown parameter \"%s\"\n", pszParmName));
03537                 return (True);
03538         }
03539 
03540         if (parm_table[parmnum].flags & FLAG_DEPRECATED) {
03541                 DEBUG(1, ("WARNING: The \"%s\" option is deprecated\n",
03542                           pszParmName));
03543         }
03544 
03545         def_ptr = parm_table[parmnum].ptr;
03546 
03547         /* we might point at a service, the default service or a global */
03548         if (snum < 0) {
03549                 parm_ptr = def_ptr;
03550         } else {
03551                 if (parm_table[parmnum].p_class == P_GLOBAL) {
03552                         DEBUG(0,
03553                               ("Global parameter %s found in service section!\n",
03554                                pszParmName));
03555                         return (True);
03556                 }
03557                 parm_ptr =
03558                         ((char *)ServicePtrs[snum]) + PTR_DIFF(def_ptr,
03559                                                             &sDefault);
03560         }
03561 
03562         if (snum >= 0) {
03563                 if (!ServicePtrs[snum]->copymap)
03564                         init_copymap(ServicePtrs[snum]);
03565 
03566                 /* this handles the aliases - set the copymap for other entries with
03567                    the same data pointer */
03568                 for (i = 0; parm_table[i].label; i++)
03569                         if (parm_table[i].ptr == parm_table[parmnum].ptr)
03570                                 ServicePtrs[snum]->copymap[i] = False;
03571         }
03572 
03573         /* if it is a special case then go ahead */
03574         if (parm_table[parmnum].special) {
03575                 parm_table[parmnum].special(snum, pszParmValue, (char **)parm_ptr);
03576                 return (True);
03577         }
03578 
03579         /* now switch on the type of variable it is */
03580         switch (parm_table[parmnum].type)
03581         {
03582                 case P_BOOL:
03583                         *(BOOL *)parm_ptr = lp_bool(pszParmValue);
03584                         break;
03585 
03586                 case P_BOOLREV:
03587                         *(BOOL *)parm_ptr = !lp_bool(pszParmValue);
03588                         break;
03589 
03590                 case P_INTEGER:
03591                         *(int *)parm_ptr = lp_int(pszParmValue);
03592                         break;
03593 
03594                 case P_CHAR:
03595                         *(char *)parm_ptr = *pszParmValue;
03596                         break;
03597 
03598                 case P_OCTAL:
03599                         i = sscanf(pszParmValue, "%o", (int *)parm_ptr);
03600                         if ( i != 1 ) {
03601                             DEBUG ( 0, ("Invalid octal number %s\n", pszParmName ));
03602                         }
03603                         break;
03604 
03605                 case P_LIST:
03606                         str_list_free((char ***)parm_ptr);
03607                         *(char ***)parm_ptr = str_list_make(pszParmValue, NULL);
03608                         break;
03609 
03610                 case P_STRING:
03611                         string_set((char **)parm_ptr, pszParmValue);
03612                         break;
03613 
03614                 case P_USTRING:
03615                         string_set((char **)parm_ptr, pszParmValue);
03616                         strupper_m(*(char **)parm_ptr);
03617                         break;
03618 
03619                 case P_GSTRING:
03620                         pstrcpy((char *)parm_ptr, pszParmValue);
03621                         break;
03622 
03623                 case P_UGSTRING:
03624                         pstrcpy((char *)parm_ptr, pszParmValue);
03625                         strupper_m((char *)parm_ptr);
03626                         break;
03627 
03628                 case P_ENUM:
03629                         lp_set_enum_parm( &parm_table[parmnum], pszParmValue, (int*)parm_ptr );
03630                         break;
03631                 case P_SEP:
03632                         break;
03633         }
03634 
03635         return (True);
03636 }
03637 
03638 /***************************************************************************
03639  Process a parameter.
03640 ***************************************************************************/
03641 
03642 static BOOL do_parameter(const char *pszParmName, const char *pszParmValue)
03643 {
03644         if (!bInGlobalSection && bGlobalOnly)
03645                 return (True);
03646 
03647         DEBUGADD(4, ("doing parameter %s = %s\n", pszParmName, pszParmValue));
03648 
03649         return (lp_do_parameter(bInGlobalSection ? -2 : iServiceIndex,
03650                                 pszParmName, pszParmValue));
03651 }
03652 
03653 /***************************************************************************
03654  Print a parameter of the specified type.
03655 ***************************************************************************/
03656 
03657 static void print_parameter(struct parm_struct *p, void *ptr, FILE * f)
03658 {
03659         int i;
03660         switch (p->type)
03661         {
03662                 case P_ENUM:
03663                         for (i = 0; p->enum_list[i].name; i++) {
03664                                 if (*(int *)ptr == p->enum_list[i].value) {
03665                                         fprintf(f, "%s",
03666                                                 p->enum_list[i].name);
03667                                         break;
03668                                 }
03669                         }
03670                         break;
03671 
03672                 case P_BOOL:
03673                         fprintf(f, "%s", BOOLSTR(*(BOOL *)ptr));
03674                         break;
03675 
03676                 case P_BOOLREV:
03677                         fprintf(f, "%s", BOOLSTR(!*(BOOL *)ptr));
03678                         break;
03679 
03680                 case P_INTEGER:
03681                         fprintf(f, "%d", *(int *)ptr);
03682                         break;
03683 
03684                 case P_CHAR:
03685                         fprintf(f, "%c", *(char *)ptr);
03686                         break;
03687 
03688                 case P_OCTAL:
03689                         fprintf(f, "%s", octal_string(*(int *)ptr));
03690                         break;
03691 
03692                 case P_LIST:
03693                         if ((char ***)ptr && *(char ***)ptr) {
03694                                 char **list = *(char ***)ptr;
03695                                 
03696                                 for (; *list; list++) {
03697                                         /* surround strings with whitespace in double quotes */
03698                                         if ( strchr_m( *list, ' ' ) )
03699                                                 fprintf(f, "\"%s\"%s", *list, ((*(list+1))?", ":""));
03700                                         else
03701                                                 fprintf(f, "%s%s", *list, ((*(list+1))?", ":""));
03702                                 }
03703                         }
03704                         break;
03705 
03706                 case P_GSTRING:
03707                 case P_UGSTRING:
03708                         if ((char *)ptr) {
03709                                 fprintf(f, "%s", (char *)ptr);
03710                         }
03711                         break;
03712 
03713                 case P_STRING:
03714                 case P_USTRING:
03715                         if (*(char **)ptr) {
03716                                 fprintf(f, "%s", *(char **)ptr);
03717                         }
03718                         break;
03719                 case P_SEP:
03720                         break;
03721         }
03722 }
03723 
03724 /***************************************************************************
03725  Check if two parameters are equal.
03726 ***************************************************************************/
03727 
03728 static BOOL equal_parameter(parm_type type, void *ptr1, void *ptr2)
03729 {
03730         switch (type) {
03731                 case P_BOOL:
03732                 case P_BOOLREV:
03733                         return (*((BOOL *)ptr1) == *((BOOL *)ptr2));
03734 
03735                 case P_INTEGER:
03736                 case P_ENUM:
03737                 case P_OCTAL:
03738                         return (*((int *)ptr1) == *((int *)ptr2));
03739 
03740                 case P_CHAR:
03741                         return (*((char *)ptr1) == *((char *)ptr2));
03742                 
03743                 case P_LIST:
03744                         return str_list_compare(*(char ***)ptr1, *(char ***)ptr2);
03745 
03746                 case P_GSTRING:
03747                 case P_UGSTRING:
03748                 {
03749                         char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
03750                         if (p1 && !*p1)
03751                                 p1 = NULL;
03752                         if (p2 && !*p2)
03753                                 p2 = NULL;
03754                         return (p1 == p2 || strequal(p1, p2));
03755                 }
03756                 case P_STRING:
03757                 case P_USTRING:
03758                 {
03759                         char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
03760                         if (p1 && !*p1)
03761                                 p1 = NULL;
03762                         if (p2 && !*p2)
03763                                 p2 = NULL;
03764                         return (p1 == p2 || strequal(p1, p2));
03765                 }
03766                 case P_SEP:
03767                         break;
03768         }
03769         return (False);
03770 }
03771 
03772 /***************************************************************************
03773  Initialize any local varients in the sDefault table.
03774 ***************************************************************************/
03775 
03776 void init_locals(void)
03777 {
03778         /* None as yet. */
03779 }
03780 
03781 /***************************************************************************
03782  Process a new section (service). At this stage all sections are services.
03783  Later we'll have special sections that permit server parameters to be set.
03784  Returns True on success, False on failure. 
03785 ***************************************************************************/
03786 
03787 static BOOL do_section(const char *pszSectionName)
03788 {
03789         BOOL bRetval;
03790         BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
03791                          (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
03792         bRetval = False;
03793 
03794         /* if we were in a global section then do the local inits */
03795         if (bInGlobalSection && !isglobal)
03796                 init_locals();
03797 
03798         /* if we've just struck a global section, note the fact. */
03799         bInGlobalSection = isglobal;
03800 
03801         /* check for multiple global sections */
03802         if (bInGlobalSection) {
03803                 DEBUG(3, ("Processing section \"[%s]\"\n", pszSectionName));
03804                 return (True);
03805         }
03806 
03807         if (!bInGlobalSection && bGlobalOnly)
03808                 return (True);
03809 
03810         /* if we have a current service, tidy it up before moving on */
03811         bRetval = True;
03812 
03813         if (iServiceIndex >= 0)
03814                 bRetval = service_ok(iServiceIndex);
03815 
03816         /* if all is still well, move to the next record in the services array */
03817         if (bRetval) {
03818                 /* We put this here to avoid an odd message order if messages are */
03819                 /* issued by the post-processing of a previous section. */
03820                 DEBUG(2, ("Processing section \"[%s]\"\n", pszSectionName));
03821 
03822                 if ((iServiceIndex = add_a_service(&sDefault, pszSectionName))
03823                     < 0) {
03824                         DEBUG(0, ("Failed to add a new service\n"));
03825                         return (False);
03826                 }
03827         }
03828 
03829         return (bRetval);
03830 }
03831 
03832 
03833 /***************************************************************************
03834  Determine if a partcular base parameter is currentl set to the default value.
03835 ***************************************************************************/
03836 
03837 static BOOL is_default(int i)
03838 {
03839         if (!defaults_saved)
03840                 return False;
03841         switch (parm_table[i].type) {
03842                 case P_LIST:
03843                         return str_list_compare (parm_table[i].def.lvalue, 
03844                                                 *(char ***)parm_table[i].ptr);
03845                 case P_STRING:
03846                 case P_USTRING:
03847                         return strequal(parm_table[i].def.svalue,
03848                                         *(char **)parm_table[i].ptr);
03849                 case P_GSTRING:
03850                 case P_UGSTRING:
03851                         return strequal(parm_table[i].def.svalue,
03852                                         (char *)parm_table[i].ptr);
03853                 case P_BOOL:
03854                 case P_BOOLREV:
03855                         return parm_table[i].def.bvalue ==
03856                                 *(BOOL *)parm_table[i].ptr;
03857                 case P_CHAR:
03858                         return parm_table[i].def.cvalue ==
03859                                 *(char *)parm_table[i].ptr;
03860                 case P_INTEGER:
03861                 case P_OCTAL:
03862                 case P_ENUM:
03863                         return parm_table[i].def.ivalue ==
03864                                 *(int *)parm_table[i].ptr;
03865                 case P_SEP:
03866                         break;
03867         }
03868         return False;
03869 }
03870 
03871 /***************************************************************************
03872 Display the contents of the global structure.
03873 ***************************************************************************/
03874 
03875 static void dump_globals(FILE *f)
03876 {
03877         int i;
03878         param_opt_struct *data;
03879         
03880         fprintf(f, "[global]\n");
03881 
03882         for (i = 0; parm_table[i].label; i++)
03883                 if (parm_table[i].p_class == P_GLOBAL &&
03884                     parm_table[i].ptr &&
03885                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) {
03886                         if (defaults_saved && is_default(i))
03887                                 continue;
03888                         fprintf(f, "\t%s = ", parm_table[i].label);
03889                         print_parameter(&parm_table[i], parm_table[i].ptr, f);
03890                         fprintf(f, "\n");
03891         }
03892         if (Globals.param_opt != NULL) {
03893                 data = Globals.param_opt;
03894                 while(data) {
03895                         fprintf(f, "\t%s = %s\n", data->key, data->value);
03896                         data = data->next;
03897                 }
03898         }
03899 
03900 }
03901 
03902 /***************************************************************************
03903  Return True if a local parameter is currently set to the global default.
03904 ***************************************************************************/
03905 
03906 BOOL lp_is_default(int snum, struct parm_struct *parm)
03907 {
03908         int pdiff = PTR_DIFF(parm->ptr, &sDefault);
03909 
03910         return equal_parameter(parm->type,
03911                                ((char *)ServicePtrs[snum]) + pdiff,
03912                                ((char *)&sDefault) + pdiff);
03913 }
03914 
03915 /***************************************************************************
03916  Display the contents of a single services record.
03917 ***************************************************************************/
03918 
03919 static void dump_a_service(service * pService, FILE * f)
03920 {
03921         int i;
03922         param_opt_struct *data;
03923         
03924         if (pService != &sDefault)
03925                 fprintf(f, "[%s]\n", pService->szService);
03926 
03927         for (i = 0; parm_table[i].label; i++) {
03928 
03929                 if (parm_table[i].p_class == P_LOCAL &&
03930                     parm_table[i].ptr &&
03931                     (*parm_table[i].label != '-') &&
03932                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
03933                 {
03934                 
03935                         int pdiff = PTR_DIFF(parm_table[i].ptr, &sDefault);
03936 
03937                         if (pService == &sDefault) {
03938                                 if (defaults_saved && is_default(i))
03939                                         continue;
03940                         } else {
03941                                 if (equal_parameter(parm_table[i].type,
03942                                                     ((char *)pService) +
03943                                                     pdiff,
03944                                                     ((char *)&sDefault) +
03945                                                     pdiff))
03946                                         continue;
03947                         }
03948 
03949                         fprintf(f, "\t%s = ", parm_table[i].label);
03950                         print_parameter(&parm_table[i],
03951                                         ((char *)pService) + pdiff, f);
03952                         fprintf(f, "\n");
03953                 }
03954         }
03955 
03956                 if (pService->param_opt != NULL) {
03957                         data = pService->param_opt;
03958                         while(data) {
03959                                 fprintf(f, "\t%s = %s\n", data->key, data->value);
03960                                 data = data->next;
03961                         }
03962                 }
03963 }
03964 
03965 /***************************************************************************
03966  Display the contents of a parameter of a single services record.
03967 ***************************************************************************/
03968 
03969 BOOL dump_a_parameter(int snum, char *parm_name, FILE * f, BOOL isGlobal)
03970 {
03971         int i;
03972         BOOL result = False;
03973         parm_class p_class;
03974         unsigned flag = 0;
03975         fstring local_parm_name;
03976         char *parm_opt;
03977         const char *parm_opt_value;
03978 
03979         /* check for parametrical option */
03980         fstrcpy( local_parm_name, parm_name);
03981         parm_opt = strchr( local_parm_name, ':');
03982 
03983         if (parm_opt) {
03984                 *parm_opt = '\0';
03985                 parm_opt++;
03986                 if (strlen(parm_opt)) {
03987                         parm_opt_value = lp_parm_const_string( snum,
03988                                 local_parm_name, parm_opt, NULL);
03989                         if (parm_opt_value) {
03990                                 printf( "%s\n", parm_opt_value);
03991                                 result = True;
03992                         }
03993                 }
03994                 return result;
03995         }
03996 
03997         /* check for a key and print the value */
03998         if (isGlobal) {
03999                 p_class = P_GLOBAL;
04000                 flag = FLAG_GLOBAL;
04001         } else
04002                 p_class = P_LOCAL;
04003 
04004         for (i = 0; parm_table[i].label; i++) {
04005                 if (strwicmp(parm_table[i].label, parm_name) == 0 &&
04006                     (parm_table[i].p_class == p_class || parm_table[i].flags & flag) &&
04007                     parm_table[i].ptr &&
04008                     (*parm_table[i].label != '-') &&
04009                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr))) 
04010                 {
04011                         void *ptr;
04012 
04013                         if (isGlobal) {
04014                                 ptr = parm_table[i].ptr;
04015                         } else {
04016                                 service * pService = ServicePtrs[snum];
04017                                 ptr = ((char *)pService) +
04018                                         PTR_DIFF(parm_table[i].ptr, &sDefault);
04019                         }
04020 
04021                         print_parameter(&parm_table[i],
04022                                         ptr, f);
04023                         fprintf(f, "\n");
04024                         result = True;
04025                         break;
04026                 }
04027         }
04028 
04029         return result;
04030 }
04031 
04032 /***************************************************************************
04033  Return info about the next service  in a service. snum==GLOBAL_SECTION_SNUM gives the globals.
04034  Return NULL when out of parameters.
04035 ***************************************************************************/
04036 
04037 struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters)
04038 {
04039         if (snum < 0) {
04040                 /* do the globals */
04041                 for (; parm_table[*i].label; (*i)++) {
04042                         if (parm_table[*i].p_class == P_SEPARATOR)
04043                                 return &parm_table[(*i)++];
04044 
04045                         if (!parm_table[*i].ptr
04046                             || (*parm_table[*i].label == '-'))
04047                                 continue;
04048 
04049                         if ((*i) > 0
04050                             && (parm_table[*i].ptr ==
04051                                 parm_table[(*i) - 1].ptr))
04052                                 continue;
04053 
04054                         return &parm_table[(*i)++];
04055                 }
04056         } else {
04057                 service *pService = ServicePtrs[snum];
04058 
04059                 for (; parm_table[*i].label; (*i)++) {
04060                         if (parm_table[*i].p_class == P_SEPARATOR)
04061                                 return &parm_table[(*i)++];
04062 
04063                         if (parm_table[*i].p_class == P_LOCAL &&
04064                             parm_table[*i].ptr &&
04065                             (*parm_table[*i].label != '-') &&
04066                             ((*i) == 0 ||
04067                              (parm_table[*i].ptr !=
04068                               parm_table[(*i) - 1].ptr)))
04069                         {
04070                                 int pdiff =
04071                                         PTR_DIFF(parm_table[*i].ptr,
04072                                                  &sDefault);
04073 
04074                                 if (allparameters ||
04075                                     !equal_parameter(parm_table[*i].type,
04076                                                      ((char *)pService) +
04077                                                      pdiff,
04078                                                      ((char *)&sDefault) +
04079                                                      pdiff))
04080                                 {
04081                                         return &parm_table[(*i)++];
04082                                 }
04083                         }
04084                 }
04085         }
04086 
04087         return NULL;
04088 }
04089 
04090 
04091 #if 0
04092 /***************************************************************************
04093  Display the contents of a single copy structure.
04094 ***************************************************************************/
04095 static void dump_copy_map(BOOL *pcopymap)
04096 {
04097         int i;
04098         if (!pcopymap)
04099                 return;
04100 
04101         printf("\n\tNon-Copied parameters:\n");
04102 
04103         for (i = 0; parm_table[i].label; i++)
04104                 if (parm_table[i].p_class == P_LOCAL &&
04105                     parm_table[i].ptr && !pcopymap[i] &&
04106                     (i == 0 || (parm_table[i].ptr != parm_table[i - 1].ptr)))
04107                 {
04108                         printf("\t\t%s\n", parm_table[i].label);
04109                 }
04110 }
04111 #endif
04112 
04113 /***************************************************************************
04114  Return TRUE if the passed service number is within range.
04115 ***************************************************************************/
04116 
04117 BOOL lp_snum_ok(int iService)
04118 {
04119         return (LP_SNUM_OK(iService) && ServicePtrs[iService]->bAvailable);
04120 }
04121 
04122 /***************************************************************************
04123  Auto-load some home services.
04124 ***************************************************************************/
04125 
04126 static void lp_add_auto_services(char *str)
04127 {
04128         char *s;
04129         char *p;
04130         int homes;
04131 
04132         if (!str)
04133                 return;
04134 
04135         s = SMB_STRDUP(str);
04136         if (!s)
04137                 return;
04138 
04139         homes = lp_servicenumber(HOMES_NAME);
04140 
04141         for (p = strtok(s, LIST_SEP); p; p = strtok(NULL, LIST_SEP)) {
04142                 char *home = get_user_home_dir(p);
04143 
04144                 if (lp_servicenumber(p) >= 0)
04145                         continue;
04146 
04147                 if (home && homes >= 0)
04148                         lp_add_home(p, homes, p, home);
04149         }
04150         SAFE_FREE(s);
04151 }
04152 
04153 /***************************************************************************
04154  Auto-load one printer.
04155 ***************************************************************************/
04156 
04157 void lp_add_one_printer(char *name, char *comment)
04158 {
04159         int printers = lp_servicenumber(PRINTERS_NAME);
04160         int i;
04161 
04162         if (lp_servicenumber(name) < 0) {
04163                 lp_add_printer(name, printers);
04164                 if ((i = lp_servicenumber(name)) >= 0) {
04165                         string_set(&ServicePtrs[i]->comment, comment);
04166                         ServicePtrs[i]->autoloaded = True;
04167                 }
04168         }
04169 }
04170 
04171 /***************************************************************************
04172  Have we loaded a services file yet?
04173 ***************************************************************************/
04174 
04175 BOOL lp_loaded(void)
04176 {
04177         return (bLoaded);
04178 }
04179 
04180 /***************************************************************************
04181  Unload unused services.
04182 ***************************************************************************/
04183 
04184 void lp_killunused(BOOL (*snumused) (int))
04185 {
04186         int i;
04187         for (i = 0; i < iNumServices; i++) {
04188                 if (!VALID(i))
04189                         continue;
04190 
04191                 /* don't kill autoloaded or usershare services */
04192                 if ( ServicePtrs[i]->autoloaded ||
04193                                 ServicePtrs[i]->usershare == USERSHARE_VALID) {
04194                         continue;
04195                 }
04196 
04197                 if (!snumused || !snumused(i)) {
04198                         free_service_byindex(i);
04199                 }
04200         }
04201 }
04202 
04203 /***************************************************************************
04204  Unload a service.
04205 ***************************************************************************/
04206 
04207 void lp_killservice(int iServiceIn)
04208 {
04209         if (VALID(iServiceIn)) {
04210                 free_service_byindex(iServiceIn);
04211         }
04212 }
04213 
04214 /***************************************************************************
04215  Save the curent values of all global and sDefault parameters into the 
04216  defaults union. This allows swat and testparm to show only the
04217  changed (ie. non-default) parameters.
04218 ***************************************************************************/
04219 
04220 static void lp_save_defaults(void)
04221 {
04222         int i;
04223         for (i = 0; parm_table[i].label; i++) {
04224                 if (i > 0 && parm_table[i].ptr == parm_table[i - 1].ptr)
04225                         continue;
04226                 switch (parm_table[i].type) {
04227                         case P_LIST:
04228                                 str_list_copy(&(parm_table[i].def.lvalue),
04229                                             *(const char ***)parm_table[i].ptr);
04230                                 break;
04231                         case P_STRING:
04232                         case P_USTRING:
04233                                 if (parm_table[i].ptr) {
04234                                         parm_table[i].def.svalue = SMB_STRDUP(*(char **)parm_table[i].ptr);
04235                                 } else {
04236                                         parm_table[i].def.svalue = NULL;
04237                                 }
04238                                 break;
04239                         case P_GSTRING:
04240                         case P_UGSTRING:
04241                                 if (parm_table[i].ptr) {
04242                                         parm_table[i].def.svalue = SMB_STRDUP((char *)parm_table[i].ptr);
04243                                 } else {
04244                                         parm_table[i].def.svalue = NULL;
04245                                 }
04246                                 break;
04247                         case P_BOOL:
04248                         case P_BOOLREV:
04249                                 parm_table[i].def.bvalue =
04250                                         *(BOOL *)parm_table[i].ptr;
04251                                 break;
04252                         case P_CHAR:
04253                                 parm_table[i].def.cvalue =
04254                                         *(char *)parm_table[i].ptr;
04255                                 break;
04256                         case P_INTEGER:
04257                         case P_OCTAL:
04258                         case P_ENUM:
04259                                 parm_table[i].def.ivalue =
04260                                         *(int *)parm_table[i].ptr;
04261                                 break;
04262                         case P_SEP:
04263                                 break;
04264                 }
04265         }
04266         defaults_saved = True;
04267 }
04268 
04269 /*******************************************************************
04270  Set the server type we will announce as via nmbd.
04271 ********************************************************************/
04272 
04273 static const struct srv_role_tab {
04274         uint32 role;
04275         const char *role_str;
04276 } srv_role_tab [] = {
04277         { ROLE_STANDALONE, "ROLE_STANDALONE" },
04278         { ROLE_DOMAIN_MEMBER, "ROLE_DOMAIN_MEMBER" },
04279         { ROLE_DOMAIN_BDC, "ROLE_DOMAIN_BDC" },
04280         { ROLE_DOMAIN_PDC, "ROLE_DOMAIN_PDC" },
04281         { 0, NULL }
04282 };
04283 
04284 const char* server_role_str(uint32 role)
04285 {
04286         int i = 0;
04287         for (i=0; srv_role_tab[i].role_str; i++) {
04288                 if (role == srv_role_tab[i].role) {
04289                         return srv_role_tab[i].role_str;
04290                 }
04291         }
04292         return NULL;
04293 }
04294 
04295 static void set_server_role(void)
04296 {
04297         server_role = ROLE_STANDALONE;
04298 
04299         switch (lp_security()) {
04300                 case SEC_SHARE:
04301                         if (lp_domain_logons())
04302                                 DEBUG(0, ("Server's Role (logon server) conflicts with share-level security\n"));
04303                         break;
04304                 case SEC_SERVER:
04305                         if (lp_domain_logons())
04306                                 DEBUG(0, ("Server's Role (logon server) conflicts with server-level security\n"));
04307                         /* this used to be considered ROLE_DOMAIN_MEMBER but that's just wrong */
04308                         server_role = ROLE_STANDALONE;
04309                         break;
04310                 case SEC_DOMAIN:
04311                         if (lp_domain_logons()) {
04312                                 DEBUG(1, ("Server's Role (logon server) NOT ADVISED with domain-level security\n"));
04313                                 server_role = ROLE_DOMAIN_BDC;
04314                                 break;
04315                         }
04316                         server_role = ROLE_DOMAIN_MEMBER;
04317                         break;
04318                 case SEC_ADS:
04319                         if (lp_domain_logons()) {
04320                                 server_role = ROLE_DOMAIN_PDC;
04321                                 break;
04322                         }
04323                         server_role = ROLE_DOMAIN_MEMBER;
04324                         break;
04325                 case SEC_USER:
04326                         if (lp_domain_logons()) {
04327 
04328                                 if (Globals.bDomainMaster) /* auto or yes */ 
04329                                         server_role = ROLE_DOMAIN_PDC;
04330                                 else
04331                                         server_role = ROLE_DOMAIN_BDC;
04332                         }
04333                         break;
04334                 default:
04335                         DEBUG(0, ("Server's Role undefined due to unknown security mode\n"));
04336                         break;
04337         }
04338 
04339         DEBUG(10, ("set_server_role: role = %s\n", server_role_str(server_role)));
04340 }
04341 
04342 /***********************************************************
04343  If we should send plaintext/LANMAN passwords in the clinet
04344 ************************************************************/
04345 
04346 static void set_allowed_client_auth(void)
04347 {
04348         if (Globals.bClientNTLMv2Auth) {
04349                 Globals.bClientLanManAuth = False;
04350         }
04351         if (!Globals.bClientLanManAuth) {
04352                 Globals.bClientPlaintextAuth = False;
04353         }
04354 }
04355 
04356 /***************************************************************************
04357  JRA.
04358  The following code allows smbd to read a user defined share file.
04359  Yes, this is my intent. Yes, I'm comfortable with that...
04360 
04361  THE FOLLOWING IS SECURITY CRITICAL CODE.
04362 
04363  It washes your clothes, it cleans your house, it guards you while you sleep...
04364  Do not f%^k with it....
04365 ***************************************************************************/
04366 
04367 #define MAX_USERSHARE_FILE_SIZE (10*1024)
04368 
04369 /***************************************************************************
04370  Check allowed stat state of a usershare file.
04371  Ensure we print out who is dicking with us so the admin can
04372  get their sorry ass fired.
04373 ***************************************************************************/
04374 
04375 static BOOL check_usershare_stat(const char *fname, SMB_STRUCT_STAT *psbuf)
04376 {
04377         if (!S_ISREG(psbuf->st_mode)) {
04378                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
04379                         "not a regular file\n",
04380                         fname, (unsigned int)psbuf->st_uid ));
04381                 return False;
04382         }
04383 
04384         /* Ensure this doesn't have the other write bit set. */
04385         if (psbuf->st_mode & S_IWOTH) {
04386                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u allows "
04387                         "public write. Refusing to allow as a usershare file.\n",
04388                         fname, (unsigned int)psbuf->st_uid ));
04389                 return False;
04390         }
04391 
04392         /* Should be 10k or less. */
04393         if (psbuf->st_size > MAX_USERSHARE_FILE_SIZE) {
04394                 DEBUG(0,("check_usershare_stat: file %s owned by uid %u is "
04395                         "too large (%u) to be a user share file.\n",
04396                         fname, (unsigned int)psbuf->st_uid,
04397                         (unsigned int)psbuf->st_size ));
04398                 return False;
04399         }
04400 
04401         return True;
04402 }
04403 
04404 /***************************************************************************
04405  Parse the contents of a usershare file.
04406 ***************************************************************************/
04407 
04408 enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, 
04409                         SMB_STRUCT_STAT *psbuf,
04410                         const char *servicename,
04411                         int snum,
04412                         char **lines,
04413                         int numlines,
04414                         pstring sharepath,
04415                         pstring comment,
04416                         SEC_DESC **ppsd,
04417                         BOOL *pallow_guest)
04418 {
04419         const char **prefixallowlist = lp_usershare_prefix_allow_list();
04420         const char **prefixdenylist = lp_usershare_prefix_deny_list();
04421         int us_vers;
04422         SMB_STRUCT_DIR *dp;
04423         SMB_STRUCT_STAT sbuf;
04424 
04425         *pallow_guest = False;
04426 
04427         if (numlines < 4) {
04428                 return USERSHARE_MALFORMED_FILE;
04429         }
04430 
04431         if (strcmp(lines[0], "#VERSION 1") == 0) {
04432                 us_vers = 1;
04433         } else if (strcmp(lines[0], "#VERSION 2") == 0) {
04434                 us_vers = 2;
04435                 if (numlines < 5) {
04436                         return USERSHARE_MALFORMED_FILE;
04437                 }
04438         } else {
04439                 return USERSHARE_BAD_VERSION;
04440         }
04441 
04442         if (strncmp(lines[1], "path=", 5) != 0) {
04443                 return USERSHARE_MALFORMED_PATH;
04444         }
04445 
04446         pstrcpy(sharepath, &lines[1][5]);
04447         trim_string(sharepath, " ", " ");
04448 
04449         if (strncmp(lines[2], "comment=", 8) != 0) {
04450                 return USERSHARE_MALFORMED_COMMENT_DEF;
04451         }
04452 
04453         pstrcpy(comment, &lines[2][8]);
04454         trim_string(comment, " ", " ");
04455         trim_char(comment, '"', '"');
04456 
04457         if (strncmp(lines[3], "usershare_acl=", 14) != 0) {
04458                 return USERSHARE_MALFORMED_ACL_DEF;
04459         }
04460 
04461         if (!parse_usershare_acl(ctx, &lines[3][14], ppsd)) {
04462                 return USERSHARE_ACL_ERR;
04463         }
04464 
04465         if (us_vers == 2) {
04466                 if (strncmp(lines[4], "guest_ok=", 9) != 0) {
04467                         return USERSHARE_MALFORMED_ACL_DEF;
04468                 }
04469                 if (lines[4][9] == 'y') {
04470                         *pallow_guest = True;
04471                 }
04472         }
04473 
04474         if (snum != -1 && (strcmp(sharepath, ServicePtrs[snum]->szPath) == 0)) {
04475                 /* Path didn't change, no checks needed. */
04476                 return USERSHARE_OK;
04477         }
04478 
04479         /* The path *must* be absolute. */
04480         if (sharepath[0] != '/') {
04481                 DEBUG(2,("parse_usershare_file: share %s: path %s is not an absolute path.\n",
04482                         servicename, sharepath));
04483                 return USERSHARE_PATH_NOT_ABSOLUTE;
04484         }
04485 
04486         /* If there is a usershare prefix deny list ensure one of these paths
04487            doesn't match the start of the user given path. */
04488         if (prefixdenylist) {
04489                 int i;
04490                 for ( i=0; prefixdenylist[i]; i++ ) {
04491                         DEBUG(10,("parse_usershare_file: share %s : checking prefixdenylist[%d]='%s' against %s\n",
04492                                 servicename, i, prefixdenylist[i], sharepath ));
04493                         if (memcmp( sharepath, prefixdenylist[i], strlen(prefixdenylist[i])) == 0) {
04494                                 DEBUG(2,("parse_usershare_file: share %s path %s starts with one of the "
04495                                         "usershare prefix deny list entries.\n",
04496                                         servicename, sharepath));
04497                                 return USERSHARE_PATH_IS_DENIED;
04498                         }
04499                 }
04500         }
04501 
04502         /* If there is a usershare prefix allow list ensure one of these paths
04503            does match the start of the user given path. */
04504 
04505         if (prefixallowlist) {
04506                 int i;
04507                 for ( i=0; prefixallowlist[i]; i++ ) {
04508                         DEBUG(10,("parse_usershare_file: share %s checking prefixallowlist[%d]='%s' against %s\n",
04509                                 servicename, i, prefixallowlist[i], sharepath ));
04510                         if (memcmp( sharepath, prefixallowlist[i], strlen(prefixallowlist[i])) == 0) {
04511                                 break;
04512                         }
04513                 }
04514                 if (prefixallowlist[i] == NULL) {
04515                         DEBUG(2,("parse_usershare_file: share %s path %s doesn't start with one of the "
04516                                 "usershare prefix allow list entries.\n",
04517                                 servicename, sharepath));
04518                         return USERSHARE_PATH_NOT_ALLOWED;
04519                 }
04520         }
04521 
04522         /* Ensure this is pointing to a directory. */
04523         dp = sys_opendir(sharepath);
04524 
04525         if (!dp) {
04526                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
04527                         servicename, sharepath));
04528                 return USERSHARE_PATH_NOT_DIRECTORY;
04529         }
04530 
04531         /* Ensure the owner of the usershare file has permission to share
04532            this directory. */
04533 
04534         if (sys_stat(sharepath, &sbuf) == -1) {
04535                 DEBUG(2,("parse_usershare_file: share %s : stat failed on path %s. %s\n",
04536                         servicename, sharepath, strerror(errno) ));
04537                 sys_closedir(dp);
04538                 return USERSHARE_POSIX_ERR;
04539         }
04540 
04541         sys_closedir(dp);
04542 
04543         if (!S_ISDIR(sbuf.st_mode)) {
04544                 DEBUG(2,("parse_usershare_file: share %s path %s is not a directory.\n",
04545                         servicename, sharepath ));
04546                 return USERSHARE_PATH_NOT_DIRECTORY;
04547         }
04548 
04549         /* Check if sharing is restricted to owner-only. */
04550         /* psbuf is the stat of the usershare definition file,
04551            sbuf is the stat of the target directory to be shared. */
04552 
04553         if (lp_usershare_owner_only()) {
04554                 /* root can share anything. */
04555                 if ((psbuf->st_uid != 0) && (sbuf.st_uid != psbuf->st_uid)) {
04556                         return USERSHARE_PATH_NOT_ALLOWED;
04557                 }
04558         }
04559 
04560         return USERSHARE_OK;
04561 }
04562 
04563 /***************************************************************************
04564  Deal with a usershare file.
04565  Returns:
04566         >= 0 - snum
04567         -1 - Bad name, invalid contents.
04568            - service name already existed and not a usershare, problem
04569             with permissions to share directory etc.
04570 ***************************************************************************/
04571 
04572 static int process_usershare_file(const char *dir_name, const char *file_name, int snum_template)
04573 {
04574         SMB_STRUCT_STAT sbuf;
04575         SMB_STRUCT_STAT lsbuf;
04576         pstring fname;
04577         pstring sharepath;
04578         pstring comment;
04579         fstring service_name;
04580         char **lines = NULL;
04581         int numlines = 0;
04582         int fd = -1;
04583         int iService = -1;
04584         TALLOC_CTX *ctx = NULL;
04585         SEC_DESC *psd = NULL;
04586         BOOL guest_ok = False;
04587 
04588         /* Ensure share name doesn't contain invalid characters. */
04589         if (!validate_net_name(file_name, INVALID_SHARENAME_CHARS, strlen(file_name))) {
04590                 DEBUG(0,("process_usershare_file: share name %s contains "
04591                         "invalid characters (any of %s)\n",
04592                         file_name, INVALID_SHARENAME_CHARS ));
04593                 return -1;
04594         }
04595 
04596         fstrcpy(service_name, file_name);
04597 
04598         pstrcpy(fname, dir_name);
04599         pstrcat(fname, "/");
04600         pstrcat(fname, file_name);
04601 
04602         /* Minimize the race condition by doing an lstat before we
04603            open and fstat. Ensure this isn't a symlink link. */
04604 
04605         if (sys_lstat(fname, &lsbuf) != 0) {
04606                 DEBUG(0,("process_usershare_file: stat of %s failed. %s\n",
04607                         fname, strerror(errno) ));
04608                 return -1;
04609         }
04610 
04611         /* This must be a regular file, not a symlink, directory or
04612            other strange filetype. */
04613         if (!check_usershare_stat(fname, &lsbuf)) {
04614                 return -1;
04615         }
04616 
04617         /* See if there is already a servicenum for this name. */
04618         /* tdb_fetch_int32 returns -1 if not found. */
04619         iService = (int)tdb_fetch_int32(ServiceHash, canonicalize_servicename(service_name) );
04620 
04621         if (iService != -1 && ServicePtrs[iService]->usershare_last_mod == lsbuf.st_mtime) {
04622                 /* Nothing changed - Mark valid and return. */
04623                 DEBUG(10,("process_usershare_file: service %s not changed.\n",
04624                         service_name ));
04625                 ServicePtrs[iService]->usershare = USERSHARE_VALID;
04626                 return iService;
04627         }
04628 
04629         /* Try and open the file read only - no symlinks allowed. */
04630 #ifdef O_NOFOLLOW
04631         fd = sys_open(fname, O_RDONLY|O_NOFOLLOW, 0);
04632 #else
04633         fd = sys_open(fname, O_RDONLY, 0);
04634 #endif
04635 
04636         if (fd == -1) {
04637                 DEBUG(0,("process_usershare_file: unable to open %s. %s\n",
04638                         fname, strerror(errno) ));
04639                 return -1;
04640         }
04641 
04642         /* Now fstat to be *SURE* it's a regular file. */
04643         if (sys_fstat(fd, &sbuf) != 0) {
04644                 close(fd);
04645                 DEBUG(0,("process_usershare_file: fstat of %s failed. %s\n",
04646                         fname, strerror(errno) ));
04647                 return -1;
04648         }
04649 
04650         /* Is it the same dev/inode as was lstated ? */
04651         if (lsbuf.st_dev != sbuf.st_dev || lsbuf.st_ino != sbuf.st_ino) {
04652                 close(fd);
04653                 DEBUG(0,("process_usershare_file: fstat of %s is a different file from lstat. "
04654                         "Symlink spoofing going on ?\n", fname ));
04655                 return -1;
04656         }
04657 
04658         /* This must be a regular file, not a symlink, directory or
04659            other strange filetype. */
04660         if (!check_usershare_stat(fname, &sbuf)) {
04661                 return -1;
04662         }
04663 
04664         lines = fd_lines_load(fd, &numlines, MAX_USERSHARE_FILE_SIZE);
04665 
04666         close(fd);
04667         if (lines == NULL) {
04668                 DEBUG(0,("process_usershare_file: loading file %s owned by %u failed.\n",
04669                         fname, (unsigned int)sbuf.st_uid ));
04670                 return -1;
04671         }
04672 
04673         /* Should we allow printers to be shared... ? */
04674         ctx = talloc_init("usershare_sd_xctx");
04675         if (!ctx) {
04676                 file_lines_free(lines);
04677                 return 1;
04678         }
04679 
04680         if (parse_usershare_file(ctx, &sbuf, service_name,
04681                         iService, lines, numlines, sharepath,
04682                         comment, &psd, &guest_ok) != USERSHARE_OK) {
04683                 talloc_destroy(ctx);
04684                 file_lines_free(lines);
04685                 return -1;
04686         }
04687 
04688         file_lines_free(lines);
04689 
04690         /* Everything ok - add the service possibly using a template. */
04691         if (iService < 0) {
04692                 const service *sp = &sDefault;
04693                 if (snum_template != -1) {
04694                         sp = ServicePtrs[snum_template];
04695                 }
04696 
04697                 if ((iService = add_a_service(sp, service_name)) < 0) {
04698                         DEBUG(0, ("process_usershare_file: Failed to add "
04699                                 "new service %s\n", service_name));
04700                         talloc_destroy(ctx);
04701                         return -1;
04702                 }
04703 
04704                 /* Read only is controlled by usershare ACL below. */
04705                 ServicePtrs[iService]->bRead_only = False;
04706         }
04707 
04708         /* Write the ACL of the new/modified share. */
04709         if (!set_share_security(service_name, psd)) {
04710                  DEBUG(0, ("process_usershare_file: Failed to set share "
04711                         "security for user share %s\n",
04712                         service_name ));
04713                 lp_remove_service(iService);
04714                 talloc_destroy(ctx);
04715                 return -1;
04716         }
04717 
04718         talloc_destroy(ctx);
04719 
04720         /* If from a template it may be marked invalid. */
04721         ServicePtrs[iService]->valid = True;
04722 
04723         /* Set the service as a valid usershare. */
04724         ServicePtrs[iService]->usershare = USERSHARE_VALID;
04725 
04726         /* Set guest access. */
04727         if (lp_usershare_allow_guests()) {
04728                 ServicePtrs[iService]->bGuest_ok = guest_ok;
04729         }
04730 
04731         /* And note when it was loaded. */
04732         ServicePtrs[iService]->usershare_last_mod = sbuf.st_mtime;
04733         string_set(&ServicePtrs[iService]->szPath, sharepath);
04734         string_set(&ServicePtrs[iService]->comment, comment);
04735 
04736         return iService;
04737 }
04738 
04739 /***************************************************************************
04740  Checks if a usershare entry has been modified since last load.
04741 ***************************************************************************/
04742 
04743 static BOOL usershare_exists(int iService, time_t *last_mod)
04744 {
04745         SMB_STRUCT_STAT lsbuf;
04746         const char *usersharepath = Globals.szUsersharePath;
04747         pstring fname;
04748 
04749         pstrcpy(fname, usersharepath);
04750         pstrcat(fname, "/");
04751         pstrcat(fname, ServicePtrs[iService]->szService);
04752 
04753         if (sys_lstat(fname, &lsbuf) != 0) {
04754                 return False;
04755         }
04756 
04757         if (!S_ISREG(lsbuf.st_mode)) {
04758                 return False;
04759         }
04760 
04761         *last_mod = lsbuf.st_mtime;
04762         return True;
04763 }
04764 
04765 /***************************************************************************
04766  Load a usershare service by name. Returns a valid servicenumber or -1.
04767 ***************************************************************************/
04768 
04769 int load_usershare_service(const char *servicename)
04770 {
04771         SMB_STRUCT_STAT sbuf;
04772         const char *usersharepath = Globals.szUsersharePath;
04773         int max_user_shares = Globals.iUsershareMaxShares;
04774         int snum_template = -1;
04775 
04776         if (*usersharepath == 0 ||  max_user_shares == 0) {
04777                 return -1;
04778         }
04779 
04780         if (sys_stat(usersharepath, &sbuf) != 0) {
04781                 DEBUG(0,("load_usershare_service: stat of %s failed. %s\n",
04782                         usersharepath, strerror(errno) ));
04783                 return -1;
04784         }
04785 
04786         if (!S_ISDIR(sbuf.st_mode)) {
04787                 DEBUG(0,("load_usershare_service: %s is not a directory.\n",
04788                         usersharepath ));
04789                 return -1;
04790         }
04791 
04792         /*
04793          * This directory must be owned by root, and have the 't' bit set.
04794          * It also must not be writable by "other".
04795          */
04796 
04797 #ifdef S_ISVTX
04798         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
04799 #else
04800         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
04801 #endif
04802                 DEBUG(0,("load_usershare_service: directory %s is not owned by root "
04803                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
04804                         usersharepath ));
04805                 return -1;
04806         }
04807 
04808         /* Ensure the template share exists if it's set. */
04809         if (Globals.szUsershareTemplateShare[0]) {
04810                 /* We can't use lp_servicenumber here as we are recommending that
04811                    template shares have -valid=False set. */
04812                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
04813                         if (ServicePtrs[snum_template]->szService &&
04814                                         strequal(ServicePtrs[snum_template]->szService,
04815                                                 Globals.szUsershareTemplateShare)) {
04816                                 break;
04817                         }
04818                 }
04819 
04820                 if (snum_template == -1) {
04821                         DEBUG(0,("load_usershare_service: usershare template share %s "
04822                                 "does not exist.\n",
04823                                 Globals.szUsershareTemplateShare ));
04824                         return -1;
04825                 }
04826         }
04827 
04828         return process_usershare_file(usersharepath, servicename, snum_template);
04829 }
04830 
04831 /***************************************************************************
04832  Load all user defined shares from the user share directory.
04833  We only do this if we're enumerating the share list.
04834  This is the function that can delete usershares that have
04835  been removed.
04836 ***************************************************************************/
04837 
04838 int load_usershare_shares(void)
04839 {
04840         SMB_STRUCT_DIR *dp;
04841         SMB_STRUCT_STAT sbuf;
04842         SMB_STRUCT_DIRENT *de;
04843         int num_usershares = 0;
04844         int max_user_shares = Globals.iUsershareMaxShares;
04845         unsigned int num_dir_entries, num_bad_dir_entries, num_tmp_dir_entries;
04846         unsigned int allowed_bad_entries = ((2*max_user_shares)/10);
04847         unsigned int allowed_tmp_entries = ((2*max_user_shares)/10);
04848         int iService;
04849         int snum_template = -1;
04850         const char *usersharepath = Globals.szUsersharePath;
04851         int ret = lp_numservices();
04852 
04853         if (max_user_shares == 0 || *usersharepath == '\0') {
04854                 return lp_numservices();
04855         }
04856 
04857         if (sys_stat(usersharepath, &sbuf) != 0) {
04858                 DEBUG(0,("load_usershare_shares: stat of %s failed. %s\n",
04859                         usersharepath, strerror(errno) ));
04860                 return ret;
04861         }
04862 
04863         /*
04864          * This directory must be owned by root, and have the 't' bit set.
04865          * It also must not be writable by "other".
04866          */
04867 
04868 #ifdef S_ISVTX
04869         if (sbuf.st_uid != 0 || !(sbuf.st_mode & S_ISVTX) || (sbuf.st_mode & S_IWOTH)) {
04870 #else
04871         if (sbuf.st_uid != 0 || (sbuf.st_mode & S_IWOTH)) {
04872 #endif
04873                 DEBUG(0,("load_usershare_shares: directory %s is not owned by root "
04874                         "or does not have the sticky bit 't' set or is writable by anyone.\n",
04875                         usersharepath ));
04876                 return ret;
04877         }
04878 
04879         /* Ensure the template share exists if it's set. */
04880         if (Globals.szUsershareTemplateShare[0]) {
04881                 /* We can't use lp_servicenumber here as we are recommending that
04882                    template shares have -valid=False set. */
04883                 for (snum_template = iNumServices - 1; snum_template >= 0; snum_template--) {
04884                         if (ServicePtrs[snum_template]->szService &&
04885                                         strequal(ServicePtrs[snum_template]->szService,
04886                                                 Globals.szUsershareTemplateShare)) {
04887                                 break;
04888                         }
04889                 }
04890 
04891                 if (snum_template == -1) {
04892                         DEBUG(0,("load_usershare_shares: usershare template share %s "
04893                                 "does not exist.\n",
04894                                 Globals.szUsershareTemplateShare ));
04895                         return ret;
04896                 }
04897         }
04898 
04899         /* Mark all existing usershares as pending delete. */
04900         for (iService = iNumServices - 1; iService >= 0; iService--) {
04901                 if (VALID(iService) && ServicePtrs[iService]->usershare) {
04902                         ServicePtrs[iService]->usershare = USERSHARE_PENDING_DELETE;
04903                 }
04904         }
04905 
04906         dp = sys_opendir(usersharepath);
04907         if (!dp) {
04908                 DEBUG(0,("load_usershare_shares:: failed to open directory %s. %s\n",
04909                         usersharepath, strerror(errno) ));
04910                 return ret;
04911         }
04912 
04913         for (num_dir_entries = 0, num_bad_dir_entries = 0, num_tmp_dir_entries = 0;
04914                         (de = sys_readdir(dp));
04915                         num_dir_entries++ ) {
04916                 int r;
04917                 const char *n = de->d_name;
04918 
04919                 /* Ignore . and .. */
04920                 if (*n == '.') {
04921                         if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
04922                                 continue;
04923                         }
04924                 }
04925 
04926                 if (n[0] == ':') {
04927                         /* Temporary file used when creating a share. */
04928                         num_tmp_dir_entries++;
04929                 }
04930 
04931                 /* Allow 20% tmp entries. */
04932                 if (num_tmp_dir_entries > allowed_tmp_entries) {
04933                         DEBUG(0,("load_usershare_shares: too many temp entries (%u) "
04934                                 "in directory %s\n",
04935                                 num_tmp_dir_entries, usersharepath));
04936                         break;
04937                 }
04938 
04939                 r = process_usershare_file(usersharepath, n, snum_template);
04940                 if (r == 0) {
04941                         /* Update the services count. */
04942                         num_usershares++;
04943                         if (num_usershares >= max_user_shares) {
04944                                 DEBUG(0,("load_usershare_shares: max user shares reached "
04945                                         "on file %s in directory %s\n",
04946                                         n, usersharepath ));
04947                                 break;
04948                         }
04949                 } else if (r == -1) {
04950                         num_bad_dir_entries++;
04951                 }
04952 
04953                 /* Allow 20% bad entries. */
04954                 if (num_bad_dir_entries > allowed_bad_entries) {
04955                         DEBUG(0,("load_usershare_shares: too many bad entries (%u) "
04956                                 "in directory %s\n",
04957                                 num_bad_dir_entries, usersharepath));
04958                         break;
04959                 }
04960 
04961                 /* Allow 20% bad entries. */
04962                 if (num_dir_entries > max_user_shares + allowed_bad_entries) {
04963                         DEBUG(0,("load_usershare_shares: too many total entries (%u) "
04964                         "in directory %s\n",
04965                         num_dir_entries, usersharepath));
04966                         break;
04967                 }
04968         }
04969 
04970         sys_closedir(dp);
04971 
04972         /* Sweep through and delete any non-refreshed usershares that are
04973            not currently in use. */
04974         for (iService = iNumServices - 1; iService >= 0; iService--) {
04975                 if (VALID(iService) && (ServicePtrs[iService]->usershare == USERSHARE_PENDING_DELETE)) {
04976                         if (conn_snum_used(iService)) {
04977                                 continue;
04978                         }
04979                         /* Remove from the share ACL db. */
04980                         DEBUG(10,("load_usershare_shares: Removing deleted usershare %s\n",
04981                                 lp_servicename(iService) ));
04982                         delete_share_security(snum2params_static(iService));
04983                         free_service_byindex(iService);
04984                 }
04985         }
04986 
04987         return lp_numservices();
04988 }
04989 
04990 /********************************************************
04991  Destroy global resources allocated in this file
04992 ********************************************************/
04993 
04994 void gfree_loadparm(void)
04995 {
04996         struct file_lists *f;
04997         struct file_lists *next;
04998         int i;
04999 
05000         lp_TALLOC_FREE();
05001 
05002         /* Free the file lists */
05003 
05004         f = file_lists;
05005         while( f ) {
05006                 next = f->next;
05007                 SAFE_FREE( f->name );
05008                 SAFE_FREE( f->subfname );
05009                 SAFE_FREE( f );
05010                 f = next;
05011         }
05012 
05013         /* Free resources allocated to services */
05014 
05015         for ( i = 0; i < iNumServices; i++ ) {
05016                 if ( VALID(i) ) {
05017                         free_service_byindex(i);
05018                 }
05019         }
05020 
05021         SAFE_FREE( ServicePtrs );
05022         iNumServices = 0;
05023 
05024         /* Now release all resources allocated to global
05025            parameters and the default service */
05026 
05027         for (i = 0; parm_table[i].label; i++) 
05028         {
05029                 if ( parm_table[i].type == P_STRING 
05030                         || parm_table[i].type == P_USTRING ) 
05031                 {
05032                         string_free( (char**)parm_table[i].ptr );
05033                 }
05034                 else if (parm_table[i].type == P_LIST) {
05035                         str_list_free( (char***)parm_table[i].ptr );
05036                 }
05037         }
05038 }
05039 
05040 /***************************************************************************
05041  Load the services array from the services file. Return True on success, 
05042  False on failure.
05043 ***************************************************************************/
05044 
05045 BOOL lp_load(const char *pszFname,
05046              BOOL global_only,
05047              BOOL save_defaults,
05048              BOOL add_ipc,
05049              BOOL initialize_globals)
05050 {
05051         pstring n2;
05052         BOOL bRetval;
05053         param_opt_struct *data, *pdata;
05054 
05055         pstrcpy(n2, pszFname);
05056         
05057         standard_sub_basic( get_current_username(), current_user_info.domain,
05058                             n2,sizeof(n2) );
05059 
05060         add_to_file_list(pszFname, n2);
05061 
05062         bRetval = False;
05063 
05064         DEBUG(3, ("lp_load: refreshing parameters\n"));
05065         
05066         bInGlobalSection = True;
05067         bGlobalOnly = global_only;
05068 
05069         init_globals(! initialize_globals);
05070         debug_init();
05071 
05072         if (save_defaults) {
05073                 init_locals();
05074                 lp_save_defaults();
05075         }
05076 
05077         if (Globals.param_opt != NULL) {
05078                 data = Globals.param_opt;
05079                 while (data) {
05080                         string_free(&data->key);
05081                         string_free(&data->value);
05082                         str_list_free(&data->list);
05083                         pdata = data->next;
05084                         SAFE_FREE(data);
05085                         data = pdata;
05086                 }
05087                 Globals.param_opt = NULL;
05088         }
05089         
05090         /* We get sections first, so have to start 'behind' to make up */
05091         iServiceIndex = -1;
05092         bRetval = pm_process(n2, do_section, do_parameter);
05093 
05094         /* finish up the last section */
05095         DEBUG(4, ("pm_process() returned %s\n", BOOLSTR(bRetval)));
05096         if (bRetval)
05097                 if (iServiceIndex >= 0)
05098                         bRetval = service_ok(iServiceIndex);
05099 
05100         lp_add_auto_services(lp_auto_services());
05101 
05102         if (add_ipc) {
05103                 /* When 'restrict anonymous = 2' guest connections to ipc$
05104                    are denied */
05105                 lp_add_ipc("IPC$", (lp_restrict_anonymous() < 2));
05106                 if ( lp_enable_asu_support() )
05107                         lp_add_ipc("ADMIN$", False);
05108         }
05109 
05110         set_server_role();
05111         set_default_server_announce_type();
05112         set_allowed_client_auth();
05113 
05114         bLoaded = True;
05115 
05116         /* Now we check bWINSsupport and set szWINSserver to 127.0.0.1 */
05117         /* if bWINSsupport is true and we are in the client            */
05118         if (in_client && Globals.bWINSsupport) {
05119                 lp_do_parameter(GLOBAL_SECTION_SNUM, "wins server", "127.0.0.1");
05120         }
05121 
05122         init_iconv();
05123 
05124         return (bRetval);
05125 }
05126 
05127 /***************************************************************************
05128  Reset the max number of services.
05129 ***************************************************************************/
05130 
05131 void lp_resetnumservices(void)
05132 {
05133         iNumServices = 0;
05134 }
05135 
05136 /***************************************************************************
05137  Return the max number of services.
05138 ***************************************************************************/
05139 
05140 int lp_numservices(void)
05141 {
05142         return (iNumServices);
05143 }
05144 
05145 /***************************************************************************
05146 Display the contents of the services array in human-readable form.
05147 ***************************************************************************/
05148 
05149 void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
05150 {
05151         int iService;
05152 
05153         if (show_defaults)
05154                 defaults_saved = False;
05155 
05156         dump_globals(f);
05157 
05158         dump_a_service(&sDefault, f);
05159 
05160         for (iService = 0; iService < maxtoprint; iService++) {
05161                 fprintf(f,"\n");
05162                 lp_dump_one(f, show_defaults, iService);
05163         }
05164 }
05165 
05166 /***************************************************************************
05167 Display the contents of one service in human-readable form.
05168 ***************************************************************************/
05169 
05170 void lp_dump_one(FILE * f, BOOL show_defaults, int snum)
05171 {
05172         if (VALID(snum)) {
05173                 if (ServicePtrs[snum]->szService[0] == '\0')
05174                         return;
05175                 dump_a_service(ServicePtrs[snum], f);
05176         }
05177 }
05178 
05179 /***************************************************************************
05180 Return the number of the service with the given name, or -1 if it doesn't
05181 exist. Note that this is a DIFFERENT ANIMAL from the internal function
05182 getservicebyname()! This works ONLY if all services have been loaded, and
05183 does not copy the found service.
05184 ***************************************************************************/
05185 
05186 int lp_servicenumber(const char *pszServiceName)
05187 {
05188         int iService;
05189         fstring serviceName;
05190         
05191         if (!pszServiceName) {
05192                 return GLOBAL_SECTION_SNUM;
05193         }
05194         
05195         for (iService = iNumServices - 1; iService >= 0; iService--) {
05196                 if (VALID(iService) && ServicePtrs[iService]->szService) {
05197                         /*
05198                          * The substitution here is used to support %U is
05199                          * service names
05200                          */
05201                         fstrcpy(serviceName, ServicePtrs[iService]->szService);
05202                         standard_sub_basic(get_current_username(),
05203                                            current_user_info.domain,
05204                                            serviceName,sizeof(serviceName));
05205                         if (strequal(serviceName, pszServiceName)) {
05206                                 break;
05207                         }
05208                 }
05209         }
05210 
05211         if (iService >= 0 && ServicePtrs[iService]->usershare == USERSHARE_VALID) {
05212                 time_t last_mod;
05213 
05214                 if (!usershare_exists(iService, &last_mod)) {
05215                         /* Remove the share security tdb entry for it. */
05216                         delete_share_security(snum2params_static(iService));
05217                         /* Remove it from the array. */
05218                         free_service_byindex(iService);
05219                         /* Doesn't exist anymore. */
05220                         return GLOBAL_SECTION_SNUM;
05221                 }
05222 
05223                 /* Has it been modified ? If so delete and reload. */
05224                 if (ServicePtrs[iService]->usershare_last_mod < last_mod) {
05225                         /* Remove it from the array. */
05226                         free_service_byindex(iService);
05227                         /* and now reload it. */
05228                         iService = load_usershare_service(pszServiceName);
05229                 }
05230         }
05231 
05232         if (iService < 0) {
05233                 DEBUG(7,("lp_servicenumber: couldn't find %s\n", pszServiceName));
05234                 return GLOBAL_SECTION_SNUM;
05235         }
05236 
05237         return (iService);
05238 }
05239 
05240 BOOL share_defined(const char *service_name)
05241 {
05242         return (lp_servicenumber(service_name) != -1);
05243 }
05244 
05245 struct share_params *get_share_params(TALLOC_CTX *mem_ctx,
05246                                       const char *sharename)
05247 {
05248         struct share_params *result;
05249         char *sname;
05250         int snum;
05251 
05252         if (!(sname = SMB_STRDUP(sharename))) {
05253                 return NULL;
05254         }
05255 
05256         snum = find_service(sname);
05257         SAFE_FREE(sname);
05258 
05259         if (snum < 0) {
05260                 return NULL;
05261         }
05262 
05263         if (!(result = TALLOC_P(mem_ctx, struct share_params))) {
05264                 DEBUG(0, ("talloc failed\n"));
05265                 return NULL;
05266         }
05267 
05268         result->service = snum;
05269         return result;
05270 }
05271 
05272 struct share_iterator *share_list_all(TALLOC_CTX *mem_ctx)
05273 {
05274         struct share_iterator *result;
05275 
05276         if (!(result = TALLOC_P(mem_ctx, struct share_iterator))) {
05277                 DEBUG(0, ("talloc failed\n"));
05278                 return NULL;
05279         }
05280 
05281         result->next_id = 0;
05282         return result;
05283 }
05284 
05285 struct share_params *next_share(struct share_iterator *list)
05286 {
05287         struct share_params *result;
05288 
05289         while (!lp_snum_ok(list->next_id) &&
05290                (list->next_id < lp_numservices())) {
05291                 list->next_id += 1;
05292         }
05293 
05294         if (list->next_id >= lp_numservices()) {
05295                 return NULL;
05296         }
05297 
05298         if (!(result = TALLOC_P(list, struct share_params))) {
05299                 DEBUG(0, ("talloc failed\n"));
05300                 return NULL;
05301         }
05302 
05303         result->service = list->next_id;
05304         list->next_id += 1;
05305         return result;
05306 }
05307 
05308 struct share_params *next_printer(struct share_iterator *list)
05309 {
05310         struct share_params *result;
05311 
05312         while ((result = next_share(list)) != NULL) {
05313                 if (lp_print_ok(result->service)) {
05314                         break;
05315                 }
05316         }
05317         return result;
05318 }
05319 
05320 /*
05321  * This is a hack for a transition period until we transformed all code from
05322  * service numbers to struct share_params.
05323  */
05324 
05325 struct share_params *snum2params_static(int snum)
05326 {
05327         static struct share_params result;
05328         result.service = snum;
05329         return &result;
05330 }
05331 
05332 /*******************************************************************
05333  A useful volume label function. 
05334 ********************************************************************/
05335 
05336 const char *volume_label(int snum)
05337 {
05338         char *ret;
05339         const char *label = lp_volume(snum);
05340         if (!*label) {
05341                 label = lp_servicename(snum);
05342         }
05343                 
05344         /* This returns a 33 byte guarenteed null terminated string. */
05345         ret = talloc_strndup(main_loop_talloc_get(), label, 32);
05346         if (!ret) {
05347                 return "";
05348         }               
05349         return ret;
05350 }
05351 
05352 /*******************************************************************
05353  Set the server type we will announce as via nmbd.
05354 ********************************************************************/
05355 
05356 static void set_default_server_announce_type(void)
05357 {
05358         default_server_announce = 0;
05359         default_server_announce |= SV_TYPE_WORKSTATION;
05360         default_server_announce |= SV_TYPE_SERVER;
05361         default_server_announce |= SV_TYPE_SERVER_UNIX;
05362 
05363         /* note that the flag should be set only if we have a 
05364            printer service but nmbd doesn't actually load the 
05365            services so we can't tell   --jerry */
05366 
05367         default_server_announce |= SV_TYPE_PRINTQ_SERVER;
05368 
05369         switch (lp_announce_as()) {
05370                 case ANNOUNCE_AS_NT_SERVER:
05371                         default_server_announce |= SV_TYPE_SERVER_NT;
05372                         /* fall through... */
05373                 case ANNOUNCE_AS_NT_WORKSTATION:
05374                         default_server_announce |= SV_TYPE_NT;
05375                         break;
05376                 case ANNOUNCE_AS_WIN95:
05377                         default_server_announce |= SV_TYPE_WIN95_PLUS;
05378                         break;
05379                 case ANNOUNCE_AS_WFW:
05380                         default_server_announce |= SV_TYPE_WFW;
05381                         break;
05382                 default:
05383                         break;
05384         }
05385 
05386         switch (lp_server_role()) {
05387                 case ROLE_DOMAIN_MEMBER:
05388                         default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
05389                         break;
05390                 case ROLE_DOMAIN_PDC:
05391                         default_server_announce |= SV_TYPE_DOMAIN_CTRL;
05392                         break;
05393                 case ROLE_DOMAIN_BDC:
05394                         default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
05395                         break;
05396                 case ROLE_STANDALONE:
05397                 default:
05398                         break;
05399         }
05400         if (lp_time_server())
05401                 default_server_announce |= SV_TYPE_TIME_SOURCE;
05402 
05403         if (lp_host_msdfs())
05404                 default_server_announce |= SV_TYPE_DFS_SERVER;
05405 }
05406 
05407 /***********************************************************
05408  returns role of Samba server
05409 ************************************************************/
05410 
05411 int lp_server_role(void)
05412 {
05413         return server_role;
05414 }
05415 
05416 /***********************************************************
05417  If we are PDC then prefer us as DMB
05418 ************************************************************/
05419 
05420 BOOL lp_domain_master(void)
05421 {
05422         if (Globals.bDomainMaster == Auto)
05423                 return (lp_server_role() == ROLE_DOMAIN_PDC);
05424 
05425         return Globals.bDomainMaster;
05426 }
05427 
05428 /***********************************************************
05429  If we are DMB then prefer us as LMB
05430 ************************************************************/
05431 
05432 BOOL lp_preferred_master(void)
05433 {
05434         if (Globals.bPreferredMaster == Auto)
05435                 return (lp_local_master() && lp_domain_master());
05436 
05437         return Globals.bPreferredMaster;
05438 }
05439 
05440 /*******************************************************************
05441  Remove a service.
05442 ********************************************************************/
05443 
05444 void lp_remove_service(int snum)
05445 {
05446         ServicePtrs[snum]->valid = False;
05447         invalid_services[num_invalid_services++] = snum;
05448 }
05449 
05450 /*******************************************************************
05451  Copy a service.
05452 ********************************************************************/
05453 
05454 void lp_copy_service(int snum, const char *new_name)
05455 {
05456         do_section(new_name);
05457         if (snum >= 0) {
05458                 snum = lp_servicenumber(new_name);
05459                 if (snum >= 0)
05460                         lp_do_parameter(snum, "copy", lp_servicename(snum));
05461         }
05462 }
05463 
05464 
05465 /*******************************************************************
05466  Get the default server type we will announce as via nmbd.
05467 ********************************************************************/
05468 
05469 int lp_default_server_announce(void)
05470 {
05471         return default_server_announce;
05472 }
05473 
05474 /*******************************************************************
05475  Split the announce version into major and minor numbers.
05476 ********************************************************************/
05477 
05478 int lp_major_announce_version(void)
05479 {
05480         static BOOL got_major = False;
05481         static int major_version = DEFAULT_MAJOR_VERSION;
05482         char *vers;
05483         char *p;
05484 
05485         if (got_major)
05486                 return major_version;
05487 
05488         got_major = True;
05489         if ((vers = lp_announce_version()) == NULL)
05490                 return major_version;
05491 
05492         if ((p = strchr_m(vers, '.')) == 0)
05493                 return major_version;
05494 
05495         *p = '\0';
05496         major_version = atoi(vers);
05497         return major_version;
05498 }
05499 
05500 int lp_minor_announce_version(void)
05501 {
05502         static BOOL got_minor = False;
05503         static int minor_version = DEFAULT_MINOR_VERSION;
05504         char *vers;
05505         char *p;
05506 
05507         if (got_minor)
05508                 return minor_version;
05509 
05510         got_minor = True;
05511         if ((vers = lp_announce_version()) == NULL)
05512                 return minor_version;
05513 
05514         if ((p = strchr_m(vers, '.')) == 0)
05515                 return minor_version;
05516 
05517         p++;
05518         minor_version = atoi(p);
05519         return minor_version;
05520 }
05521 
05522 /***********************************************************
05523  Set the global name resolution order (used in smbclient).
05524 ************************************************************/
05525 
05526 void lp_set_name_resolve_order(const char *new_order)
05527 {
05528         string_set(&Globals.szNameResolveOrder, new_order);
05529 }
05530 
05531 const char *lp_printername(int snum)
05532 {
05533         const char *ret = _lp_printername(snum);
05534         if (ret == NULL || (ret != NULL && *ret == '\0'))
05535                 ret = lp_const_servicename(snum);
05536 
05537         return ret;
05538 }
05539 
05540 
05541 /***********************************************************
05542  Allow daemons such as winbindd to fix their logfile name.
05543 ************************************************************/
05544 
05545 void lp_set_logfile(const char *name)
05546 {
05547         string_set(&Globals.szLogFile, name);
05548         pstrcpy(debugf, name);
05549 }
05550 
05551 /*******************************************************************
05552  Return the max print jobs per queue.
05553 ********************************************************************/
05554 
05555 int lp_maxprintjobs(int snum)
05556 {
05557         int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
05558         if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
05559                 maxjobs = PRINT_MAX_JOBID - 1;
05560 
05561         return maxjobs;
05562 }
05563 
05564 const char *lp_printcapname(void)
05565 {
05566         if ((Globals.szPrintcapname != NULL) &&
05567             (Globals.szPrintcapname[0] != '\0'))
05568                 return Globals.szPrintcapname;
05569 
05570         if (sDefault.iPrinting == PRINT_CUPS) {
05571 #ifdef HAVE_CUPS
05572                 return "cups";
05573 #else
05574                 return "lpstat";
05575 #endif
05576         }
05577 
05578         if (sDefault.iPrinting == PRINT_BSD)
05579                 return "/etc/printcap";
05580 
05581         return PRINTCAP_NAME;
05582 }
05583 
05584 /*******************************************************************
05585  Ensure we don't use sendfile if server smb signing is active.
05586 ********************************************************************/
05587 
05588 static uint32 spoolss_state;
05589 
05590 BOOL lp_disable_spoolss( void )
05591 {
05592         if ( spoolss_state == SVCCTL_STATE_UNKNOWN )
05593                 spoolss_state = _lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
05594 
05595         return spoolss_state == SVCCTL_STOPPED ? True : False;
05596 }
05597 
05598 void lp_set_spoolss_state( uint32 state )
05599 {
05600         SMB_ASSERT( (state == SVCCTL_STOPPED) || (state == SVCCTL_RUNNING) );
05601 
05602         spoolss_state = state;
05603 }
05604 
05605 uint32 lp_get_spoolss_state( void )
05606 {
05607         return lp_disable_spoolss() ? SVCCTL_STOPPED : SVCCTL_RUNNING;
05608 }
05609 
05610 /*******************************************************************
05611  Ensure we don't use sendfile if server smb signing is active.
05612 ********************************************************************/
05613 
05614 BOOL lp_use_sendfile(int snum)
05615 {
05616         /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */
05617         if (Protocol < PROTOCOL_NT1) {
05618                 return False;
05619         }
05620         return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && !srv_is_signing_active());
05621 }
05622 
05623 /*******************************************************************
05624  Turn off sendfile if we find the underlying OS doesn't support it.
05625 ********************************************************************/
05626 
05627 void set_use_sendfile(int snum, BOOL val)
05628 {
05629         if (LP_SNUM_OK(snum))
05630                 ServicePtrs[snum]->bUseSendfile = val;
05631         else
05632                 sDefault.bUseSendfile = val;
05633 }
05634 
05635 /*******************************************************************
05636  Turn off storing DOS attributes if this share doesn't support it.
05637 ********************************************************************/
05638 
05639 void set_store_dos_attributes(int snum, BOOL val)
05640 {
05641         if (!LP_SNUM_OK(snum))
05642                 return;
05643         ServicePtrs[(snum)]->bStoreDosAttributes = val;
05644 }
05645 
05646 void lp_set_mangling_method(const char *new_method)
05647 {
05648         string_set(&Globals.szManglingMethod, new_method);
05649 }
05650 
05651 /*******************************************************************
05652  Global state for POSIX pathname processing.
05653 ********************************************************************/
05654 
05655 static BOOL posix_pathnames;
05656 
05657 BOOL lp_posix_pathnames(void)
05658 {
05659         return posix_pathnames;
05660 }
05661 
05662 /*******************************************************************
05663  Change everything needed to ensure POSIX pathname processing (currently
05664  not much).
05665 ********************************************************************/
05666 
05667 void lp_set_posix_pathnames(void)
05668 {
05669         posix_pathnames = True;
05670 }
05671 
05672 /*******************************************************************
05673  Global state for POSIX lock processing - CIFS unix extensions.
05674 ********************************************************************/
05675 
05676 BOOL posix_default_lock_was_set;
05677 static enum brl_flavour posix_cifsx_locktype; /* By default 0 == WINDOWS_LOCK */
05678 
05679 enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp)
05680 {
05681         if (posix_default_lock_was_set) {
05682                 return posix_cifsx_locktype;
05683         } else {
05684                 return fsp->posix_open ? POSIX_LOCK : WINDOWS_LOCK;
05685         }
05686 }
05687 
05688 /*******************************************************************
05689 ********************************************************************/
05690 
05691 void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val)
05692 {
05693         posix_default_lock_was_set = True;
05694         posix_cifsx_locktype = val;
05695 }

Sambaに対してSat Aug 29 21:23:12 2009に生成されました。  doxygen 1.4.7