|
25 | 25 |
|
26 | 26 | #include <fcntl.h> |
27 | 27 | #include <malloc.h> |
| 28 | +#include <libgen.h> |
28 | 29 | #include <sys/mman.h> |
29 | 30 | #include <sys/prctl.h> |
30 | 31 |
|
@@ -1408,6 +1409,95 @@ int bus_kernel_open_bus_fd(const char *bus, char **path) { |
1408 | 1409 | return fd; |
1409 | 1410 | } |
1410 | 1411 |
|
| 1412 | +int bus_kernel_create_endpoint(const char *bus_name, const char *ep_name, char **ep_path) { |
| 1413 | + _cleanup_free_ char *path; |
| 1414 | + struct kdbus_cmd_make *make; |
| 1415 | + struct kdbus_item *n; |
| 1416 | + size_t size; |
| 1417 | + int fd; |
| 1418 | + |
| 1419 | + fd = bus_kernel_open_bus_fd(bus_name, &path); |
| 1420 | + if (fd < 0) |
| 1421 | + return fd; |
| 1422 | + |
| 1423 | + size = ALIGN8(offsetof(struct kdbus_cmd_make, items)); |
| 1424 | + size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(ep_name) + 1); |
| 1425 | + |
| 1426 | + make = alloca0(size); |
| 1427 | + make->size = size; |
| 1428 | + make->flags = KDBUS_MAKE_ACCESS_WORLD; |
| 1429 | + |
| 1430 | + n = make->items; |
| 1431 | + |
| 1432 | + n->type = KDBUS_ITEM_MAKE_NAME; |
| 1433 | + n->size = offsetof(struct kdbus_item, str) + strlen(ep_name) + 1; |
| 1434 | + strcpy(n->str, ep_name); |
| 1435 | + |
| 1436 | + if (ioctl(fd, KDBUS_CMD_EP_MAKE, make) < 0) { |
| 1437 | + safe_close(fd); |
| 1438 | + return -errno; |
| 1439 | + } |
| 1440 | + |
| 1441 | + /* The higher 32bit of the flags field are considered |
| 1442 | + * 'incompatible flags'. Refuse them all for now. */ |
| 1443 | + if (make->flags > 0xFFFFFFFFULL) { |
| 1444 | + safe_close(fd); |
| 1445 | + return -ENOTSUP; |
| 1446 | + } |
| 1447 | + |
| 1448 | + if (ep_path) { |
| 1449 | + asprintf(ep_path, "%s/%s", dirname(path), ep_name); |
| 1450 | + if (!*ep_path) |
| 1451 | + return -ENOMEM; |
| 1452 | + } |
| 1453 | + |
| 1454 | + return fd; |
| 1455 | +} |
| 1456 | + |
| 1457 | +int bus_kernel_set_endpoint_policy(int fd, uid_t uid, BusEndpoint *ep) { |
| 1458 | + |
| 1459 | + struct kdbus_cmd_update *update; |
| 1460 | + struct kdbus_item *n; |
| 1461 | + BusEndpointPolicy *po; |
| 1462 | + Iterator i; |
| 1463 | + size_t size; |
| 1464 | + int r; |
| 1465 | + |
| 1466 | + size = ALIGN8(offsetof(struct kdbus_cmd_update, items)); |
| 1467 | + |
| 1468 | + HASHMAP_FOREACH(po, ep->policy_hash, i) { |
| 1469 | + size += ALIGN8(offsetof(struct kdbus_item, str) + strlen(po->name) + 1); |
| 1470 | + size += ALIGN8(offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access)); |
| 1471 | + } |
| 1472 | + |
| 1473 | + update = alloca0(size); |
| 1474 | + update->size = size; |
| 1475 | + |
| 1476 | + n = update->items; |
| 1477 | + |
| 1478 | + HASHMAP_FOREACH(po, ep->policy_hash, i) { |
| 1479 | + n->type = KDBUS_ITEM_NAME; |
| 1480 | + n->size = offsetof(struct kdbus_item, str) + strlen(po->name) + 1; |
| 1481 | + strcpy(n->str, po->name); |
| 1482 | + n = KDBUS_ITEM_NEXT(n); |
| 1483 | + |
| 1484 | + n->type = KDBUS_ITEM_POLICY_ACCESS; |
| 1485 | + n->size = offsetof(struct kdbus_item, policy_access) + sizeof(struct kdbus_policy_access); |
| 1486 | + |
| 1487 | + n->policy_access.type = KDBUS_POLICY_ACCESS_USER; |
| 1488 | + n->policy_access.access = bus_kernel_translate_access(po->access); |
| 1489 | + n->policy_access.id = uid; |
| 1490 | + |
| 1491 | + n = KDBUS_ITEM_NEXT(n); |
| 1492 | + } |
| 1493 | + |
| 1494 | + r = ioctl(fd, KDBUS_CMD_EP_UPDATE, update); |
| 1495 | + if (r < 0) |
| 1496 | + return -errno; |
| 1497 | + |
| 1498 | + return 0; |
| 1499 | +} |
| 1500 | + |
1411 | 1501 | int bus_kernel_make_starter( |
1412 | 1502 | int fd, |
1413 | 1503 | const char *name, |
|
0 commit comments