|
1 // Copyright (c) 2004-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 // CPolicyProxy class |
|
15 // |
|
16 // |
|
17 |
|
18 #include "SD_STD.H" |
|
19 #include "Sd_PolicyProxy.h" |
|
20 #include "D32SQL.H" |
|
21 |
|
22 using namespace DBSC; |
|
23 |
|
24 /** |
|
25 TDbsFunction enum value is used as an index in KDbsFunc2SecurityPolicyMask array. |
|
26 For each TDbsFunction enum value there is a set of security policies, |
|
27 which have to be satisified by the caller capabilities (at least one of them) - |
|
28 before the related operation to be executed. |
|
29 @internalComponent |
|
30 */ |
|
31 static const TUint8 KDbsFunc2SecurityPolicyMask[EDbsLast] = |
|
32 { |
|
33 /*EDbsResourceMark*/ EPTNone, |
|
34 /*EDbsResourceCheck*/ EPTNone, |
|
35 /*EDbsResourceCount*/ EPTNone, |
|
36 /*EDbsSetHeapFailure*/ EPTNone, |
|
37 /*EDbsOpenDatabase*/ EPTRead | EPTWrite | EPTSchema, //---The caller capabilities will be asserted later, when the db security uid is known |
|
38 /*EDbsClose*/ EPTNone, //---EDbsClose may be used to close every possible type of server side dbms object |
|
39 /*EDbsDatabaseAuthenticate*/EPTNone, //---Not supported for secure shared databases |
|
40 /*EDbsDatabaseDestroy*/ EPTSchema, //---Only admin can destroy the database |
|
41 /*EDbsDatabaseBegin*/ EPTRead | EPTWrite | EPTSchema, //---Begin transaction, which makes sense if the caller wants to change the database schema or to insert/delete/update database tables or to protect its "read" operations |
|
42 /*EDbsDatabaseCommit*/ EPTRead | EPTWrite | EPTSchema, //---Commit transaction, which makes sense if the caller wants to change the database schema or to insert/delete/update database tables or to protect its "read" operations |
|
43 /*EDbsDatabaseRollback*/ EPTRead | EPTWrite | EPTSchema, //---Rollback transaction, which makes sense if the caller wants to change the database schema or to insert/delete/update database tables or to protect its "read" operations |
|
44 /*EDbsDatabaseProperty*/ EPTNone, |
|
45 /*EDbsDatabaseCreateTable*/ EPTSchema, |
|
46 /*EDbsDatabaseTables*/ EPTNone, |
|
47 /*EDbsDatabaseColumns*/ EPTNone, |
|
48 /*EDbsDatabaseIndexes*/ EPTNone, |
|
49 /*EDbsDatabaseKeys*/ EPTNone, |
|
50 /*EDbsDatabaseOpenObserver*/EPTNone, |
|
51 /*EDbsDatabaseOpenUtility*/ EPTWrite, //---Compact/Recover operations |
|
52 /*EDbsDatabaseOpenDropTable*/EPTSchema, |
|
53 /*EDbsDatabaseOpenAlterTable*/EPTSchema, |
|
54 /*EDbsDatabaseOpenCreateIndex*/EPTSchema, |
|
55 /*EDbsDatabaseOpenDropIndex*/EPTSchema, |
|
56 /*EDbsDatabaseExecute*/ EPTWrite | EPTSchema, //---either CREATE/DROP/ALTER database operations or INSERT/UPDATE/DELETE table operations. An additional caller capabilities check will be made after the parsing of the sql string. |
|
57 /*EDbsDatabasePrepareView*/ EPTRead, //---"SELECT" sql string |
|
58 /*EDbsDatabaseOpenTable*/ EPTRead | EPTWrite, //---If the caller neither have capabilities for read or write table security policies, then the the caller cannot open the table. |
|
59 /*EDbsObserverNotify*/ EPTNone, |
|
60 /*EDbsObserverCancel*/ EPTNone, |
|
61 /*EDbsIncrementalNext*/ EPTNone, |
|
62 /*EDbsCursorColumnTypes*/ EPTNone, |
|
63 /*EDbsCursorReset*/ EPTNone, //---Moves the cursor at the beginning of the table/dataset |
|
64 /*EDbsCursorEvaluate*/ EPTNone, |
|
65 /*EDbsCursorUnevaluated*/ EPTNone, |
|
66 /*EDbsCursorSetIndex*/ EPTRead, |
|
67 /*EDbsCursorSeek*/ EPTRead, |
|
68 /*EDbsCursorAtBeginning*/ EPTNone, |
|
69 /*EDbsCursorAtEnd*/ EPTNone, |
|
70 /*EDbsCursorAtRow*/ EPTNone, |
|
71 /*EDbsCursorCount*/ EPTRead | EPTWrite, |
|
72 /*EDbsCursorGotoPos*/ EPTRead, |
|
73 /*EDbsCursorBookmark*/ EPTRead, |
|
74 /*EDbsCursorGotoBookmark*/ EPTRead, |
|
75 /*EDbsCursorGet*/ EPTRead, |
|
76 /*EDbsCursorInsert*/ EPTWrite, |
|
77 /*EDbsCursorUpdate*/ EPTWrite, |
|
78 /*EDbsCursorRetrieveRow*/ EPTNone, //---Used by "Insert" operations sometime |
|
79 /*EDbsCursorCancel*/ EPTNone, |
|
80 /*EDbsCursorPut*/ EPTWrite, |
|
81 /*EDbsCursorDelete*/ EPTWrite, |
|
82 /*EDbsCursorColumns*/ EPTNone, |
|
83 /*EDbsCursorColumnDef*/ EPTNone, |
|
84 /*EDbsCursorSetNull*/ EPTWrite, |
|
85 /*EDbsCursorColumnSize*/ EPTNone, |
|
86 /*EDbsCursorColumnSource*/ EPTRead, //---Used for large BLOB fields - read ops |
|
87 /*EDbsCursorColumnSink*/ EPTWrite, //---Used for large BLOB fields - write ops |
|
88 /*EDbsCursorOpenConstraint*/EPTRead, |
|
89 /*EDbsCursorMatch*/ EPTRead, |
|
90 /*EDbsCursorFind*/ EPTRead, |
|
91 /*EDbsStreamRead*/ EPTNone, |
|
92 /*EDbsStreamWrite*/ EPTNone, |
|
93 /*EDbsStreamSize*/ EPTNone, |
|
94 /*EDbsStreamSynch*/ EPTNone, |
|
95 /*EDbsCreateDatabase*/ EPTSchema, |
|
96 /*EDbsDatabaseList*/ EPTNone, |
|
97 /*EDbsCopyDatabase*/ EPTSchema, |
|
98 /*EDbsDeleteDatabase*/ EPTSchema, |
|
99 /*EDbsGetSecurityPolicy*/ EPTNone, |
|
100 /*EDbsReserveDriveSpace*/ EPTNone, |
|
101 /*EDbsFreeReservedSpace*/ EPTNone, |
|
102 /*EDbsReserveGetAccess*/ EPTNone, |
|
103 /*EDbsReserveReleaseAccess*/EPTNone, |
|
104 /*EDbsGetBackupPath*/ EPTNone, |
|
105 /*EDbsGetBackupPaths*/ EPTNone |
|
106 }; |
|
107 |
|
108 /** |
|
109 This function returns bit-field mask value, containing security policies types (R/W/S) |
|
110 Each security policy contains a set of Capabilities/SID/VID. |
|
111 In order particular database operation to be executed, the caller Capabilities/SID/VID have |
|
112 to be checked against security policy Capabilities/SID/VID. |
|
113 Don't forget to map new DBMS functions here! |
|
114 @param aFunction DBMS server function code |
|
115 @return An integer mask with a set of security policy types. The caller has to satisfy at least |
|
116 one of of them. |
|
117 */ |
|
118 static TUint DbsFunction2PolicyMask(TDbsFunction aFunction) |
|
119 { |
|
120 __ASSERT(aFunction < EDbsLast); |
|
121 return KDbsFunc2SecurityPolicyMask[aFunction]; |
|
122 } |
|
123 |
|
124 /** |
|
125 Extracts DBMS server function code from aMessage argument. |
|
126 @param aMessage DBMS server message |
|
127 @return DBMS server function code |
|
128 @internalComponent |
|
129 */ |
|
130 static TDbsFunction Message2Function(const RMessage2& aMessage) |
|
131 { |
|
132 TDbsFunction func = ::DbsFunction(aMessage.Function()); |
|
133 return static_cast <TDbsFunction> (func & ~KDbsObjectReturn); |
|
134 } |
|
135 |
|
136 /** |
|
137 */ |
|
138 inline CPolicyProxy::CPolicyProxy(RFs& aFs):iFs(aFs) |
|
139 { |
|
140 } |
|
141 |
|
142 /** |
|
143 Standard phase-one factory method for CPolicyProxy instances. |
|
144 @param aFs A file server session instance |
|
145 @param aPrivatePath DBMS server private data path |
|
146 @return A pointer to the created CPolicyProxy instance. |
|
147 @leave KErrNoMemory |
|
148 */ |
|
149 CPolicyProxy* CPolicyProxy::NewL(RFs& aFs,const TDesC& aPrivatePath) |
|
150 { |
|
151 CPolicyProxy* self = new (ELeave) CPolicyProxy(aFs); |
|
152 CleanupStack::PushL(self); |
|
153 self->ConstructL(aPrivatePath); |
|
154 CleanupStack::Pop(self); |
|
155 return self; |
|
156 } |
|
157 |
|
158 /** |
|
159 */ |
|
160 CPolicyProxy::~CPolicyProxy() |
|
161 { |
|
162 if(iPolicySpace) //iPolicySpace can be NULL in OOM tests |
|
163 { |
|
164 iPolicySpace->Release(); |
|
165 } |
|
166 } |
|
167 |
|
168 /** |
|
169 Returns requested database security policy interface, which cannot be NULL. |
|
170 @param aDbPolicyRequest Request params: request type (secure/non-secure) and domain UID |
|
171 @return A const pointer to the related UID security policy object. |
|
172 */ |
|
173 const MPolicy* CPolicyProxy::DbPolicyL(const TDbPolicyRequest& aDbPolicyRequest) |
|
174 { |
|
175 return iPolicySpace->DbPolicyL(aDbPolicyRequest); |
|
176 } |
|
177 |
|
178 /** |
|
179 Returns requested table security policy interface, which cannot be NULL. |
|
180 @param aDbPolicyRequest Request params: request type (secure/non-secure) and domain UID |
|
181 @param aTblName Database table name |
|
182 @return A const pointer to the related table security policy object. |
|
183 */ |
|
184 const MPolicy* CPolicyProxy::TblPolicyL(const TDbPolicyRequest& aDbPolicyRequest, |
|
185 const TDesC& aTblName) |
|
186 { |
|
187 return iPolicySpace->TblPolicyL(aDbPolicyRequest, aTblName); |
|
188 } |
|
189 |
|
190 /** |
|
191 This method is used to get the SQL related MPolicy interface and the related security |
|
192 policy type. |
|
193 If aUPRequest.iRqAccess is EATNonSecure, then the default security policy will be returned. |
|
194 Currently the DBMS can process the following SQL strings: |
|
195 1)DDL - CREATE/DROP/ALTER SQL statements - EPTSchema database access level. |
|
196 2)DML - INSERT/UPDATE/DELETE SQL statements. Only one table can be put after the "FROM" |
|
197 SQL keyword. EPTWrite table access level. |
|
198 3)QUERY- SELECT SQL statements. Only one table can be out after the "FROM" SQL keyword. |
|
199 EPTRead table access level. |
|
200 @param aDbPolicyRequest A const reference to an object packing security policy uid and the request type: |
|
201 secure/non-secure. |
|
202 @param aSql SQL string |
|
203 @param aPolicyType An output parameter, referencing the location, where the policy type will be stored. |
|
204 @return A const pointer to the related policy interface. It cannot be NULL, and must not be deleted. |
|
205 @leave One of the system-wide error codes. |
|
206 */ |
|
207 const MPolicy* CPolicyProxy::SqlPolicyL(const TDbPolicyRequest& aDbPolicyRequest, const TDesC& aSql, |
|
208 TPolicyType& aPolicyType) |
|
209 { |
|
210 const MPolicy* policy = NULL; |
|
211 aPolicyType = EPTNone; |
|
212 //Get table name and sql type. |
|
213 TSqlParser2 sqlParser; |
|
214 sqlParser.ParseL(aSql); |
|
215 Sql::TStatementType sqlType = sqlParser.StatementType(); |
|
216 //Reinitialize aSqlSecurityPolicyData, which is sql type dependent. |
|
217 switch(sqlType) |
|
218 { |
|
219 case Sql::EDDL: |
|
220 //Database EPTSchema access level |
|
221 policy = DbPolicyL(aDbPolicyRequest); |
|
222 aPolicyType = EPTSchema; |
|
223 break; |
|
224 case Sql::EDML: |
|
225 default: |
|
226 {//Table access level - EPTRead or EPTWrite. |
|
227 const TDesC& tblName = sqlParser.TableName(); |
|
228 __ASSERT(tblName.Length() > 0); |
|
229 TBuf<KDbMaxName> tblNameBuf; |
|
230 tblNameBuf.Copy(tblName); |
|
231 policy = TblPolicyL(aDbPolicyRequest, tblNameBuf); |
|
232 aPolicyType = sqlType == Sql::EDML ? EPTWrite : EPTRead; |
|
233 } |
|
234 break; |
|
235 } |
|
236 __ASSERT(policy); |
|
237 return policy; |
|
238 } |
|
239 |
|
240 /** |
|
241 Returns backup&restore SID for the databases, the access to which is controlled by the |
|
242 security policy, identified by aDbUid parameter. |
|
243 @param aDbUid Domain UID |
|
244 @return Backup&restore SID for the supplied domain UID |
|
245 @leave KErrArgument if there is no security policy domain for the supplied UID. |
|
246 */ |
|
247 TSecureId CPolicyProxy::BackupSIDL(TUid aDbUid) const |
|
248 { |
|
249 return iPolicySpace->BackupSIDL(aDbUid); |
|
250 } |
|
251 |
|
252 /** |
|
253 Asserts caller capabilities/SID/VID, packed in aMessage parameter against the security policy |
|
254 managed by aPolicy parameter. The caller has to satisfy at least one of the related to |
|
255 the message security policies. |
|
256 @param aMessage An object whith caller capabilities/SID/VID, which has to be checked. |
|
257 @param aPolicy A const reference to the security policy object. |
|
258 @leave KErrPermissionDenied The caller has no enough rights for the requested DBMS operation |
|
259 */ |
|
260 void CPolicyProxy::CheckL(const RMessage2& aMessage, const MPolicy& aPolicy) const |
|
261 { |
|
262 TDbsFunction func = ::Message2Function(aMessage); |
|
263 TUint mask = ::DbsFunction2PolicyMask(func); |
|
264 if(mask != EPTNone) |
|
265 { |
|
266 for(TInt c=0;c<KPolicyTypesCount;++c) |
|
267 { |
|
268 TPolicyType policyType = static_cast <TPolicyType> (1 << c); |
|
269 if(policyType & mask) |
|
270 { |
|
271 if(aPolicy.Check(aMessage, policyType)) |
|
272 { |
|
273 return; |
|
274 } |
|
275 } |
|
276 } |
|
277 __LEAVE(KErrPermissionDenied); |
|
278 } |
|
279 } |
|
280 |
|
281 /** |
|
282 Asserts caller capabilities/SID/VID, packed in aMessage parameter against the security policy |
|
283 managed by aPolicy parameter. |
|
284 @param aPolicyType The policy type, against which the check has to be done. |
|
285 @param aMessage An object whith caller capabilities/SID/VID, which has to be checked. |
|
286 @param aPolicy A const reference to the security policy object. |
|
287 @leave KErrPermissionDenied The caller has no enough rights for the requested DBMS operation |
|
288 */ |
|
289 void CPolicyProxy::CheckL(TPolicyType aPolicyType, const RMessage2& aMessage, const MPolicy& aPolicy) const |
|
290 { |
|
291 if(aPolicyType != EPTNone) |
|
292 { |
|
293 if(!aPolicy.Check(aMessage, aPolicyType)) |
|
294 { |
|
295 __LEAVE(KErrPermissionDenied); |
|
296 } |
|
297 } |
|
298 } |
|
299 |
|
300 /** |
|
301 Standard phase-two construction method for CPolicyProxy instances. |
|
302 @param aPrivatePath DBMS server private data path |
|
303 @leave KErrNoMemory |
|
304 */ |
|
305 void CPolicyProxy::ConstructL(const TDesC& aPrivatePath) |
|
306 { |
|
307 iPolicySpace = TPolicySpaceFactory::NewPolicySpaceL(iFs, aPrivatePath); |
|
308 } |
|
309 |