1/*
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25/*
26 *  DLDBListCFPref.h
27 */
28#ifndef _SECURITY_DLDBLISTCFPREF_H_
29#define _SECURITY_DLDBLISTCFPREF_H_
30
31#include <Security/SecKeychain.h>
32#include <security_utilities/cfutilities.h>
33#include <CoreFoundation/CFDictionary.h>
34#include <security_cdsa_client/DLDBList.h>
35#include <security_cdsa_utilities/cssmdb.h>
36#include <stdexcept>
37#include <CoreFoundation/CFNumber.h>
38#include <CoreFoundation/CFDate.h>
39
40namespace Security
41{
42
43class PasswordDBLookup
44{
45protected:
46    string mDirectory;
47    string mName;
48    bool mValid;
49    uid_t mCurrent;
50    time_t mTime;
51
52public:
53    PasswordDBLookup ();
54
55    void lookupInfoOnUID (uid_t uid);
56    const string& getDirectory () {return mDirectory;}
57    const string& getName () {return mName;}
58};
59
60class DLDbListCFPref
61{
62public:
63    DLDbListCFPref(SecPreferencesDomain domain = kSecPreferencesDomainUser);
64    ~DLDbListCFPref();
65
66	void set(SecPreferencesDomain domain);
67
68    void save();
69    vector<DLDbIdentifier>& list() { return mSearchList; }
70
71    static DLDbIdentifier makeDLDbIdentifier (const CSSM_GUID &guid, const CSSM_VERSION &version,
72											  uint32 subserviceId, CSSM_SERVICE_TYPE subserviceType,
73											  const char* dbName, CSSM_NET_ADDRESS *dbLocation);
74
75	static DLDbIdentifier cfDictionaryRefToDLDbIdentifier(CFDictionaryRef theDict);
76    static CFDictionaryRef dlDbIdentifierToCFDictionaryRef(const DLDbIdentifier& dldbIdentifier);
77	bool revert(bool force);
78
79	void add(const DLDbIdentifier &);
80	void remove(const DLDbIdentifier &);
81	void rename(const DLDbIdentifier &oldId, const DLDbIdentifier &newId);
82	bool member(const DLDbIdentifier &);
83	const vector<DLDbIdentifier> &searchList();
84	void searchList(const vector<DLDbIdentifier> &);
85	void defaultDLDbIdentifier(const DLDbIdentifier &);
86	const DLDbIdentifier &defaultDLDbIdentifier();
87	void loginDLDbIdentifier(const DLDbIdentifier &);
88	const DLDbIdentifier &loginDLDbIdentifier();
89	void forceUserSearchListReread ();
90
91    DLDbIdentifier LoginDLDbIdentifier();
92    DLDbIdentifier JaguarLoginDLDbIdentifier();
93
94    static string ExpandTildesInPath(const string &inPath);
95	static string StripPathStuff(const string &inPath);
96    static string AbbreviatedPath(const string &inPath);
97
98protected:
99	SecPreferencesDomain mDomain;
100    bool hasChanged() const { return mChanged; }
101    void changed(bool hasChanged) { mChanged = hasChanged; }
102
103	enum PwInfoType
104	{
105		kHomeDir,
106		kUsername
107	};
108
109    static PasswordDBLookup *mPdbLookup;
110	static string getPwInfo(PwInfoType type);
111    static void clearPWInfo ();
112
113    void resetCachedValues();
114	bool loadPropertyList(bool force);
115	void writePropertyList();
116	int testAndFixPropertyList();
117
118	enum ID_Direction
119	{
120		UNPRIV,
121		PRIV
122	};
123	uid_t	savedEUID;
124	gid_t	savedEGID;
125
126	void changeIdentity(ID_Direction);
127
128
129private:
130	CFAbsoluteTime mPrefsTimeStamp;
131	struct timespec mTimespec;
132	CFMutableDictionaryRef mPropertyList;
133
134	string mPrefsPath, mHomeDir, mUserName;
135	vector<DLDbIdentifier> mSearchList;
136	DLDbIdentifier mDefaultDLDbIdentifier;
137	DLDbIdentifier mLoginDLDbIdentifier;
138    bool mChanged, mSearchListSet, mDefaultDLDbIdentifierSet, mLoginDLDbIdentifierSet;
139};
140
141class CCFValue
142{
143public:
144    template <class T>
145    T cfref() const { return reinterpret_cast<T>(CFTypeRef(mRef)); }
146
147	CCFValue() {}
148	CCFValue(CFTypeRef ref) : mRef(ref) {}
149	CCFValue &operator =(CFTypeRef ref) { mRef = ref; return *this; }
150
151    CCFValue &operator = (bool value)
152    {
153        mRef = value?kCFBooleanTrue:kCFBooleanFalse;
154        return *this;
155    }
156
157/*
158    CCFValue &operator = (const string &value) { string(value); return *this; }
159
160    void string(const string &value, CFStringEncoding encoding=kCFStringEncodingMacRoman)
161    {
162        mRef = CFStringCreate();
163CFStringRef CFStringCreateWithBytes(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean isExternalRepresentation);
164        if (!mRef) throw std::bad_alloc;
165        CFRelease(mRef);
166    }
167*/
168
169    bool hasValue() const { return mRef; }
170
171    operator bool() const
172    {
173        if (!mRef) return false;
174        if (::CFGetTypeID(mRef) != ::CFBooleanGetTypeID())
175            throw std::logic_error("wrong type in property list");
176
177        return ::CFBooleanGetValue(cfref<CFBooleanRef>());
178    }
179
180    operator sint32() const
181    {
182        if (!mRef) return 0;
183        if (::CFGetTypeID(mRef) != ::CFNumberGetTypeID())
184            throw std::logic_error("wrong type in property list");
185
186        sint32 val;
187        ::CFNumberGetValue(cfref<CFNumberRef>(),kCFNumberSInt32Type,&val);
188        return val;
189    }
190
191    operator uint32() const { return uint32(sint32(*this)); }
192
193    operator const string() const { return getString(); }
194
195    const string getString(CFStringEncoding encoding=kCFStringEncodingUTF8) const
196    {
197        if (!mRef)
198            throw std::logic_error("missing string in property list");
199        if (::CFGetTypeID(mRef) != ::CFStringGetTypeID())
200            throw std::logic_error("wrong type in property list");
201
202        const char *tmpStr=::CFStringGetCStringPtr(cfref<CFStringRef>(),encoding);
203        if (tmpStr == NULL)
204        {
205            CFIndex maxLen = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfref<CFStringRef>()), encoding);
206            auto_array<char> buffer(maxLen + 1);
207
208            if (!::CFStringGetCString(cfref<CFStringRef>(),buffer.get(),maxLen + 1,encoding))
209                throw std::logic_error("could not convert string from property list");
210
211            tmpStr=buffer.get();
212            return string(tmpStr?tmpStr:"");
213        }
214        return string(tmpStr?tmpStr:"");
215    }
216private:
217	CFCopyRef<CFTypeRef>mRef;
218};
219
220} // end namespace Security
221
222#endif /* !_SECURITY_DLDBLISTCFPREF_H_ */
223