Your IP : 3.128.201.71
# Copyright 2020 FELDSAM s.r.o. (www.feldhost.net)
# Copyright 2002-2023, OpenNebula Project, OpenNebula Systems
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Abstract rules of the type USER RESOURCE RIGHTS
# which are:
# USER -> #<num>
# @<num>
# ALL
# RESOURCE -> + separated list and "/{#,@,%}<num>|ALL"
# VM
# HOST
# NET
# IMAGE
# USER
# TEMPLATE
# GROUP
# DATASTORE
# CLUSTER
# DOCUMENT
# ZONE
# SECGROUP
# VDC
# VROUTER
# MARKETPLACE
# MARKETPLACEAPP
# VMGROUP
# RIGHTS -> + separated list
# USE
# MANAGE
# ADMIN
# CREATE
import re
USERS = {
"UID": 0x100000000,
"GID": 0x200000000,
"ALL": 0x400000000,
"CLUSTER": 0x800000000
}
RESOURCES = {
"VM" : 0x1000000000,
"HOST": 0x2000000000,
"NET": 0x4000000000,
"IMAGE": 0x8000000000,
"USER": 0x10000000000,
"TEMPLATE": 0x20000000000,
"GROUP": 0x40000000000,
"DATASTORE": 0x100000000000,
"CLUSTER": 0x200000000000,
"DOCUMENT": 0x400000000000,
"ZONE": 0x800000000000,
"SECGROUP": 0x1000000000000,
"VDC": 0x2000000000000,
"VROUTER": 0x4000000000000,
"MARKETPLACE": 0x8000000000000,
"MARKETPLACEAPP": 0x10000000000000,
"VMGROUP": 0x20000000000000,
"VNTEMPLATE": 0x40000000000000,
"BACKUPJOB": 0x100000000000000,
}
RIGHTS = {
"USE": 0x1, # Auth. to use an object
"MANAGE": 0x2, # Auth. to perform management actions
"ADMIN": 0x4, # Auth. to perform administrative actions
"CREATE": 0x8 # Auth. to create an object
}
class OneAcl():
# Converts a string in the form [#<id>, @<id>, *] to a hex. number
#
# @param users [String] Users component string
#
# @return [String] A string containing a hex number
def parse_users(self, users):
return hex(self.calculate_ids(users))
# Converts a resources string to a hex. number
#
# @param resources [String] Resources component string
#
# @return [String] A string containing a hex number
def parse_resources(self, resources):
ret = 0
resources = resources.split("/")
if len(resources) != 2:
raise Exception("Resource '{}' malformed".format("/".join(resources)))
res = resources[0].split("+")
for resource in res:
if not resource.upper() in RESOURCES:
raise Exception("Resource '{}' does not exist".format(resource))
ret += RESOURCES[resource.upper()]
ret += self.calculate_ids(resources[1])
return hex(ret)
# Converts a rights string to a hex. number
#
# @param rights [String] Rights component string
#
# @return [String] A string containing a hex number
def parse_rights(self, rights):
ret = 0
rights = rights.split("+")
for right in rights:
if not right.upper() in RIGHTS:
raise Exception("Right '{}' does not exist".format(right))
ret += RIGHTS[right.upper()]
return hex(ret)
# Converts a string in the form [#<id>, *] to a hex. number
#
# @param zone [String] Zone component string
#
# @return [String] A string containing a hex number
def parse_zone(self, zone):
return hex(self.calculate_ids(zone))
# Parses a rule string, e.g. "#5 HOST+VM/@12 INFO+CREATE+DELETE #0"
#
# @param rule_str [String] an ACL rule in string format
#
# @return Tuple an Tuple containing 3(4) strings (hex 64b numbers)
def parse_rule(self, rule_str):
ret = []
rule_str = rule_str.split(" ")
if len(rule_str) != 3 and len(rule_str) != 4:
raise Exception("String needs three or four components: User, Resource, Rights [,Zone]")
ret.append(self.parse_users(rule_str[0]))
ret.append(self.parse_resources(rule_str[1]))
ret.append(self.parse_rights(rule_str[2]))
if len(rule_str) == 3:
return ret[0], ret[1], ret[2]
ret.append(self.parse_zone(rule_str[3]))
return ret[0], ret[1], ret[2], ret[3]
# Calculates the numeric value for a String containing an individual
# (#<id>), group (@<id>) or all (*) ID component
#
# @param id_str [String] Rule Id string
#
# @return [Integer] the numeric value for the given id_str
def calculate_ids(self, id_str):
if not re.match('^([\#@\%]\d+|\*)$', id_str):
raise Exception("ID string '{}' malformed".format(id_str))
users_value = 0
if id_str[0] == "#":
value = USERS["UID"]
users_value = int(id_str[1:]) + value
if id_str[0] == "@":
value = USERS["GID"]
users_value = int(id_str[1:]) + value
if id_str[0] == "*":
users_value = USERS["ALL"]
if id_str[0] == "%":
value = USERS["CLUSTER"]
users_value = int(id_str[1:]) + value
return users_value