#include <xpc/private.h>
#include <syslog.h>
#include <sandbox.h>
+#include <security_keychain/StorageManager.h>
dispatch_once_t AppSandboxChecked;
xpc_object_t KeychainHomeFromXPC;
mCurrent = uid;
mTime = currentTime;
- secdebug("secpref", "uid=%d caching home=%s", uid, pw->pw_dir);
+ secinfo("secpref", "uid=%d caching home=%s", uid, pw->pw_dir);
endpwent();
}
DLDbListCFPref::DLDbListCFPref(SecPreferencesDomain domain) : mDomain(domain), mPropertyList(NULL), mChanged(false),
mSearchListSet(false), mDefaultDLDbIdentifierSet(false), mLoginDLDbIdentifierSet(false)
{
- secdebug("secpref", "New DLDbListCFPref %p for domain %d", this, domain);
+ secinfo("secpref", "New DLDbListCFPref %p for domain %d", this, domain);
loadPropertyList(true);
}
mDomain = domain;
- secdebug("secpref", "DLDbListCFPref %p domain set to %d", this, domain);
+ secinfo("secpref", "DLDbListCFPref %p domain set to %d", this, domain);
if (loadPropertyList(true))
resetCachedValues();
MacOSError::throwMe(errSecInvalidPrefsDomain);
}
- secdebug("secpref", "force=%s prefsPath=%s", force ? "true" : "false",
+ secinfo("secpref", "force=%s prefsPath=%s", force ? "true" : "false",
prefsPath.c_str());
CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
// The prefs file should at least be made readable by user/group/other and writable by the owner.
// Change from euid to ruid if needed for the duration of the new prefs file creat.
- mode_t mode = 0666;
+ mode_t mode = 0644;
changeIdentity(UNPRIV);
int fd = open(mPrefsPath.c_str(), O_WRONLY|O_CREAT|O_TRUNC, mode);
changeIdentity(PRIV);
{
char *prefsPath = (char *)mPrefsPath.c_str();
- int fd1, fd2, retval;
+ int fd1, retval;
struct stat stbuf;
if((fd1 = open(prefsPath, O_RDONLY)) < 0) {
if(stbuf.st_uid != getuid()) {
char tempfile[MAXPATHLEN+1];
- snprintf(tempfile, MAXPATHLEN, "%s.XXXXX", prefsPath);
- mktemp(tempfile);
- changeIdentity(UNPRIV);
- if((fd2 = open(tempfile, O_RDWR | O_CREAT | O_EXCL, 0666)) < 0) {
- retval = -1;
+ changeIdentity(UNPRIV);
+
+ snprintf(tempfile, MAXPATHLEN, "%s.XXXXXX", prefsPath);
+ int fd2 = mkstemp(tempfile);
+ if (fd2 < 0 || ::fchmod(fd2, 0644) != 0) {
+ ::unlink(tempfile);
+ retval = -1;
} else {
copyfile_state_t s = copyfile_state_alloc();
retval = fcopyfile(fd1, fd2, s, COPYFILE_DATA);
copyfile_state_free(s);
- if(!retval) retval = ::unlink(prefsPath);
- if(!retval) retval = ::rename(tempfile, prefsPath);
+ if (retval) {
+ ::unlink(tempfile);
+ } else {
+ retval = ::unlink(prefsPath);
+ if(!retval) retval = ::rename(tempfile, prefsPath);
+ }
}
changeIdentity(PRIV);
- close(fd2);
+ if (fd2 >= 0)
+ close(fd2);
}
close(fd1);
return retval;
void
DLDbListCFPref::searchList(const vector<DLDbIdentifier> &searchList)
{
+ if(searchList.size() == 0) {
+ mSearchList.clear();
+ mSearchListSet = false;
+ changed(true);
+ return;
+ }
+
vector<DLDbIdentifier> newList(searchList);
mSearchList.swap(newList);
mSearchListSet = true;
}
}
+// Caution: if the backing file for the defaultDLDbIdentifier doesn't exist (or if the plist file is corrupt),
+// this will return a DLDbIdentifier with a NULL impl
const DLDbIdentifier &
DLDbListCFPref::defaultDLDbIdentifier()
{
CFDictionaryRef defaultDict = reinterpret_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(defaultArray, 0));
try
{
- secdebug("secpref", "getting default DLDbIdentifier from defaultDict");
+ secinfo("secpref", "getting default DLDbIdentifier from defaultDict");
mDefaultDLDbIdentifier = cfDictionaryRefToDLDbIdentifier(defaultDict);
- secdebug("secpref", "now we think the default keychain is %s", (mDefaultDLDbIdentifier) ? mDefaultDLDbIdentifier.dbName() : "<NULL>");
+ secinfo("secpref", "now we think the default keychain is %s", (mDefaultDLDbIdentifier) ? mDefaultDLDbIdentifier.dbName() : "<NULL>");
}
catch (...)
{
if (!defaultArray)
{
-
// If the Panther style login keychain actually exists we use that otherwise no
// default is set.
mDefaultDLDbIdentifier = loginDLDbIdentifier();
- secdebug("secpref", "now we think the default keychain is: %s", (mDefaultDLDbIdentifier) ? mDefaultDLDbIdentifier.dbName() :
- "Name doesn't exist");
-
+
+ //Since we might be changing the keychain filename, we have to stat the right file. Delegate the knowledge of which files to StorageManager; DLDbListCFPref should contain "login.keychain".
+ DLDbIdentifier actualIdentifier = KeychainCore::StorageManager::mungeDLDbIdentifier(mDefaultDLDbIdentifier, false);
+ secinfo("secpref", "now we think the default keychain is: %s (actual: %s)",
+ (mDefaultDLDbIdentifier) ? mDefaultDLDbIdentifier.dbName() : "Name doesn't exist",
+ (actualIdentifier) ? actualIdentifier.dbName() : "Name doesn't exist");
+
struct stat st;
int st_result = -1;
-
- if (mDefaultDLDbIdentifier.mImpl != NULL)
- {
- st_result = stat(mDefaultDLDbIdentifier.dbName(), &st);
- }
-
+
+ if (mDefaultDLDbIdentifier.mImpl != NULL && actualIdentifier.mImpl != NULL)
+ {
+ st_result = stat(actualIdentifier.dbName(), &st);
+
+ // Always claim that the system keychain exists for purposes of the search list
+ if (st_result && 0 == strncmp(actualIdentifier.dbName(), kSystemKeychainPath, strlen(kSystemKeychainPath))) {
+ secnotice("secpref", "System keychain (%s) does not exist. Continuing as if it does...", actualIdentifier.dbName());
+ st_result = 0;
+ }
+ }
+
if (st_result)
{
- secdebug("secpref", "stat(%s) -> %d", mDefaultDLDbIdentifier.dbName(), st_result);
+ secinfo("secpref", "stat(%s) -> %d", actualIdentifier.dbName(), st_result);
mDefaultDLDbIdentifier = DLDbIdentifier(); // initialize a NULL keychain
- secdebug("secpref", "after DLDbIdentifier(), we think the default keychain is %s", static_cast<bool>(mDefaultDLDbIdentifier) ? mDefaultDLDbIdentifier.dbName() : "<NULL>");
+ secinfo("secpref", "after DLDbIdentifier(), we think the default keychain is %s", static_cast<bool>(mDefaultDLDbIdentifier) ? mDefaultDLDbIdentifier.dbName() : "<NULL>");
}
}
CFDictionaryRef loginDict = reinterpret_cast<CFDictionaryRef>(CFArrayGetValueAtIndex(loginArray, 0));
try
{
- secdebug("secpref", "Getting login DLDbIdentifier from loginDict");
+ secinfo("secpref", "Getting login DLDbIdentifier from loginDict");
mLoginDLDbIdentifier = cfDictionaryRefToDLDbIdentifier(loginDict);
- secdebug("secpref", "we think the login keychain is %s", static_cast<bool>(mLoginDLDbIdentifier) ? mLoginDLDbIdentifier.dbName() : "<NULL>");
+ secinfo("secpref", "we think the login keychain is %s", static_cast<bool>(mLoginDLDbIdentifier) ? mLoginDLDbIdentifier.dbName() : "<NULL>");
}
catch (...)
{
if (!loginArray)
{
mLoginDLDbIdentifier = LoginDLDbIdentifier();
- secdebug("secpref", "after LoginDLDbIdentifier(), we think the login keychain is %s", static_cast<bool>(mLoginDLDbIdentifier) ? mLoginDLDbIdentifier.dbName() : "<NULL>");
+ secinfo("secpref", "after LoginDLDbIdentifier(), we think the login keychain is %s", static_cast<bool>(mLoginDLDbIdentifier) ? mLoginDLDbIdentifier.dbName() : "<NULL>");
}
mLoginDLDbIdentifierSet = true;