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, *aclTmp2 = NULL;
89 LL_FOREACH_SAFE(acl, aclTmp1, aclTmp2)
91 LL_DELETE(acl, aclTmp1);
98 * This internal method converts ACL data into JSON format.
100 * Note: Caller needs to invoke 'free' when finished done using
103 char * BinToAclJSON(const OicSecAcl_t * acl)
105 cJSON *jsonRoot = NULL;
106 char *jsonStr = NULL;
110 jsonRoot = cJSON_CreateObject();
111 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
113 cJSON *jsonAclArray = NULL;
114 cJSON_AddItemToObject (jsonRoot, OIC_JSON_ACL_NAME, jsonAclArray = cJSON_CreateArray());
115 VERIFY_NON_NULL(TAG, jsonAclArray, ERROR);
119 char base64Buff[B64ENCODE_OUT_SAFESIZE(sizeof(((OicUuid_t*)0)->id)) + 1] = {};
122 B64Result b64Ret = B64_OK;
124 cJSON *jsonAcl = cJSON_CreateObject();
126 // Subject -- Mandatory
128 if (memcmp(&(acl->subject), &WILDCARD_SUBJECT_ID, sizeof(OicUuid_t)) == 0)
130 inLen = WILDCARD_SUBJECT_ID_LEN;
134 inLen = sizeof(OicUuid_t);
136 b64Ret = b64Encode(acl->subject.id, inLen, base64Buff,
137 sizeof(base64Buff), &outLen);
138 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
139 cJSON_AddStringToObject(jsonAcl, OIC_JSON_SUBJECT_NAME, base64Buff );
141 // Resources -- Mandatory
142 cJSON *jsonRsrcArray = NULL;
143 cJSON_AddItemToObject (jsonAcl, OIC_JSON_RESOURCES_NAME, jsonRsrcArray = cJSON_CreateArray());
144 VERIFY_NON_NULL(TAG, jsonRsrcArray, ERROR);
145 for (size_t i = 0; i < acl->resourcesLen; i++)
147 cJSON_AddItemToArray (jsonRsrcArray, cJSON_CreateString(acl->resources[i]));
150 // Permissions -- Mandatory
151 cJSON_AddNumberToObject (jsonAcl, OIC_JSON_PERMISSION_NAME, acl->permission);
153 //Period & Recurrence -- Not Mandatory
154 if(0 != acl->prdRecrLen)
156 cJSON *jsonPeriodArray = NULL;
157 cJSON_AddItemToObject (jsonAcl, OIC_JSON_PERIODS_NAME,
158 jsonPeriodArray = cJSON_CreateArray());
159 VERIFY_NON_NULL(TAG, jsonPeriodArray, ERROR);
160 for (size_t i = 0; i < acl->prdRecrLen; i++)
162 cJSON_AddItemToArray (jsonPeriodArray,
163 cJSON_CreateString(acl->periods[i]));
167 //Recurrence -- Not Mandatory
168 if(0 != acl->prdRecrLen && acl->recurrences)
170 cJSON *jsonRecurArray = NULL;
171 cJSON_AddItemToObject (jsonAcl, OIC_JSON_RECURRENCES_NAME,
172 jsonRecurArray = cJSON_CreateArray());
173 VERIFY_NON_NULL(TAG, jsonRecurArray, ERROR);
174 for (size_t i = 0; i < acl->prdRecrLen; i++)
176 cJSON_AddItemToArray (jsonRecurArray,
177 cJSON_CreateString(acl->recurrences[i]));
181 // Owners -- Mandatory
182 cJSON *jsonOwnrArray = NULL;
183 cJSON_AddItemToObject (jsonAcl, OIC_JSON_OWNERS_NAME, jsonOwnrArray = cJSON_CreateArray());
184 VERIFY_NON_NULL(TAG, jsonOwnrArray, ERROR);
185 for (size_t i = 0; i < acl->ownersLen; i++)
189 b64Ret = b64Encode(acl->owners[i].id, sizeof(((OicUuid_t*)0)->id), base64Buff,
190 sizeof(base64Buff), &outLen);
191 VERIFY_SUCCESS(TAG, b64Ret == B64_OK, ERROR);
193 cJSON_AddItemToArray (jsonOwnrArray, cJSON_CreateString(base64Buff));
196 // Attach current acl node to Acl Array
197 cJSON_AddItemToArray(jsonAclArray, jsonAcl);
201 jsonStr = cJSON_PrintUnformatted(jsonRoot);
207 cJSON_Delete(jsonRoot);
213 * This internal method converts JSON ACL into binary ACL.
215 OicSecAcl_t * JSONToAclBin(const char * jsonStr)
217 OCStackResult ret = OC_STACK_ERROR;
218 OicSecAcl_t * headAcl = NULL;
219 OicSecAcl_t * prevAcl = NULL;
220 cJSON *jsonRoot = NULL;
221 cJSON *jsonAclArray = NULL;
223 VERIFY_NON_NULL(TAG, jsonStr, ERROR);
225 jsonRoot = cJSON_Parse(jsonStr);
226 VERIFY_NON_NULL(TAG, jsonRoot, ERROR);
228 jsonAclArray = cJSON_GetObjectItem(jsonRoot, OIC_JSON_ACL_NAME);
229 VERIFY_NON_NULL(TAG, jsonAclArray, ERROR);
231 if (cJSON_Array == jsonAclArray->type)
233 int numAcl = cJSON_GetArraySize(jsonAclArray);
236 VERIFY_SUCCESS(TAG, numAcl > 0, INFO);
239 cJSON *jsonAcl = cJSON_GetArrayItem(jsonAclArray, idx);
240 VERIFY_NON_NULL(TAG, jsonAcl, ERROR);
242 OicSecAcl_t *acl = (OicSecAcl_t*)OICCalloc(1, sizeof(OicSecAcl_t));
243 VERIFY_NON_NULL(TAG, acl, ERROR);
245 headAcl = (headAcl) ? headAcl : acl;
251 size_t jsonObjLen = 0;
252 cJSON *jsonObj = NULL;
254 unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
256 B64Result b64Ret = B64_OK;
258 // Subject -- Mandatory
259 jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_SUBJECT_NAME);
260 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
261 VERIFY_SUCCESS(TAG, cJSON_String == jsonObj->type, ERROR);
263 b64Ret = b64Decode(jsonObj->valuestring, strlen(jsonObj->valuestring), base64Buff,
264 sizeof(base64Buff), &outLen);
265 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(acl->subject.id)), ERROR);
266 memcpy(acl->subject.id, base64Buff, outLen);
268 // Resources -- Mandatory
269 jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_RESOURCES_NAME);
270 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
271 VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
273 acl->resourcesLen = cJSON_GetArraySize(jsonObj);
274 VERIFY_SUCCESS(TAG, acl->resourcesLen > 0, ERROR);
275 acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
276 VERIFY_NON_NULL(TAG, (acl->resources), ERROR);
281 cJSON *jsonRsrc = cJSON_GetArrayItem(jsonObj, idxx);
282 VERIFY_NON_NULL(TAG, jsonRsrc, ERROR);
284 jsonObjLen = strlen(jsonRsrc->valuestring) + 1;
285 acl->resources[idxx] = (char*)OICMalloc(jsonObjLen);
286 VERIFY_NON_NULL(TAG, (acl->resources[idxx]), ERROR);
287 OICStrcpy(acl->resources[idxx], jsonObjLen, jsonRsrc->valuestring);
288 } while ( ++idxx < acl->resourcesLen);
290 // Permissions -- Mandatory
291 jsonObj = cJSON_GetObjectItem(jsonAcl,
292 OIC_JSON_PERMISSION_NAME);
293 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
294 VERIFY_SUCCESS(TAG, cJSON_Number == jsonObj->type, ERROR);
295 acl->permission = jsonObj->valueint;
297 //Period -- Not Mandatory
298 cJSON *jsonPeriodObj = cJSON_GetObjectItem(jsonAcl,
299 OIC_JSON_PERIODS_NAME);
302 VERIFY_SUCCESS(TAG, cJSON_Array == jsonPeriodObj->type,
304 acl->prdRecrLen = cJSON_GetArraySize(jsonPeriodObj);
305 if(acl->prdRecrLen > 0)
307 acl->periods = (char**)OICCalloc(acl->prdRecrLen,
309 VERIFY_NON_NULL(TAG, acl->periods, ERROR);
311 cJSON *jsonPeriod = NULL;
312 for(size_t i = 0; i < acl->prdRecrLen; i++)
314 jsonPeriod = cJSON_GetArrayItem(jsonPeriodObj, i);
315 VERIFY_NON_NULL(TAG, jsonPeriod, ERROR);
317 jsonObjLen = strlen(jsonPeriod->valuestring) + 1;
318 acl->periods[i] = (char*)OICMalloc(jsonObjLen);
319 VERIFY_NON_NULL(TAG, acl->periods[i], ERROR);
320 OICStrcpy(acl->periods[i], jsonObjLen,
321 jsonPeriod->valuestring);
326 //Recurrence -- Not mandatory
327 cJSON *jsonRecurObj = cJSON_GetObjectItem(jsonAcl,
328 OIC_JSON_RECURRENCES_NAME);
331 VERIFY_SUCCESS(TAG, cJSON_Array == jsonRecurObj->type,
333 if(acl->prdRecrLen > 0)
335 acl->recurrences = (char**)OICCalloc(acl->prdRecrLen,
337 VERIFY_NON_NULL(TAG, acl->recurrences, ERROR);
339 cJSON *jsonRecur = NULL;
340 for(size_t i = 0; i < acl->prdRecrLen; i++)
342 jsonRecur = cJSON_GetArrayItem(jsonRecurObj, i);
343 jsonObjLen = strlen(jsonRecur->valuestring) + 1;
344 acl->recurrences[i] = (char*)OICMalloc(jsonObjLen);
345 VERIFY_NON_NULL(TAG, acl->recurrences[i], ERROR);
346 OICStrcpy(acl->recurrences[i], jsonObjLen,
347 jsonRecur->valuestring);
352 // Owners -- Mandatory
353 jsonObj = cJSON_GetObjectItem(jsonAcl, OIC_JSON_OWNERS_NAME);
354 VERIFY_NON_NULL(TAG, jsonObj, ERROR);
355 VERIFY_SUCCESS(TAG, cJSON_Array == jsonObj->type, ERROR);
357 acl->ownersLen = cJSON_GetArraySize(jsonObj);
358 VERIFY_SUCCESS(TAG, acl->ownersLen > 0, ERROR);
359 acl->owners = (OicUuid_t*)OICCalloc(acl->ownersLen, sizeof(OicUuid_t));
360 VERIFY_NON_NULL(TAG, (acl->owners), ERROR);
365 cJSON *jsonOwnr = cJSON_GetArrayItem(jsonObj, idxx);
366 VERIFY_NON_NULL(TAG, jsonOwnr, ERROR);
367 VERIFY_SUCCESS(TAG, cJSON_String == jsonOwnr->type, ERROR);
370 b64Ret = b64Decode(jsonOwnr->valuestring, strlen(jsonOwnr->valuestring), base64Buff,
371 sizeof(base64Buff), &outLen);
373 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(acl->owners[idxx].id)),
375 memcpy(acl->owners[idxx].id, base64Buff, outLen);
376 } while ( ++idxx < acl->ownersLen);
379 } while( ++idx < numAcl);
385 cJSON_Delete(jsonRoot);
386 if (OC_STACK_OK != ret)
388 DeleteACLList(headAcl);
394 static bool UpdatePersistentStorage(const OicSecAcl_t *acl)
396 // Convert ACL data into JSON for update to persistent storage
397 char *jsonStr = BinToAclJSON(acl);
400 cJSON *jsonAcl = cJSON_Parse(jsonStr);
403 if ((jsonAcl) && (OC_STACK_OK == UpdateSVRDatabase(OIC_JSON_ACL_NAME, jsonAcl)))
407 cJSON_Delete(jsonAcl);
412 * This method removes ACE for the subject and resource from the ACL
414 * @param subject - subject of the ACE
415 * @param resource - resource of the ACE
418 * OC_STACK_RESOURCE_DELETED on success
419 * OC_STACK_NO_RESOURC on failure to find the appropriate ACE
420 * OC_STACK_INVALID_PARAM on invalid parameter
422 static OCStackResult RemoveACE(const OicUuid_t * subject,
423 const char * resource)
425 OC_LOG(INFO, TAG, PCF("IN RemoveACE"));
427 OicSecAcl_t *acl = NULL;
428 OicSecAcl_t *tempAcl = NULL;
429 bool deleteFlag = false;
430 OCStackResult ret = OC_STACK_NO_RESOURCE;
432 if(memcmp(subject->id, &WILDCARD_SUBJECT_ID, sizeof(subject->id)) == 0)
434 OC_LOG_V (INFO, TAG, PCF("%s received invalid parameter"), __func__ );
435 return OC_STACK_INVALID_PARAM;
438 //If resource is NULL then delete all the ACE for the subject.
441 LL_FOREACH_SAFE(gAcl, acl, tempAcl)
443 if(memcmp(acl->subject.id, subject->id, sizeof(subject->id)) == 0)
445 LL_DELETE(gAcl, acl);
453 //Looping through ACL to find the right ACE to delete. If the required resource is the only
454 //resource in the ACE for the subject then delete the whole ACE. If there are more resources
455 //than the required resource in the ACE, for the subject then just delete the resource from
457 LL_FOREACH_SAFE(gAcl, acl, tempAcl)
459 if(memcmp(acl->subject.id, subject->id, sizeof(subject->id)) == 0)
461 if(1 == acl->resourcesLen && strcmp(acl->resources[0], resource) == 0)
463 LL_DELETE(gAcl, acl);
472 for(i = 0; i < acl->resourcesLen; i++)
474 if(strcmp(acl->resources[i], resource) == 0)
482 OICFree(acl->resources[resPos]);
483 acl->resources[resPos] = NULL;
484 acl->resourcesLen -= 1;
485 for(i = resPos; i < acl->resourcesLen; i++)
487 acl->resources[i] = acl->resources[i+1];
499 if(UpdatePersistentStorage(gAcl))
501 ret = OC_STACK_RESOURCE_DELETED;
507 static OCEntityHandlerResult HandleACLGetRequest (const OCEntityHandlerRequest * ehRequest)
509 // Convert ACL data into JSON for transmission
510 char* jsonStr = BinToAclJSON(gAcl);
513 * A device should 'always' have a default ACL. Therefore,
514 * jsonStr should never be NULL.
516 OCEntityHandlerResult ehRet = (jsonStr ? OC_EH_OK : OC_EH_ERROR);
518 // Send response payload to request originator
519 SendSRMResponse(ehRequest, ehRet, jsonStr);
523 OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
527 static OCEntityHandlerResult HandleACLPostRequest (const OCEntityHandlerRequest * ehRequest)
529 OCEntityHandlerResult ehRet = OC_EH_ERROR;
531 // Convert JSON ACL data into binary. This will also validate the ACL data received.
532 OicSecAcl_t* newAcl = JSONToAclBin(((OCSecurityPayload*)ehRequest->payload)->securityData);
536 // Append the new ACL to existing ACL
537 LL_APPEND(gAcl, newAcl);
539 if(UpdatePersistentStorage(gAcl))
541 ehRet = OC_EH_RESOURCE_CREATED;
545 // Send payload to request originator
546 SendSRMResponse(ehRequest, ehRet, NULL);
548 OC_LOG_V (INFO, TAG, PCF("%s RetVal %d"), __func__ , ehRet);
552 static OCEntityHandlerResult HandleACLDeleteRequest(const OCEntityHandlerRequest *ehRequest)
554 OC_LOG (INFO, TAG, PCF("Processing ACLDeleteRequest"));
555 OCEntityHandlerResult ehRet = OC_EH_ERROR;
557 if(NULL == ehRequest->query)
561 OicParseQueryIter_t parseIter = {.attrPos=NULL};
562 OicUuid_t subject = {.id={0}};
563 char * resource = NULL;
565 //Parsing REST query to get subject & resource
566 ParseQueryIterInit((unsigned char *)ehRequest->query, &parseIter);
568 while(GetNextQuery(&parseIter))
570 if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_SUBJECT_NAME, parseIter.attrLen) == 0)
572 unsigned char base64Buff[sizeof(((OicUuid_t*)0)->id)] = {};
574 B64Result b64Ret = B64_OK;
576 b64Ret = b64Decode((char *)parseIter.valPos, parseIter.valLen, base64Buff,
577 sizeof(base64Buff), &outLen);
579 VERIFY_SUCCESS(TAG, (b64Ret == B64_OK && outLen <= sizeof(subject.id)), ERROR);
580 memcpy(subject.id, base64Buff, outLen);
582 if(strncasecmp((char *)parseIter.attrPos, OIC_JSON_RESOURCES_NAME, parseIter.attrLen) == 0)
584 resource = (char *)OICMalloc(parseIter.valLen);
585 VERIFY_NON_NULL(TAG, resource, ERROR);
586 OICStrcpy(resource, sizeof(resource), (char *)parseIter.valPos);
590 if(OC_STACK_RESOURCE_DELETED == RemoveACE(&subject, resource))
592 ehRet = OC_EH_RESOURCE_DELETED;
596 // Send payload to request originator
597 SendSRMResponse(ehRequest, ehRet, NULL);
604 * This internal method is the entity handler for ACL resources and
605 * will handle REST request (GET/PUT/POST/DEL) for them.
607 OCEntityHandlerResult ACLEntityHandler (OCEntityHandlerFlag flag,
608 OCEntityHandlerRequest * ehRequest,
609 void* callbackParameter)
611 OC_LOG(INFO, TAG, PCF("Received request ACLEntityHandler\n"));
612 OCEntityHandlerResult ehRet = OC_EH_ERROR;
619 if (flag & OC_REQUEST_FLAG)
621 // TODO : Handle PUT and DEL methods
622 OC_LOG (INFO, TAG, PCF("Flag includes OC_REQUEST_FLAG"));
623 switch (ehRequest->method)
626 ehRet = HandleACLGetRequest(ehRequest);
630 ehRet = HandleACLPostRequest(ehRequest);
634 ehRet = HandleACLDeleteRequest(ehRequest);
639 SendSRMResponse(ehRequest, ehRet, NULL);
647 * This internal method is used to create '/oic/sec/acl' resource.
649 OCStackResult CreateACLResource()
653 ret = OCCreateResource(&gAclHandle,
654 OIC_RSRC_TYPE_SEC_ACL,
659 OC_OBSERVABLE | OC_SECURE | OC_EXPLICIT_DISCOVERABLE);
661 if (OC_STACK_OK != ret)
663 OC_LOG (FATAL, TAG, PCF("Unable to instantiate ACL resource"));
670 * This internal method is to retrieve the default ACL.
671 * If SVR database in persistent storage got corrupted or
672 * is not available for some reason, a default ACL is created
673 * which allows user to initiate ACL provisioning again.
675 OCStackResult GetDefaultACL(OicSecAcl_t** defaultAcl)
677 OCStackResult ret = OC_STACK_ERROR;
679 OicUuid_t ownerId = {.id={}};
682 * TODO In future, when new virtual resources will be added in OIC
683 * specification, Iotivity stack should be able to add them in
684 * existing SVR database. To support this, we need to add 'versioning'
685 * mechanism in SVR database.
688 const char *rsrcs[] = {
689 OC_RSRVD_WELL_KNOWN_URI,
691 OC_RSRVD_PLATFORM_URI,
692 OC_RSRVD_RESOURCE_TYPES_URI,
694 OC_RSRVD_PRESENCE_URI,
695 #endif //WITH_PRESENCE
703 return OC_STACK_INVALID_PARAM;
706 OicSecAcl_t *acl = (OicSecAcl_t *)OICCalloc(1, sizeof(OicSecAcl_t));
707 VERIFY_NON_NULL(TAG, acl, ERROR);
709 // Subject -- Mandatory
710 memcpy(&(acl->subject), &WILDCARD_SUBJECT_ID, sizeof(acl->subject));
712 // Resources -- Mandatory
713 acl->resourcesLen = sizeof(rsrcs)/sizeof(rsrcs[0]);
715 acl->resources = (char**)OICCalloc(acl->resourcesLen, sizeof(char*));
716 VERIFY_NON_NULL(TAG, (acl->resources), ERROR);
718 for (size_t i = 0; i < acl->resourcesLen; i++)
720 size_t len = strlen(rsrcs[i]) + 1;
721 acl->resources[i] = (char*)OICMalloc(len * sizeof(char));
722 VERIFY_NON_NULL(TAG, (acl->resources[i]), ERROR);
723 OICStrcpy(acl->resources[i], len, rsrcs[i]);
726 acl->permission = PERMISSION_READ;
729 acl->recurrences = NULL;
731 // Device ID is the owner of this default ACL
732 ret = GetDoxmDeviceID( &ownerId);
733 VERIFY_SUCCESS(TAG, OC_STACK_OK == ret, FATAL);
736 acl->owners = (OicUuid_t*)OICMalloc(sizeof(OicUuid_t));
737 VERIFY_NON_NULL(TAG, (acl->owners), ERROR);
738 memcpy(acl->owners, &ownerId, sizeof(OicUuid_t));
747 if (ret != OC_STACK_OK)
757 * Initialize ACL resource by loading data from persistent storage.
759 * @retval OC_STACK_OK for Success, otherwise some error value
761 OCStackResult InitACLResource()
763 OCStackResult ret = OC_STACK_ERROR;
765 // Read ACL resource from PS
766 char* jsonSVRDatabase = GetSVRDatabase();
770 // Convert JSON ACL into binary format
771 gAcl = JSONToAclBin(jsonSVRDatabase);
772 OICFree(jsonSVRDatabase);
775 * If SVR database in persistent storage got corrupted or
776 * is not available for some reason, a default ACL is created
777 * which allows user to initiate ACL provisioning again.
779 if (!jsonSVRDatabase || !gAcl)
781 GetDefaultACL(&gAcl);
782 // TODO Needs to update persistent storage
784 VERIFY_NON_NULL(TAG, gAcl, FATAL);
786 // Instantiate 'oic.sec.acl'
787 ret = CreateACLResource();
790 if (OC_STACK_OK != ret)
798 * Perform cleanup for ACL resources.
802 void DeInitACLResource()
804 OCDeleteResource(gAclHandle);
812 * This method is used by PolicyEngine to retrieve ACL for a Subject.
814 * @param subjectId ID of the subject for which ACL is required.
815 * @param savePtr is used internally by @ref GetACLResourceData to maintain index between
816 * successive calls for same subjectId.
818 * @retval reference to @ref OicSecAcl_t if ACL is found, else NULL
820 * @note On the first call to @ref GetACLResourceData, savePtr should point to NULL
822 const OicSecAcl_t* GetACLResourceData(const OicUuid_t* subjectId, OicSecAcl_t **savePtr)
824 OicSecAcl_t *acl = NULL;
825 OicSecAcl_t *begin = NULL;
827 if ( NULL == subjectId)
833 * savePtr MUST point to NULL if this is the 'first' call to retrieve ACL for
836 if (NULL == *savePtr)
843 * If this is a 'successive' call, search for location pointed by
844 * savePtr and assign 'begin' to the next ACL after it in the linked
845 * list and start searching from there.
847 LL_FOREACH(gAcl, acl)
856 // Find the next ACL corresponding to the 'subjectID' and return it.
857 LL_FOREACH(begin, acl)
859 if (memcmp(&(acl->subject), subjectId, sizeof(OicUuid_t)) == 0)
866 // Cleanup in case no ACL is found