1#!/usr/bin/env python3 2# 3# Copyright (C) 2012-2019 Red Hat, Inc. 4# 5# This library is free software; you can redistribute it and/or 6# modify it under the terms of the GNU Lesser General Public 7# License as published by the Free Software Foundation; either 8# version 2.1 of the License, or (at your option) any later version. 9# 10# This library is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13# Lesser General Public License for more details. 14# 15# You should have received a copy of the GNU Lesser General Public 16# License along with this library. If not, see 17# <http://www.gnu.org/licenses/>. 18# 19 20import re 21import sys 22 23objects = [ 24 "CONNECT", "DOMAIN", "INTERFACE", "NETWORK_PORT", 25 "NETWORK", "NODE_DEVICE", "NWFILTER_BINDING", 26 "NWFILTER", "SECRET", "STORAGE_POOL", "STORAGE_VOL", 27] 28 29objectstr = "|".join(objects) 30 31# Data we're going to be generating looks like this 32# 33# <policyconfig> 34# <action id="org.libvirt.unix.monitor"> 35# <description>Monitor local virtualized systems</description> 36# <message>System policy prevents monitoring of 37# local virtualized systems</message> 38# <defaults> 39# <allow_any>yes</allow_any> 40# <allow_inactive>yes</allow_inactive> 41# <allow_active>yes</allow_active> 42# </defaults> 43# </action> 44# ...more <action> rules... 45# </policyconfig> 46 47opts = {} 48in_opts = False 49 50perms = {} 51 52aclfile = sys.argv[1] 53with open(aclfile, "r") as fh: 54 for line in fh: 55 if in_opts: 56 if "*/" in line: 57 in_opts = False 58 else: 59 m = re.search(r'''\*\s*\@(\w+):\s*(.*?)\s*$''', line) 60 if m is not None: 61 opts[m.group(1)] = m.group(2) 62 elif "**" in line: 63 in_opts = True 64 else: 65 m = re.search(r'''VIR_ACCESS_PERM_(%s)_((?:\w|_)+),''' % 66 objectstr, line) 67 if m is not None: 68 obj = m.group(1).lower() 69 perm = m.group(2).lower() 70 if perm == "last": 71 continue 72 73 obj = obj.replace("_", "-") 74 perm = perm.replace("_", "-") 75 76 if obj not in perms: 77 perms[obj] = {} 78 perms[obj][perm] = { 79 "desc": opts.get("desc", None), 80 "message": opts.get("message", None), 81 "anonymous": opts.get("anonymous", None), 82 } 83 opts = {} 84 85print('<?xml version="1.0" encoding="UTF-8"?>') 86print('<!DOCTYPE policyconfig PUBLIC ' + 87 '"-//freedesktop//DTD polkit Policy Configuration 1.0//EN"') 88print(' "http://www.freedesktop.org/software/polkit/policyconfig-1.dtd">') 89print('<policyconfig>') 90print(' <vendor>Libvirt Project</vendor>') 91print(' <vendor_url>https://libvirt.org</vendor_url>') 92 93for obj in sorted(perms.keys()): 94 for perm in sorted(perms[obj].keys()): 95 description = perms[obj][perm]["desc"] 96 message = perms[obj][perm]["message"] 97 anonymous = perms[obj][perm]["anonymous"] 98 99 if description is None: 100 raise Exception("missing description for %s.%s" % (obj, perm)) 101 if message is None: 102 raise Exception("missing message for %s.%s" % (obj, perm)) 103 104 allow_any = "no" 105 if anonymous: 106 allow_any = "yes" 107 allow_inactive = allow_any 108 allow_active = allow_any 109 110 print(' <action id="org.libvirt.api.%s.%s">' % (obj, perm)) 111 print(' <description>%s</description>' % description) 112 print(' <message>%s</message>' % message) 113 print(' <defaults>') 114 print(' <allow_any>%s</allow_any>' % allow_any) 115 print(' <allow_inactive>%s</allow_inactive>' % allow_inactive) 116 print(' <allow_active>%s</allow_active>' % allow_active) 117 print(' </defaults>') 118 print(' </action>') 119 120print('</policyconfig>') 121