Browse Source

server_history_update: Add access control to alter historical data.

Peter Rustler 6 years ago
parent
commit
a4c968f4c6

+ 15 - 0
include/ua_plugin_access_control.h

@@ -89,6 +89,21 @@ struct UA_AccessControl {
     UA_Boolean (*allowDeleteReference)(UA_Server *server, UA_AccessControl *ac,
                                        const UA_NodeId *sessionId, void *sessionContext,
                                        const UA_DeleteReferencesItem *item);
+
+    /* Allow insert,replace,update of historical data */
+    UA_Boolean (*allowHistoryUpdateUpdateData)(UA_Server *server, UA_AccessControl *ac,
+                                               const UA_NodeId *sessionId, void *sessionContext,
+                                               const UA_NodeId *nodeId,
+                                               UA_PerformUpdateType performInsertReplace,
+                                               const UA_DataValue *value);
+
+    /* Allow delete of historical data */
+    UA_Boolean (*allowHistoryUpdateDeleteRawModified)(UA_Server *server, UA_AccessControl *ac,
+                                                      const UA_NodeId *sessionId, void *sessionContext,
+                                                      const UA_NodeId *nodeId,
+                                                      UA_DateTime startTimestamp,
+                                                      UA_DateTime endTimestamp,
+                                                      bool isDeleteModified);
 };
 
 _UA_END_DECLS

+ 17 - 0
include/ua_server.h

@@ -1291,6 +1291,23 @@ UA_StatusCode UA_EXPORT
 UA_Server_getNamespaceByName(UA_Server *server, const UA_String namespaceUri,
                              size_t* foundIndex);
 
+#ifdef UA_ENABLE_HISTORIZING
+UA_Boolean UA_EXPORT
+UA_Server_AccessControl_allowHistoryUpdateUpdateData(UA_Server *server,
+                                                     const UA_NodeId *sessionId, void *sessionContext,
+                                                     const UA_NodeId *nodeId,
+                                                     UA_PerformUpdateType performInsertReplace,
+                                                     const UA_DataValue *value);
+
+UA_Boolean UA_EXPORT
+UA_Server_AccessControl_allowHistoryUpdateDeleteRawModified(UA_Server *server,
+                                                            const UA_NodeId *sessionId, void *sessionContext,
+                                                            const UA_NodeId *nodeId,
+                                                            UA_DateTime startTimestamp,
+                                                            UA_DateTime endTimestamp,
+                                                            bool isDeleteModified);
+#endif // UA_ENABLE_HISTORIZING
+
 _UA_END_DECLS
 
 #endif /* UA_SERVER_H_ */

+ 21 - 0
plugins/historydata/ua_historydatabase_default.c

@@ -329,6 +329,15 @@ updateData_service_default(UA_Server *server,
     result->operationResultsSize = details->updateValuesSize;
     result->operationResults = (UA_StatusCode*)UA_Array_new(result->operationResultsSize, &UA_TYPES[UA_TYPES_STATUSCODE]);
     for (size_t i = 0; i < details->updateValuesSize; ++i) {
+        if (!UA_Server_AccessControl_allowHistoryUpdateUpdateData(server,
+                                                                  sessionId,
+                                                                  sessionContext,
+                                                                  &details->nodeId,
+                                                                  details->performInsertReplace,
+                                                                  &details->updateValues[i])) {
+            result->operationResults[i] = UA_STATUSCODE_BADUSERACCESSDENIED;
+            continue;
+        }
         switch (details->performInsertReplace) {
         case UA_PERFORMUPDATETYPE_INSERT:
             if (!setting->historizingBackend.insertDataValue) {
@@ -421,6 +430,18 @@ deleteRawModified_service_default(UA_Server *server,
         result->statusCode = UA_STATUSCODE_BADHISTORYOPERATIONUNSUPPORTED;
         return;
     }
+
+    if (!UA_Server_AccessControl_allowHistoryUpdateDeleteRawModified(server,
+                                                                     sessionId,
+                                                                     sessionContext,
+                                                                     &details->nodeId,
+                                                                     details->startTime,
+                                                                     details->endTime,
+                                                                     details->isDeleteModified)) {
+        result->statusCode = UA_STATUSCODE_BADUSERACCESSDENIED;
+        return;
+    }
+
     result->statusCode
             = setting->historizingBackend.removeDataValue(server,
                                                           setting->historizingBackend.context,

+ 22 - 0
plugins/ua_accesscontrol_default.c

@@ -167,6 +167,26 @@ allowDeleteReference_default(UA_Server *server, UA_AccessControl *ac,
     return true;
 }
 
+static UA_Boolean
+allowHistoryUpdateUpdateData_default(UA_Server *server, UA_AccessControl *ac,
+                                     const UA_NodeId *sessionId, void *sessionContext,
+                                     const UA_NodeId *nodeId,
+                                     UA_PerformUpdateType performInsertReplace,
+                                     const UA_DataValue *value) {
+    return true;
+}
+
+static UA_Boolean
+allowHistoryUpdateDeleteRawModified_default(UA_Server *server, UA_AccessControl *ac,
+                                            const UA_NodeId *sessionId, void *sessionContext,
+                                            const UA_NodeId *nodeId,
+                                            UA_DateTime startTimestamp,
+                                            UA_DateTime endTimestamp,
+                                            bool isDeleteModified) {
+    return true;
+}
+
+
 /***************************************/
 /* Create Delete Access Control Plugin */
 /***************************************/
@@ -202,6 +222,8 @@ UA_AccessControl_default(UA_AccessControl *ac,
     ac->getUserExecutableOnObject = getUserExecutableOnObject_default;
     ac->allowAddNode = allowAddNode_default;
     ac->allowAddReference = allowAddReference_default;
+    ac->allowHistoryUpdateUpdateData = allowHistoryUpdateUpdateData_default;
+    ac->allowHistoryUpdateDeleteRawModified = allowHistoryUpdateDeleteRawModified_default;
     ac->allowDeleteNode = allowDeleteNode_default;
     ac->allowDeleteReference = allowDeleteReference_default;
 

+ 37 - 0
src/server/ua_server.c

@@ -523,3 +523,40 @@ UA_Server_run(UA_Server *server, volatile UA_Boolean *running) {
     }
     return UA_Server_run_shutdown(server);
 }
+
+#ifdef UA_ENABLE_HISTORIZING
+/* Allow insert of historical data */
+UA_Boolean
+UA_Server_AccessControl_allowHistoryUpdateUpdateData(UA_Server *server,
+                                                     const UA_NodeId *sessionId, void *sessionContext,
+                                                     const UA_NodeId *nodeId,
+                                                     UA_PerformUpdateType performInsertReplace,
+                                                     const UA_DataValue *value) {
+    if(server->config.accessControl.allowHistoryUpdateUpdateData &&
+            !server->config.accessControl.allowHistoryUpdateUpdateData(server, &server->config.accessControl,
+                                                                       sessionId, sessionContext, nodeId,
+                                                                       performInsertReplace, value)) {
+        return false;
+    }
+    return true;
+}
+
+/* Allow delete of historical data */
+UA_Boolean
+UA_Server_AccessControl_allowHistoryUpdateDeleteRawModified(UA_Server *server,
+                                                            const UA_NodeId *sessionId, void *sessionContext,
+                                                            const UA_NodeId *nodeId,
+                                                            UA_DateTime startTimestamp,
+                                                            UA_DateTime endTimestamp,
+                                                            bool isDeleteModified) {
+    if(server->config.accessControl.allowHistoryUpdateDeleteRawModified &&
+            !server->config.accessControl.allowHistoryUpdateDeleteRawModified(server, &server->config.accessControl,
+                                                                              sessionId, sessionContext, nodeId,
+                                                                              startTimestamp, endTimestamp,
+                                                                              isDeleteModified)) {
+        return false;
+    }
+    return true;
+
+}
+#endif // UA_ENABLE_HISTORIZING