0657 nwnss: import residual NSS backend providers

This commit is contained in:
Mario Fetka
2026-06-16 18:15:52 +00:00
parent 7db083f169
commit be8f05dc34
14 changed files with 17126 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
/****************************************************************************
|
| (C) Copyright 2001 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Advance File Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
| $RCSfile$
| $Revision: 465 $
|
|---------------------------------------------------------------------------
| This module is used to:
| This defines globals and prototypes for the background checker.
+-------------------------------------------------------------------------*/
#ifndef _SEQUPDATER_H_
#define _SEQUPDATER_H_
#if zLINUX
extern void SEQ_StartProcess(void);
extern void SEQ_StopProcess(void);
extern void SEQ_Sleep(NINT seconds);
extern void SEQ_Wakeup(void);
#endif
#endif /* _SEQUPDATER_H_ */

View File

@@ -184,6 +184,18 @@ add_library(nwnss SHARED
comn/common/comnEFL.c
comn/common/comnLog.c
comn/common/checker.c
comn/common/cSA.c
comn/common/hmc.c
comn/common/repair.c
comn/common/cmdLineRecovery.c
comn/common/seqUpdater.c
comn/common/comnStartup.c
comn/sbs/sbsMgmt.c
comn/authsys/zasAuthModel.c
comn/authsys/zasAuthSpace.c
comn/authsys/zasAuthCache.c
comn/authsys/unixAuthModel.c
comn/compression/nwAlgo.c
comn/common/ndpIdBrokerShared.c
library/misc/sysimp.c
comn/main/comnCmdline.c

View File

@@ -0,0 +1,512 @@
/****************************************************************************
|
| (C) Copyright 2003 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| Novell Storage Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2005-08-10 01:03:51 +0530 (Wed, 10 Aug 2005) $
|
| $RCSfile$
| $Revision: 1177 $
|
|---------------------------------------------------------------------------
| This module is used to:
| These are the authorization routines for the Unix authorization
| model.
+-------------------------------------------------------------------------*/
#include <linux/module.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <omni.h> /* NSS Library*/
#include "zParams.h"
#include "pssConnection.h"
#include "msgName.h"
#include "objectIDStore.h"
#include "checker.h"
#include "unixAuthModel.h"
#include "unixAuthSpace.h"
#include "zasAuthSpace.h"
/*-------------------------------------------------------------------------
* Global variables
*-------------------------------------------------------------------------*/
NINT UXASindex; /* the index assigned to the Unix authorization space */
BOOL UXASAuthStarted = FALSE;
NINT UX_InitialMode = 0x750;
struct AuthModelOps_s UnixAuthorizeModelOps;
/***************************************************************************
* This will be called at Authorization model init time
***************************************************************************/
STATUS UXAS_Startup(void)
{
GeneralMsg_s genMsg;
AuthModelBeast_s *authModel;
AuthSpaceBeast_s *authSpace;
ASSERT_MPKNSS_LOCK();
COMN_STRUCT_INIT(genMsg);
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
if ((authModel = COMN_RegisterAuthorizeModel(&genMsg, AUTH_MODEL_VERSION,
zFTYPE_UNIX_AUTH_MODEL, MSGNot("Unix"), &UnixAuthorizeModelOps)) == NULL)
{
return zFAILURE;
}
if ((authSpace = COMN_RegisterAuthorizeSpace(&genMsg, authModel,
zFTYPE_UNIX_AUTH_SPACE, MSGNot("UnixToUnix"),
(AuthSpaceOps_s *)&UnixAuthorizeSpaceOps)) == NULL)
{
return zFAILURE;
}
if ((authSpace = COMN_RegisterAuthorizeSpace(&genMsg, authModel,
zFTYPE_ZAS_AUTH_SPACE, MSGNot("NetWareToUnix"),
(AuthSpaceOps_s *)&NetWareToUnixAuthorizeSpaceOps)) == NULL)
{
return zFAILURE;
}
UXASAuthStarted = TRUE;
return zOK;
}
/***************************************************************************
* This will be called at Authorization shutdown time
***************************************************************************/
void UXAS_Shutdown(void)
{
ASSERT_MPKNSS_LOCK();
UXASAuthStarted = FALSE;
return;
}
/***************************************************************************
* This routine is called when an auth beast is allocated in memory
* (it may still be on disk)
***************************************************************************/
STATUS UXAUTH_ConstructAuthBeast(
GeneralMsg_s *genMsg,
AuthBeast_s *authBeast)
{
UXASAuthorizeInfo_s *authInfo;
AuthCtrl_s *connInfo;
ASSERT_MPKNSS_LOCK();
authInfo = (UXASAuthorizeInfo_s *)zalloc(sizeof(UXASAuthorizeInfo_s));
if (authInfo == NULL)
{
SetErrno(genMsg,zERR_NO_MEMORY);
return zFAILURE;
}
authBeast->AUTHauthInfo.unx = authInfo;
connInfo = &genMsg->pssConn.ptr->authInfo;
authInfo->p.version = UXAS_CURRENT_AUTH_VERSION;
authInfo->p.groupID = zINVALID_USERID;
// if (connInfo->numAuthenticatedIDs > 1)
// {
// authInfo->p.groupID = connInfo->authenticatedIDs[1];
// }
authInfo->p.mode = UX_InitialMode;
return zOK;
}
/***************************************************************************
* This routine is called when an auth beast is freed from memory
* (it may still be on disk)
***************************************************************************/
void UXAUTH_DestructAuthBeast(
AuthBeast_s *authBeast)
{
ASSERT_MPKNSS_LOCK();
free(authBeast->AUTHauthInfo.unx);
return;
}
/***************************************************************************
* This routine is called when an auth beast is written to storage
***************************************************************************/
NINT UXAUTH_PackedSize(
AuthBeast_s *authBeast)
{
ASSERT_MPKNSS_LOCK();
return sizeof(UXASPersistentAuthInfo_s);
}
/***************************************************************************
* This routine is called when an auth beast is written to storage
***************************************************************************/
BYTE *UXAUTH_PackAuthBeast(
AuthBeast_s *authBeast,
BYTE *storeBuffer)
{
UXASAuthorizeInfo_s *authInfo;
ASSERT_MPKNSS_LOCK();
authInfo = authBeast->AUTHauthInfo.unx;
memcpy(storeBuffer, &authInfo->p, sizeof(UXASPersistentAuthInfo_s));
return storeBuffer + sizeof(UXASPersistentAuthInfo_s);
}
/**************************************************************************
* This routine is called when we have done a "getPackedSize" but we can't
* do the pack due to an error.
***************************************************************************/
void UXAUTH_NoPackAuthBeastCleanup(
AuthBeast_s *authBeast)
{
ASSERT_MPKNSS_LOCK();
return;
}
/***************************************************************************
* This routine is called when an auth beast is read from storage
***************************************************************************/
BYTE *UXAUTH_UnpackAuthBeast(
GeneralMsg_s *genMsg,
AuthBeast_s *authBeast,
BYTE *storeBuffer)
{
UXASAuthorizeInfo_s *authInfo;
ASSERT_MPKNSS_LOCK();
authInfo = authBeast->AUTHauthInfo.unx;
zASSERT (authBeast->AUTHbeastVersion == CURRENT_BEAST_VERSION);
memcpy(&authInfo->p, storeBuffer, sizeof(UXASPersistentAuthInfo_s));
return storeBuffer + sizeof(UXASPersistentAuthInfo_s);
}
/***************************************************************************
*
* This routine is called when a name is added to the name tree.
*
***************************************************************************/
STATUS UXAUTH_AddAuthInfo(
GeneralMsg_s *genMsg,
AuthBeast_s *authBeast,
Zid_t parentZid,
Latch_s *parentLatch)
{
return zOK;
}
/***************************************************************************
*
* This routine is called when a name is deleted from the name tree
*
***************************************************************************/
STATUS UXAUTH_RemoveAuthInfo(
GeneralMsg_s *genMsg,
AuthBeast_s *authBeast,
Zid_t parentZid,
Xaction_s *xaction)
{
return zOK;
}
/***************************************************************************
*
* This routine is called when a file is actually deleted. It cleans up the
* associated overflow beasts.
*
***************************************************************************/
STATUS UXAUTH_DeleteAuthInfo(
GeneralMsg_s *genMsg,
AuthBeast_s *authBeast,
Zid_t parentZid)
{
return zOK;
}
/***************************************************************************
*
* This routine is called to determine if there is auth info that needs
* to be cleaned up. If so then it returns TRUE.
*
***************************************************************************/
BOOL UXAUTH_IsAuthInfo(
GeneralMsg_s *genMsg,
AuthBeast_s *authBeast)
{
return FALSE;
}
/****************************************************************************
* This routine is used to initialize the authorization info for a newly
* created volume. It must only change items in the volume's rootdir.
* The caller will have the rootdir xlatched and will ensure that the
* rootdir gets written and the latch released on successful return. On
* error return the volume will not get created.
*****************************************************************************/
STATUS UXAUTH_InitVolumeAuthInfo(
GeneralMsg_s *genMsg,
Volume_s *volBeast)
{
#if NSS_DEBUG IS_ENABLED
AuthBeast_s *rootdir = (AuthBeast_s *)volBeast->rootdir;
ASSERT_MPKNSS_LOCK();
ASSERT_XLATCH(&rootdir->AUTHbeastLatch);
#endif
return(zOK);
}
/****************************************************************************
*
* This routine removes a list of trustees from all objects in a given
* volume. Currently it is calling a routine that is also called from
* the authorization space for some symantic agent requests. The authorization
* space routine could have been placed directly in the ops tables, but since
* this is an infrequently used call I gave it its own routine to avoid
* confusion.
*
****************************************************************************/
STATUS UXAUTH_RemoveIDsFromAVolume(
GeneralMsg_s *genMsg,
NamingMsg_s *nameMsg,
UserID_t *IDlist,
NINT IDcount)
{
SearchMsg_s searchMsg;
NINT i;
File_s *file;
ASSERT_MPKNSS_LOCK();
COMN_STRUCT_INIT(searchMsg);
COMN_SETUP_SEARCH_MSG (&searchMsg, 0,
SMAPOPT_32BitMode | SMAPOPT_searchAllDirs | SMAPOPT_matchAllEntries,
zNTYPE_FILE);
COMN_SET_NAMING_MSG_PARSEMODE(nameMsg, NAMPMODE_DoNotResolveLeafName);
if (COMN_WildOpen(genMsg, nameMsg, &searchMsg) != zOK)
{
goto cleanup;
}
/* search all entries for the user IDs */
for(;;)
{ /* look at each file in the system */
genMsg->flags |= DO_NOT_SEND_FSHOOKS;
if (COMN_WildRead(genMsg, nameMsg, &searchMsg) != zOK)
{
genMsg->flags &= ~DO_NOT_SEND_FSHOOKS;
if (GetErrno(genMsg) == zERR_NAME_NOT_FOUND_IN_DIRECTORY)
{ /* normal end */
ClearErrno(genMsg);
COMN_WildClose(genMsg, &searchMsg);
return zOK;
}
goto cleanupClose;
}
genMsg->flags &= ~DO_NOT_SEND_FSHOOKS;
file = nameMsg->curFile;
for (i = 0; i < IDcount; i++)
{ /* check each user in the list */
if (LB_GUIDCompare(&file->auth.authInfo.unx->p.groupID, &IDlist[i])
== 0)
{
file->auth.authInfo.unx->p.groupID = zINVALID_USERID;
COMN_MARK_BEAST_DIRTY(&file->FILEroot);
}
}
}
cleanupClose:
COMN_WildClose(genMsg, &searchMsg);
cleanup:
return zFAILURE;
}
/****************************************************************************
*
* This function adds the NDS object GUIDs to the User store for all
* structures in the ZAS auth model.
*
****************************************************************************/
STATUS UXAUTH_AddObjectNames(
GeneralMsg_s *genMsg,
Volume_s *volume,
AuthBeast_s *beast)
{
UXASAuthorizeInfo_s *authInfo;
/* Add the trustees and visibility entries */
authInfo = beast->AUTHauthInfo.unx;
OID_AddEntryIfNotThere(genMsg, volume, &beast->authInfo.unx->p.groupID);
ClearErrno(genMsg);
return zOK;
}
/****************************************************************************
*
* This function checks the IDs for a beast to see if they are still good
*
****************************************************************************/
STATUS UXAUTH_CheckUserIDs(
GeneralMsg_s *genMsg,
Volume_s *volume,
AuthBeast_s *beast)
{
UXASAuthorizeInfo_s *authInfo;
BOOL isOK;
authInfo = beast->AUTHauthInfo.unx;
if (CHK_VerifyID(genMsg, volume, &beast->authInfo.unx->p.groupID,
&isOK) == zOK)
{
if (!isOK)
{
beast->authInfo.unx->p.groupID = zINVALID_USERID;
COMN_MARK_BEAST_DIRTY(&beast->AUTHroot);
}
}
return zOK;
}
/***************************************************************************
*
* This routine is called when the information for the authorization system
* (i.e. caching) may need to be invalidated.
*
***************************************************************************/
STATUS UXAUTH_InvalidateAuthInfo(
GeneralMsg_s *genMsg)
{
return zOK;
}
/****************************************************************************
*
* This function changes the authorization Owner ID for a beast
*
****************************************************************************/
STATUS UXAS_ChangeOwner(
GeneralMsg_s *genMsg,
NamingMsg_s *nameMsg,
AuthBeast_s *beast,
UserID_t *newOwner)
{
ModifyInfoMsg_s infoMsg;
zInfo_s info;
info.id.owner = *newOwner;
COMN_STRUCT_INIT(infoMsg);
COMN_SETUP_MODIFY_INFO_MSG(&infoMsg, zMOD_OWNER_ID, &info,
zINFO_VERSION_A);
return COMN_ModifyInfo(genMsg, nameMsg, &infoMsg);
}
/****************************************************************************
*
* This function changes the authorization group ID for a beast
*
****************************************************************************/
STATUS UXAS_ChangeGroup(
AuthBeast_s *beast,
UserID_t *newGroup)
{
beast->authInfo.unx->p.groupID = *newGroup;
COMN_MARK_BEAST_DIRTY(&beast->AUTHroot);
return zOK;
}
/****************************************************************************
*
* This function changes the Unix mode bits for a beast
*
****************************************************************************/
STATUS UXAS_ChangeMode(
AuthBeast_s *beast,
NINT mode)
{
beast->authInfo.unx->p.mode = mode;
COMN_MARK_BEAST_DIRTY(&beast->AUTHroot);
return zOK;
}
/****************************************************************************
*
* This function get the authorization info for the Unix auth model.
*
****************************************************************************/
STATUS UXAS_GetAuthInfo(
AuthBeast_s *beast,
UserID_t *groupID,
NINT *mode)
{
*groupID = beast->authInfo.unx->p.groupID;
*mode = beast->authInfo.unx->p.mode;
return zOK;
}
/****************************************************************************
*
* This function puts a 32 bit Unix ID into the correct field of the GUID.
*
****************************************************************************/
void UXAS_StoreIDInGUID(
NINT id,
UserID_t *guid)
{
guid->timeLow = id;
guid->clockSeqHighAndReserved = -1; /* indicate this is a numeric ID not a GUID */
return;
}
/***************************************************************************
* The authorization operations for the system
***************************************************************************/
struct AuthModelOps_s UnixAuthorizeModelOps =
{
UXAUTH_ConstructAuthBeast,
UXAUTH_DestructAuthBeast,
UXAUTH_PackedSize,
UXAUTH_PackAuthBeast,
UXAUTH_NoPackAuthBeastCleanup,
UXAUTH_UnpackAuthBeast,
UXAUTH_AddAuthInfo,
UXAUTH_RemoveAuthInfo,
UXAUTH_DeleteAuthInfo,
UXAUTH_IsAuthInfo,
UXAUTH_MayIDoThis,
UXAUTH_InitVolumeAuthInfo,
UXAUTH_RemoveIDsFromAVolume,
UXAUTH_AddObjectNames,
UXAUTH_CheckUserIDs,
UXAUTH_InvalidateAuthInfo,
};

View File

@@ -0,0 +1,439 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Advance File Services (NSS) Initialization module
|
|---------------------------------------------------------------------------
|
| $Author: cteerlink $
| $Date: 2006-12-01 04:07:06 +0530 (Fri, 01 Dec 2006) $
|
| $RCSfile$
| $Revision: 1712 $
|
|---------------------------------------------------------------------------
| This module is used to:
| This is the authorization cash for the system.
+-------------------------------------------------------------------------*/
#include <guid.h>
#include <stdlib.h>
#include <string.h>
#include <wio.h>
#include <xError.h>
#include "zasAuthCache.h"
#include "pssStartup.h"
#include "csa.h"
AuthCacheCtrl_s AuthCache = /* control head for the authorization hash */
{
{0}, /* latch */
0, /* activation count */
HASH_TABLE_SIZE - 1, /* hashMask */
NULL, /* pointer to hash array */
{NULL, NULL}, /* LRU */
DEFAULT_AUTH_CACHE_SIZE, /* max number of entries */
0, /* number of entries in the cache */
0, /* signature count */
0 /* reset count */
};
/**************************************************************************
* This will initialize the authorization cache for the entire system
**************************************************************************/
STATUS ZAS_CacheInit(
GeneralMsg_s *genMsg)
{
NINT i;
NINT hashSize;
ASSERT_MPKNSS_LOCK();
X_LATCH(&AuthCache.latch);
if (AuthCache.hash == NULL)
{ /* first init */
hashSize = AuthCache.maxEntries;
AuthCache.hash = zalloc(hashSize * sizeof(DQhead_t));
if (AuthCache.hash == NULL)
{
SetErrno (genMsg, zERR_NO_MEMORY);
UNX_LATCH(&AuthCache.latch);
return zFAILURE;
}
for (i=0; i < hashSize; i++)
{
DQ_INIT(&(*AuthCache.hash)[i]);
}
AuthCache.hashMask = hashSize - 1;
DQ_INIT(&AuthCache.LRUqueue);
AuthCache.numEntries = 0;
AuthCache.signatureCount = 0;
AuthCache.activationCount = 0;
AuthCache.resetCount = 0;
}
AuthCache.activationCount++;
UNX_LATCH(&AuthCache.latch);
return zOK;
}
/**************************************************************************
* This will cleanup the authorization cache for the entire system.
**************************************************************************/
void ZAS_CacheUninit(void)
{
DQhead_t *hp;
NINT i;
AuthCacheNode_s *item;
ASSERT_MPKNSS_LOCK();
X_LATCH(&AuthCache.latch);
if (AuthCache.activationCount == 1 && AuthCache.hash != NULL)
{
for (hp=&(*AuthCache.hash)[0],i=AuthCache.hashMask+1;i > 0;hp++,i--)
{
for (;;)
{
DQ_DEQ(hp, item, AuthCacheNode_s, hashLink);
if (item != NULL)
free(item);
else
break;
}
zASSERT(DQ_EMPTY(hp));
}
free(AuthCache.hash);
AuthCache.hash = NULL;
DQ_INIT(&AuthCache.LRUqueue);
}
AuthCache.activationCount--;
UNX_LATCH(&AuthCache.latch);
}
/**************************************************************************
* This generates the HASH value for an entry
**************************************************************************/
STATIC NINT ZAS_Hash(
NINT domainID,
EffectiveACL_s *EACL)
{
NINT hash=0;
NINT index;
ASSERT_MPKNSS_LOCK();
ASSERT_LATCH(&AuthCache.latch);
for (index = 0; index < EACL->numEntries; index++)
{
hash += EACL->entry[index].trusteeID.timeLow;
hash += EACL->entry[index].rights;
}
hash += domainID << 8;
// aprintf(LGREEN, MSGNot("Hash=%x\n"),hash);
return hash;
}
/**************************************************************************
* This will try and locate an item in the auth cache. If found it will
* return a pointer to the AuthCache_s structure. If not found it returns
* a NULL.
*
* WARNING
* The restart count is part of the cache key!!!!
* You must first ensure that the volume's activation count == AuthBeast's
* restart count. This is not tested here for performance reasons.
*
**************************************************************************/
AuthCacheNode_s *ZAS_GetEACLCacheEntry(
NINT cacheIndex,
NINT signature)
{
AuthCacheNode_s *cacheNode;
DQhead_t *hashptr;
ASSERT_MPKNSS_LOCK();
if (cacheIndex == INVALID_EACL_CACHE_INDEX)
return NULL;
// X_LATCH(&AuthCache.latch);
if (cacheIndex > (AuthCache.maxEntries - 1))
{
return NULL;
}
hashptr = &(*AuthCache.hash)[cacheIndex];
DQ_FOREACH(hashptr, cacheNode, AuthCacheNode_s, hashLink)
{
if (signature == cacheNode->signature)
{
DQ_RMV(cacheNode, LRUlink);
DQ_ENQ(&AuthCache.LRUqueue, cacheNode, LRUlink);
// UNX_LATCH(&AuthCache.latch);
return cacheNode;
}
}
// UNX_LATCH(&AuthCache.latch);
return NULL;
}
/**************************************************************************
* This will add the given EACL to the cache. It checks to see if the entry
* is already there. If it is, the cache node is returned and the new entry
* is freed. Otherwise, the entry is added and the new cache ID is returned.
**************************************************************************/
AuthCacheNode_s *ZAS_AddEACLCacheEntry(
AuthCacheNode_s *newEntry,
NINT inputResetCount,
LONG *cacheIndex)
{
AuthCacheNode_s *cacheNode;
DQhead_t *hashptr;
ASSERT_MPKNSS_LOCK();
ASSERT_XLATCH(&AuthCache.latch);
// X_LATCH(&AuthCache.latch);
if (inputResetCount != AuthCache.resetCount)
{ /* The cache that newEntry is based on has been reset */
// UNX_LATCH(&AuthCache.latch);
return NULL;
}
newEntry->hashValue = ZAS_Hash(newEntry->domainID, &newEntry->EACL);
*cacheIndex = newEntry->hashValue & AuthCache.hashMask;
hashptr = &(*AuthCache.hash)[*cacheIndex];
DQ_FOREACH(hashptr, cacheNode, AuthCacheNode_s, hashLink)
{
if (newEntry->hashValue == cacheNode->hashValue &&
newEntry->EACL.numEntries == cacheNode->EACL.numEntries &&
newEntry->domainID == cacheNode->domainID)
{ /* these the same entry */
if (memcmp(&newEntry->EACL.entry, &cacheNode->EACL.entry,
newEntry->EACL.numEntries * sizeof(ACLEntry_s)) == 0)
{
/* fix up the LRU queue */
DQ_RMV(cacheNode, LRUlink);
DQ_ENQ(&AuthCache.LRUqueue, cacheNode, LRUlink);
free(newEntry);
// UNX_LATCH(&AuthCache.latch);
#if NSS_DEBUG IS_ENABLED
// DBG_DebugPrintf(YELLOW, MSGNot("Put cache entry at end of LRU"));
// ZAS_DisplayCache();
#endif
return cacheNode;
}
}
}
/* we only get here if the entry is not found */
while (AuthCache.numEntries >= AuthCache.maxEntries)
{ /* if we have all the entries allowed */
DQ_DEQ(&AuthCache.LRUqueue, cacheNode, AuthCacheNode_s, LRUlink);
DQ_RMV(cacheNode, hashLink);
AuthCache.numEntries--;
free(cacheNode);
}
AuthCache.numEntries++;
newEntry->signature = AuthCache.signatureCount++;
NULLIFY(&newEntry->hashLink);
DQ_PUSH(&(*AuthCache.hash)[*cacheIndex], newEntry, hashLink); /* link of hash list */
NULLIFY(&newEntry->LRUlink);
DQ_ENQ(&AuthCache.LRUqueue, newEntry, LRUlink); /* link to the LRU queue */
// UNX_LATCH(&AuthCache.latch);
#if NSS_DEBUG IS_ENABLED
// DBG_DebugPrintf(YELLOW, MSGNot("Added a cache entry"));
// ZAS_DisplayCache();
#endif
return newEntry;
}
/**************************************************************************
* This will try and locate an item in the auth cache. If found it will
* remove it.
**************************************************************************/
void ZAS_RemoveEACLCacheEntry(
NINT cacheIndex,
NINT signature)
{
AuthCacheNode_s *cacheNode;
DQhead_t *hashptr;
ASSERT_MPKNSS_LOCK();
if (cacheIndex == INVALID_EACL_CACHE_INDEX)
return;
if (cacheIndex > (AuthCache.maxEntries - 1))
{
return;
}
X_LATCH(&AuthCache.latch);
hashptr = &(*AuthCache.hash)[cacheIndex];
DQ_FOREACH(hashptr, cacheNode, AuthCacheNode_s, hashLink)
{
if (signature == cacheNode->signature)
{
DQ_RMV(cacheNode, LRUlink);
DQ_RMV(cacheNode, hashLink);
free(cacheNode);
AuthCache.numEntries--;
UNX_LATCH(&AuthCache.latch);
return;
}
}
UNX_LATCH(&AuthCache.latch);
return;
}
/**************************************************************************
* This will invalidate the cache entries that might not be valid since an
* ACL entry has changed.
**************************************************************************/
STATUS ZAS_InvalidateEACLCacheEntries(
GeneralMsg_s *genMsg,
UserID_t *trusteeID,
BOOL checkXLSS)
{
AuthCacheNode_s *cacheNode;
AuthCacheNode_s *holdCacheNode;
DQhead_t *hashPtr;
NINT hashIndex;
NINT listIndex;
#if NSS_DEBUG IS_ENABLED
AuthPartialResets++;
#endif
ASSERT_MPKNSS_LOCK();
X_LATCH(&AuthCache.latch);
AuthCache.resetCount++;
for (hashIndex=0; hashIndex <= AuthCache.hashMask; hashIndex++)
{ /* for each hash table entry */
hashPtr = &(*AuthCache.hash)[hashIndex];
DQ_FOREACH(hashPtr, cacheNode, AuthCacheNode_s, hashLink)
{
for (listIndex=0; listIndex < cacheNode->EACL.numEntries;
listIndex++)
{ /* for each EACL entry */
if (LB_GUIDCompare(&cacheNode->EACL.entry[listIndex].trusteeID,
trusteeID) == 0)
{ /* if this is the correct entry */
holdCacheNode = cacheNode;
cacheNode = OPREV(cacheNode, AuthCacheNode_s, hashLink);
DQ_RMV(holdCacheNode, LRUlink);
DQ_RMV(holdCacheNode, hashLink);
free(holdCacheNode);
AuthCache.numEntries--;
break;
}
}
}
}
UNX_LATCH(&AuthCache.latch);
if (checkXLSS)
{
CSA_InvalidateAuthCache(genMsg, trusteeID, FALSE);
}
return zOK;
}
/**************************************************************************
* This will invalidate all EACL cache entries.
*
**************************************************************************/
STATUS ZAS_InvalidateEntireEACLCache(
GeneralMsg_s *genMsg,
BOOL checkXLSS)
{
AuthCacheNode_s *cacheNode;
AuthCacheNode_s *holdCacheNode;
DQhead_t *hashPtr;
NINT hashIndex;
#if NSS_DEBUG IS_ENABLED
AuthResets++;
#endif
ASSERT_MPKNSS_LOCK();
X_LATCH(&AuthCache.latch);
AuthCache.resetCount++;
for (hashIndex=0; hashIndex <= AuthCache.hashMask; hashIndex++)
{ /* for each hash table entry */
hashPtr = &(*AuthCache.hash)[hashIndex];
DQ_FOREACH(hashPtr, cacheNode, AuthCacheNode_s, hashLink)
{
holdCacheNode = cacheNode;
cacheNode = OPREV(cacheNode, AuthCacheNode_s, hashLink);
DQ_RMV(holdCacheNode, LRUlink);
DQ_RMV(holdCacheNode, hashLink);
free(holdCacheNode);
AuthCache.numEntries--;
}
}
UNX_LATCH(&AuthCache.latch);
zASSERT(AuthCache.numEntries == 0);
if (checkXLSS)
{
UserID_t trusteeID;
CSA_InvalidateAuthCache(genMsg, &trusteeID, TRUE);
}
return zOK;
}
#if NSS_DEBUG IS_ENABLED
/**************************************************************************
* This will go through and display all AuthCache nodes.
**************************************************************************/
void ZAS_DisplayCache(void)
{
DQhead_t *hashp;
NINT i,j;
AuthCacheNode_s *node;
ASSERT_MPKNSS_LOCK();
// wActivate(zDbgScreen);
// wPause(zDbgScreen,-1);
DBG_DebugPrintf(LGRAY,MSGNot("-------- AuthCache Contents --------\n"));
S_LATCH(&AuthCache.latch);
if (AuthCache.hash != NULL)
{
zASSERT(AuthCache.numEntries <= AuthCache.maxEntries);
for (hashp=&(*AuthCache.hash)[0],i=0; i <= AuthCache.hashMask; hashp++,i++)
{
DQ_FOREACH(hashp, node, AuthCacheNode_s, hashLink)
{
DBG_DebugPrintf(GREEN,MSGNot("Hash=%3d Signature=%3d Domain=%3d\n"),
i, node->signature, node->domainID);
for (j = 0; j < node->EACL.numEntries; j++)
{
DBG_DebugPrintf(LGRAY,MSGNot(" trustee=0x%08x rights=0x%04x attributes=0x%04x\n"),
node->EACL.entry[j].trusteeID,
node->EACL.entry[j].rights,
node->EACL.entry[j].attributes);
}
}
}
}
UNS_LATCH(&AuthCache.latch);
// wPause(zDbgScreen,0);
}
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1392
src/nwnss/comn/common/cSA.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,367 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996, 2004 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Advance File Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: blarsen $
| $Date: 2007-09-12 22:29:07 +0530 (Wed, 12 Sep 2007) $
|
| $RCSfile$
| $Revision: 2203 $
|
|---------------------------------------------------------------------------
| This module is used to initialize the common layer
|
+-------------------------------------------------------------------------*/
#include <linux/module.h>
#include <stdlib.h>
#include <procdefs.h>
#include <bits.h>
#include <config.h>
#include <encp.h>
#define _NSS_ENCP_H_ /* flag we have included ENCP.H already*/
#include <loader.h>
#include <xError.h>
#include <stdio.h>
#include <string.h>
#include <pssConfig.h>
#include <control.h>
#include "pssConnection.h"
#include "nameScan.h"
#include "nssFSHooks.h"
#include "eventSys.h"
#include "volume.h"
#include "adminVolume.h"
#include "pssStartup.h"
#include "objectIDStore.h"
#include "purgeDir.h"
#include <nameSpace.h>
#include <cmCompFile.h>
#include <comnCompress.h>
#include <comnPublics.h>
#include <comnZAS.h>
#include <evs.h>
#include <extAttrBeast.h>
#include <macNSpace.h>
#include <uxaction.h>
#include <unixAuthModel.h>
#include <unixNSpace.h>
#include <zasAuthModel.h>
#if _FSHOOKS IS_ENABLED
FSHookParms_s FSHooksList[MAX_NUMBER_FSHOOKS];
statusfunc_t FSHooksCall[MAX_NUMBER_FSHOOKS];
#endif
STATUS NSSUT_MediaFormatTestAllSizes(void);
statusfunc_t LegacyEventReport[NUM_LEGACY_EVENTS];
/****************************************************************************
* COMN_FSHOOKS_Startup
*****************************************************************************/
void COMN_FSHOOKS_Startup()
{
#if _FSHOOKS IS_ENABLED
LONG retList;
struct InternalPublicDefinitionStructure *symRec;
LONG result;
ASSERT_MPKNSS_LOCK();
ZOS_FindPublicRecordStructure(result, MSGNot("\x10""FSHookParmsArray"), 0,
&retList, (LONG *)&symRec)
if (result != 0)
{
return;
}
memcpy(&FSHooksList, symRec->IPDActualAddress,
sizeof(FSHookParms_s) * MAX_NUMBER_FSHOOKS);
#endif
return;
}
/****************************************************************************
* COMN_Startup
*****************************************************************************/
#if zNETWARE
extern STATUS nfsStartup();
extern void nfsShutdown();
#endif
extern STATUS CSA_Startup(void);
extern void CSA_Shutdown(void);
STATUS COMN_Startup(
GeneralMsg_s *genMsg)
{
STATUS rc;
ASSERT_MPKNSS_LOCK();
rc = NSSUT_MediaFormatTestAllSizes();
if ( rc != zOK )
{
SetErrno(genMsg, rc);
return zFAILURE;
}
#if zNETWARE
if ((rc = nfsStartup()) != zOK)
{
SetErrno(genMsg, rc);
return zFAILURE;
}
#endif
COMN_FSHOOKS_Startup();
if (OID_Startup() != zOK)
{
#if zNETWARE
nfsShutdown();
#endif
return zFAILURE;
}
if (ADMINVOL_StartupPhase2(genMsg) != zOK)
{
OID_Shutdown();
#if zNETWARE
nfsShutdown();
#endif
return zFAILURE;
}
if ((rc = CSA_Startup()) != zOK)
{
OID_Shutdown();
#if zNETWARE
nfsShutdown();
#endif
return zFAILURE;
}
INIT_LATCH(&PurgeDirLatch);
return zOK;
}
/****************************************************************************
* COMN_Shutdown
*****************************************************************************/
void COMN_Shutdown()
{
extern unicode_t *ZIDToFileNameVolumeName;
ASSERT_MPKNSS_LOCK();
CSA_Shutdown();
NMSG_ShutdownWorkBufferMemory();
free(ZIDToFileNameVolumeName);
ZIDToFileNameVolumeName = NULL;
OID_Shutdown();
#if zNETWARE
nfsShutdown();
#endif
}
typedef struct NSSPersistentItems_s {
char *NPI_Name;
int NPI_Size;
char *NPI_LastItemName;
int NPI_LastItem;
int NPI_SizePacked;
int NPI_LastItemPacked;
} NSSPersistentItems_s;
NSSPersistentItems_s NPIList[] = {
// cmCompFile.h
{ "CompChunkHdr_s", sizeof(CompChunkHdr_s), "algoVersion", offsetof(CompChunkHdr_s,algoVersion), 10, 9 },
{ "CompFileLayoutID_s", sizeof(CompFileLayoutID_s), "unused", offsetof(CompFileLayoutID_s,unused), 4, 3 },
{ "CompFileHdr_s", sizeof(CompFileHdr_s), "chunkStateVector[DIRECT_CHUNK_VECTOR_BYTES]", offsetof(CompFileHdr_s,chunkStateVector[DIRECT_CHUNK_VECTOR_BYTES]), 22, 22 },
// cmControl.h
{ "VolumeCompAttr_s", sizeof(VolumeCompAttr_s), "algorithms_used", offsetof(VolumeCompAttr_s,algorithms_used), 24, 16 },
// comnBeasts.h
{ "PersistentNameEntry_s", sizeof(PersistentNameEntry_s), "name[0]", offsetof(PersistentNameEntry_s,name[0]),
#if NSS_DEBUG IS_ENABLED
262,
#else
6,
#endif
6 },
{ "PersistentParentEntry_s", sizeof(PersistentParentEntry_s), "zid", offsetof(PersistentParentEntry_s,zid), 20, 12 },
{ "DeletedPersistentParentEntry_s", sizeof(DeletedPersistentParentEntry_s), "ID", offsetof(DeletedPersistentParentEntry_s,ID), 20, 4 },
{ "V1_DeletedPersistentParentEntry_s", sizeof(V1_DeletedPersistentParentEntry_s), "ID", offsetof(V1_DeletedPersistentParentEntry_s,ID), 8, 4 },
{ "TypeSpecificPersistentParentEntry_s", sizeof(TypeSpecificPersistentParentEntry_s), "u.deleted.ID", offsetof(TypeSpecificPersistentParentEntry_s,u.deleted.ID), 20, 4 },
{ "PersistentNamed2_s", sizeof(PersistentNamed2_s), "reserved", offsetof(PersistentNamed2_s,reserved), 20, 18 },
{ "PersistentNamed3_s", sizeof(PersistentNamed3_s), "hardLinkZid", offsetof(PersistentNamed3_s,hardLinkZid), 28, 20 },
{ "V1_PersistentAuthBeast_s", sizeof(V1_PersistentAuthBeast_s), "ownerID", offsetof(V1_PersistentAuthBeast_s,ownerID), 16, 0 },
{ "PersistentFile_s", sizeof(PersistentFile_s), "archiverID", offsetof(PersistentFile_s,archiverID), 68, 52 },
{ "V1_PersistentFile_s", sizeof(V1_PersistentFile_s), "archiverID", offsetof(V1_PersistentFile_s,archiverID), 32, 28 },
{ "MFLKey_s", sizeof(MFLKey_s), "zid", offsetof(MFLKey_s,zid), 8, 0 },
{ "MFLValue_s", sizeof(MFLValue_s), "reserved", offsetof(MFLValue_s,reserved), 8, 4 },
{ "MFLEntry_s", sizeof(MFLEntry_s), "value", offsetof(MFLEntry_s,value), 16, 8 },
{ "PersistentComp_s", sizeof(PersistentComp_s), "unused[4]", offsetof(PersistentComp_s,unused[4]), 24, 24 },
// compCompress.h
{ "PersistentCompressInfo_s", sizeof(PersistentCompressInfo_s), "action", offsetof(PersistentCompressInfo_s,action), 28, 27 },
{ "PackedCompInfo_s", sizeof(PackedCompInfo_s), "cmInfo", offsetof(PackedCompInfo_s,cmInfo), 32, 4 },
// comnZAS.h:
{ "ACLEntry_s", sizeof(ACLEntry_s), "attributes", offsetof(ACLEntry_s,attributes), 20, 18 },
{ "VisEntry_s", sizeof(VisEntry_s), "count", offsetof(VisEntry_s,count), 20, 16 },
{ "V1_ACLEntry_s", sizeof(V1_ACLEntry_s), "attributes", offsetof(V1_ACLEntry_s,attributes), 8, 6 },
{ "V1_VisEntry_s", sizeof(V1_VisEntry_s), "count", offsetof(V1_VisEntry_s,count), 8, 4 },
{ "PersistentZasAclOverflowBeast_s", sizeof(PersistentZasAclOverflowBeast_s), "numEntries", offsetof(PersistentZasAclOverflowBeast_s,numEntries), 12, 8 },
{ "PersistentZasVisOverflowBeast_s", sizeof(PersistentZasVisOverflowBeast_s), "numEntries", offsetof(PersistentZasVisOverflowBeast_s,numEntries), 12, 8 },
// evs.h
{ "PersistentVolumeCrypt_s", sizeof(PersistentVolumeCrypt_s), "macLen", offsetof(PersistentVolumeCrypt_s,macLen), 128, 124 },
// extAttrBeast.h
{ "PersistentExtAttrBeast_s", sizeof(PersistentExtAttrBeast_s), "extAttrUserFlags", offsetof(PersistentExtAttrBeast_s,extAttrUserFlags), 4, 0 },
// hardLinkBeast.h
{ "PersistentHardLink_s", sizeof(PersistentHardLink_s), "reserved2", offsetof(PersistentHardLink_s,reserved2), 44, 12 },
// macNSpace.h
{ "PackedMacInfo_s", sizeof(PackedMacInfo_s), "macInfo.dirRightsMask", offsetof(PackedMacInfo_s,macInfo.dirRightsMask), 48, 44 },
// volume.h
{ "LoggedPersistentVolume_s", sizeof(LoggedPersistentVolume_s), "LPV_reserved[32-30]", offsetof(LoggedPersistentVolume_s,LPV_reserved[32-30]), 128, 128 },
{ "VolInfoLog_s", sizeof(VolInfoLog_s), "VIL_value", offsetof(VolInfoLog_s,VIL_value), 16, 8 },
{ "PersistentVolume_s", sizeof(PersistentVolume_s), "PV_reserved3[18]", offsetof(PersistentVolume_s,PV_reserved3[18]), 256, 256 },
{ "PersistentPool_s", sizeof(PersistentPool_s), "PP_reserved[64-22-4]", offsetof(PersistentPool_s,PP_reserved[64-22-4]), 256, 256 },
{ "LoggedPersistentPool_s", sizeof(LoggedPersistentPool_s), "LPP_reserved[64-8]", offsetof(LoggedPersistentPool_s,LPP_reserved[64-8]), 256, 256 },
// unixAuthModel.h
{ "UXASPersistentAuthInfo_s", sizeof(UXASPersistentAuthInfo_s), "unused[8]", offsetof(UXASPersistentAuthInfo_s,unused[8]), 56, 56 },
// unixNSpace.h:
{ "zUnixInfo_Layout1_s", sizeof(zUnixInfo_Layout1_s), "filler[2]", offsetof(zUnixInfo_Layout1_s,filler[2]), 24, 24 },
{ "PackedUnixInfo_Layout1_s", sizeof(PackedUnixInfo_Layout1_s), "reserved", offsetof(PackedUnixInfo_Layout1_s,reserved), 32, 28 },
{ "PackedUnixInfo_s", sizeof(PackedUnixInfo_s), "unixInfo.variableSize", offsetof(PackedUnixInfo_s,unixInfo.variableSize), 52, 50 },
// uxaction.h
{ "UserXactionLogRec_s", sizeof(UserXactionLogRec_s), "type", offsetof(UserXactionLogRec_s,type), 48, 44 },
{ "UserXactionLogBuffer_s", sizeof(UserXactionLogBuffer_s), "time", offsetof(UserXactionLogBuffer_s,time), 16, 12 },
// zasAuthModel.h
{ "ZASPersistentAuthInfo_s ", sizeof(ZASPersistentAuthInfo_s ), "visibilityList[MAX_VISIBILITY_TRUSTEES_IN_BEAST]", offsetof(ZASPersistentAuthInfo_s ,visibilityList[MAX_VISIBILITY_TRUSTEES_IN_BEAST]), 204, 204 },
{ "V1_ZASPersistentAuthInfo_s", sizeof(V1_ZASPersistentAuthInfo_s), "numVisibilityTrusteesAssigned", offsetof(V1_ZASPersistentAuthInfo_s,numVisibilityTrusteesAssigned), 40, 38 },
// zOmni.h
{ "GUID_t", sizeof(GUID_t), "node[6]", offsetof(GUID_t,node[6]), 16, 16 },
// zParams.h
{ "zMacInfo_s", sizeof(zMacInfo_s), "dirRightsMask", offsetof(zMacInfo_s,dirRightsMask), 44, 40 },
{ "zUnixInfo_s", sizeof(zUnixInfo_s), "variableSize", offsetof(zUnixInfo_s,variableSize), 48, 46 },
};
#if MEDIA_FORMAT_DISPLAY_SIZES
STATUS ZLOG_ssprintf(
NINT bufferLength,
BYTE **bufferAddress,
NINT *retLen,
const char *format,
...)
{
va_list args;
int added; /* Does not include the NULL */
va_start( args, format );
added = LB_vsnprintf( *bufferAddress + *retLen,
bufferLength - *retLen, format, args );
if ( added < 0 )
{ /* Encoding error in format string */
return( zERR_BAD_PARAMETER_VALUE );
}
if ( added >= (bufferLength - *retLen) )
{ /* Could do a re-alloc here and then error on out of memory */
*retLen = bufferLength; /* Say we are using whole buffer so
* that next call to us returns no
* space left. This way callers can call
* us many times in a row and only need
* to check for an error after the last
* call.
*/
return( zERR_BUFFER_TOO_SMALL );
}
*retLen += added;
return( zOK );
} /* End of ZLOG_ssprintf() */
#endif
#if MEDIA_FORMAT_DISPLAY_SIZES
void NSSUT_DisplayAll(
NINT bufferLength,
BYTE **bufferAddress,
NINT *retLen ) /* This indicates how much of buffer is
* already filled in. We must update
* as we fill things in.
*/
{
int i;
ZLOG_ssprintf(bufferLength, bufferAddress, retLen, "<NSS>\n");
for ( i = 0; i < NELEMS(NPIList); ++i )
{
#if 1 // XML
ZLOG_ssprintf(bufferLength, bufferAddress, retLen, "<item name=\"%s\" size=\"%u\" last=\"%u\"/>\n",
NPIList[i].NPI_Name, NPIList[i].NPI_Size, NPIList[i].NPI_LastItem);
#else // In format to place into "NSSPersistentItems_s NPIList[]"
ZLOG_ssprintf(bufferLength, bufferAddress, retLen, "\t{ \"%s\", sizeof(%s), \"%s\", offsetof(%s,%s), %u, %u },\n",
NPIList[i].NPI_Name, NSSZPI[i].NPI_Name,
NPIList[i].NPI_LastItemName, NPIList[i].NPI_Name, NPIList[i].NPI_LastItemName,
NPIList[i].NPI_Size, NPIList[i].NPI_LastItem);
#endif
if ( NPIList[i].NPI_Size != NPIList[i].NPI_SizePacked )
{
zASSERT("Persistent structure size is not correct"==NULL);
}
if ( NPIList[i].NPI_LastItem != NPIList[i].NPI_LastItemPacked )
{
zASSERT("Persistent structure offsetof is not correct"==NULL);
}
}
ZLOG_ssprintf(bufferLength, bufferAddress, retLen, "</NSS>\n");
}
#else
void NSSUT_DisplayAll( NINT bufferLength, BYTE **bufferAddress, NINT *retLen ) {} /* Keep NetWare linker happy */
#endif
STATUS NSSUT_MediaFormatTestAllSizes( )
{
int i;
STATUS status = zOK;
for ( i = 0; i < NELEMS(NPIList); ++i )
{
if ( NPIList[i].NPI_Size != NPIList[i].NPI_SizePacked )
{
printf("sizeof %d. %s\n", i, NPIList[i].NPI_Name);
zASSERT("Persistent structure size is not correct"==NULL);
status = zERR_MEDIA_CORRUPTED;
}
if ( NPIList[i].NPI_LastItem != NPIList[i].NPI_LastItemPacked )
{
printf("offsetof %d. %s\n", i, NPIList[i].NPI_Name);
zASSERT("Persistent structure offsetof is not correct"==NULL);
status = zERR_MEDIA_CORRUPTED;
}
}
return status;
}

1355
src/nwnss/comn/common/hmc.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,257 @@
/****************************************************************************
|
| (C) Copyright 2001 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| Novell Storage Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2005-08-10 01:03:51 +0530 (Wed, 10 Aug 2005) $
|
| $RCSfile$
| $Revision: 1177 $
|
|---------------------------------------------------------------------------
| This module has the routines used to run the background checker.
+-------------------------------------------------------------------------*/
#include <linux/module.h>
#if zLINUX
#include <stdlib.h>
#include <stdio.h>
#include "comnPublics.h"
#include "pssStartup.h"
#include "pssConfig.h"
#include "pssConnection.h"
#include "seqUpdater.h"
/* GLOBALS */
THREAD SEQ_ThreadID;
BOOL SEQ_ThreadRunning = FALSE;
BOOL SEQ_ShutdownRequest = FALSE;
BOOL SEQ_Sleeping = FALSE;
OneShot_s SEQ_Alarm;
/***************************************************************************
* This function is called when the alarm goes off
***************************************************************************/
void SEQ_TimedOut(
NINT seconds)
{
zASSERT(SEQ_Sleeping);
Continue(SEQ_ThreadID);
SEQ_Sleeping = FALSE;
}
/***************************************************************************
* This function puts the updater to sleep for the specified number of
* seconds.
***************************************************************************/
void SEQ_Sleep(
NINT seconds)
{
ASSERT_MPKNSS_LOCK();
INIT_ONESHOT(SEQ_Alarm);
secOneShot( &SEQ_Alarm, seconds, SEQ_TimedOut);
SEQ_Sleeping = TRUE;
Wait();
}
/***************************************************************************
* This function is called to wake up the updater before the normal time.
***************************************************************************/
void SEQ_Wakeup()
{
if (SEQ_Sleeping)
{
CANCEL_ALARM(SEQ_Alarm);
Continue(SEQ_ThreadID);
SEQ_Sleeping = FALSE;
}
}
/**************************************************************************
* This function checks to see if we are shutting down the updater.
* It returns TRUE in that case.
***************************************************************************/
BOOL SEQ_ShutdownUpdater( void )
{
/*
* If updating has been suspended and not forced on then return TRUE.
*/
if ((!Config.SecEquiv.updater && !Config.SecEquiv.forceUpdater) ||
SEQ_ShutdownRequest)
{
return TRUE;
}
return FALSE;
}
/**************************************************************************
* This function is used to update the security equivalence vectors of all
* NSS connections.
*
* This will loop through the PSSConnection list and call all of the
* CNCT_UpdatePSSConnection routine on each connection.
***************************************************************************/
void SEQ_UpdateAllPSSConnections( void )
{
NSSConnection_s *pssConn;
ASSERT_MPKNSS_LOCK();
/* If we have been told to stop, don't start */
if (SEQ_ShutdownUpdater())
{
return;
}
DQ_FOREACH(&CNCT_PSSConnectionList, pssConn, NSSConnection_s, link)
{
pssConn->connUseCount++;
COMN_UpdatePSSConnection( pssConn );
pssConn->connUseCount--;
/* If we have been told to stop, stop now */
if (SEQ_ShutdownUpdater())
{
return;
}
}
}
/**************************************************************************
* This function is scheduled as a background thread to update the cached
* security equivalence vectors of the system.
***************************************************************************/
void SEQ_UpdaterThread(
THREAD threadID,
void *info)
{
MPKNSS_LOCK();
SEQ_ThreadRunning = TRUE;
aprintf(YELLOW, "NSS background security equivalence updating scheduled.\n");
/*
* Pause at startup to let the server get going without getting in the
* way.
*/
SEQ_Sleep(Config.SecEquiv.updaterInterval);
if (SEQ_ShutdownRequest)
{
goto exit;
}
/* Main body of the updater */
for (;;)
{
if (SEQ_ShutdownRequest)
{
break;
}
if (Config.SecEquiv.intervalChanged)
{
/* We just changed intervals, go back to sleep for the new interval */
Config.SecEquiv.intervalChanged = FALSE;
}
else
{
/*
* If updating has not been suspended then go for it...
*/
if ((Config.SecEquiv.updater) || (Config.SecEquiv.forceUpdater))
{
aprintf(YELLOW, "NSS background security equivalence updater running ...\n");
SEQ_UpdateAllPSSConnections();
aprintf(YELLOW, "NSS background security equivalence updater completed ...\n");
}
/* Reset the force flag if we were forced to update one time */
Config.SecEquiv.forceUpdater = FALSE;
}
/*
* Sleep until time to start again.
*/
SEQ_Sleep(Config.SecEquiv.updaterInterval);
}
exit:
aprintf(YELLOW, "NSS background security equivalence updater shut down.\n");
SEQ_ThreadRunning = FALSE;
MPKNSS_UNLOCK();
}
/**************************************************************************
* This function schedules a background thread to update the
* Security Equivalence Cache.
***************************************************************************/
void SEQ_StartProcess()
{
ZOS_StartThread(SEQ_ThreadID, "NSS Security Equivalence Updater",
(void *(*)(THREAD, void *))SEQ_UpdaterThread,
0, 0, NULL);
if (SEQ_ThreadID == 0)
{
errPrintf(WHERE, Module, -1,
MSG("Unable to start the background security equivalence updater.\n", 0));
}
return;
}
/**************************************************************************
* This function shuts down the background updater thread.
***************************************************************************/
void SEQ_StopProcess()
{
NINT count;
enum
{
SEQ_MAX_SHUTDOWN_SECONDS = 30
};
SEQ_ShutdownRequest = TRUE;
SEQ_Wakeup();
for (count = 0; count < SEQ_MAX_SHUTDOWN_SECONDS; count++)
{
if (!SEQ_ThreadRunning)
{
return;
}
LB_delay(1000);
}
errPrintf(WHERE, Module, -1,
MSG("Unable to shutdown the background security equivalence updater.\n", 0));
return;
}
#endif

View File

@@ -0,0 +1,417 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996-1998 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Advance File Services (NSS) Command Line Support module
|
|---------------------------------------------------------------------------
|
| $Author: blarsen $
| $Date: 2006-09-06 03:03:38 +0530 (Wed, 06 Sep 2006) $
|
| $RCSfile$
| $Revision: 1522 $
|
|---------------------------------------------------------------------------
| Module Description:
|
+-------------------------------------------------------------------------*/
#include "nwAlgo.h"
LONG
NSSCCDSetFileSize(
IoHandle_t internalHandle,
LONG fileSize,
LONG internalFileSize)
{
return ALGOMGR_setStreamSize(CM_STREAM(internalHandle), internalFileSize);
}
LONG
NSSCCDDecompressBuildFile( IoHandle_t outHandle, LONG offset, LONG size,
LONG prevSize, LONG nextSize )
{
/* XXX Determine if there's anything to do here */
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "buildfile(offset=%ld, size=%ld, psize=%ld, nsize=%ld) called\n",
offset, size, prevSize, nextSize));
if (offset != 0)
return (LONG)0;
ALGOMGR_setStreamSize(CM_STREAM(outHandle), size);
return (LONG)0;
}
LONG
NSSCCDGetWriteCacheBlock( IoHandle_t ioHandle, LONG cacheBlockNumber,
LONG noFlushFlag, BYTE **cacheBlock, LONG *cacheHandle )
{
STATUS rc;
LONG holeFlag;
LONG size;
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "---------- getwrite: fseek(offset=%ld) handle=%d\n",
cacheBlockNumber * CD_SYSTEM_CACHE_BUFFER_SIZE, ioHandle->nextfreeIobuf+1));
ioHandle->iobuf[ioHandle->nextfreeIobuf].offset =
cacheBlockNumber * CD_SYSTEM_CACHE_BUFFER_SIZE;
CD_ASSERT((! ISVALID_HANDLE(ioHandle->iobuf[ioHandle->nextfreeIobuf].cmbuf)));
rc = ALGOMGR_fetchStreamBuf(CM_STREAM(ioHandle),
ioHandle->iobuf[ioHandle->nextfreeIobuf].offset,
&ioHandle->iobuf[ioHandle->nextfreeIobuf].cmbuf, CM_STREAM_MODE_WRITE,
CD_SYSTEM_CACHE_BUFFER_SIZE, cacheBlock, &size, &holeFlag);
if (rc == zOK)
{
*cacheHandle = ioHandle->nextfreeIobuf+1;
ioHandle->nextfreeIobuf = (ioHandle->nextfreeIobuf + 1) % WRITE_CACHE_BUFFER_RANGE;
}
else *cacheHandle = 0;
return rc;
}
LONG
NSSCCDReturnWriteCacheBlock( LONG cacheHandle, IoHandle_t ioHandle,
LONG numberOfSectors, LONG noFlushFlag )
{
STATUS rc;
LONG offset;
if ((cacheHandle == 0) || (cacheHandle > WRITE_CACHE_BUFFER_RANGE))
return UNCOMPRESS_ERROR_INVALID_OFFSET;
-- cacheHandle;
offset = ioHandle->iobuf[cacheHandle].offset;
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "---------- returnwrite: fseek(offset=%ld) handle=%d\n", offset, cacheHandle+1));
if (offset != ALGOMGR_getStreamPosition(CM_STREAM(ioHandle))) {
#if 0
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "---------- write_off %ld != %ld\n", offset,
ALGOMGR_getStreamPosition(CM_STREAM(ioHandle))));
#endif
ALGOMGR_setStreamPosition(CM_STREAM(ioHandle), (QUAD)offset);
}
CD_ASSERT((ISVALID_HANDLE(ioHandle->iobuf[cacheHandle].cmbuf)));
rc = ALGOMGR_releaseStreamBuf(CM_STREAM(ioHandle),
ioHandle->iobuf[cacheHandle].cmbuf, TRUE);
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "---------- wrote (secsize=%d, nsectors=%ld, offset=%ld)\n",
CD_SYSTEM_SECTOR_SIZE, numberOfSectors, offset));
INVALIDATE_HANDLE(ioHandle->iobuf[cacheHandle].cmbuf);
return rc;
}
LONG
NSSCCDGetReadCacheBlock( IoHandle_t ioHandle, LONG cacheBlockNumber,
LONG *realBytesRead, BYTE **cacheBlock, LONG *cacheHandle,
LONG *holeFlag )
{
STATUS rc;
CMStream_t stream = CM_STREAM(ioHandle);
ioHandle->iobuf[ioHandle->nextfreeIobuf].offset =
cacheBlockNumber * CD_SYSTEM_CACHE_BUFFER_SIZE;
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "getread: offset=%d handle=%d\n",
ioHandle->iobuf[ioHandle->nextfreeIobuf].offset, ioHandle->nextfreeIobuf+1));
*holeFlag = 0;
if (ioHandle->iobuf[ioHandle->nextfreeIobuf].offset != ALGOMGR_getStreamPosition(stream)) {
rc = ALGOMGR_setStreamPosition(stream,
(QUAD)ioHandle->iobuf[ioHandle->nextfreeIobuf].offset);
if (rc != 0) {
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "fseek(offset=%ld)",
ioHandle->iobuf[ioHandle->nextfreeIobuf].offset));
return rc;
}
}
*realBytesRead = CD_SYSTEM_CACHE_BUFFER_SIZE;
rc = ALGOMGR_fetchStreamBuf(stream,
ioHandle->iobuf[ioHandle->nextfreeIobuf].offset,
&ioHandle->iobuf[ioHandle->nextfreeIobuf].cmbuf, CM_STREAM_MODE_READ,
*realBytesRead, cacheBlock, realBytesRead, holeFlag);
if ((rc == zOK) && (*holeFlag == 0))
{
*cacheHandle = ioHandle->nextfreeIobuf+1;
ioHandle->nextfreeIobuf = (ioHandle->nextfreeIobuf + 1) % READ_CACHE_BUFFER_RANGE;
}
else *cacheHandle = 0;
return rc;
}
void
NSSCCDReturnReadCacheBlock(IoHandle_t ioHandle, LONG cacheHandle)
{
if ((cacheHandle == 0) || (cacheHandle > READ_CACHE_BUFFER_RANGE))
return;
-- cacheHandle;
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "return_read: offset=%d, handle=%d\n",
ioHandle->iobuf[cacheHandle].offset, cacheHandle+1));
(void) ALGOMGR_releaseStreamBuf(CM_STREAM(ioHandle),
ioHandle->iobuf[cacheHandle].cmbuf, FALSE);
}
LONG NSSCCDGetReadAheadBuffer(readCache_tp ra, BYTE **cachePointer,
LONG *validBytes, LONG *holeFlag)
{
LONG retCode;
LONG nextBufferToBeUsed = ra->CacheNextToBeUsed; // & CD_READ_CACHE_MASK;
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "read_ahead used=%d, freed=%d: ",
nextBufferToBeUsed, ra->CacheNextToBeFreed));
if (ra->CacheHandles[nextBufferToBeUsed] != 0) {
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "overreading offset=%d !!\n",
((IoHandle_s *)ra->CacheReadFileHandle)->iobuf[
ra->CacheHandles[nextBufferToBeUsed]-1].offset));
CD_ASSERT((0));
}
retCode = NSSCCDGetReadCacheBlock(ra->CacheReadFileHandle,
// ra->CacheNextToBeUsed, validBytes, cachePointer,
ra->CacheNextBlockToRead, validBytes, cachePointer,
&ra->CacheHandles[nextBufferToBeUsed], holeFlag);
if (retCode != 0)
return retCode;
if (! *validBytes)
return CD_ERROR_READ_ZERO_BYTES;
ra->CacheNextBlockToRead++;
if (*holeFlag)
{
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, " ~~~ holeFlag is on\n"));
}
else
{
ra->CacheNextToBeUsed ++;
ra->CacheNextToBeUsed &= CD_READ_CACHE_MASK;
}
return (LONG)0;
}
LONG NSSCCDFreeReadAheadBuffer(readCache_tp ra)
{
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "free_read_ahead used=%d, freed=%d:\n",
ra->CacheNextToBeUsed, ra->CacheNextToBeFreed));
NSSCCDReturnReadCacheBlock(ra->CacheReadFileHandle,
ra->CacheHandles[ra->CacheNextToBeFreed]);
ra->CacheHandles[ra->CacheNextToBeFreed] = 0; /* Some invalid value */
ra->CacheNextToBeFreed++;
ra->CacheNextToBeFreed &= CD_READ_CACHE_MASK;
return (LONG)0;
}
LONG
NSSCCDPrepareForRead( IoHandle_t ioHandle, LONG fileSize,
readCache_tpp readCacheHandleReturn)
{
readCache_tp ra;
if ((ra = (readCache_tp)CD_MALLOC(sizeof(readCache_t))) == NULL)
return( zERR_NO_MEMORY );
memset(ra, (LONG)0, sizeof(readCache_t));
ra->CacheReadFileHandle = ioHandle;
ioHandle->nextfreeIobuf = 0;
*readCacheHandleReturn = ra;
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "Preparing to read\n"));
ALGOMGR_setStreamPosition(CM_STREAM(ioHandle), 0);
return((LONG)0);
}
LONG NSSCCDStopReadAhead(readCache_tp ra)
{
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "Stopping read\n"));
while (ra->CacheNextToBeFreed != ra->CacheNextToBeUsed)
{
if (ra->CacheHandles[ra->CacheNextToBeFreed] == 0)
{
NWALGO_DBG_PRINTF((NWALGO_DBG_COLOR, "freeing NULL buffer, used=%d, freed=%d:\n",
ra->CacheNextToBeUsed, ra->CacheNextToBeFreed));
++ ra->CacheNextToBeFreed;
ra->CacheNextToBeFreed &= CD_READ_CACHE_MASK;
CD_ASSERT((0));
}
else {
NSSCCDFreeReadAheadBuffer(ra);
}
}
CD_FREE( ra );
return((LONG)0);
}
STATIC STATUS
NWALGO_init()
{
return zOK;
}
STATIC STATUS
NWALGO_compressStream(
BYTE algoVersion,
CMStream_t uncompStream, /* read-only */
CMStream_t compStream, /* write */
CMStream_t tempStream, /* write/read
* For NW algorithm use */
BYTE minPercentGain)
{
LONG ccode;
QUAD fileSize = ALGOMGR_getStreamSize(uncompStream);
CompressStatus_t compressStatus;
IoHandle_s uncompHandle, compHandle, tempHandle;
ADDR compressHandle;
memset( &compressStatus, 0, sizeof(compressStatus) );
compressStatus.totalInitialBlocks =
(fileSize + CD_SYSTEM_CACHE_BUFFER_SIZE - 1)
>> CD_SYSTEM_CACHE_BUFFER_SHIFT;
compressStatus.minimumPercentageGain = minPercentGain;
memset( &uncompHandle, 0, sizeof(uncompHandle) );
uncompHandle.CM_stream = uncompStream;
uncompHandle.nextfreeIobuf = 0;
memset( &compHandle, 0, sizeof(compHandle) );
compHandle.CM_stream = compStream;
compHandle.nextfreeIobuf = 0;
memset( &tempHandle, 0, sizeof(tempHandle) );
tempHandle.CM_stream = tempStream;
tempHandle.nextfreeIobuf = 0;
ccode = CCDCompressFile(&uncompHandle, &compHandle, &tempHandle,
fileSize, 0, &compressHandle, "", &compressStatus);
switch (ccode) {
case 0:
return zOK;
case COMPRESS_ERROR_OUT_OF_RAM:
return zERR_NO_MEMORY;
case COMPRESS_ERROR_READ_ZERO_BYTES:
case COMPRESS_ERROR_READ_BEYOND_EOF:
return zERR_END_OF_FILE;
case COMPRESS_ERROR_ABORTED:
return zERR_CM_ABORTED;
case COMPRESS_ERROR_UNCOMPRESSABLE:
return zERR_CM_CANT_COMPRESS;
case COMPRESS_ERROR_CODE_COUNTS_MISMATCH:
case COMPRESS_ERROR_TOTALS_MISMATCH:
case COMPRESS_ERROR_TREE_TOO_BIG:
case COMPRESS_ERROR_MATCH_SIZE_FAIL:
case COMPRESS_ERROR_TEMP_FILE_ERROR:
return zERR_CM_COMP_ALGO_ERROR;
case COMPRESS_ERROR_NO_RESOURCES:
return zERR_NO_MEMORY;
case COMPRESS_ERROR_HOLE_COUNT_MISMATCH:
case COMPRESS_ERROR_FILE_TOO_BIG:
return zERR_FILE_TOO_LARGE;
case COMPRESS_ERROR_WRITE_TREE_ERROR:
return zERR_CM_COMP_ALGO_ERROR;
case COMPRESS_ERROR_NO_MIN_PERCENT:
case COMPRESS_ERROR_NO_MIN_BYTES:
return zERR_CM_CANT_COMPRESS;
case COMPRESS_ERROR_INVALID_HOLE:
return zERR_CM_COMP_ALGO_ERROR;
case COMPRESS_ERROR_TRY_AGAIN:
return zERR_NO_MEMORY;
default:
return ccode;
}
}
STATIC STATUS
NWALGO_uncompressStream(
BYTE algoVersion,
CMStream_t compStream,
CMStream_t uncompStream)
{
LONG ccode;
IoHandle_s compHandle, uncompHandle;
ADDR compressHandle;
memset( &compHandle, 0, sizeof(compHandle) );
compHandle.CM_stream = compStream;
compHandle.nextfreeIobuf = 0;
memset( &uncompHandle, 0, sizeof(uncompHandle) );
uncompHandle.CM_stream = uncompStream;
uncompHandle.nextfreeIobuf = 0;
ccode = CCDStartDecompress(&compHandle, &uncompHandle, &compressHandle,
"", 0, 0);
switch (ccode) {
case 0:
return zOK;
case UNCOMPRESS_ERROR_OUT_OF_RAM:
return zERR_NO_MEMORY;
case UNCOMPRESS_ERROR_READ_ZERO_BYTES:
case UNCOMPRESS_ERROR_READ_BEYOND_EOF:
return zERR_END_OF_FILE;
case UNCOMPRESS_ERROR_ABORTED:
return zERR_CM_ABORTED;
case UNCOMPRESS_ERROR_INVALID_DATA_COUNT:
case UNCOMPRESS_ERROR_INVALID_LENGTH_COUNT:
case UNCOMPRESS_ERROR_INVALID_OFFSET_COUNT:
case UNCOMPRESS_ERROR_INVALID_HOLES:
case UNCOMPRESS_ERROR_INVALID_OFFSET:
case UNCOMPRESS_ERROR_INVALID_LENGTH:
case UNCOMPRESS_ERROR_HOLE_COUNT_MISMATCH:
return zERR_CM_CORRUPT_COMPRESSED_FILE;
case UNCOMPRESS_ERROR_UNKNOWN_VERSION:
return zERR_CM_UNKNOWN_COMP_ALGO_VERSION;
case UNCOMPRESS_ERROR_FILE_TOO_SMALL:
return zERR_CM_UNKNOWN_COMP_ALGO_VERSION;
case UNCOMPRESS_ERROR_TREE_TOO_BIG:
return zERR_FILE_TOO_LARGE;
case UNCOMPRESS_ERROR_WRITE_BEYOND_EOF:
return zERR_END_OF_FILE;
case UNCOMPRESS_ERROR_INVALID_HEADER:
return zERR_CM_INVALID_COMP_FILE_HEADER;
case UNCOMPRESS_ERROR_CORRUPT_COMPRESSED_FILE:
return zERR_CM_CORRUPT_COMPRESSED_FILE;
case UNCOMPRESS_ERROR_TRY_AGAIN:
case UNCOMPRESS_ERROR_TRY_AGAIN_FOREVER:
return zERR_NO_MEMORY;
default: ;
return ccode;
}
}
STATIC void
NWALGO_uninit()
{
}
STATIC CompAlgoIF_s NWALGO_ops = {
NWALGO_init,
NWALGO_compressStream,
NWALGO_uncompressStream,
NWALGO_uninit,
};
STATUS
NWALGO_startup()
{
return ALGOMGR_registerCompAlgo(NSS_COMP_ALGO_ID_NETWARE, &NWALGO_ops);
}
CompAlgoStartupFn_t CM_defaultAlgoStartupFn = NWALGO_startup;

View File

@@ -0,0 +1,680 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Advance File Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: blarsen $
| $Date: 2006-01-21 04:09:53 +0530 (Sat, 21 Jan 2006) $
|
| $RCSfile$
| $Revision: 1315 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Management volume files
+-------------------------------------------------------------------------*/
#include <procdefs.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pssDebug.h>
#include <xError.h>
#include <xUnicode.h>
#include <comnBeastClass.h>
#include <zPublics.h>
#include <guid.h>
#include "msgGen.h"
#include "msgName.h"
#include "comnPublics.h"
#include "xmlNSS.h"
#include "mgmt.h"
#include "nssPubs.h"
#include "sbsMFL.h"
#include "xmlTags.h"
typedef struct MFLControlCookie_s
{
// Volume_s *volume;
NINT currentOp;
#define MFL_OP_NONE 0
#define MFL_OP_ENUMERATE 1
#define MFL_OP_GET_STATUS 2
#define MFL_OP_VERIFY 3
#define MFL_OP_REPAIR 4
#define MFL_OP_END 99
union
{
struct
{
BOOL isDynamic; /* include files modified during enumeration? */
NINT nameSpaceID; /* use this name space for returning path names */
NINT pathFormat; /* Character encoding to use for path names */
MFLCursor_s cursor;
BOOL isMFLincomplete;
BOOL done; /* Is enumeration done? */
} enumerate;
} s; /* operation's internal state */
SNINT resultLen;
BYTE resultBuf[2 * zGET_NAME_VARIABLE_DATA_SIZE];
} MFLControlCookie_s;
/****************************************************************************
* Cleanup at file close time
****************************************************************************/
void cleanupMFLControlCookie(
VirtInfo_s *virtInfoe)
{
return;
// MFLControlCookie_s *mflCookie =
// (MFLControlCookie_s *)virtInfo->memPtr;
//
// if (mflCookie == NULL)
// {
// return;
// }
// /* Unlock the volume */
// COMN_UnlockVolumeActive(mflCookie->volume, FALSE);
}
/****************************************************************************
* Allocate a cookie structure for MFL.
****************************************************************************/
STATUS allocateCookie(
VirtInfo_s *virtInfo)
{
MFLControlCookie_s *mflCookie;
/* If we have not allocated a cookie then do so. */
if (virtInfo->memPtr == NULL)
{
mflCookie = zalloc(sizeof(MFLControlCookie_s));
if (mflCookie == NULL)
{
return zERR_NO_MEMORY;
}
virtInfo->memPtr = mflCookie;
virtInfo->closeFunc = cleanupMFLControlCookie;
mflCookie->currentOp = MFL_OP_NONE;
}
return zOK;
}
/****************************************************************************
* Send whatever is in the result buffer. Return TRUE if we filled the
* output buffer.
****************************************************************************/
BOOL sendResult(
MFLControlCookie_s *mflCookie,
NINT *bufBytesLeft,
BYTE **outBuf,
NINT *outLen)
{
NINT retLen;
if (mflCookie->resultLen > 0)
{
retLen = (*bufBytesLeft < mflCookie->resultLen)
? *bufBytesLeft : mflCookie->resultLen;
if (retLen > 0)
{
memmove(*outBuf, mflCookie->resultBuf, retLen);
*outBuf += retLen;
*outLen += retLen;
*bufBytesLeft -= retLen;
mflCookie->resultLen -= retLen;
if (mflCookie->resultLen > 0)
{
memmove(mflCookie->resultBuf, (mflCookie->resultBuf + retLen),
mflCookie->resultLen);
}
}
}
return !(*bufBytesLeft);
}
/****************************************************************************
* Generate the modified files list for this volume.
* NOTE: This is a cookie type read function.
****************************************************************************/
/* VIRTUAL FILE -- READ FUNCTION */
STATUS SBS_volumeMFLControlReadFunc(
NINT parmLen,
utf8_t *parm,
VirtInfo_s *virtInfo)
{
STATUS status;
Volume_s *volume;
GeneralMsg_s genMsg;
MFLEntry_s *mflEntries = NULL;
NINT numEntriesRequested, numEntriesObtained, i;
BOOL mflIncompleteFlag;
MFLControlCookie_s *mflCookie;
BYTE *path = NULL;
NINT bufBytesLeft = virtInfo->resultBufferSize;
BYTE *outBuf = virtInfo->resultBuffer;
NINT *retLen = &virtInfo->resultEOF;
typedef struct Stack_s {
NamingMsg_s nameMsg;
GetNameMsg_s gfnMsg;
zGetName_s nameBuffer;
BYTE volName[zMAX_COMPONENT_NAME];
} Stack_s;
STACK_ALLOC();
MPKNSS_LOCK();
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
*retLen = 0;
if ((status = allocateCookie(virtInfo)) != zOK)
{
STACK_FREE();
return zFAILURE;
}
mflCookie = (MFLControlCookie_s *)virtInfo->memPtr;
/*
* Send anything that happens to be held in the result buffer. If this
* fills the output buffer then we are done with this request.
*/
if (sendResult(mflCookie, &bufBytesLeft, &outBuf, retLen))
{
goto done;
}
/* If no operation pending then make it an enumerate */
if (mflCookie->currentOp == MFL_OP_NONE)
{
mflCookie->currentOp = MFL_OP_ENUMERATE;
mflCookie->s.enumerate.isDynamic = TRUE;
mflCookie->s.enumerate.nameSpaceID = zNSPACE_LONG;
// mflCookie->s.enumerate.pathFormat = zPFMT_UTF8;
mflCookie->s.enumerate.pathFormat = zPFMT_ASCII;
mflCookie->s.enumerate.cursor.lastZidReturned = zINVALID_ZID;
mflCookie->s.enumerate.isMFLincomplete = FALSE;
mflCookie->s.enumerate.done = FALSE;
/* send out the start tag */
strcpy(mflCookie->resultBuf, MSGNot("<"TAG_NSSREPLY">\n<"
TAG_MODIFIEDFILELIST">\n"));
mflCookie->resultLen = strlen(mflCookie->resultBuf);
}
else if ((mflCookie->currentOp != MFL_OP_ENUMERATE) ||
((mflCookie->currentOp == MFL_OP_ENUMERATE) &&
mflCookie->s.enumerate.done))
{
if (mflCookie->resultLen == 0)
{
mflCookie->currentOp = MFL_OP_END;
}
goto done;
}
/* We reach here only if there is an unfinished MFL enumeration */
zASSERT((mflCookie->currentOp == MFL_OP_ENUMERATE) &&
! mflCookie->s.enumerate.done);
/* allocate memory for return data and for path */
mflEntries = malloc((MAX_MFL_ENTRIES_PER_SCOOP * sizeof(MFLEntry_s)) +
zMAX_FULL_NAME);
if (! mflEntries)
{
status = zERR_NO_MEMORY;
goto sendRetcode;
}
path = (BYTE *)(mflEntries) + (MAX_MFL_ENTRIES_PER_SCOOP * sizeof(MFLEntry_s));
/* Obtain the volume ptr */
memcpy(aStack->volName, parm, parmLen);
aStack->volName[parmLen] = 0;
if ((status = findVolume(aStack->volName, &volume)) != zOK)
{
status = zERR_VOLUME_NOT_FOUND;
goto sendRetcode;
}
if (COMN_LockVolumeActive(&genMsg, volume, FALSE) != zOK)
{
status = GetErrno(&genMsg);
COMN_Release(&volume);
goto sendRetcode;
}
/* Check if there is an actively maintained MFL for this volume */
if (! SBS_MFL_ENABLED(volume))
{
status = zERR_MFL_NOT_ENABLED;
COMN_UnlockVolumeActive(volume, FALSE);
COMN_Release(&volume);
goto sendRetcode;
}
COMN_USE_BEAST(&volume->VOLroot);
COMN_INIT_NAMING_MSG(&aStack->nameMsg);
COMN_SET_NAMING_MSG_VOLUME(&aStack->nameMsg, volume);
COMN_STRUCT_INIT(aStack->gfnMsg);
COMN_SETUP_GET_NAME_MSG(&aStack->gfnMsg, zGFN_INCLUDE_PATH, 0,
mflCookie->s.enumerate.pathFormat,
mflCookie->s.enumerate.nameSpaceID, &aStack->nameBuffer,
sizeof(zGetName_s));
while (bufBytesLeft > 0)
{
numEntriesRequested = MAX_MFL_ENTRIES_PER_SCOOP;
if (volume->VOLcomnVolOps.VOL_enumerateMFL(&genMsg, volume,
(mflCookie->s.enumerate.isDynamic ?
(volume->VOLepoch + 1) : volume->VOLepoch),
numEntriesRequested,
&mflCookie->s.enumerate.cursor.lastZidReturned,
mflEntries, &numEntriesObtained, &mflIncompleteFlag) != zOK)
{
if (GetErrno(&genMsg) != zERR_ZID_NOT_FOUND)
{
status = GetErrno(&genMsg);
goto errorReleaseNameMsg;
}
ClearErrno(&genMsg);
mflCookie->s.enumerate.done = TRUE;
}
mflCookie->s.enumerate.isMFLincomplete =
mflCookie->s.enumerate.isMFLincomplete || mflIncompleteFlag;
for (i = 0; i < numEntriesObtained; ++i)
{
COMN_SETUP_NAMING_MSG_VOLUME_ZID( &aStack->nameMsg, volume->volumeID,
/* cnt zFNU_FIRST_PARENT,*/ zINVALID_ZID, mflEntries[i].key.zid,
mflEntries[i].key.zid, SLATCHED,
mflCookie->s.enumerate.nameSpaceID, zNTYPE_FILE,
NULL);
status = COMN_GetName(&genMsg, &aStack->nameMsg, &aStack->gfnMsg);
COMN_UNLATCH_AND_RELEASE_NAMEMSG_BEASTS_KEEP_LATCHTYPE(&aStack->nameMsg);
aStack->nameMsg.parseFlags &= ~NAMPFL_nameMsgFullyResolved;
if ((status != zOK) && (GetErrno(&genMsg) != zERR_ZID_NOT_FOUND))
{
status = GetErrno(&genMsg);
goto errorReleaseNameMsg;
}
status = zOK;
mflCookie->s.enumerate.cursor.lastZidReturned = mflEntries[i].key.zid;
sprintf(mflCookie->resultBuf + mflCookie->resultLen,
MSGNot("<" TAG_FILE "><" TAG_NAME ">%s</" TAG_NAME "><"
TAG_ID ">%Ld</" TAG_ID "></" TAG_FILE ">\n"),
&aStack->nameBuffer.variableData[0],
mflEntries[i].key.zid);
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
if (sendResult(mflCookie, &bufBytesLeft, &outBuf, retLen))
{
break;
}
}
/* Normal end of enumeration */
if ((numEntriesObtained == 0) || mflCookie->s.enumerate.done)
{
mflCookie->s.enumerate.done = TRUE;
sprintf(mflCookie->resultBuf + mflCookie->resultLen,
MSGNot("<" TAG_STATUS " " ATR_COMPLETE "=\"%s\"/>\n</"
TAG_MODIFIEDFILELIST ">\n"),
mflCookie->s.enumerate.isMFLincomplete
? MSGNot("no") : MSGNot("yes"));
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
MGMT_BuildResultNSS(status,
mflCookie->resultBuf + mflCookie->resultLen);
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
sprintf(mflCookie->resultBuf + mflCookie->resultLen,
MSGNot("</" TAG_NSSREPLY ">\n"));
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
sendResult(mflCookie, &bufBytesLeft, &outBuf, retLen);
break;
}
}
COMN_CleanupNameMsg(&genMsg, &aStack->nameMsg);
COMN_Release(&volume);
free(mflEntries);
done:
MPKNSS_UNLOCK();
STACK_FREE();
return zOK;
errorReleaseNameMsg:
COMN_CleanupNameMsg(&genMsg, &aStack->nameMsg);
COMN_Release(&volume);
sendRetcode:
/* send the error code */
sprintf(mflCookie->resultBuf + mflCookie->resultLen,
MSGNot("</" TAG_MODIFIEDFILELIST ">\n"));
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
MGMT_BuildResultNSS(status,
mflCookie->resultBuf + mflCookie->resultLen);
mflCookie->resultLen += strlen(mflCookie->resultBuf + mflCookie->resultLen);
sprintf(mflCookie->resultBuf + mflCookie->resultLen,
MSGNot("</" TAG_NSSREPLY ">\n"));
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
sendResult(mflCookie, &bufBytesLeft, &outBuf, retLen);
/* Reset state and get ready to perform next operation */
mflCookie->currentOp = MFL_OP_END;
if (mflEntries)
{
free(mflEntries);
}
MPKNSS_UNLOCK();
STACK_FREE();
return zOK;
}
/****************************************************************************
* Parse the MFL operation from the XML
****************************************************************************/
STATIC STATUS
parseMFLOp(
GeneralMsg_s *genMsg,
XML_ElementInfo_s *element,
MFLControlCookie_s *mflCookie)
{
XML_ElementInfo_s elementInfo;
utf8_t *tagName;
NINT tagLen;
if (XML_GetNextTag(element->dataStart, element->dataEnd, &elementInfo,
&tagName, &tagLen) != zOK)
{
goto badFormat;
}
if (memcmp(tagName, MSGNot(TAG_LISTMFL), tagLen) == 0)
{
/* Initialize the cookie */
mflCookie->currentOp = MFL_OP_ENUMERATE;
mflCookie->s.enumerate.isDynamic = TRUE;
mflCookie->s.enumerate.nameSpaceID = zNSPACE_LONG;
mflCookie->s.enumerate.pathFormat = zPFMT_ASCII;
mflCookie->s.enumerate.cursor.lastZidReturned = zINVALID_ZID;
mflCookie->s.enumerate.isMFLincomplete = FALSE;
mflCookie->s.enumerate.done = FALSE;
if (XML_GetTagAttribute(MSGNot(ATR_NAMESPACE), &elementInfo) == zOK)
{
if (memcmp(MSGNot("zNSPACE_DOS"), elementInfo.attributeValueStart,
elementInfo.attributeValueEnd -
elementInfo.attributeValueStart + 1) == 0)
{
mflCookie->s.enumerate.nameSpaceID = zNSPACE_DOS;
}
else if (memcmp(MSGNot("zNSPACE_MAC"), elementInfo.attributeValueStart,
elementInfo.attributeValueEnd -
elementInfo.attributeValueStart + 1) == 0)
{
mflCookie->s.enumerate.nameSpaceID = zNSPACE_MAC;
}
else if (memcmp(MSGNot("zNSPACE_UNIX"), elementInfo.attributeValueStart,
elementInfo.attributeValueEnd -
elementInfo.attributeValueStart + 1) == 0)
{
mflCookie->s.enumerate.nameSpaceID = zNSPACE_UNIX;
}
else if (memcmp(MSGNot("zNSPACE_LONG"), elementInfo.attributeValueStart,
elementInfo.attributeValueEnd -
elementInfo.attributeValueStart + 1) == 0)
{
mflCookie->s.enumerate.nameSpaceID = zNSPACE_LONG;
}
else
{
goto badFormat;
}
}
// if (XML_GetTagAttribute(MSGNot("pathFormat"), &elementInfo) == zOK)
// {
// if (memcmp(MSGNot("zPFMT_ASCII"), elementInfo.attributeValueStart,
// elementInfo.attributeValueEnd -
// elementInfo.attributeValueStart + 1) == 0)
// {
// mflCookie->s.enumerate.pathFormat = zPFMT_ASCII;
// }
// else if (memcmp(MSGNot("zPFMT_UTF8"), elementInfo.attributeValueStart,
// elementInfo.attributeValueEnd -
// elementInfo.attributeValueStart + 1) == 0)
// {
// mflCookie->s.enumerate.pathFormat = zPFMT_UTF8;
// }
// else if (memcmp(MSGNot("zPFMT_UNICODE"), elementInfo.attributeValueStart,
// elementInfo.attributeValueEnd -
// elementInfo.attributeValueStart + 1) == 0)
// {
// mflCookie->s.enumerate.pathFormat = zPFMT_UNICODE;
// }
// else
// {
// goto badFormat;
// }
// }
// if (XML_GetTagAttribute(MSGNot("isDynamic"), &elementInfo) == zOK)
// {
// if (memcmp(MSGNot("yes"), elementInfo.attributeValueStart,
// elementInfo.attributeValueEnd -
// elementInfo.attributeValueStart + 1) == 0)
// {
// mflCookie->s.enumerate.isDynamic = TRUE;
// }
// else
// {
// mflCookie->s.enumerate.isDynamic = FALSE;
// }
// }
}
else if (memcmp(tagName, MSGNot(TAG_GETSTATUSMFL), tagLen) == 0)
{
mflCookie->currentOp = MFL_OP_GET_STATUS;
}
else if (memcmp(tagName, MSGNot(TAG_VERIFYMFL), tagLen) == 0)
{
mflCookie->currentOp = MFL_OP_VERIFY;
}
else if (memcmp(tagName, MSGNot(TAG_REPAIRMFL), tagLen) == 0)
{
mflCookie->currentOp = MFL_OP_REPAIR;
}
else
{
mflCookie->currentOp = MFL_OP_END;
SetErrno(genMsg, zERR_BAD_TRANSFORMATION);
return zFAILURE;
}
return zOK;
badFormat:
SetErrno(genMsg, zERR_BAD_TRANSFORMATION);
return zFAILURE;
}
/****************************************************************************
* Generate the modified files list for this volume.
****************************************************************************/
/* VIRTUAL FILE -- WRITE FUNCTION */
STATUS SBS_volumeMFLControlWriteFunc(
NINT parmLen,
utf8_t *parm,
NINT dataLen,
BYTE *data,
NINT offset,
VirtInfo_s *virtInfo)
{
GeneralMsg_s genMsg;
MFLAdminParms_s adminParms;
STATUS status;
MFLControlCookie_s *mflCookie;
Volume_s *volume;
XML_ElementInfo_s element;
typedef struct Stack_s {
BYTE volName[zMAX_COMPONENT_NAME];
} Stack_s;
STACK_ALLOC();
MPKNSS_LOCK();
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
if ((status = MGMT_FindFirstElement(virtInfo, TAG_NSSREQUEST, dataLen,
data, offset, &element)) != zOK)
{
goto done;
}
volume = NULL;
if ((status = allocateCookie(virtInfo)) != zOK)
{
goto done;
}
mflCookie = (MFLControlCookie_s *)virtInfo->memPtr;
mflCookie->currentOp = MFL_OP_END;
/* send out the start tag */
strcpy(mflCookie->resultBuf, MSGNot("<"TAG_NSSREPLY">\n<"TAG_MODIFIEDFILELIST">\n"));
mflCookie->resultLen = strlen(mflCookie->resultBuf);
/* Obtain the volume ptr */
memcpy(aStack->volName, parm, parmLen);
aStack->volName[parmLen] = 0;
if ((status = findVolume(aStack->volName, &volume)) != zOK)
{
status = zERR_VOLUME_NOT_FOUND;
goto sendReturnCode;
}
if (COMN_LockVolumeActive(&genMsg, volume, FALSE) != zOK)
{
status = GetErrno(&genMsg);
goto sendReturnCodeRelease;
}
/* Check if there is an actively maintained MFL for this volume */
if (!SBS_MFL_ENABLED(volume))
{
status = zERR_MFL_NOT_ENABLED;
goto sendReturnCodeUnlock;
}
if ((status = parseMFLOp(&genMsg, &element, mflCookie)) != zOK)
{
status = GetErrno(&genMsg);
goto sendReturnCodeUnlock;
}
switch (mflCookie->currentOp)
{
case MFL_OP_NONE:
case MFL_OP_END:
case MFL_OP_ENUMERATE:
break;
case MFL_OP_GET_STATUS:
status = volume->VOLcomnVolOps.VOL_administerMFL(&genMsg, volume,
VOL_MFL_ADMIN_GET_STATUS_OP, &adminParms);
if (status == zOK)
{
sprintf(mflCookie->resultBuf + mflCookie->resultLen,
MSGNot("<"TAG_STATUS" "ATR_COMPLETE"=\"%s\"/>\n"),
adminParms.status.incomplete ? MSGNot("no") : MSGNot("yes"));
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
}
break;
case MFL_OP_VERIFY:
status = volume->VOLcomnVolOps.VOL_administerMFL(&genMsg, volume,
VOL_MFL_ADMIN_VERIFY_OP, &adminParms);
if (status == zOK)
{
sprintf(&mflCookie->resultBuf[mflCookie->resultLen],
MSGNot("<"TAG_STATISTICS" "
ATR_NUMMODIFIEDFILES"=\"%lu\" "
ATR_NUMMISSINGENTRIES"=\"%lu\" "
ATR_NUMEXTRAENTRIES"=\"%lu\"/>\n"),
adminParms.verifyStats.numModifiedFiles,
adminParms.verifyStats.numMissingEntries,
adminParms.verifyStats.numExtraEntries);
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
}
break;
case MFL_OP_REPAIR:
status = volume->VOLcomnVolOps.VOL_administerMFL(&genMsg, volume,
VOL_MFL_ADMIN_FIX_OP, &adminParms);
if (status == zOK)
{
sprintf(&mflCookie->resultBuf[mflCookie->resultLen],
MSGNot("<"TAG_STATISTICS" "
ATR_NUMMODIFIEDFILES"=\"%lu\" "
ATR_NUMMISSINGENTRIES"=\"%lu\" "
ATR_NUMEXTRAENTRIES"=\"%lu\" "
ATR_NUMADDERRORS"=\"%ld\" "
ATR_NUMDELETEERRORS"=\"%ld\"/>\n"),
adminParms.verifyStats.numModifiedFiles,
adminParms.verifyStats.numMissingEntries,
adminParms.verifyStats.numExtraEntries,
adminParms.verifyStats.numAddErrors,
adminParms.verifyStats.numDeleteErrors);
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
}
break;
default:
SetErrno(&genMsg, zERR_NOT_SUPPORTED);
status = zFAILURE;
break;
}
sendReturnCodeUnlock:
COMN_UnlockVolumeActive(volume, FALSE);
sendReturnCodeRelease:
COMN_Release(&volume);
sendReturnCode:
if (mflCookie->currentOp != MFL_OP_ENUMERATE || status != zOK)
{
sprintf(mflCookie->resultBuf + mflCookie->resultLen,
MSGNot("</" TAG_MODIFIEDFILELIST ">\n"));
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
MGMT_BuildResultNSS(status,
mflCookie->resultBuf + mflCookie->resultLen);
mflCookie->resultLen += strlen(mflCookie->resultBuf + mflCookie->resultLen);
sprintf(mflCookie->resultBuf + mflCookie->resultLen,
MSGNot("</" TAG_NSSREPLY ">\n"));
mflCookie->resultLen += strlen(mflCookie->resultBuf +
mflCookie->resultLen);
status = zOK;
}
done:
MPKNSS_UNLOCK();
STACK_FREE();
return status;
}