|
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <s32buf.h> |
|
17 #include "SqlSecurityImpl.h" |
|
18 #include "SqlUtil.h" |
|
19 |
|
20 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
21 //////////////////////////// CSqlSecurityPolicy implementation //////////////////////////////////////// |
|
22 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
23 |
|
24 /** |
|
25 Casts aPolicyType parameter to an integer value, which is used as policy index. |
|
26 |
|
27 @param aPolicyType Security policy type: schema, write, read |
|
28 |
|
29 @return Security policy type casted to an integer value, which is used as a poicy index |
|
30 */ |
|
31 inline TInt CSqlSecurityPolicy::PolicyType2Index(RSqlSecurityPolicy::TPolicyType aPolicyType) |
|
32 { |
|
33 return static_cast <TInt> (aPolicyType); |
|
34 } |
|
35 |
|
36 /** |
|
37 Returns a pointer to the data of the current flat buffer cell. The pointer type is CSqlSecurityPolicy::TPolicyItem. |
|
38 |
|
39 @param aBegin Points to the beginning of flat buffer header |
|
40 @param aCurrent Points to a cell in the flat buffer header, to which data a pointer will be cast and returned. |
|
41 |
|
42 @return CSqlSecurityPolicy::TPolicyItem pointer, which can be used for R/W operations on the database security policy data. |
|
43 */ |
|
44 inline CSqlSecurityPolicy::TPolicyItem* CSqlSecurityPolicy::PolicyItemPtr(const RSqlBufFlat::TCell* aBegin, const RSqlBufFlat::TCell* aCurrent) |
|
45 { |
|
46 __SQLASSERT(aBegin != NULL && aCurrent != NULL, ESqlPanicBadArgument); |
|
47 __SQLASSERT(aCurrent->iPos != 0, ESqlPanicBadArgument); |
|
48 const TUint8* begin = reinterpret_cast <const TUint8*> (aBegin); |
|
49 return reinterpret_cast <CSqlSecurityPolicy::TPolicyItem*> (const_cast <TUint8*> (begin) + aCurrent->iPos); |
|
50 } |
|
51 |
|
52 /** |
|
53 Searhes the flat buffer for an entry, which "object type" and "object name" attributes match aObjectType and aObjectName parameters. |
|
54 If such entry exists, a pointer to the entry's data will be returned. |
|
55 |
|
56 @param aObjectType Database object type |
|
57 @param aObjectName Database object name |
|
58 |
|
59 @return A pointer to the data of an entry which "object type" and "object name" attributes match aObjectType and aObjectName parameters. |
|
60 If no such entry exists, the function returns NULL. |
|
61 */ |
|
62 const CSqlSecurityPolicy::TPolicyItem* CSqlSecurityPolicy::FindPolicyItemPtr(RSqlSecurityPolicy::TObjectType aObjectType, |
|
63 const TDesC& aObjectName) const |
|
64 { |
|
65 const RSqlBufFlat::TCell* begin = iBufFlat.Header(); |
|
66 __SQLASSERT(begin != NULL, ESqlPanicInternalError); |
|
67 const RSqlBufFlat::TCell* end = begin + Count(); |
|
68 const RSqlBufFlat::TCell* current = begin + CSqlSecurityPolicy::EDbPolicyIdx;//ignore default and database policiy types ("current" points before the first non-database policy) |
|
69 while(++current < end) |
|
70 { |
|
71 if(current->iPos > 0 && current->Type() == (TInt)aObjectType) //if present and the same type as aObjectType |
|
72 { |
|
73 const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, current); |
|
74 __SQLASSERT(item != NULL, ESqlPanicInternalError); |
|
75 __SQLASSERT(((current->Size() - sizeof(CSqlSecurityPolicy::TPolicyItem) - sizeof(TInt)) / sizeof(TUint16)) == item->NameSize(), ESqlPanicInternalError); |
|
76 if(::CompareNoCase16(aObjectName, TPtrC(item->NamePtr(), item->NameSize())) == 0) |
|
77 { |
|
78 return item; |
|
79 } |
|
80 } |
|
81 } |
|
82 return NULL; |
|
83 } |
|
84 |
|
85 /** |
|
86 Standard, phase-one CSqlSecurityPolicy factory method. |
|
87 |
|
88 @param aDefaultPolicy Default security policy which will be used as a default replacement for all database and |
|
89 database object security policies. |
|
90 |
|
91 @return A pointer to the created CSqlSecurityPolicy instance. |
|
92 |
|
93 @leave KErrNoMemory, an out of memory condition has occurred; |
|
94 */ |
|
95 CSqlSecurityPolicy* CSqlSecurityPolicy::NewL(const TSecurityPolicy& aDefaultPolicy) |
|
96 { |
|
97 CSqlSecurityPolicy* self = CSqlSecurityPolicy::NewLC(aDefaultPolicy); |
|
98 CleanupStack::Pop(self); |
|
99 return self; |
|
100 } |
|
101 |
|
102 /** |
|
103 Standard, phase-one CSqlSecurityPolicy factory method. |
|
104 |
|
105 @param aDefaultPolicy Default security policy which will be used as a default replacement for all database and |
|
106 database object security policies. |
|
107 |
|
108 @return A pointer to the created CSqlSecurityPolicy instance. |
|
109 |
|
110 @leave KErrNoMemory, an out of memory condition has occurred; |
|
111 */ |
|
112 CSqlSecurityPolicy* CSqlSecurityPolicy::NewLC(const TSecurityPolicy& aDefaultPolicy) |
|
113 { |
|
114 CSqlSecurityPolicy* self = new (ELeave) CSqlSecurityPolicy; |
|
115 CleanupStack::PushL(self); |
|
116 self->ConstructL(aDefaultPolicy); |
|
117 return self; |
|
118 } |
|
119 |
|
120 /** |
|
121 */ |
|
122 CSqlSecurityPolicy::~CSqlSecurityPolicy() |
|
123 { |
|
124 iBufFlat.Close(); |
|
125 } |
|
126 |
|
127 /** |
|
128 @return A const reference to the flat buffer |
|
129 */ |
|
130 const RSqlBufFlat& CSqlSecurityPolicy::BufFlat() const |
|
131 { |
|
132 return iBufFlat; |
|
133 } |
|
134 |
|
135 /** |
|
136 @return A reference to the flat buffer |
|
137 */ |
|
138 RSqlBufFlat& CSqlSecurityPolicy::BufFlat() |
|
139 { |
|
140 return iBufFlat; |
|
141 } |
|
142 |
|
143 /** |
|
144 @return Database security policy entry count. This number is at least 2, because every CSqlSecurityPolicy object has by default |
|
145 one default security policy entry and one database security policy entry. |
|
146 */ |
|
147 TInt CSqlSecurityPolicy::Count() const |
|
148 { |
|
149 const RSqlBufFlat::TCell* begin = iBufFlat.Header(); |
|
150 __SQLASSERT(begin != NULL, ESqlPanicInternalError); |
|
151 return *reinterpret_cast <const TInt*> (reinterpret_cast <const TUint8*> (begin) + (begin + CSqlSecurityPolicy::ECountIdx)->iPos); |
|
152 } |
|
153 |
|
154 /** |
|
155 Sets the number of database security entries. |
|
156 */ |
|
157 void CSqlSecurityPolicy::SetCount(TInt aCount) |
|
158 { |
|
159 __SQLASSERT(aCount >= 0, ESqlPanicBadArgument); |
|
160 RSqlBufFlat::TCell* begin = iBufFlat.Header(); |
|
161 __SQLASSERT(begin != NULL, ESqlPanicInternalError); |
|
162 *reinterpret_cast <TInt*> (reinterpret_cast <TUint8*> (begin) + (begin + CSqlSecurityPolicy::ECountIdx)->iPos) = aCount; |
|
163 } |
|
164 |
|
165 /** |
|
166 Sets the default policy. |
|
167 */ |
|
168 void CSqlSecurityPolicy::SetDefaultPolicy(const TSecurityPolicy& aPolicy) |
|
169 { |
|
170 RSqlBufFlat::TCell* begin = iBufFlat.Header(); |
|
171 __SQLASSERT(begin != NULL, ESqlPanicInternalError); |
|
172 CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDefaultPolicyIdx); |
|
173 __SQLASSERT(item != NULL, ESqlPanicInternalError); |
|
174 item->iPolicy[0] = aPolicy; |
|
175 } |
|
176 |
|
177 /** |
|
178 @param aPolicyType Database security policy type: RSqlSecurityPolicy::ESchemaPolicy, |
|
179 RSqlSecurityPolicy::EReadPolicy, RSqlSecurityPolicy::EWritePolicy. |
|
180 @param aPolicy Security policy data used for setting the related database security policy. |
|
181 |
|
182 @return KErrNone |
|
183 |
|
184 @panic SqlDb 4 In _DEBUG mode. Invalid policy type. |
|
185 */ |
|
186 TInt CSqlSecurityPolicy::SetDbPolicy(RSqlSecurityPolicy::TPolicyType aPolicyType, const TSecurityPolicy& aPolicy) |
|
187 { |
|
188 const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType); |
|
189 __SQLASSERT((TUint)KPolicyIndex < EPolicyTypeCount, ESqlPanicBadArgument); |
|
190 RSqlBufFlat::TCell* begin = iBufFlat.Header(); |
|
191 __SQLASSERT(begin != NULL, ESqlPanicInternalError); |
|
192 CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDbPolicyIdx); |
|
193 __SQLASSERT(item != NULL, ESqlPanicInternalError); |
|
194 //KPolicyIndex value is tested at the beginning of the function |
|
195 //coverity[overrun-local] |
|
196 item->iPolicy[KPolicyIndex] = aPolicy; |
|
197 return KErrNone; |
|
198 } |
|
199 |
|
200 /** |
|
201 If there is no entry in the container for the object with aObjectName name, a new entry for this object will be |
|
202 created and all object security policies will be initialized with the default security policy. aPolicyType object |
|
203 policy will be reinitialized with aPolicy argument after that. |
|
204 |
|
205 If an entry for aObjectName object already exists, its aPolicyType security policy will be reinitialized with aPolicy |
|
206 argument. |
|
207 |
|
208 @param aObjectType Database object type. At the moment there is only one database object type allowed for use with |
|
209 SetPolicy() - RSqlSecurityPolicy::ETable. |
|
210 @param aObjectName Database object name. It cannot be a null descriptor. |
|
211 @param aPolicyType Database object security policy type: RSqlSecurityPolicy::EReadPolicy, |
|
212 RSqlSecurityPolicy::EWritePolicy. |
|
213 @param aPolicy Security policy data used for setting the related database object security policy type. |
|
214 |
|
215 @return KErrNone, operation completed successfully; |
|
216 KErrNoMemory, an out of memory condition has occurred; |
|
217 KErrNotSupported, the count of the security policies is too big. |
|
218 |
|
219 @panic SqlDb 4 In _DEBUG mode. Invalid policy type. |
|
220 @panic SqlDb 4 In _DEBUG mode. Invalid database object name (Null descriptor). |
|
221 */ |
|
222 TInt CSqlSecurityPolicy::SetPolicy(RSqlSecurityPolicy::TObjectType aObjectType, const TDesC& aObjectName, |
|
223 RSqlSecurityPolicy::TPolicyType aPolicyType, const TSecurityPolicy& aPolicy) |
|
224 { |
|
225 const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType); |
|
226 __SQLASSERT((TUint)KPolicyIndex < EPolicyTypeCount, ESqlPanicBadArgument); |
|
227 __SQLASSERT(aObjectName.Length() > 0, ESqlPanicBadArgument); |
|
228 CSqlSecurityPolicy::TPolicyItem* item = const_cast <CSqlSecurityPolicy::TPolicyItem*> (FindPolicyItemPtr(aObjectType, aObjectName)); |
|
229 if(item) |
|
230 {//There is a field in the flat buffer for {aObjectType, aObjectName}. Set the policy. |
|
231 //KPolicyIndex value is tested at the beginning of the function |
|
232 //coverity[overrun-local] |
|
233 item->iPolicy[KPolicyIndex] = aPolicy; |
|
234 return KErrNone; |
|
235 } |
|
236 //No field in the flat buffer for {aObjectType, aObjectName}. |
|
237 TInt idx = Count(); |
|
238 if(idx >= iBufFlat.Count()) |
|
239 { |
|
240 return KErrNotSupported; |
|
241 } |
|
242 //Create and fill a new CSqlSecurityPolicy::TPolicyItem object. |
|
243 const TInt KPolicyDataLen = TPolicyItem::CalcSize(aObjectName.Length()); |
|
244 TUint8* buf = new TUint8[KPolicyDataLen]; |
|
245 if(!buf) |
|
246 { |
|
247 return KErrNoMemory; |
|
248 } |
|
249 item = reinterpret_cast <CSqlSecurityPolicy::TPolicyItem*> (buf); |
|
250 //coverity[DEADCODE] |
|
251 //The ASSERT might be useful in catching future defect in this function |
|
252 __SQLASSERT(item != NULL, ESqlPanicInternalError); |
|
253 TSecurityPolicy defaultPolicy = DefaultPolicy(); |
|
254 for(TInt i=0;i<CSqlSecurityPolicy::EPolicyTypeCount;++i) |
|
255 { |
|
256 item->iPolicy[i] = defaultPolicy; |
|
257 } |
|
258 item->iPolicy[KPolicyIndex] = aPolicy; |
|
259 //Set the object name length and the object name. |
|
260 *item->NameSizePtr() = aObjectName.Length(); |
|
261 TPtr name(item->NamePtr(), item->NameSize()); |
|
262 name.Copy(aObjectName); |
|
263 //Copy the item in iBufFlat and release the allocated memory. |
|
264 TInt err = iBufFlat.SetField(idx, (TInt)aObjectType, item, KPolicyDataLen); |
|
265 delete [] buf; |
|
266 if(err == KErrNone) |
|
267 { |
|
268 SetCount(idx + 1); |
|
269 } |
|
270 return err; |
|
271 } |
|
272 |
|
273 /** |
|
274 @return The default security policy. |
|
275 */ |
|
276 TSecurityPolicy CSqlSecurityPolicy::DefaultPolicy() const |
|
277 { |
|
278 const RSqlBufFlat::TCell* begin = iBufFlat.Header(); |
|
279 __SQLASSERT(begin != NULL, ESqlPanicInternalError); |
|
280 const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDefaultPolicyIdx); |
|
281 __SQLASSERT(item != NULL, ESqlPanicInternalError); |
|
282 return item->iPolicy[0]; |
|
283 } |
|
284 |
|
285 /** |
|
286 @param aPolicyType Database security policy type: RSqlSecurityPolicy::ESchemaPolicy, |
|
287 RSqlSecurityPolicy::EReadPolicy, RSqlSecurityPolicy::EWritePolicy. |
|
288 |
|
289 Note: By default all database security policies will be initialized with the default security policy. |
|
290 |
|
291 @return The requested database security policy. |
|
292 |
|
293 @panic SqlDb 4 In _DEBUG mode. Invalid policy type. |
|
294 */ |
|
295 TSecurityPolicy CSqlSecurityPolicy::DbPolicy(RSqlSecurityPolicy::TPolicyType aPolicyType) const |
|
296 { |
|
297 const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType); |
|
298 __SQLASSERT((TUint)KPolicyIndex < EPolicyTypeCount, ESqlPanicBadArgument); |
|
299 const RSqlBufFlat::TCell* begin = iBufFlat.Header(); |
|
300 __SQLASSERT(begin != NULL, ESqlPanicInternalError); |
|
301 const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(begin, begin + CSqlSecurityPolicy::EDbPolicyIdx); |
|
302 __SQLASSERT(item != NULL, ESqlPanicInternalError); |
|
303 //KPolicyIndex value is tested at the beginning of the function |
|
304 //coverity[overrun-local] |
|
305 return item->iPolicy[KPolicyIndex]; |
|
306 } |
|
307 |
|
308 /** |
|
309 Searches the container for an entry belonging to an object with aObjectName name and aObjectType type. If such entry |
|
310 exists the method returns aPolicyType object security policy. |
|
311 |
|
312 If there is no entry for the object with aObjectName name, the default security policy will be returned. |
|
313 |
|
314 @param aObjectType Database object type. At the moment there is only one database object type allowed for use with |
|
315 Policy() - RSqlSecurityPolicy::ETable. |
|
316 @param aObjectName Database object name. It cannot be a null descriptor. |
|
317 @param aPolicyType Database object security policy type: RSqlSecurityPolicy::ERead, RSqlSecurityPolicy::EWrite. |
|
318 |
|
319 Note: By default all database object security policies will be initialized with the default security policy. |
|
320 |
|
321 @return The requested security policy |
|
322 |
|
323 @panic SqlDb 4 In _DEBUG mode. Invalid policy type. |
|
324 @panic SqlDb 4 In _DEBUG mode. Invalid onject name (Null descriptor). |
|
325 */ |
|
326 TSecurityPolicy CSqlSecurityPolicy::Policy(RSqlSecurityPolicy::TObjectType aObjectType, |
|
327 const TDesC& aObjectName, RSqlSecurityPolicy::TPolicyType aPolicyType) |
|
328 { |
|
329 const TInt KPolicyIndex = CSqlSecurityPolicy::PolicyType2Index(aPolicyType); |
|
330 __SQLASSERT((TUint)KPolicyIndex < EPolicyTypeCount, ESqlPanicBadArgument); |
|
331 __SQLASSERT(aObjectName.Length() > 0, ESqlPanicBadArgument); |
|
332 const CSqlSecurityPolicy::TPolicyItem* item = FindPolicyItemPtr(aObjectType, aObjectName); |
|
333 //KPolicyIndex value is tested at the beginning of the function |
|
334 //coverity[overrun-local] |
|
335 return item ? item->iPolicy[KPolicyIndex] : DefaultPolicy(); |
|
336 } |
|
337 |
|
338 /** |
|
339 */ |
|
340 CSqlSecurityPolicy::CSqlSecurityPolicy() |
|
341 { |
|
342 } |
|
343 |
|
344 /** |
|
345 Standard, phase-two CSqlSecurityPolicy construction method. |
|
346 |
|
347 Note: By default all database security policies will be initialized with the default security policy. |
|
348 |
|
349 @param aDefaultPolicy Security policy data used for setting the default database security policy and |
|
350 database security policies. |
|
351 |
|
352 @leave KErrNoMemory, an out of memory condition has occurred; |
|
353 */ |
|
354 void CSqlSecurityPolicy::ConstructL(const TSecurityPolicy& aDefaultPolicy) |
|
355 { |
|
356 //Create the policy flat buffer. |
|
357 __SQLLEAVE_IF_ERROR(iBufFlat.SetCount(CSqlSecurityPolicy::EMaxCount)); |
|
358 //Reserve places for the default policy and database policies. |
|
359 CSqlSecurityPolicy::TPolicyItem item; |
|
360 for(TInt i=0;i<CSqlSecurityPolicy::EPolicyTypeCount;++i) |
|
361 { |
|
362 item.iPolicy[i] = aDefaultPolicy; |
|
363 } |
|
364 TInt count = CSqlSecurityPolicy::EDbPolicyIdx + 1;//count + default policy + database policy; |
|
365 __SQLLEAVE_IF_ERROR(iBufFlat.SetField(CSqlSecurityPolicy::ECountIdx, 0, &count, sizeof(count))); |
|
366 __SQLLEAVE_IF_ERROR(iBufFlat.SetField(CSqlSecurityPolicy::EDefaultPolicyIdx, 0, &item, sizeof(item) - sizeof(TSecurityPolicy) * (CSqlSecurityPolicy::EPolicyTypeCount - 1))); |
|
367 __SQLLEAVE_IF_ERROR(iBufFlat.SetField(CSqlSecurityPolicy::EDbPolicyIdx, 0, &item, sizeof(item))); |
|
368 } |
|
369 |
|
370 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
371 //////////////////// TSqlSecurityPolicyIterator implementation ////////////////////////////// |
|
372 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
373 |
|
374 /** |
|
375 @param aSecuritySettings Const reference to CSqlSecurityPolicy object on which content the iterator will work. |
|
376 */ |
|
377 TSqlSecurityPolicyIterator::TSqlSecurityPolicyIterator(const CSqlSecurityPolicy& aSqlSecurityPolicy) : |
|
378 iBegin(aSqlSecurityPolicy.iBufFlat.Header()), |
|
379 iCurrent(iBegin + CSqlSecurityPolicy::EDbPolicyIdx),//ignore the default and database policies |
|
380 iEnd(iBegin + aSqlSecurityPolicy.Count()), |
|
381 iCurPolicyIdx(CSqlSecurityPolicy::EPolicyTypeCount) |
|
382 { |
|
383 __SQLASSERT(iBegin != NULL, ESqlPanicInternalError); |
|
384 } |
|
385 |
|
386 /** |
|
387 Moves the iterator one step forward and gives a read-only access to the next database object security policy. |
|
388 |
|
389 @param aObjectType Output parameter. Next database object type, if the iteration was successful. |
|
390 @param aObjectName Output parameter. Set to point to the next database object name, if the iteration was successful. |
|
391 @param aPolicyType Output parameter. Next database object security policy type, if the iteration was successful. |
|
392 @param aPolicy Output parameter. Next database object security policy, if the iteration was successful. |
|
393 |
|
394 @return Non-zero - successful iteration step, zero otherwise (no more security policies in the CSqlSecurityPolicy container). |
|
395 */ |
|
396 TBool TSqlSecurityPolicyIterator::Next(RSqlSecurityPolicy::TObjectType& aObjectType, TPtrC& aObjectName, |
|
397 RSqlSecurityPolicy::TPolicyType& aPolicyType, TSecurityPolicy& aPolicy) |
|
398 { |
|
399 if(++iCurPolicyIdx >= CSqlSecurityPolicy::EPolicyTypeCount) |
|
400 { |
|
401 iCurPolicyIdx = static_cast <TInt> (RSqlSecurityPolicy::EReadPolicy); |
|
402 if(++iCurrent >= iEnd) |
|
403 { |
|
404 return EFalse; |
|
405 } |
|
406 } |
|
407 const CSqlSecurityPolicy::TPolicyItem* item = CSqlSecurityPolicy::PolicyItemPtr(iBegin, iCurrent); |
|
408 __SQLASSERT(item != NULL, ESqlPanicInternalError); |
|
409 aObjectType = static_cast <RSqlSecurityPolicy::TObjectType> (iCurrent->Type()); |
|
410 aPolicyType = static_cast <RSqlSecurityPolicy::TPolicyType> (iCurPolicyIdx); |
|
411 aPolicy = item->iPolicy[iCurPolicyIdx]; |
|
412 aObjectName.Set(item->NamePtr(), item->NameSize()); |
|
413 return ETrue; |
|
414 } |