1 //******************************************************************
3 // Copyright 2015 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
25 #include "oic_malloc.h"
26 #include "oic_string.h"
29 #include "resourcemanager.h"
30 #include "aclresource.h"
31 #include "psinterface.h"
33 #include "srmresourcestrings.h"
34 #include "doxmresource.h"
35 #include "srmutility.h"
36 #include "ocserverrequest.h"
44 #define TAG PCF("SRM-ACL")
46 OicSecAcl_t *gAcl = NULL;
47 static OCResourceHandle gAclHandle = NULL;
50 * This function frees OicSecAcl_t object's fields and object itself.
52 static void FreeACE(OicSecAcl_t *ace)
57 OC_LOG (INFO, TAG, PCF("Invalid Parameter"));
62 for (i = 0; i < ace->resourcesLen; i++)
64 OICFree(ace->resources[i]);
66 OICFree(ace->resources);
68 //Clean Period & Recurrence
69 for(i = 0; i < ace->prdRecrLen; i++)
71 OICFree(ace->periods[i]);
72 OICFree(ace->recurrences[i]);
74 OICFree(ace->periods);
75 OICFree(ace->recurrences);
80 // Clean ACL node itself
84 void DeleteACLList(OicSecAcl_t* acl)
88 OicSecAcl_t *aclTmp1 = NULL;
89 OicSecAcl_t *aclTmp2 = NULL;
90 LL_FOREACH_SAFE(acl, aclTmp1, aclTmp2)
92 LL_DELETE(acl, aclTmp1);
99 * This internal method converts ACL data into JSON format.
101 * Note: Caller needs to invoke 'free' when finished done using
104 char * BinToAclJSON(const OicSecAcl_t * acl)
106 cJSON *jsonRoot = NULL;
107 char *jsonStr = NULL;
111 jsonRoot = cJSON_CreateObject();
112 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
114 cJSON *jsonAclArray = NULL;
115 cJSON_AddItemToObject (jsonRoot, OIC_JSON_ACL_NAME, jsonAclArray = cJSON_CreateArray());
116 VERIFY_NON_NULL(TAG, jsonAclArray, ERROR);
120 char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
123 B64Result b64Ret = B64_OK;
125 cJSON *jsonAcl = cJSON_CreateObject();
127 // Subject -- Mandatory
129 if (memcmp(&(acl->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0)
131 inLen = WILDCARD_SUBJECT_ID_LEN;
135 inLen = sizeof(OicUuid_t);
137 b64Ret = b64Encode(acl->subject.id, inLen, base64Buff,
138 sizeof(base64Buff), &outLen);
139 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
140 cJSON_AddStringToObject(jsonAcl, OIC_JSON_SUBJECT_NAME, base64Buff );
142 // Resources -- Mandatory
143 cJSON *jsonRsrcArray = NULL;
144 cJSON_AddItemToObject (jsonAcl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray = cJSON_CreateArray());
145 VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);
146 for (size_t i = 0; i < acl->resourcesLen; i++)
148 cJSON_AddItemToArray (jsonRsrcArray, cJSON_CreateString(acl->resources[i]));
151 // Permissions -- Mandatory
152 cJSON_AddNumberToObject (jsonAcl, OIC_JSON_PERMISSION_NAME, acl->permission);
154 //Period & Recurrence -- Not Mandatory
155 if(0 != acl->prdRecrLen)
157 cJSON *jsonPeriodArray = NULL;
158 cJSON_AddItemToObject (jsonAcl, OIC_JSON_PERIODS_NAME,
159 jsonPeriodArray = cJSON_CreateArray());
160 VERIFY_NON_NULL(TAG, jsonPeriodArray, ERROR);
161 for (size_t i = 0; i < acl->prdRecrLen; i++)
163 cJSON_AddItemToArray (jsonPeriodArray,
164 cJSON_CreateString(acl->periods[i]));
168 //Recurrence -- Not Mandatory
169 if(0 != acl->prdRecrLen && acl->recurrences)
171 cJSON *jsonRecurArray = NULL;
172 cJSON_AddItemToObject (jsonAcl, OIC_JSON_RECURRENCES_NAME,
173 jsonRecurArray = cJSON_CreateArray());
174 VERIFY_NON_NULL(TAG, jsonRecurArray, ERROR);
175 for (size_t i = 0; i < acl->prdRecrLen; i++)
177 cJSON_AddItemToArray (jsonRecurArray,
178 cJSON_CreateString(acl->recurrences[i]));
182 // Owners -- Mandatory
183 cJSON *jsonOwnrArray = NULL;
184 cJSON_AddItemToObject (jsonAcl, OIC_JSON_OWNERS_NAME, jsonOwnrArray = cJSON_CreateArray());
185 VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
186 for (size_t i = 0; i < acl->ownersLen; i++)
190 b64Ret = b64Encode(acl->owners[i].id, sizeof(((OicUuid_t*)0)->id), base64Buff,
191 sizeof(base64Buff), &outLen);
192 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
194 cJSON_AddItemToArray (jsonOwnrArray, cJSON_CreateString(base64Buff));
197 // Attach current acl node to Acl Array
198 cJSON_AddItemToArray(jsonAclArray, jsonAcl);
202 jsonStr = cJSON_PrintUnformatted(jsonRoot);
208 cJSON_Delete(jsonRoot);
214 * This internal method converts JSON ACL into binary ACL.
216 OicSecAcl_t * JSONToAclBin(const char * jsonStr)
218 OCStackResult ret = OC_STACK_ERROR;
219 OicSecAcl_t * headAcl = NULL;
220 OicSecAcl_t * prevAcl = NULL;
221 cJSON *jsonRoot = NULL;
222 cJSON *jsonAclArray = NULL;
224 VERIFY_NON_NULL(TAG, jsonStr, ERROR);
226 jsonRoot = cJSON_Parse(jsonStr);
227 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
229 jsonAclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_ACL_NAME);
230 VERIFY_NON_NULL(TAG, jsonAclArray, ERROR);
232 if (cJSON_Array == jsonAclArray->type)
234 int numAcl = cJSON_GetArraySize(jsonAclArray);
237 VERIFY_SUCCESS(TAG, numAcl > 0, INFO);
240 cJSON *jsonAcl = cJSON_GetArrayItem(jsonAclArray, idx);
241 VERIFY_NON_NULL(TAG, jsonAcl, ERROR);
243 OicSecAcl_t *acl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
244 VERIFY_NON_NULL(TAG, acl, ERROR);
246 headAcl = (headAcl) ? headAcl : acl;
252 size_t jsonObjLen = 0;
253 cJSON *jsonObj = NULL;
255 unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
257 B64Result b64Ret = B64_OK;
259 // Subject -- Mandatory
260 jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_SUBJECT_NAME);
261 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
262 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
264 b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
265 sizeof(base64Buff), &outLen);
266 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(acl->subject.id)), ERROR);
267 memcpy(acl->subject.id, base64Buff, outLen);
269 // Resources -- Mandatory
270 jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_RESOURCES_NAME);
271 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
272 VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
274 acl->resourcesLen = cJSON_GetArraySize(jsonObj);
275 VERIFY_SUCCESS(TAG, acl->resourcesLen > 0, ERROR);
276 acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
277 VERIFY_NON_NULL(TAG, (acl->resources), ERROR);
282 cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
283 VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
285 jsonObjLen = strlen(jsonRsrc->valuestring) + 1;
286 acl->resources[idxx] = (char*)OICMalloc(jsonObjLen);
287 VERIFY_NON_NULL(TAG, (acl->resources[idxx]), ERROR);
288 OICStrcpy(acl->resources[idxx], jsonObjLen, jsonRsrc->valuestring);
289 } while ( ++idxx < acl->resourcesLen);
291 // Permissions -- Mandatory
292 jsonObj = cJSON_GetObjectItem(jsonAcl,
293 OIC_JSON_PERMISSION_NAME);
294 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
295 VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
296 acl->permission = jsonObj->valueint;
298 //Period -- Not Mandatory
299 cJSON *jsonPeriodObj = cJSON_GetObjectItem(jsonAcl,
300 OIC_JSON_PERIODS_NAME);
303 VERIFY_SUCCESS(TAG, cJSON_Array == jsonPeriodObj->type,
305 acl->prdRecrLen = cJSON_GetArraySize(jsonPeriodObj);
306 if(acl->prdRecrLen > 0)
308 acl->periods = (char**)OICCalloc(acl->prdRecrLen,
310 VERIFY_NON_NULL(TAG, acl->periods, ERROR);
312 cJSON *jsonPeriod = NULL;
313 for(size_t i = 0; i < acl->prdRecrLen; i++)
315 jsonPeriod = cJSON_GetArrayItem(jsonPeriodObj, i);
316 VERIFY_NON_NULL(TAG, jsonPeriod, ERROR);
318 jsonObjLen = strlen(jsonPeriod->valuestring) + 1;
319 acl->periods[i] = (char*)OICMalloc(jsonObjLen);
320 VERIFY_NON_NULL(TAG, acl->periods[i], ERROR);
321 OICStrcpy(acl->periods[i], jsonObjLen,
322 jsonPeriod->valuestring);
327 //Recurrence -- Not mandatory
328 cJSON *jsonRecurObj = cJSON_GetObjectItem(jsonAcl,
329 OIC_JSON_RECURRENCES_NAME);
332 VERIFY_SUCCESS(TAG, cJSON_Array == jsonRecurObj->type,
334 if(acl->prdRecrLen > 0)
336 acl->recurrences = (char**)OICCalloc(acl->prdRecrLen,
338 VERIFY_NON_NULL(TAG, acl->recurrences, ERROR);
340 cJSON *jsonRecur = NULL;
341 for(size_t i = 0; i < acl->prdRecrLen; i++)
343 jsonRecur = cJSON_GetArrayItem(jsonRecurObj, i);
344 jsonObjLen = strlen(jsonRecur->valuestring) + 1;
345 acl->recurrences[i] = (char*)OICMalloc(jsonObjLen);
346 VERIFY_NON_NULL(TAG, acl->recurrences[i], ERROR);
347 OICStrcpy(acl->recurrences[i], jsonObjLen,
348 jsonRecur->valuestring);
353 // Owners -- Mandatory
354 jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_OWNERS_NAME);
355 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
356 VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
358 acl->ownersLen = cJSON_GetArraySize(jsonObj);
359 VERIFY_SUCCESS(TAG, acl->ownersLen > 0, ERROR);
360 acl->owners = (OicUuid_t*)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
361 VERIFY_NON_NULL(TAG, (acl->owners), ERROR);
366 cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx);
367 VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
368 VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
371 b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff,
372 sizeof(base64Buff), &outLen);
374 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(acl->owners[idxx].id)),
376 memcpy(acl->owners[idxx].id, base64Buff, outLen);
377 } while ( ++idxx < acl->ownersLen);
380 } while( ++idx < numAcl);
386 cJSON_Delete(jsonRoot);
387 if (OC_STACK_OK != ret)
389 DeleteACLList(headAcl);
395 static bool UpdatePersistentStorage(const OicSecAcl_t *acl)
397 // Convert ACL data into JSON for update to persistent storage
398 char *jsonStr = BinToAclJSON(acl);
401 cJSON *jsonAcl = cJSON_Parse(jsonStr);
404 if ((jsonAcl) && (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_ACL_NAME, jsonAcl)))
408 cJSON_Delete(jsonAcl);
413 * This method removes ACE for the subject and resource from the ACL
415 * @param subject - subject of the ACE
416 * @param resource - resource of the ACE
419 * OC_STACK_RESOURCE_DELETED on success
420 * OC_STACK_NO_RESOURC on failure to find the appropriate ACE
421 * OC_STACK_INVALID_PARAM on invalid parameter
423 static OCStackResult RemoveACE(const OicUuid_t * subject,
424 const char * resource)
426 OC_LOG(INFO, TAG, PCF("IN RemoveACE"));
428 OicSecAcl_t *acl = NULL;
429 OicSecAcl_t *tempAcl = NULL;
430 bool deleteFlag = false;
431 OCStackResult ret = OC_STACK_NO_RESOURCE;
433 if(memcmp(subject->id, &WILDCARD_SUBJECT_ID, sizeof(subject->id)) == 0)
435 OC_LOG_V (INFO, TAG, PCF("%s received invalid parameter"), __func__ );
436 return OC_STACK_INVALID_PARAM;
439 //If resource is NULL then delete all the ACE for the subject.
442 LL_FOREACH_SAFE(gAcl, acl, tempAcl)
444 if(memcmp(acl->subject.id, subject->id, sizeof(subject->id)) == 0)
446 LL_DELETE(gAcl, acl);
454 //Looping through ACL to find the right ACE to delete. If the required resource is the only
455 //resource in the ACE for the subject then delete the whole ACE. If there are more resources
456 //than the required resource in the ACE, for the subject then just delete the resource from
458 LL_FOREACH_SAFE(gAcl, acl, tempAcl)
460 if(memcmp(acl->subject.id, subject->id, sizeof(subject->id)) == 0)
462 if(1 == acl->resourcesLen && strcmp(acl->resources[0], resource) == 0)
464 LL_DELETE(gAcl, acl);
473 for(i = 0; i < acl->resourcesLen; i++)
475 if(strcmp(acl->resources[i], resource) == 0)
483 OICFree(acl->resources[resPos]);
484 acl->resources[resPos] = NULL;
485 acl->resourcesLen -= 1;
486 for(i = resPos; i < acl->resourcesLen; i++)
488 acl->resources[i] = acl->resources[i+1];
500 if(UpdatePersistentStorage(gAcl))
502 ret = OC_STACK_RESOURCE_DELETED;
508 static OCEntityHandlerResult HandleACLGetRequest (const OCEntityHandlerRequest * ehRequest)
510 // Convert ACL data into JSON for transmission
511 char* jsonStr = BinToAclJSON(gAcl);
514 * A device should 'always' have a default ACL. Therefore,
515 * jsonStr should never be NULL.
517 OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
519 // Send response payload to request originator
520 SendSRMResponse(ehRequest, ehRet, jsonStr);
524 OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
528 static OCEntityHandlerResult HandleACLPostRequest (const OCEntityHandlerRequest * ehRequest)
530 OCEntityHandlerResult ehRet = OC_EH_ERROR;
532 // Convert JSON ACL data into binary. This will also validate the ACL data received.
533 OicSecAcl_t* newAcl = JSONToAclBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
537 // Append the new ACL to existing ACL
538 LL_APPEND(gAcl, newAcl);
540 if(UpdatePersistentStorage(gAcl))
542 ehRet = OC_EH_RESOURCE_CREATED;
546 // Send payload to request originator
547 SendSRMResponse(ehRequest, ehRet, NULL);
549 OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
553 static OCEntityHandlerResult HandleACLDeleteRequest(const OCEntityHandlerRequest *ehRequest)
555 OC_LOG (INFO, TAG, PCF("Processing ACLDeleteRequest"));
556 OCEntityHandlerResult ehRet = OC_EH_ERROR;
558 if(NULL == ehRequest->query)
562 OicParseQueryIter_t parseIter = {.attrPos=NULL};
563 OicUuid_t subject = {.id={0}};
564 char * resource = NULL;
566 //Parsing REST query to get subject & resource
567 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
569 while(GetNextQuery(&parseIter))
571 if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECT_NAME, parseIter.attrLen) == 0)
573 unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
575 B64Result b64Ret = B64_OK;
577 b64Ret = b64Decode((char *)parseIter.valPos, parseIter.valLen, base64Buff,
578 sizeof(base64Buff), &outLen);
580 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(subject.id)), ERROR);
581 memcpy(subject.id, base64Buff, outLen);
583 if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_RESOURCES_NAME, parseIter.attrLen) == 0)
585 resource = (char *)OICMalloc(parseIter.valLen);
586 VERIFY_NON_NULL(TAG, resource, ERROR);
587 OICStrcpy(resource, sizeof(resource), (char *)parseIter.valPos);
591 if(OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource))
593 ehRet = OC_EH_RESOURCE_DELETED;
597 // Send payload to request originator
598 SendSRMResponse(ehRequest, ehRet, NULL);
605 * This internal method is the entity handler for ACL resources and
606 * will handle REST request (GET/PUT/POST/DEL) for them.
608 OCEntityHandlerResult ACLEntityHandler (OCEntityHandlerFlag flag,
609 OCEntityHandlerRequest * ehRequest,
610 void* callbackParameter)
612 OC_LOG(INFO, TAG, PCF("Received request ACLEntityHandler"));
613 (void)callbackParameter;
614 OCEntityHandlerResult ehRet = OC_EH_ERROR;
621 if (flag & OC_REQUEST_FLAG)
623 // TODO : Handle PUT and DEL methods
624 OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
625 switch (ehRequest->method)
628 ehRet = HandleACLGetRequest(ehRequest);
632 ehRet = HandleACLPostRequest(ehRequest);
636 ehRet = HandleACLDeleteRequest(ehRequest);
641 SendSRMResponse(ehRequest, ehRet, NULL);
649 * This internal method is used to create '/oic/sec/acl' resource.
651 OCStackResult CreateACLResource()
655 ret = OCCreateResource(&gAclHandle,
656 OIC_RSRC_TYPE_SEC_ACL,
661 OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
663 if (OC_STACK_OK != ret)
665 OC_LOG (FATAL, TAG, PCF("Unable to instantiate ACL resource"));
672 * This internal method is to retrieve the default ACL.
673 * If SVR database in persistent storage got corrupted or
674 * is not available for some reason, a default ACL is created
675 * which allows user to initiate ACL provisioning again.
677 OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl)
679 OCStackResult ret = OC_STACK_ERROR;
681 OicUuid_t ownerId = {.id = {0}};
684 * TODO In future, when new virtual resources will be added in OIC
685 * specification, Iotivity stack should be able to add them in
686 * existing SVR database. To support this, we need to add 'versioning'
687 * mechanism in SVR database.
690 const char *rsrcs[] = {
691 OC_RSRVD_WELL_KNOWN_URI,
693 OC_RSRVD_PLATFORM_URI,
694 OC_RSRVD_RESOURCE_TYPES_URI,
696 OC_RSRVD_PRESENCE_URI,
697 #endif //WITH_PRESENCE
705 return OC_STACK_INVALID_PARAM;
708 OicSecAcl_t *acl = (OicSecAcl_t *)OICCalloc(1, sizeof(OicSecAcl_t));
709 VERIFY_NON_NULL(TAG, acl, ERROR);
711 // Subject -- Mandatory
712 memcpy(&(acl->subject), &WILDCARD_SUBJECT_ID, sizeof(acl->subject));
714 // Resources -- Mandatory
715 acl->resourcesLen = sizeof(rsrcs)/sizeof(rsrcs[0]);
717 acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
718 VERIFY_NON_NULL(TAG, (acl->resources), ERROR);
720 for (size_t i = 0; i < acl->resourcesLen; i++)
722 size_t len = strlen(rsrcs[i]) + 1;
723 acl->resources[i] = (char*)OICMalloc(len * sizeof(char));
724 VERIFY_NON_NULL(TAG, (acl->resources[i]), ERROR);
725 OICStrcpy(acl->resources[i], len, rsrcs[i]);
728 acl->permission = PERMISSION_READ;
731 acl->recurrences = NULL;
733 // Device ID is the owner of this default ACL
734 ret = GetDoxmDeviceID( &ownerId);
735 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, FATAL);
738 acl->owners = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
739 VERIFY_NON_NULL(TAG, (acl->owners), ERROR);
740 memcpy(acl->owners, &ownerId, sizeof(OicUuid_t));
749 if (ret != OC_STACK_OK)
759 * Initialize ACL resource by loading data from persistent storage.
761 * @retval OC_STACK_OK for Success, otherwise some error value
763 OCStackResult InitACLResource()
765 OCStackResult ret = OC_STACK_ERROR;
767 // Read ACL resource from PS
768 char* jsonSVRDatabase = GetSVRDatabase();
772 // Convert JSON ACL into binary format
773 gAcl = JSONToAclBin(jsonSVRDatabase);
774 OICFree(jsonSVRDatabase);
777 * If SVR database in persistent storage got corrupted or
778 * is not available for some reason, a default ACL is created
779 * which allows user to initiate ACL provisioning again.
781 if (!jsonSVRDatabase || !gAcl)
783 GetDefaultACL(&gAcl);
784 // TODO Needs to update persistent storage
786 VERIFY_NON_NULL(TAG, gAcl, FATAL);
788 // Instantiate 'oic.sec.acl'
789 ret = CreateACLResource();
792 if (OC_STACK_OK != ret)
800 * Perform cleanup for ACL resources.
804 void DeInitACLResource()
806 OCDeleteResource(gAclHandle);
814 * This method is used by PolicyEngine to retrieve ACL for a Subject.
816 * @param subjectId ID of the subject for which ACL is required.
817 * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
818 * successive calls for same subjectId.
820 * @retval reference to @ref OicSecAcl_t if ACL is found, else NULL
822 * @note On the first call to @ref GetACLResourceData, savePtr should point to NULL
824 const OicSecAcl_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAcl_t **savePtr)
826 OicSecAcl_t *acl = NULL;
827 OicSecAcl_t *begin = NULL;
829 if ( NULL == subjectId)
835 * savePtr MUST point to NULL if this is the 'first' call to retrieve ACL for
838 if (NULL == *savePtr)
845 * If this is a 'successive' call, search for location pointed by
846 * savePtr and assign 'begin' to the next ACL after it in the linked
847 * list and start searching from there.
849 LL_FOREACH(gAcl, acl)
858 // Find the next ACL corresponding to the 'subjectID' and return it.
859 LL_FOREACH(begin, acl)
861 if (memcmp(&(acl->subject), subjectId, sizeof(OicUuid_t)) == 0)
868 // Cleanup in case no ACL is found