/ OSX / libsecurity_cdsa_client / lib / mdsclient.cpp
mdsclient.cpp
  1  /*
  2   * Copyright (c) 2000-2004,2011,2014 Apple Inc. All Rights Reserved.
  3   * 
  4   * The contents of this file constitute Original Code as defined in and are
  5   * subject to the Apple Public Source License Version 1.2 (the 'License').
  6   * You may not use this file except in compliance with the License. Please obtain
  7   * a copy of the License at http://www.apple.com/publicsource and read it before
  8   * using this file.
  9   * 
 10   * This Original Code and all software distributed under the License are
 11   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
 12   * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
 13   * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 14   * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
 15   * specific language governing rights and limitations under the License.
 16   */
 17  
 18  
 19  //
 20  // mdsclient - friendly interface to CDSA MDS API
 21  //
 22  #include <security_cdsa_client/mdsclient.h>
 23  #include <Security/mdspriv.h>
 24  
 25  
 26  namespace Security {
 27  namespace MDSClient {
 28  
 29  
 30  //
 31  // The MDS access object singleton
 32  //
 33  ModuleNexus<Directory> mds;
 34  
 35  
 36  //
 37  // Directory construction initializes MDS and opens the "CDSA" database
 38  //
 39  Directory::Directory()
 40  	: mMemoryFunctions(Allocator::standard())
 41  {
 42  	StLock<Mutex> _(mInitLock);
 43  	CssmError::check(MDS_Initialize(&mCallerGuid, &mMemoryFunctions,
 44  		this, &mCDSA.DLHandle));
 45  	mCDSA.DBHandle = CSSM_INVALID_HANDLE;
 46  }
 47  
 48  
 49  //
 50  // Cleanup (only called if the ModuleNexus is explicitly reset)
 51  //
 52  Directory::~Directory()
 53  {
 54  	if (mCDSA.DBHandle)
 55  		CssmError::check(DbClose(mCDSA));
 56  	CssmError::check(MDS_Terminate(mds()));
 57  }
 58  
 59  
 60  //
 61  // Open MDS database if needed
 62  //
 63  const MDS_DB_HANDLE &Directory::cdsa() const
 64  {
 65  	if (mCDSA.DBHandle == CSSM_INVALID_HANDLE) {
 66  		StLock<Mutex> _(mInitLock);
 67  		if (mCDSA.DBHandle == CSSM_INVALID_HANDLE)
 68  			CssmError::check(DbOpen(mCDSA.DLHandle, MDS_CDSA_DIRECTORY_NAME, NULL,
 69  				CSSM_DB_ACCESS_READ,	// access mode
 70  				NULL,					// credentials
 71  				NULL,					// OpenParameters
 72  				&mCDSA.DBHandle));
 73  	}
 74  	return mCDSA;
 75  }
 76  
 77  
 78  //
 79  // The DLAccess implementation for MDS.
 80  // We don't ever return record data, of course; we just zero it out.
 81  //
 82  CSSM_HANDLE Directory::dlGetFirst(const CSSM_QUERY &query, CSSM_DB_RECORD_ATTRIBUTE_DATA &attributes,
 83  	CSSM_DATA *data, CSSM_DB_UNIQUE_RECORD *&id)
 84  {
 85  	CSSM_HANDLE result;
 86  	switch (CSSM_RETURN rc = DataGetFirst(cdsa(), &query, &result, &attributes, NULL, &id)) {
 87  	case CSSM_OK:
 88  		if (data)
 89  			*data = CssmData();
 90  		return result;
 91  	case CSSMERR_DL_ENDOFDATA:
 92  		return CSSM_INVALID_HANDLE;
 93  	default:
 94  		CssmError::throwMe(rc);
 95  	}
 96  }
 97  
 98  bool Directory::dlGetNext(CSSM_HANDLE handle, CSSM_DB_RECORD_ATTRIBUTE_DATA &attributes,
 99  	CSSM_DATA *data, CSSM_DB_UNIQUE_RECORD *&id)
100  {
101  	CSSM_RETURN rc = DataGetNext(cdsa(), handle, &attributes, NULL, &id);
102  	switch (rc) {
103  	case CSSM_OK:
104  		if (data)
105  			*data = CssmData();
106  		return true;
107  	case CSSMERR_DL_ENDOFDATA:
108  		return false;
109  	default:
110  		CssmError::throwMe(rc);
111  	}
112  }
113  
114  void Directory::dlAbortQuery(CSSM_HANDLE handle)
115  {
116  	CssmError::check(DataAbortQuery(cdsa(), handle));
117  }
118  
119  void Directory::dlFreeUniqueId(CSSM_DB_UNIQUE_RECORD *id)
120  {
121  	CssmError::check(FreeUniqueRecord(cdsa(), id));
122  }
123  
124  void Directory::dlDeleteRecord(CSSM_DB_UNIQUE_RECORD *id)
125  {
126  	CssmError::check(DataDelete(cdsa(), id));
127  }
128  
129  Allocator &Directory::allocator()
130  {
131  	return Allocator::standard();
132  }
133  
134  
135  //
136  // Public MDS operations
137  //
138  void Directory::install()
139  {
140  	CssmError::check(MDS_Install(this->mds()));
141  }
142  
143  void Directory::install(const MDS_InstallDefaults *defaults,
144  	const char *path, const char *subdir, const char *file)
145  {
146  	CssmError::check(MDS_InstallFile(this->mds(), defaults, path, subdir, file));
147  }
148  
149  void Directory::uninstall(const char *guid, uint32 ssid)
150  {
151  	CssmError::check(MDS_RemoveSubservice(this->mds(), guid, ssid));
152  }
153  
154  
155  } // end namespace MDSClient
156  } // end namespace Security