X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/5c19dc3ae3bd8e40a9c028b0deddd50ff337692c..07691282a056c4efea71e1e505527601e8cc166b:/OSX/libsecurity_keychain/lib/DLDBListCFPref.cpp diff --git a/OSX/libsecurity_keychain/lib/DLDBListCFPref.cpp b/OSX/libsecurity_keychain/lib/DLDBListCFPref.cpp index 4836f4dc..aa168bd8 100644 --- a/OSX/libsecurity_keychain/lib/DLDBListCFPref.cpp +++ b/OSX/libsecurity_keychain/lib/DLDBListCFPref.cpp @@ -41,6 +41,7 @@ #include #include #include +#include dispatch_once_t AppSandboxChecked; xpc_object_t KeychainHomeFromXPC; @@ -96,7 +97,7 @@ void PasswordDBLookup::lookupInfoOnUID (uid_t uid) 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(); } @@ -113,7 +114,7 @@ PasswordDBLookup *DLDbListCFPref::mPdbLookup = NULL; 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); } @@ -123,7 +124,7 @@ void DLDbListCFPref::set(SecPreferencesDomain domain) 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(); @@ -164,7 +165,7 @@ DLDbListCFPref::loadPropertyList(bool force) 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(); @@ -306,7 +307,7 @@ DLDbListCFPref::writePropertyList() // 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); @@ -341,7 +342,7 @@ DLDbListCFPref::testAndFixPropertyList() { char *prefsPath = (char *)mPrefsPath.c_str(); - int fd1, fd2, retval; + int fd1, retval; struct stat stbuf; if((fd1 = open(prefsPath, O_RDONLY)) < 0) { @@ -354,20 +355,27 @@ DLDbListCFPref::testAndFixPropertyList() 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; @@ -957,6 +965,13 @@ DLDbListCFPref::searchList() void DLDbListCFPref::searchList(const vector &searchList) { + if(searchList.size() == 0) { + mSearchList.clear(); + mSearchListSet = false; + changed(true); + return; + } + vector newList(searchList); mSearchList.swap(newList); mSearchListSet = true; @@ -973,6 +988,8 @@ DLDbListCFPref::defaultDLDbIdentifier(const DLDbIdentifier &dlDbIdentifier) } } +// 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() { @@ -988,9 +1005,9 @@ DLDbListCFPref::defaultDLDbIdentifier() CFDictionaryRef defaultDict = reinterpret_cast(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() : ""); + secinfo("secpref", "now we think the default keychain is %s", (mDefaultDLDbIdentifier) ? mDefaultDLDbIdentifier.dbName() : ""); } catch (...) { @@ -1001,26 +1018,35 @@ DLDbListCFPref::defaultDLDbIdentifier() 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(mDefaultDLDbIdentifier) ? mDefaultDLDbIdentifier.dbName() : ""); + secinfo("secpref", "after DLDbIdentifier(), we think the default keychain is %s", static_cast(mDefaultDLDbIdentifier) ? mDefaultDLDbIdentifier.dbName() : ""); } } @@ -1055,9 +1081,9 @@ DLDbListCFPref::loginDLDbIdentifier() CFDictionaryRef loginDict = reinterpret_cast(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(mLoginDLDbIdentifier) ? mLoginDLDbIdentifier.dbName() : ""); + secinfo("secpref", "we think the login keychain is %s", static_cast(mLoginDLDbIdentifier) ? mLoginDLDbIdentifier.dbName() : ""); } catch (...) { @@ -1069,7 +1095,7 @@ DLDbListCFPref::loginDLDbIdentifier() if (!loginArray) { mLoginDLDbIdentifier = LoginDLDbIdentifier(); - secdebug("secpref", "after LoginDLDbIdentifier(), we think the login keychain is %s", static_cast(mLoginDLDbIdentifier) ? mLoginDLDbIdentifier.dbName() : ""); + secinfo("secpref", "after LoginDLDbIdentifier(), we think the login keychain is %s", static_cast(mLoginDLDbIdentifier) ? mLoginDLDbIdentifier.dbName() : ""); } mLoginDLDbIdentifierSet = true;