2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
23 #include "DLDBListCFPref.h"
24 #include <Security/cssmapple.h>
25 #include <Security/debugging.h>
29 #include <sys/types.h>
34 using namespace CssmClient
;
36 static const double kDLDbListCFPrefRevertInterval
= 30.0;
38 // normal debug calls, which get stubbed out for deployment builds
39 #define x_debug(str) secdebug("KClogin",(str))
40 #define x_debug1(fmt,arg1) secdebug("KClogin",(fmt),(arg1))
41 #define x_debug2(fmt,arg1,arg2) secdebug("KClogin",(fmt),(arg1),(arg2))
43 #define kKeyGUID CFSTR("GUID")
44 #define kKeySubserviceId CFSTR("SubserviceId")
45 #define kKeySubserviceType CFSTR("SubserviceType")
46 #define kKeyDbName CFSTR("DbName")
47 #define kKeyDbLocation CFSTR("DbLocation")
48 #define kKeyActive CFSTR("Active")
49 #define kKeyMajorVersion CFSTR("MajorVersion")
50 #define kKeyMinorVersion CFSTR("MinorVersion")
51 #define kDefaultDLDbListKey CFSTR("DLDBSearchList")
52 #define kDefaultKeychainKey CFSTR("DefaultKeychain")
53 #define kLoginKeychainKey CFSTR("LoginKeychain")
54 #define kUserDefaultPath "~/Library/Preferences/com.apple.security.plist"
55 #define kSystemDefaultPath "/Library/Preferences/com.apple.security.plist"
56 #define kCommonDefaultPath "/Library/Preferences/com.apple.security-common.plist"
57 #define kLoginKeychainPathPrefix "~/Library/Keychains/"
58 #define kUserLoginKeychainPath "~/Library/Keychains/login.keychain"
59 #define kSystemLoginKeychainPath "/Library/Keychains/System.keychain"
62 // A utility class for managing password database lookups
64 const time_t kPasswordCacheExpire
= 30; // number of seconds cached password db info is valid
66 PasswordDBLookup::PasswordDBLookup () : mValid (false), mCurrent (0), mTime (0)
70 void PasswordDBLookup::lookupInfoOnUID (uid_t uid
)
72 time_t currentTime
= time (NULL
);
74 if (!mValid
|| uid
!= mCurrent
|| currentTime
- mTime
>= kPasswordCacheExpire
)
76 struct passwd
* pw
= getpwuid(uid
);
79 UnixError::throwMe (EPERM
);
82 mDirectory
= pw
->pw_dir
;
88 x_debug2("PasswordDBLookup::lookupInfoOnUID: uid=%d caching home=%s", uid
, pw
->pw_dir
);
94 PasswordDBLookup
*DLDbListCFPref::mPdbLookup
= NULL
;
96 //-------------------------------------------------------------------------------------
98 // Lists of DL/DBs, with CFPreferences backing store
100 //-------------------------------------------------------------------------------------
102 DLDbListCFPref::DLDbListCFPref(SecPreferencesDomain domain
) : mDomain(domain
), mPropertyList(NULL
), mChanged(false),
103 mSearchListSet(false), mDefaultDLDbIdentifierSet(false), mLoginDLDbIdentifierSet(false)
105 x_debug2("New DLDbListCFPref %p for domain %d", this, domain
);
106 loadPropertyList(true);
109 void DLDbListCFPref::set(SecPreferencesDomain domain
)
115 x_debug2("DLDbListCFPref %p domain set to %d", this, domain
);
117 if (loadPropertyList(true))
121 DLDbListCFPref::~DLDbListCFPref()
125 x_debug1("~DLDbListCFPref %p", this);
128 CFRelease(mPropertyList
);
132 DLDbListCFPref::loadPropertyList(bool force
)
138 case kSecPreferencesDomainUser
:
139 prefsPath
= ExpandTildesInPath(kUserDefaultPath
);
141 case kSecPreferencesDomainSystem
:
142 prefsPath
= kSystemDefaultPath
;
144 case kSecPreferencesDomainCommon
:
145 prefsPath
= kCommonDefaultPath
;
148 MacOSError::throwMe(errSecInvalidPrefsDomain
);
151 x_debug2("DLDbListCFPref::loadPropertyList: force=%s prefsPath=%s", force
? "true" : "false",
154 CFAbsoluteTime now
= CFAbsoluteTimeGetCurrent();
156 // If for some reason the prefs file path has changed, blow away the old plist and force an update
157 if (mPrefsPath
!= prefsPath
)
159 mPrefsPath
= prefsPath
;
162 CFRelease(mPropertyList
);
163 mPropertyList
= NULL
;
166 mPrefsTimeStamp
= now
;
170 if (now
- mPrefsTimeStamp
< kDLDbListCFPrefRevertInterval
)
173 mPrefsTimeStamp
= now
;
177 if (stat(mPrefsPath
.c_str(), &st
))
183 if (CFDictionaryGetCount(mPropertyList
) == 0)
185 CFRelease(mPropertyList
);
188 mPropertyList
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
196 if (mTimespec
.tv_sec
== st
.st_mtimespec
.tv_sec
197 && mTimespec
.tv_nsec
== st
.st_mtimespec
.tv_nsec
)
201 mTimespec
= st
.st_mtimespec
;
204 CFMutableDictionaryRef thePropertyList
= NULL
;
205 CFMutableDataRef xmlData
= NULL
;
206 CFStringRef errorString
= NULL
;
211 fd
= open(mPrefsPath
.c_str(), O_RDONLY
, 0);
215 off_t theSize
= lseek(fd
, 0, SEEK_END
);
219 if (lseek(fd
, 0, SEEK_SET
))
222 xmlData
= CFDataCreateMutable(NULL
, CFIndex(theSize
));
225 CFDataSetLength(xmlData
, CFIndex(theSize
));
226 void *buffer
= reinterpret_cast<void *>(CFDataGetMutableBytePtr(xmlData
));
229 ssize_t bytesRead
= read(fd
, buffer
, theSize
);
230 if (bytesRead
!= theSize
)
233 thePropertyList
= CFMutableDictionaryRef(CFPropertyListCreateFromXMLData(NULL
, xmlData
, kCFPropertyListMutableContainers
, &errorString
));
234 if (!thePropertyList
)
237 if (CFGetTypeID(thePropertyList
) != CFDictionaryGetTypeID())
239 CFRelease(thePropertyList
);
240 thePropertyList
= NULL
;
250 CFRelease(errorString
);
252 if (!thePropertyList
)
254 thePropertyList
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
259 if (CFEqual(mPropertyList
, thePropertyList
))
261 // The new property list is the same as the old one, so nothing has changed.
262 CFRelease(thePropertyList
);
265 CFRelease(mPropertyList
);
268 mPropertyList
= thePropertyList
;
273 DLDbListCFPref::writePropertyList()
275 if (!mPropertyList
|| CFDictionaryGetCount(mPropertyList
) == 0)
277 // There is nothing in the mPropertyList dictionary,
278 // so we don't need a prefs file.
279 unlink(mPrefsPath
.c_str());
283 CFDataRef xmlData
= CFPropertyListCreateXMLData(NULL
, mPropertyList
);
285 return; // Bad out of memory or something evil happened let's act like CF and do nothing.
288 int fd
= open(mPrefsPath
.c_str(), O_WRONLY
|O_CREAT
|O_TRUNC
, mode
);
291 const void *buffer
= CFDataGetBytePtr(xmlData
);
292 size_t toWrite
= CFDataGetLength(xmlData
);
293 /* ssize_t bytesWritten = */ write(fd
, buffer
, toWrite
);
294 // Emulate CFPreferences by not checking for any errors.
299 mTimespec
= st
.st_mtimespec
;
307 mPrefsTimeStamp
= CFAbsoluteTimeGetCurrent();
311 DLDbListCFPref::resetCachedValues()
313 // Unset the login and default Keychain.
314 mLoginDLDbIdentifier
= mDefaultDLDbIdentifier
= DLDbIdentifier();
316 // Clear the searchList.
321 // Note that none of our cached values are valid
322 mSearchListSet
= mDefaultDLDbIdentifierSet
= mLoginDLDbIdentifierSet
= false;
324 mPrefsTimeStamp
= CFAbsoluteTimeGetCurrent();
327 void DLDbListCFPref::save()
332 // Resync from disc to make sure we don't clobber anyone elses changes.
333 // @@@ This is probably already done by the next layer up so we don't
334 // really need to do it here again.
335 loadPropertyList(true);
337 // Do the searchList first since it might end up invoking defaultDLDbIdentifier() which can set
338 // mLoginDLDbIdentifierSet and mDefaultDLDbIdentifierSet to true.
341 // Make a temporary CFArray with the contents of the vector
342 if (mSearchList
.size() == 1 && mSearchList
[0] == defaultDLDbIdentifier() && mSearchList
[0] == LoginDLDbIdentifier())
344 // The only element in the search list is the default keychain, which is a
345 // post Jaguar style login keychain, so omit the entry from the prefs file.
346 CFDictionaryRemoveValue(mPropertyList
, kDefaultDLDbListKey
);
350 CFMutableArrayRef searchArray
= CFArrayCreateMutable(kCFAllocatorDefault
, mSearchList
.size(), &kCFTypeArrayCallBacks
);
351 for (DLDbList::const_iterator ix
=mSearchList
.begin();ix
!=mSearchList
.end();ix
++)
353 CFDictionaryRef aDict
= dlDbIdentifierToCFDictionaryRef(*ix
);
354 CFArrayAppendValue(searchArray
, aDict
);
358 CFDictionarySetValue(mPropertyList
, kDefaultDLDbListKey
, searchArray
);
359 CFRelease(searchArray
);
363 if (mLoginDLDbIdentifierSet
)
365 // Make a temporary CFArray with the login keychain
366 CFArrayRef loginArray
= NULL
;
367 if (!mLoginDLDbIdentifier
)
369 loginArray
= CFArrayCreate(kCFAllocatorDefault
, NULL
, 0, &kCFTypeArrayCallBacks
);
371 else if (!(mLoginDLDbIdentifier
== LoginDLDbIdentifier())
372 && !(mLoginDLDbIdentifier
== JaguarLoginDLDbIdentifier()))
374 CFDictionaryRef aDict
= dlDbIdentifierToCFDictionaryRef(mLoginDLDbIdentifier
);
375 const void *value
= reinterpret_cast<const void *>(aDict
);
376 loginArray
= CFArrayCreate(kCFAllocatorDefault
, &value
, 1, &kCFTypeArrayCallBacks
);
382 CFDictionarySetValue(mPropertyList
, kLoginKeychainKey
, loginArray
);
383 CFRelease(loginArray
);
386 CFDictionaryRemoveValue(mPropertyList
, kLoginKeychainKey
);
389 if (mDefaultDLDbIdentifierSet
)
391 // Make a temporary CFArray with the default keychain
392 CFArrayRef defaultArray
= NULL
;
393 if (!mDefaultDLDbIdentifier
)
395 defaultArray
= CFArrayCreate(kCFAllocatorDefault
, NULL
, 0, &kCFTypeArrayCallBacks
);
397 else if (!(mDefaultDLDbIdentifier
== LoginDLDbIdentifier()))
399 CFDictionaryRef aDict
= dlDbIdentifierToCFDictionaryRef(mDefaultDLDbIdentifier
);
400 const void *value
= reinterpret_cast<const void *>(aDict
);
401 defaultArray
= CFArrayCreate(kCFAllocatorDefault
, &value
, 1, &kCFTypeArrayCallBacks
);
407 CFDictionarySetValue(mPropertyList
, kDefaultKeychainKey
, defaultArray
);
408 CFRelease(defaultArray
);
411 CFDictionaryRemoveValue(mPropertyList
, kDefaultKeychainKey
);
419 //----------------------------------------------------------------------
421 //----------------------------------------------------------------------
423 DLDbIdentifier
DLDbListCFPref::LoginDLDbIdentifier()
425 CSSM_VERSION theVersion
={};
426 CssmSubserviceUid
ssuid(gGuidAppleCSPDL
,&theVersion
,0,CSSM_SERVICE_DL
|CSSM_SERVICE_CSP
);
427 CssmNetAddress
*dbLocation
=NULL
;
430 case kSecPreferencesDomainUser
:
431 return DLDbIdentifier(ssuid
, ExpandTildesInPath(kUserLoginKeychainPath
).c_str(), dbLocation
);
434 case kSecPreferencesDomainSystem
:
435 case kSecPreferencesDomainCommon
:
436 return DLDbIdentifier(ssuid
, kSystemLoginKeychainPath
, dbLocation
);
440 DLDbIdentifier
DLDbListCFPref::JaguarLoginDLDbIdentifier()
442 CSSM_VERSION theVersion
={};
443 CssmSubserviceUid
ssuid(gGuidAppleCSPDL
,&theVersion
,0,CSSM_SERVICE_DL
|CSSM_SERVICE_CSP
);
444 CssmNetAddress
*dbLocation
=NULL
;
447 case kSecPreferencesDomainUser
:
449 string basepath
= ExpandTildesInPath(kLoginKeychainPathPrefix
) + getPwInfo(kUsername
);
450 return DLDbIdentifier(ssuid
,basepath
.c_str(),dbLocation
);
452 case kSecPreferencesDomainSystem
:
453 case kSecPreferencesDomainCommon
:
454 return DLDbIdentifier(ssuid
, kSystemLoginKeychainPath
, dbLocation
);
457 return DLDbIdentifier();
461 DLDbIdentifier
DLDbListCFPref::cfDictionaryRefToDLDbIdentifier(CFDictionaryRef theDict
)
463 // We must get individual values from the dictionary and store in basic types
464 if (CFGetTypeID(theDict
) != CFDictionaryGetTypeID())
465 throw std::logic_error("wrong type in property list");
468 CCFValue
vGuid(::CFDictionaryGetValue(theDict
,kKeyGUID
));
469 string guidStr
=vGuid
;
470 const Guid
guid(guidStr
.c_str());
473 CSSM_VERSION theVersion
={0,};
474 CCFValue
vMajor(::CFDictionaryGetValue(theDict
,kKeyMajorVersion
));
475 theVersion
.Major
= vMajor
;
476 CCFValue
vMinor(::CFDictionaryGetValue(theDict
,kKeyMinorVersion
));
477 theVersion
.Minor
= vMinor
;
480 CCFValue
vSsid(::CFDictionaryGetValue(theDict
,kKeySubserviceId
));
481 uint32 subserviceId
=sint32(vSsid
);
484 CSSM_SERVICE_TYPE subserviceType
=CSSM_SERVICE_DL
;
485 CCFValue
vSsType(::CFDictionaryGetValue(theDict
,kKeySubserviceType
));
486 subserviceType
=vSsType
;
488 // Get DbName from dictionary
489 CCFValue
vDbName(::CFDictionaryGetValue(theDict
,kKeyDbName
));
490 string dbName
=vDbName
;
492 // jch Get DbLocation from dictionary
493 CssmNetAddress
*dbLocation
=NULL
;
495 // Create a local CssmSubserviceUid
496 CssmSubserviceUid
ssuid(guid
,&theVersion
,subserviceId
,subserviceType
);
498 return DLDbIdentifier(ssuid
,ExpandTildesInPath(dbName
).c_str(),dbLocation
);
501 void DLDbListCFPref::clearPWInfo ()
503 if (mPdbLookup
!= NULL
)
510 string
DLDbListCFPref::getPwInfo(PwInfoType type
)
512 // Get our effective uid
513 uid_t uid
= geteuid();
514 // If we are setuid root use the real uid instead
515 if (!uid
) uid
= getuid();
517 // get the password entries
518 if (mPdbLookup
== NULL
)
520 mPdbLookup
= new PasswordDBLookup ();
523 mPdbLookup
->lookupInfoOnUID (uid
);
529 result
= mPdbLookup
->getDirectory ();
532 result
= mPdbLookup
->getName ();
539 string
DLDbListCFPref::ExpandTildesInPath(const string
&inPath
)
541 if ((short)inPath
.find("~/",0,2) == 0)
542 return getPwInfo(kHomeDir
) + inPath
.substr(1);
547 string
DLDbListCFPref::StripPathStuff(const string
&inPath
)
549 if (inPath
.find("/private/var/automount/Network/",0,31) == 0)
550 return inPath
.substr(22);
551 if (inPath
.find("/private/automount/Servers/",0,27) == 0)
552 return "/Network" + inPath
.substr(18);
553 if (inPath
.find("/automount/Servers/",0,19) == 0)
554 return "/Network" + inPath
.substr(10);
555 if (inPath
.find("/private/automount/Network/",0,27) == 0)
556 return inPath
.substr(18);
557 if (inPath
.find("/automount/Network/",0,19) == 0)
558 return inPath
.substr(10);
559 if (inPath
.find("/private/Network/",0,17) == 0)
560 return inPath
.substr(8);
564 string
DLDbListCFPref::AbbreviatedPath(const string
&inPath
)
566 string path
= StripPathStuff(inPath
);
567 string home
= StripPathStuff(getPwInfo(kHomeDir
) + "/");
568 size_t homeLen
= home
.length();
570 if (homeLen
> 1 && path
.find(home
.c_str(), 0, homeLen
) == 0)
571 return "~" + path
.substr(homeLen
- 1);
576 CFDictionaryRef
DLDbListCFPref::dlDbIdentifierToCFDictionaryRef(const DLDbIdentifier
& dldbIdentifier
)
578 CFRef
<CFMutableDictionaryRef
> aDict(CFDictionaryCreateMutable(kCFAllocatorDefault
,0,
579 &kCFTypeDictionaryKeyCallBacks
,&kCFTypeDictionaryValueCallBacks
));
581 throw ::std::bad_alloc();
583 // Put SUBSERVICE_UID in dictionary
584 char buffer
[Guid::stringRepLength
+1];
585 const CssmSubserviceUid
& ssuid
=dldbIdentifier
.ssuid();
586 const Guid
&theGuid
= Guid::overlay(ssuid
.Guid
);
587 CFRef
<CFStringRef
> stringGuid(::CFStringCreateWithCString(kCFAllocatorDefault
,
588 theGuid
.toString(buffer
),kCFStringEncodingMacRoman
));
590 ::CFDictionarySetValue(aDict
,kKeyGUID
,stringGuid
);
592 if (ssuid
.SubserviceId
!=0)
594 CFRef
<CFNumberRef
> subserviceId(::CFNumberCreate(kCFAllocatorDefault
,kCFNumberSInt32Type
,&ssuid
.SubserviceId
));
596 ::CFDictionarySetValue(aDict
,kKeySubserviceId
,subserviceId
);
598 if (ssuid
.SubserviceType
!=0)
600 CFRef
<CFNumberRef
> subserviceType(CFNumberCreate(kCFAllocatorDefault
,kCFNumberSInt32Type
,&ssuid
.SubserviceType
));
602 ::CFDictionarySetValue(aDict
,kKeySubserviceType
,subserviceType
);
604 if (ssuid
.Version
.Major
!=0 && ssuid
.Version
.Minor
!=0)
606 CFRef
<CFNumberRef
> majorVersion(::CFNumberCreate(kCFAllocatorDefault
,kCFNumberSInt32Type
,&ssuid
.Version
.Major
));
608 ::CFDictionarySetValue(aDict
,kKeyMajorVersion
,majorVersion
);
609 CFRef
<CFNumberRef
> minorVersion(::CFNumberCreate(kCFAllocatorDefault
,kCFNumberSInt32Type
,&ssuid
.Version
.Minor
));
611 ::CFDictionarySetValue(aDict
,kKeyMinorVersion
,minorVersion
);
614 // Put DbName in dictionary
615 const char *dbName
=dldbIdentifier
.dbName();
618 CFRef
<CFStringRef
> theDbName(::CFStringCreateWithCString(kCFAllocatorDefault
,AbbreviatedPath(dbName
).c_str(),kCFStringEncodingMacRoman
));
619 ::CFDictionarySetValue(aDict
,kKeyDbName
,theDbName
);
621 // Put DbLocation in dictionary
622 const CSSM_NET_ADDRESS
*dbLocation
=dldbIdentifier
.dbLocation();
623 if (dbLocation
!=NULL
&& dbLocation
->AddressType
!=CSSM_ADDR_NONE
)
625 CFRef
<CFDataRef
> theData(::CFDataCreate(kCFAllocatorDefault
,dbLocation
->Address
.Data
,dbLocation
->Address
.Length
));
627 ::CFDictionarySetValue(aDict
,kKeyDbLocation
,theData
);
634 bool DLDbListCFPref::revert(bool force
)
636 // If the prefs have not been refreshed in the last kDLDbListCFPrefRevertInterval
637 // seconds or we are asked to force a reload, then reload.
638 if (!loadPropertyList(force
))
646 DLDbListCFPref::add(const DLDbIdentifier
&dldbIdentifier
)
648 for (vector
<DLDbIdentifier
>::const_iterator ix
= searchList().begin(); ix
!= mSearchList
.end(); ++ix
)
650 if (*ix
==dldbIdentifier
) // already in list
654 mSearchList
.push_back(dldbIdentifier
);
659 DLDbListCFPref::remove(const DLDbIdentifier
&dldbIdentifier
)
661 // Make sure mSearchList is set
663 for (vector
<DLDbIdentifier
>::iterator ix
= mSearchList
.begin(); ix
!= mSearchList
.end(); ++ix
)
665 if (*ix
==dldbIdentifier
) // found in list
667 mSearchList
.erase(ix
);
674 const vector
<DLDbIdentifier
> &
675 DLDbListCFPref::searchList()
679 CFArrayRef searchList
= reinterpret_cast<CFArrayRef
>(CFDictionaryGetValue(mPropertyList
, kDefaultDLDbListKey
));
680 if (searchList
&& CFGetTypeID(searchList
) != CFArrayGetTypeID())
685 CFIndex top
= CFArrayGetCount(searchList
);
686 // Each entry is a CFDictionary; peel it off & add it to the array
687 for (CFIndex idx
= 0; idx
< top
; ++idx
)
689 CFDictionaryRef theDict
= reinterpret_cast<CFDictionaryRef
>(CFArrayGetValueAtIndex(searchList
, idx
));
692 mSearchList
.push_back(cfDictionaryRefToDLDbIdentifier(theDict
));
696 // Drop stuff that doesn't parse on the floor.
700 // If there were entries specified, but they were invalid revert to using the
701 // default keychain in the searchlist.
702 if (top
> 0 && mSearchList
.size() == 0)
706 // The default when no search list is specified is to only search the
708 if (!searchList
&& static_cast<bool>(defaultDLDbIdentifier()))
709 mSearchList
.push_back(mDefaultDLDbIdentifier
);
711 mSearchListSet
= true;
718 DLDbListCFPref::searchList(const vector
<DLDbIdentifier
> &searchList
)
720 vector
<DLDbIdentifier
> newList(searchList
);
721 mSearchList
.swap(newList
);
722 mSearchListSet
= true;
727 DLDbListCFPref::defaultDLDbIdentifier(const DLDbIdentifier
&dlDbIdentifier
)
729 if (!(defaultDLDbIdentifier() == dlDbIdentifier
))
731 mDefaultDLDbIdentifier
= dlDbIdentifier
;
736 const DLDbIdentifier
&
737 DLDbListCFPref::defaultDLDbIdentifier()
739 if (!mDefaultDLDbIdentifierSet
)
741 CFArrayRef defaultArray
= reinterpret_cast<CFArrayRef
>(CFDictionaryGetValue(mPropertyList
, kDefaultKeychainKey
));
742 if (defaultArray
&& CFGetTypeID(defaultArray
) != CFArrayGetTypeID())
745 if (defaultArray
&& CFArrayGetCount(defaultArray
) > 0)
747 CFDictionaryRef defaultDict
= reinterpret_cast<CFDictionaryRef
>(CFArrayGetValueAtIndex(defaultArray
, 0));
750 x_debug("Getting default DLDbIdentifier from defaultDict");
751 mDefaultDLDbIdentifier
= cfDictionaryRefToDLDbIdentifier(defaultDict
);
752 x_debug1("Now we think the default keychain is %s", (mDefaultDLDbIdentifier
) ? mDefaultDLDbIdentifier
.dbName() : "<NULL>");
756 // If defaultArray doesn't parse fall back on the default way of getting the default keychain
763 // If the Panther style login keychain actually exists we use that otherwise no
765 mDefaultDLDbIdentifier
= loginDLDbIdentifier();
766 x_debug1("Now we think the default keychain is %s", (mDefaultDLDbIdentifier
) ? mDefaultDLDbIdentifier
.dbName() : "<NULL>");
769 int st_result
= stat(mDefaultDLDbIdentifier
.dbName(), &st
);
772 x_debug2("stat() of %s returned %d", mDefaultDLDbIdentifier
.dbName(), st_result
);
773 mDefaultDLDbIdentifier
= DLDbIdentifier();
774 x_debug1("After DLDbIdentifier(), we think the default keychain is %s", static_cast<bool>(mDefaultDLDbIdentifier
) ? mDefaultDLDbIdentifier
.dbName() : "<NULL>");
778 mDefaultDLDbIdentifierSet
= true;
781 return mDefaultDLDbIdentifier
;
785 DLDbListCFPref::loginDLDbIdentifier(const DLDbIdentifier
&dlDbIdentifier
)
787 if (!(loginDLDbIdentifier() == dlDbIdentifier
))
789 mLoginDLDbIdentifier
= dlDbIdentifier
;
794 const DLDbIdentifier
&
795 DLDbListCFPref::loginDLDbIdentifier()
797 if (!mLoginDLDbIdentifierSet
)
799 CFArrayRef loginArray
= reinterpret_cast<CFArrayRef
>(CFDictionaryGetValue(mPropertyList
, kLoginKeychainKey
));
800 if (loginArray
&& CFGetTypeID(loginArray
) != CFArrayGetTypeID())
803 if (loginArray
&& CFArrayGetCount(loginArray
) > 0)
805 CFDictionaryRef loginDict
= reinterpret_cast<CFDictionaryRef
>(CFArrayGetValueAtIndex(loginArray
, 0));
808 x_debug("Getting login DLDbIdentifier from loginDict");
809 mLoginDLDbIdentifier
= cfDictionaryRefToDLDbIdentifier(loginDict
);
810 x_debug1("We think the login keychain is %s", static_cast<bool>(mLoginDLDbIdentifier
) ? mLoginDLDbIdentifier
.dbName() : "<NULL>");
814 // If loginArray doesn't parse fall back on the default way of getting the login keychain.
821 // If the jaguar login keychain actually exists we use that otherwise no
822 // login keychain is set.
823 x_debug("No loginDict found, calling JaguarLoginDLDbIdentifier()");
824 mLoginDLDbIdentifier
= JaguarLoginDLDbIdentifier();
825 x_debug1("After JaguarLoginDLDbIdentifier(), we think the login keychain is %s", static_cast<bool>(mLoginDLDbIdentifier
) ? mLoginDLDbIdentifier
.dbName() : "<NULL>");
828 int st_result
= stat(mLoginDLDbIdentifier
.dbName(), &st
);
831 // Jaguar login Keychain didn't exist, so assume new style one.
832 x_debug2("stat() of %s returned %d", mLoginDLDbIdentifier
.dbName(), st_result
);
833 mLoginDLDbIdentifier
= LoginDLDbIdentifier();
834 x_debug1("After LoginDLDbIdentifier(), we think the login keychain is %s", static_cast<bool>(mLoginDLDbIdentifier
) ? mLoginDLDbIdentifier
.dbName() : "<NULL>");
838 mLoginDLDbIdentifierSet
= true;
841 return mLoginDLDbIdentifier
;