/usr/bin/crlrefresh
/usr/bin/security
/usr/bin/smbutil
-/usr/libexec/airportd
/usr/local/bin/cmsutil
/usr/sbin/configd
/usr/sbin/pppd
);
buildSettings = {
BUILD_VARIANTS = "normal debug";
- CURRENT_PROJECT_VERSION = 29035;
+ CURRENT_PROJECT_VERSION = 30544;
FRAMEWORK_SEARCH_PATHS = "/usr/local/SecurityPieces/Frameworks /usr/local/SecurityPieces/Components/securityd $(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
INSTALL_PATH = /usr/sbin;
- OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
+ OPT_CPPXFLAGS = "$(OPT_CXFLAGS) -fno-enforce-eh-specs -fno-implement-inlines -fcoalesce-templates";
OPT_CXFLAGS = "-DNDEBUG $(OPT_INLINEXFLAGS)";
- OPT_INLINEXFLAGS = "-finline-functions";
+ OPT_INLINEXFLAGS = " -finline-functions --param max-inline-insns-single=150 --param max-inline-insns-auto=150 --param max-inline-insns=300 --param min-inline-insns=90";
OPT_LDXFLAGS = "-dead_strip";
OPT_LDXNOPIC = ",_nopic";
OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
- OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O1 -fno-inline";
+ OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
OTHER_CFLAGS_normal = "$(OPT_CXFLAGS) $(OTHER_CFLAGS)";
OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
- OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O0 -fno-inline";
OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS)";
OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
OTHER_LDFLAGS = "-lbsm";
OPT_LDFLAGS = "";
OPT_LDXFLAGS = "";
OPT_LDXNOPIC = "";
- OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -O1 -fno-inline";
- OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CPLUSPLUSFLAGS) -O1 -fno-inline";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CPLUSPLUSFLAGS) -O0 -fno-inline";
};
isa = PBXBuildStyle;
name = "normal with debug";
//
// The default AclSource denies having an ACL at all
//
-AclSource::~AclSource()
-{ /* virtual */ }
-
SecurityServerAcl &AclSource::acl()
{
CssmError::throwMe(CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED);
class AclSource {
protected:
AclSource() { }
- virtual ~AclSource();
public:
virtual SecurityServerAcl &acl(); // defaults to "no ACL; throw exception"
if (mPassphraseCheck)
{
- create("builtin", "confirm-access-password", noSecuritySession);
+ create("builtin", "confirm-access-password", NULL);
CssmAutoData data(Allocator::standard(Allocator::sensitive));
}
else
{
- create("builtin", "confirm-access", noSecuritySession);
+ create("builtin", "confirm-access", NULL);
setInput(hints, context);
invoke();
}
hints.insert(AuthItemRef(AGENT_HINT_APPLICATION_PATH, AuthValueOverlay(strlen(aclPath), const_cast<char*>(aclPath))));
- create("builtin", "code-identity", noSecuritySession);
+ create("builtin", "code-identity", NULL);
setInput(hints, context);
status = invoke();
hints.insert(mClientHints.begin(), mClientHints.end());
- create("builtin", "unlock-keychain", noSecuritySession);
+ create("builtin", "unlock-keychain", NULL);
do
{
switch (initialReason)
{
case SecurityAgent::newDatabase:
- create("builtin", "new-passphrase", noSecuritySession);
+ create("builtin", "new-passphrase", NULL);
break;
case SecurityAgent::changePassphrase:
- create("builtin", "change-passphrase", noSecuritySession);
+ create("builtin", "change-passphrase", NULL);
break;
default:
assert(false);
// CSSM_ATTRIBUTE_ALERT_TITLE (optional alert panel title)
if (false == verify) { // import
- create("builtin", "generic-unlock", noSecuritySession);
+ create("builtin", "generic-unlock", NULL);
} else { // verify passphrase (export)
// new-passphrase-generic works with the pre-4 June 2004 agent;
// generic-new-passphrase is required for the new agent
- create("builtin", "generic-new-passphrase", noSecuritySession);
+ create("builtin", "generic-new-passphrase", NULL);
}
AuthItem *passwordItem;
hints.insert(mClientHints.begin(), mClientHints.end());
- create("builtin", "generic-unlock-kcblob", noSecuritySession);
+ create("builtin", "generic-unlock-kcblob", NULL);
AuthItem *secretItem;
void CodeSignatures::open(const char *path)
{
mDb.open(path, O_RDWR | O_CREAT, 0644);
- if (mDb)
- mDb.flush();
+ mDb.flush();
IFDUMPING("equiv", debugDump("reopen"));
}
//
bool CodeSignatures::find(Identity &id, uid_t user)
{
- if (!mDb)
- return false;
if (id.mState != Identity::untried)
return id.mState == Identity::valid;
try {
void CodeSignatures::makeLink(Identity &id, const string &ident, bool forUser, uid_t user)
{
- if (!mDb)
- UnixError::throwMe(ENOENT);
DbKey key('H', id.getHash(mSigner), forUser, user);
if (!mDb.put(key, StringData(ident)))
UnixError::throwMe();
void CodeSignatures::removeLink(const CssmData &hash, const char *name, bool forSystem)
{
- if (!mDb)
- UnixError::throwMe(ENOENT);
AclIdentity code(hash, name);
uid_t user = Server::process().uid();
if (forSystem && user) // only root user can remove forSystem links
return false;
}
- // don't bother the user if the db is MIA
- if (!mDb) {
- secdebug("codesign", "database not open; cannot verify");
- return false;
- }
-
// ah well. Establish mediator objects for database signature links
AclIdentity aclIdentity(trustedSignature, comment ? comment->interpretedAs<const char>() : NULL);
return false;
}
}
-
+
// ask the user
QueryCodeCheck query;
query.inferHints(process);
if (!how)
how = "dump";
CssmData key, value;
- if (!mDb) {
- dump("CODE EQUIVALENTS DATABASE IS NOT OPEN (%s)", how);
+ if (!mDb.first(key, value)) {
+ dump("CODE EQUIVALENTS DATABASE IS EMPTY (%s)\n", how);
} else {
- if (!mDb.first(key, value)) {
- dump("CODE EQUIVALENTS DATABASE IS EMPTY (%s)\n", how);
- } else {
- dump("CODE EQUIVALENTS DATABASE DUMP (%s)\n", how);
- do {
- const char *header = key.interpretedAs<const char>();
- size_t headerLength = strlen(header) + 1;
- dump("%s:", header);
- dumpData(key.at(headerLength), key.length() - headerLength);
- dump(" => ");
- dumpData(value);
- dump("\n");
- } while (mDb.next(key, value));
- dump("END DUMP\n");
- }
+ dump("CODE EQUIVALENTS DATABASE DUMP (%s)\n", how);
+ do {
+ const char *header = key.interpretedAs<const char>();
+ size_t headerLength = strlen(header) + 1;
+ dump("%s:", header);
+ dumpData(key.at(headerLength), key.length() - headerLength);
+ dump(" => ");
+ dumpData(value);
+ dump("\n");
+ } while (mDb.next(key, value));
+ dump("END DUMP\n");
}
}
// Throws exceptions if decoding fails.
// Memory returned in privateAclBlob is allocated and becomes owned by caller.
//
-void DatabaseCryptoCore::decodeCore(const DbBlob *blob, void **privateAclBlob)
+void DatabaseCryptoCore::decodeCore(DbBlob *blob, void **privateAclBlob)
{
assert(mHaveMaster); // must have master key installed
decryptor.mode(CSSM_ALGMODE_CBCPadIV8);
decryptor.padding(CSSM_PADDING_PKCS1);
decryptor.key(mMasterKey);
- CssmData ivd = CssmData::wrap(blob->iv); decryptor.initVector(ivd);
- CssmData cryptoBlob = CssmData::wrap(blob->cryptoBlob(), blob->cryptoBlobLength());
+ CssmData ivd(blob->iv, sizeof(blob->iv)); decryptor.initVector(ivd);
+ CssmData cryptoBlob(blob->cryptoBlob(), blob->cryptoBlobLength());
CssmData decryptedBlob, remData;
decryptor.decrypt(cryptoBlob, decryptedBlob, remData);
DbBlob::PrivateBlob *privateBlob = decryptedBlob.interpretedAs<DbBlob::PrivateBlob>();
// verify signature on the whole blob
CssmData signChunk[] = {
- CssmData::wrap(blob->data(), fieldOffsetOf(&DbBlob::blobSignature)),
- CssmData::wrap(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
+ CssmData(blob->data(), fieldOffsetOf(&DbBlob::blobSignature)),
+ CssmData(blob->publicAclBlob(), blob->publicAclBlobLength() + blob->cryptoBlobLength())
};
CSSM_ALGORITHMS verifyAlgorithm = CSSM_ALGID_SHA1HMAC;
#if defined(COMPAT_OSX_10_0)
#endif
VerifyMac verifier(Server::csp(), verifyAlgorithm);
verifier.key(mSigningKey);
- verifier.verify(signChunk, 2, CssmData::wrap(blob->blobSignature));
+ verifier.verify(signChunk, 2, CssmData(blob->blobSignature, sizeof(blob->blobSignature)));
// all checks out; start extracting fields
if (privateAclBlob) {
void setup(const DbBlob *blob, const CssmData &passphrase);
void setup(const DbBlob *blob, CssmClient::Key master);
- void decodeCore(const DbBlob *blob, void **privateAclBlob = NULL);
+ void decodeCore(DbBlob *blob, void **privateAclBlob = NULL);
DbBlob *encodeCore(const DbBlob &blobTemplate,
const CssmData &publicAcl, const CssmData &privateAcl) const;
void importSecrets(const DatabaseCryptoCore &src);
namespace Flippers {
+
+//
+// Automatically generated flippers
+//
+#include "flip_gen.cpp"
+
+
//
// The raw byte reversal flipper
//
}
-//
-// Flip a CSSM_DB_ATTRIBUTE_INFO, also very polymorphic
-//
-void flip(CSSM_DB_ATTRIBUTE_INFO &obj)
-{
- bool flippedAttributeNameFormat = false;
- // check and see if obj is in host byte order. If not, flip it now
- if (obj.AttributeNameFormat > CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER)
- {
- flip(obj.AttributeNameFormat);
- flippedAttributeNameFormat = true;
- }
-
- switch (obj.AttributeNameFormat)
- {
- case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
- {
- flip(obj.Label.AttributeID);
- }
- break;
- }
-
- flip (obj.AttributeFormat);
-
- if (!flippedAttributeNameFormat)
- {
- flip(obj.AttributeNameFormat);
- }
-
-}
-
-//
-// Automatically generated flippers
-//
-#include "flip_gen.cpp"
-
-
} // end namespace Flippers
// It's a bad idea to try to flip a const, so flag that
//
template <class T>
-inline void flip(const T &);
+inline void flip(const T &)
+{ tryingToFlipAConstWontWork(); }
//
//
void flip(void *addr, size_t size);
-void flip(CSSM_DB_ATTRIBUTE_INFO &obj);
-inline void flip(CssmDbAttributeInfo &obj) { flip(static_cast<CSSM_DB_ATTRIBUTE_INFO &>(obj)); }
//
// Include automatically generated flipper declarations
CSSM_KEY_SIZE/CssmKeySize *
CSSM_KEYHEADER/CssmKey::Header *
CSSM_KEY/CssmKey KeyHeader
-CSSM_QUERY/CssmQuery RecordType Conjunctive NumSelectionPredicates QueryLimits QueryFlags
-CSSM_DB_ATTRIBUTE_DATA/CssmDbAttributeData NumberOfValues
-CSSM_DB_RECORD_ATTRIBUTE_DATA/CssmDbRecordAttributeData DataRecordType SemanticInformation NumberOfAttributes
+
#
# Authorization structures
blob->validate(CSSMERR_APPLEDL_INVALID_DATABASE_BLOB);
switch (blob->version()) {
#if defined(COMPAT_OSX_10_0)
- case DbBlob::version_MacOS_10_0:
+ case blob->version_MacOS_10_0:
break;
#endif
- case DbBlob::version_MacOS_10_1:
+ case blob->version_MacOS_10_1:
break;
default:
CssmError::throwMe(CSSMERR_APPLEDL_INCOMPATIBLE_DATABASE_BLOB);
blob->validate(CSSMERR_APPLEDL_INVALID_KEY_BLOB);
switch (blob->version()) {
#if defined(COMPAT_OSX_10_0)
- case KeyBlob::version_MacOS_10_0:
+ case blob->version_MacOS_10_0:
break;
#endif
- case KeyBlob::version_MacOS_10_1:
+ case blob->version_MacOS_10_1:
break;
default:
CssmError::throwMe(CSSMERR_APPLEDL_INCOMPATIBLE_KEY_BLOB);
#include <security_cdsa_utilities/acl_preauth.h>
#include "acl_keychain.h"
+
//
// Local functions of the main program driver
//
// install MDS and initialize the local CSSM
server.loadCssm();
-
+
// okay, we're ready to roll
Syslog::notice("Entering service");
secdebug("SS", "%s initialized", bootstrapName);
#include "server.h"
#include <securityd_client/ucspNotify.h>
+
Listener::ListenerMap Listener::listeners;
Mutex Listener::setLock;
{
secdebug("notify", "%p sending domain %ld event 0x%lx to port %d process %d",
this, domain, event, mPort.port(), process.pid());
-
+
// send mach message (via MIG simpleroutine)
if (IFDEBUG(kern_return_t rc =) ucsp_notify_sender_notify(mPort,
domain, event, data.data(), data.length(),
static AclSource &aclBearer(AclKind kind, CSSM_HANDLE handle);
// Generic version of handle lookup
- template <class ProcessBearer>
- static RefPointer<ProcessBearer> find(CSSM_HANDLE handle, CSSM_RETURN notFoundError)
+ template <class Type>
+ static RefPointer<Type> find(CSSM_HANDLE handle, CSSM_RETURN notFoundError)
{
- RefPointer<ProcessBearer> object =
- HandleObject::findRef<ProcessBearer>(handle, notFoundError);
+ RefPointer<Type> object =
+ HandleObject::findRef<Type>(handle, notFoundError);
if (object->process() != Server::process())
CssmError::throwMe(notFoundError);
return object;
void Session::mergeCredentials(CredentialSet &creds)
{
secdebug("SSsession", "%p merge creds @%p", this, &creds);
- CredentialSet updatedCredentials = creds;
+ CredentialSet updatedCredentials = creds;
for (CredentialSet::const_iterator it = creds.begin(); it != creds.end(); it++)
if (((*it)->isShared() && (*it)->isValid())) {
CredentialSet::iterator old = mSessionCreds.find(*it);
updatedCredentials.insert(*old);
}
}
- creds.swap(updatedCredentials);
+ creds.swap(updatedCredentials);
}
void kill();
-protected:
+private:
static PortMap<Session> mSessions;
};
class PortMap : public Mutex, public std::map<Port, RefPointer<Node> > {
typedef std::map<Port, RefPointer<Node> > _Map;
public:
- bool contains(mach_port_t port) const { return this->find(port) != this->end(); }
+ bool contains(mach_port_t port) const { return find(port) != end(); }
Node *getOpt(mach_port_t port) const
{
- typename _Map::const_iterator it = this->find(port);
- return (it == this->end()) ? NULL : it->second;
+ typename _Map::const_iterator it = find(port);
+ return (it == end()) ? NULL : it->second;
}
Node *get(mach_port_t port) const
{
- typename _Map::const_iterator it = this->find(port);
- assert(it != this->end());
+ typename _Map::const_iterator it = find(port);
+ assert(it != end());
return it->second;
}
Node *get(mach_port_t port, OSStatus error) const
{
- typename _Map::const_iterator it = this->find(port);
- if (it == this->end())
+ typename _Map::const_iterator it = find(port);
+ if (it == end())
MacOSError::throwMe(error);
return it->second;
}
template <class Node>
void PortMap<Node>::dump()
{
- for (typename _Map::const_iterator it = this->begin(); it != this->end(); it++)
+ for (typename _Map::const_iterator it = begin(); it != end(); it++)
it->second->dump();
}
void Token::resetAcls()
{
- StLock<Mutex> _(*this);
- mResetLevel++;
- secdebug("token", "%p reset (level=%d, propagating to %ld common(s)",
- this, mResetLevel, mCommons.size());
- for (CommonSet::const_iterator it = mCommons.begin(); it != mCommons.end(); )
- RefPointer<TokenDbCommon>(*it++)->resetAcls();
+ CommonSet tmpCommons;
+ {
+ StLock<Mutex> _(*this);
+ mResetLevel++;
+ secdebug("token", "%p reset (level=%d, propagating to %ld common(s)",
+ this, mResetLevel, mCommons.size());
+ // Make a copy to avoid deadlock with TokenDbCommon lock
+ tmpCommons = mCommons;
+ }
+ for (CommonSet::const_iterator it = tmpCommons.begin(); it != tmpCommons.end(); it++)
+ RefPointer<TokenDbCommon>(*it)->resetAcls();
}
void Token::addCommon(TokenDbCommon &dbc)
{
+ secdebug("token", "%p addCommon TokenDbCommon %p", this, &dbc);
mCommons.insert(&dbc);
}
void Token::removeCommon(TokenDbCommon &dbc)
{
- assert(mCommons.find(&dbc) != mCommons.end());
- mCommons.erase(&dbc);
+ secdebug("token", "%p removeCommon TokenDbCommon %p", this, &dbc);
+ if (mCommons.find(&dbc) != mCommons.end())
+ mCommons.erase(&dbc);
}
this, &reader(), reader().name().c_str());
if (mTokend)
mTokend->faultRelay(NULL); // unregister (no more faults, please)
- notify(kNotificationCDSARemoval);
mds().uninstall(mGuid.toString().c_str(), mSubservice);
+ secdebug("token", "%p mds uninstall complete", this);
this->kill();
+ secdebug("token", "%p kill complete", this);
+ notify(kNotificationCDSARemoval);
secdebug("token", "%p removal complete", this);
}
//
void Token::kill()
{
- StLock<Mutex> _(*this);
- if (mTokend)
+ // Avoid holding the lock across call to resetAcls
+ // This can cause deadlock on card removal
{
- mTokend = NULL; // cast loose our tokend (if any)
- // Take us out of the map
- StLock<Mutex> _(mSSIDLock);
- SSIDMap::iterator it = mSubservices.find(mSubservice);
- assert(it != mSubservices.end() && it->second == this);
- if (it != mSubservices.end() && it->second == this)
- mSubservices.erase(it);
+ StLock<Mutex> _(*this);
+ if (mTokend)
+ {
+ mTokend = NULL; // cast loose our tokend (if any)
+ // Take us out of the map
+ StLock<Mutex> _(mSSIDLock);
+ SSIDMap::iterator it = mSubservices.find(mSubservice);
+ assert(it != mSubservices.end() && it->second == this);
+ if (it != mSubservices.end() && it->second == this)
+ mSubservices.erase(it);
+ }
}
-
+
resetAcls(); // release our TokenDbCommons
PerGlobal::kill(); // generic action
void Token::notify(NotificationEvent event)
{
NameValueDictionary nvd;
- CssmSubserviceUid ssuid(mGuid, NULL, h2n (mSubservice),
- h2n(CSSM_SERVICE_DL | CSSM_SERVICE_CSP));
+ CssmSubserviceUid ssuid(mGuid, NULL, mSubservice,
+ CSSM_SERVICE_DL | CSSM_SERVICE_CSP);
nvd.Insert(new NameValuePair(SSUID_KEY, CssmData::wrap(ssuid)));
CssmData data;
nvd.Export(data);
}
-//
-// FaultRelay
-//
-FaultRelay::~FaultRelay()
-{ /* virtual */ }
-
-
//
// Debug dump support
//
//
class FaultRelay {
public:
- virtual ~FaultRelay();
virtual void relayFault(bool async) = 0;
};
TokenDbCommon::TokenDbCommon(Session &ssn, Token &tk, const char *name)
: DbCommon(ssn), mDbName(name ? name : ""), mResetLevel(0)
{
+ secdebug("tokendb", "creating tokendbcommon %p: with token %p", this, &tk);
parent(tk);
}
+TokenDbCommon::~TokenDbCommon()
+{
+ secdebug("tokendb", "destroying tokendbcommon %p", this);
+ token().removeCommon(*this); // unregister from Token
+}
+
Token &TokenDbCommon::token() const
{
return parent<Token>();
if (!mAdornments.empty()) {
mAdornments.clearAdornments(); // clear ACL state
session().removeReference(*this); // unhook from SSN
- token().removeCommon(*this); // unregister from Token
}
+ token().removeCommon(*this); // unregister from Token
}
access().authenticate(CSSM_DB_ACCESS_RESET, NULL);
}
-
//
// Construct a TokenDatabase given subservice information.
// We are currently ignoring the 'name' argument.
class TokenDbCommon : public DbCommon, public Adornable {
public:
TokenDbCommon(Session &ssn, Token &tk, const char *name);
-
+ ~TokenDbCommon();
+
Token &token() const;
uint32 subservice() const { return token().subservice(); }
void resetAcls();
void lockProcessing();
-
+
typedef Token::ResetGeneration ResetGeneration;
private:
DATA_OUT(data), KeyHandle *hKey, SearchHandle *hSearch, RecordHandle *hRecord)
{
BEGIN_IPC
- relocate (query, queryBase, queryLength);
- relocate (inAttributes, inAttributesBase, inAttributesLength);
+ relocate(query, queryBase, queryLength);
+ relocate(inAttributes, inAttributesBase, inAttributesLength);
RefPointer<Database::Search> search;
RefPointer<Database::Record> record;
*hKey = key ? key->handle() : noKey;
// return attributes (assumes relocated flat blob)
- flips(outAttrs, outAttributes, outAttributesBase);
- // flipCssmDbAttributeData(outAttrs, outAttributes, outAttributesBase);
+ flips(outAttrs, outAttributes, outAttributesBase);
*outAttributesLength = outAttrsLength;
// return data (temporary fix)
if (getData) {
- if (key) {
- flip (*outData.interpretedAs<CssmKey>());
- }
-
*data = outData.data();
*dataLength = outData.length();
}
// return data (temporary fix)
if (getData) {
- if (key) {
- flip (*outData.interpretedAs<CssmKey>());
- }
-
*data = outData.data();
*dataLength = outData.length();
}
// return data (temporary fix)
if (getData) {
- if (key) {
- flip (*outData.interpretedAs<CssmKey>());
- }
-
*data = outData.data();
*dataLength = outData.length();
}
// none at all. use the canonical transient store
return Server::optionalDatabase(noDb);
}
-
-
-
-void fixDbAttributes (CssmDbAttributeData &data)
-{
- /*
- NOTE TO FUTURE MAINTAINERS OF THIS CODE:
-
- This code is called by two different routines; the relocation walker on the input attributes, and flips
- on the output attributtes. This is bad, because the relocation walker flips the Info data structure,
- and flips does not. We could fix this in flips, but flips is a template and does different things
- depending on what its parameters are. As a result, the best place to do this is here.
- */
-
- // pull this data out first, so that it is unperverted once the flip occurs
- unsigned limit = data.size ();
- unsigned format = data.format ();
- CssmData* values = data.values ();
-
- // flip if it is safe to do so
- if (format > CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX) // is the format screwed up?
- {
- flip (data.info ());
- limit = data.size ();
- format = data.format ();
- values = data.values ();
- }
-
- unsigned i;
-
- for (i = 0; i < limit; ++i)
- {
- switch (format)
- {
- case CSSM_DB_ATTRIBUTE_FORMAT_UINT32:
- Flippers::flip(*(uint32*) values[i].data ());
- break;
-
- case CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32:
- {
- CssmData& d = values[i];
- int numValues = d.length() / sizeof (UInt32);
- int j;
- UInt32* v = (UInt32*) d.data();
- for (j = 0; j < numValues; ++j)
- {
- Flippers::flip (v[j]);
- }
- }
- break;
- }
- }
-}
-
-
-
-void fixDbAttributes (CssmQuery &query)
-{
- unsigned i;
- unsigned numItems = query.size ();
- for (i = 0; i < numItems; ++i)
- {
- fixDbAttributes(query.predicates()[i].attribute());
- }
-}
-
-
-
-void fixDbAttributes (CssmDbRecordAttributeData &data)
-{
- unsigned i;
- unsigned numItems = data.size ();
- for (i = 0; i < numItems; ++i)
- {
- fixDbAttributes(data.attributes()[i]);
- }
-}
};
-//
-// Fix DBAttributes, which have to be processed specially
-//
-void fixDbAttributes (CssmDbAttributeData &data);
-void fixDbAttributes (CssmQuery &query);
-void fixDbAttributes (CssmDbRecordAttributeData &data);
-
-template<class T>
-void fixDbAttributes(T &n) {} // handle the default case
-
-
//
// Process an incoming (IPC) data blob of type T.
// This relocates pointers to fit in the local address space,
CheckingReconstituteWalker relocator(obj, base, size,
Server::process().byteFlipped());
walk(relocator, base);
-
- // resolve weird type interdependency in DB_ATTRIBUTE_DATA
- if (Server::process().byteFlipped())
- fixDbAttributes(*obj);
}
}
}
-void flipCssmDbAttributeData (CssmDbRecordAttributeData *value, CssmDbRecordAttributeData **&addr, CssmDbRecordAttributeData **&base);
-
//
// Take an object at value, flip it, and return appropriately flipped
// addr/base pointers ready to be returned through IPC.
{
*addr = *base = value;
if (flipClient()) {
- // resolve weird type inter-dependency in DB_ATTRIBUTE_DATA
- if (value)
- fixDbAttributes(*value);
FlipWalker w; // collector
walk(w, value); // collect all flippings needed
w.doFlips(); // execute flips (flips value but leaves addr alone)
}
}
+
//
// Take a DATA type RPC argument purportedly representing a Blob of some kind,
// turn it into a Blob, and fail properly if it's not kosher.