summaryrefslogtreecommitdiff
path: root/examples/polkit/libvirt-acl.rules
blob: dd6836599adb6b696d76756fb3d25a045fec12e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * This example defines two groups of roles any user/group can be assigned to.
 * An "admin" role which grants full access to all APIs on all objects to its
 * members, and other roles which allows their members to all APIs defined in
 * restrictedActions on domains matching a regular expressions assigned to
 * each role. (Jump below the Role class definition to see them.) Users who
 * belong to an "operator" role can act on any domain (matching ".*" RE),
 * while members of "userA", "userB", and "userC" roles are limited by more
 * specific REs.
 *
 * A virtualization host admin would define domains with names prefixed by
 * customer names and create a separate role for each customer restricting
 * its members to manage only domains with the corresponding prefix.
 */

function Role(name) {
    this.name = name;

    this.users = [];
    this.groups = [];

    this.check = function(subject, api, domain) {
        var validUser = false

        if (this.users.indexOf(subject.user) >= 0) {
            validUser = true;
        } else {
            for (var i = 0; i < subject.groups.length; i++) {
                if (this.groups.indexOf(subject.groups[i]) >= 0) {
                    validUser = true;
                    break;
                }
            }
        }

        if (validUser &&
            (this.name == "admin" ||
             !domain ||
             (this.domains && domain.match(this.domains)))) {
            var msg = "Access granted: " +
                      "user = " + subject.user +
                      ", groups = [" + subject.groups + "]" +
                      ", role = " + this.name +
                      ", api = " + api;
            if (domain)
                msg += ", domain = " + domain;
            polkit.log(msg);
            return true
        }

        return false;
    };
}


/* Basic operations and monitoring on a limited set of domains. */
var userA = new Role("userA");
userA.domains = /^a/;
userA.users = ["userA1", "userA2", "userA3", "multiUser"];
userA.groups = ["groupA1", "groupA2"];

var userB = new Role("userB");
userB.domains = /^b/;
userB.users = ["userB1", "userB2", "userB3", "multiUser"];
userB.groups = ["groupB1", "groupB2", "multiGroup"];

var userC = new Role("userC");
userC.domains = /^c/;
userC.users = ["userC1", "userC2", "userC3"];
userC.groups = ["groupC1", "groupC2", "multiGroup"];

/* Same as users but on any domain. */
var operator = new Role("operator");
operator.domains = /.*/;
operator.users = ["powerUser1", "powerUser2"];
operator.groups = ["powerGroup1", "powerGroup2", "powerGroup3"];

var users = [operator, userA, userB, userC];

/* Full access. */
var admin = new Role("admin");
admin.users = ["adminUser1"];
admin.groups = ["adminGroup1"];


restrictedActions = [
    "domain.core-dump",
    "domain.fs-freeze",
    "domain.fs-trim",
    "domain.getattr",
    "domain.hibernate",
    "domain.init-control",
    "domain.inject-nmi",
    "domain.open-device",
    "domain.open-graphics",
    "domain.pm-control",
    "domain.read",
    "domain.reset",
    "domain.save",
    "domain.screenshot",
    "domain.send-input",
    "domain.send-signal",
    "domain.set-password",
    "domain.set-time",
    "domain.snapshot",
    "domain.start",
    "domain.stop",
    "domain.suspend"
];

polkit.addRule(function(action, subject) {
    if (action.id.indexOf("org.libvirt.api.") != 0)
        return polkit.Result.NOT_HANDLED;

    var api = action.id.replace("org.libvirt.api.", "");
    var domain = action.lookup("domain_name");

    if (admin.check(subject, api, domain))
        return polkit.Result.YES;

    if (restrictedActions.indexOf(api) < 0)
        return polkit.Result.NOT_HANDLED;

    for (var i = 0; i < users.length; i++) {
        if (users[i].check(subject, api, domain))
            return polkit.Result.YES;
    }

    return polkit.Result.NO;
});