1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * manage device node user ACL
4  */
5 
6 #include <errno.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <sys/stat.h>
10 
11 #include "sd-login.h"
12 
13 #include "device-util.h"
14 #include "devnode-acl.h"
15 #include "login-util.h"
16 #include "log.h"
17 #include "udev-builtin.h"
18 
builtin_uaccess(sd_device * dev,sd_netlink ** rtnl,int argc,char * argv[],bool test)19 static int builtin_uaccess(sd_device *dev, sd_netlink **rtnl, int argc, char *argv[], bool test) {
20         const char *path = NULL, *seat;
21         bool changed_acl = false;
22         uid_t uid;
23         int r;
24 
25         umask(0022);
26 
27         /* don't muck around with ACLs when the system is not running systemd */
28         if (!logind_running())
29                 return 0;
30 
31         r = sd_device_get_devname(dev, &path);
32         if (r < 0) {
33                 log_device_error_errno(dev, r, "Failed to get device name: %m");
34                 goto finish;
35         }
36 
37         if (sd_device_get_property_value(dev, "ID_SEAT", &seat) < 0)
38                 seat = "seat0";
39 
40         r = sd_seat_get_active(seat, NULL, &uid);
41         if (r < 0) {
42                 if (IN_SET(r, -ENXIO, -ENODATA))
43                         /* No active session on this seat */
44                         r = 0;
45                 else
46                         log_device_error_errno(dev, r, "Failed to determine active user on seat %s: %m", seat);
47 
48                 goto finish;
49         }
50 
51         r = devnode_acl(path, true, false, 0, true, uid);
52         if (r < 0) {
53                 log_device_full_errno(dev, r == -ENOENT ? LOG_DEBUG : LOG_ERR, r, "Failed to apply ACL: %m");
54                 goto finish;
55         }
56 
57         changed_acl = true;
58         r = 0;
59 
60 finish:
61         if (path && !changed_acl) {
62                 int k;
63 
64                 /* Better be safe than sorry and reset ACL */
65                 k = devnode_acl(path, true, false, 0, false, 0);
66                 if (k < 0) {
67                         log_device_full_errno(dev, k == -ENOENT ? LOG_DEBUG : LOG_ERR, k, "Failed to apply ACL: %m");
68                         if (r >= 0)
69                                 r = k;
70                 }
71         }
72 
73         return r;
74 }
75 
76 const UdevBuiltin udev_builtin_uaccess = {
77         .name = "uaccess",
78         .cmd = builtin_uaccess,
79         .help = "Manage device node user ACL",
80 };
81