int link_new(Manager *m, Link **ret, int ifindex, const char *ifname) { _cleanup_(link_freep) Link *l = NULL; int r; assert(m); assert(ifindex > 0); r = hashmap_ensure_allocated(&m->links, NULL); if (r < 0) return r; r = hashmap_ensure_allocated(&m->links_by_name, &string_hash_ops); if (r < 0) return r; l = new0(Link, 1); if (!l) return -ENOMEM; l->manager = m; l->ifname = strdup(ifname); if (!l->ifname) return -ENOMEM; r = hashmap_put(m->links_by_name, l->ifname, l); if (r < 0) return r; l->ifindex = ifindex; r = hashmap_put(m->links, INT_TO_PTR(ifindex), l); if (r < 0) return r; if (ret) *ret = l; l = NULL; return 0; }
int raw_import_new( RawImport **ret, sd_event *event, const char *image_root, RawImportFinished on_finished, void *userdata) { _cleanup_(raw_import_unrefp) RawImport *i = NULL; int r; assert(ret); i = new0(RawImport, 1); if (!i) return -ENOMEM; i->input_fd = i->output_fd = -1; i->on_finished = on_finished; i->userdata = userdata; RATELIMIT_INIT(i->progress_rate_limit, 100 * USEC_PER_MSEC, 1); i->last_percent = (unsigned) -1; i->image_root = strdup(image_root ?: "/var/lib/machines"); if (!i->image_root) return -ENOMEM; i->grow_machine_directory = path_startswith(i->image_root, "/var/lib/machines"); if (event) i->event = sd_event_ref(event); else { r = sd_event_default(&i->event); if (r < 0) return r; } *ret = TAKE_PTR(i); return 0; }
_public_ int sd_bus_get_property_trivial( sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *error, char type, void *ptr) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; int r; bus_assert_return(bus, -EINVAL, error); bus_assert_return(isempty(interface) || interface_name_is_valid(interface), -EINVAL, error); bus_assert_return(member_name_is_valid(member), -EINVAL, error); bus_assert_return(bus_type_is_trivial(type), -EINVAL, error); bus_assert_return(ptr, -EINVAL, error); bus_assert_return(!bus_pid_changed(bus), -ECHILD, error); if (!BUS_IS_OPEN(bus->state)) { r = -ENOTCONN; goto fail; } r = sd_bus_call_method(bus, destination, path, "org.freedesktop.DBus.Properties", "Get", error, &reply, "ss", strempty(interface), member); if (r < 0) return r; r = sd_bus_message_enter_container(reply, 'v', CHAR_TO_STR(type)); if (r < 0) goto fail; r = sd_bus_message_read_basic(reply, type, ptr); if (r < 0) goto fail; return 0; fail: return sd_bus_error_set_errno(error, r); }
int dns_transaction_new(DnsTransaction **ret, DnsScope *s, DnsQuestion *q) { _cleanup_(dns_transaction_freep) DnsTransaction *t = NULL; int r; assert(ret); assert(s); assert(q); r = hashmap_ensure_allocated(&s->manager->dns_transactions, NULL); if (r < 0) return r; t = new0(DnsTransaction, 1); if (!t) return -ENOMEM; t->dns_fd = -1; t->question = dns_question_ref(q); do random_bytes(&t->id, sizeof(t->id)); while (t->id == 0 || hashmap_get(s->manager->dns_transactions, UINT_TO_PTR(t->id))); r = hashmap_put(s->manager->dns_transactions, UINT_TO_PTR(t->id), t); if (r < 0) { t->id = 0; return r; } LIST_PREPEND(transactions_by_scope, s->transactions, t); t->scope = s; if (ret) *ret = t; t = NULL; return 0; }
static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { _cleanup_(link_unrefp) Link *link = userdata; int r; assert(link); assert(!link->ipv4ll_address); r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) { log_link_error_errno(link, r, "could not set ipv4ll address: %m"); link_enter_failed(link); } else if (r >= 0) manager_rtnl_process_address(rtnl, m, link->manager); link->ipv4ll_address = true; if (link->ipv4ll_route) link_check_ready(link); return 1; }
static int start_default_target(sd_bus *bus) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; log_info("Starting default target"); /* Start these units only if we can replace base.target with it */ r = sd_bus_call_method(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartUnit", &error, NULL, "ss", "default.target", "isolate"); if (r < 0) log_error("Failed to start default target: %s", bus_error_message(&error, r)); return r; }
int link_config_ctx_new(link_config_ctx **ret) { _cleanup_(link_config_ctx_freep) link_config_ctx *ctx = NULL; if (!ret) return -EINVAL; ctx = new0(link_config_ctx, 1); if (!ctx) return -ENOMEM; LIST_HEAD_INIT(ctx->links); ctx->ethtool_fd = -1; ctx->enable_name_policy = true; *ret = ctx; ctx = NULL; return 0; }
int tar_pull_new( TarPull **ret, sd_event *event, const char *image_root, TarPullFinished on_finished, void *userdata) { _cleanup_(tar_pull_unrefp) TarPull *i = NULL; int r; assert(ret); assert(event); i = new0(TarPull, 1); if (!i) return -ENOMEM; i->on_finished = on_finished; i->userdata = userdata; i->image_root = strdup(image_root ?: "/var/lib/machines"); if (!i->image_root) return -ENOMEM; i->grow_machine_directory = path_startswith(i->image_root, "/var/lib/machines"); i->event = sd_event_ref(event); r = curl_glue_new(&i->glue, i->event); if (r < 0) return r; i->glue->on_finished = pull_job_curl_on_finished; i->glue->userdata = i; *ret = i; i = NULL; return 0; }
int address_label_configure( AddressLabel *label, Link *link, sd_netlink_message_handler_t callback, bool update) { _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; int r; assert(label); assert(link); assert(link->ifindex > 0); assert(link->manager); assert(link->manager->rtnl); r = sd_rtnl_message_new_addrlabel(link->manager->rtnl, &req, RTM_NEWADDRLABEL, link->ifindex, AF_INET6); if (r < 0) return log_error_errno(r, "Could not allocate RTM_NEWADDR message: %m"); r = sd_rtnl_message_addrlabel_set_prefixlen(req, label->prefixlen); if (r < 0) return log_error_errno(r, "Could not set prefixlen: %m"); r = sd_netlink_message_append_u32(req, IFAL_LABEL, label->label); if (r < 0) return log_error_errno(r, "Could not append IFAL_LABEL attribute: %m"); r = sd_netlink_message_append_in6_addr(req, IFA_ADDRESS, &label->in_addr.in6); if (r < 0) return log_error_errno(r, "Could not append IFA_ADDRESS attribute: %m"); r = sd_netlink_call_async(link->manager->rtnl, req, callback, link, 0, NULL); if (r < 0) return log_error_errno(r, "Could not send rtnetlink message: %m"); link_ref(link); return 0; }
_public_ int sd_bus_call_method( sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *error, sd_bus_message **reply, const char *types, ...) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; bus_assert_return(bus, -EINVAL, error); bus_assert_return(!bus_pid_changed(bus), -ECHILD, error); if (!BUS_IS_OPEN(bus->state)) { r = -ENOTCONN; goto fail; } r = sd_bus_message_new_method_call(bus, &m, destination, path, interface, member); if (r < 0) goto fail; if (!isempty(types)) { va_list ap; va_start(ap, types); r = sd_bus_message_appendv(m, types, ap); va_end(ap); if (r < 0) goto fail; } return sd_bus_call(bus, m, 0, error, reply); fail: return sd_bus_error_set_errno(error, r); }
static int dns_transaction_make_packet(DnsTransaction *t) { _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL; unsigned n, added = 0; int r; assert(t); if (t->sent) return 0; r = dns_packet_new_query(&p, t->scope->protocol, 0); if (r < 0) return r; for (n = 0; n < t->question->n_keys; n++) { r = dns_scope_good_key(t->scope, t->question->keys[n]); if (r < 0) return r; if (r == 0) continue; r = dns_packet_append_key(p, t->question->keys[n], NULL); if (r < 0) return r; added++; } if (added <= 0) return -EDOM; DNS_PACKET_HEADER(p)->qdcount = htobe16(added); DNS_PACKET_HEADER(p)->id = t->id; t->sent = p; p = NULL; return 0; }
static int kbdtbl_new_from_locale(kbdtbl **out, kbdctx *kc, const char *locale) { _cleanup_(kbdtbl_unrefp) kbdtbl *kt = NULL; assert_return(out, -EINVAL); assert_return(locale, -EINVAL); kt = new0(kbdtbl, 1); if (!kt) return -ENOMEM; kt->ref = 1; kt->xkb_compose_table = xkb_compose_table_new_from_locale(kc->xkb_context, locale, XKB_COMPOSE_COMPILE_NO_FLAGS); if (!kt->xkb_compose_table) return errno > 0 ? -errno : -EFAULT; *out = kt; kt = NULL; return 0; }
static int fix_acl(int fd, uid_t uid) { #ifdef HAVE_ACL _cleanup_(acl_freep) acl_t acl = NULL; acl_entry_t entry; acl_permset_t permset; assert(fd >= 0); if (uid <= SYSTEM_UID_MAX) return 0; /* Make sure normal users can read (but not write or delete) * their own coredumps */ acl = acl_get_fd(fd); if (!acl) return log_error_errno(errno, "Failed to get ACL: %m"); if (acl_create_entry(&acl, &entry) < 0 || acl_set_tag_type(entry, ACL_USER) < 0 || acl_set_qualifier(entry, &uid) < 0) { log_error_errno(errno, "Failed to patch ACL: %m"); return -errno; } if (acl_get_permset(entry, &permset) < 0 || acl_add_perm(permset, ACL_READ) < 0 || calc_acl_mask_if_needed(&acl) < 0) { log_warning_errno(errno, "Failed to patch ACL: %m"); return -errno; } if (acl_set_fd(fd, acl) < 0) return log_error_errno(errno, "Failed to apply ACL: %m"); #endif return 0; }
static usec_t get_startup_time(Context *c) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; usec_t t = 0; int r; assert(c); r = sd_bus_get_property_trivial( c->bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UserspaceTimestamp", &error, 't', &t); if (r < 0) { log_error_errno(r, "Failed to get timestamp: %s", bus_error_message(&error, r)); return 0; } return t; }
static int method_get_product_uuid(sd_bus_message *m, void *userdata, sd_bus_error *error) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; Context *c = userdata; int interactive, r; assert(m); assert(c); if (!c->has_uuid) return sd_bus_error_set(error, BUS_ERROR_NO_PRODUCT_UUID, "Failed to read product UUID from /sys/class/dmi/id/product_uuid"); r = sd_bus_message_read(m, "b", &interactive); if (r < 0) return r; r = bus_verify_polkit_async( m, CAP_SYS_ADMIN, "org.freedesktop.hostname1.get-product-uuid", NULL, interactive, UID_INVALID, &c->polkit_registry, error); if (r < 0) return r; if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ r = sd_bus_message_new_method_return(m, &reply); if (r < 0) return r; r = sd_bus_message_append_array(reply, 'y', &c->uuid, sizeof(c->uuid)); if (r < 0) return r; return sd_bus_send(NULL, reply, NULL); }
static int setup_monitor(MonitorNetlinkGroup sender, sd_event *event, sd_device_monitor **ret) { _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL; const char *subsystem, *devtype, *tag; Iterator i; int r; r = device_monitor_new_full(&monitor, sender, -1); if (r < 0) return log_error_errno(r, "Failed to create netlink socket: %m"); (void) sd_device_monitor_set_receive_buffer_size(monitor, 128*1024*1024); r = sd_device_monitor_attach_event(monitor, event); if (r < 0) return log_error_errno(r, "Failed to attach event: %m"); HASHMAP_FOREACH_KEY(devtype, subsystem, arg_subsystem_filter, i) { r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, subsystem, devtype); if (r < 0) return log_error_errno(r, "Failed to apply subsystem filter '%s%s%s': %m", subsystem, devtype ? "/" : "", strempty(devtype)); }
static int set_timezone(sd_bus *bus, char **args, unsigned n) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; assert(args); assert(n == 2); polkit_agent_open_if_enabled(); r = sd_bus_call_method(bus, "org.freedesktop.timedate1", "/org/freedesktop/timedate1", "org.freedesktop.timedate1", "SetTimezone", &error, NULL, "sb", args[1], arg_ask_password); if (r < 0) log_error("Failed to set time zone: %s", bus_error_message(&error, -r)); return r; }
static int show_timesync_status(int argc, char **argv, void *userdata) { _cleanup_(sd_event_unrefp) sd_event *event = NULL; sd_bus *bus = userdata; int r; assert(bus); r = show_timesync_status_once(bus); if (r < 0) return r; if (!arg_monitor) return 0; r = sd_event_default(&event); if (r < 0) return log_error_errno(r, "Failed to get event loop: %m"); r = sd_bus_match_signal(bus, NULL, "org.freedesktop.timesync1", "/org/freedesktop/timesync1", "org.freedesktop.DBus.Properties", "PropertiesChanged", on_properties_changed, NULL); if (r < 0) return log_error_errno(r, "Failed to request match for PropertiesChanged signal: %m"); r = sd_bus_attach_event(bus, event, SD_EVENT_PRIORITY_NORMAL); if (r < 0) return log_error_errno(r, "Failed to attach bus to event loop: %m"); r = sd_event_loop(event); if (r < 0) return log_error_errno(r, "Failed to run event loop: %m"); return 0; }
static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, void *userdata) { _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL; ssize_t space, length; sd_lldp *lldp = userdata; struct timespec ts; assert(fd >= 0); assert(lldp); space = next_datagram_size_fd(fd); if (space < 0) return log_lldp_errno(space, "Failed to determine datagram size to read: %m"); n = lldp_neighbor_new(space); if (!n) return -ENOMEM; length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT); if (length < 0) { if (errno == EAGAIN || errno == EINTR) return 0; return log_lldp_errno(errno, "Failed to read LLDP datagram: %m"); } if ((size_t) length != n->raw_size) { log_lldp("Packet size mismatch."); return -EINVAL; } /* Try to get the timestamp of this packet if it is known */ if (ioctl(fd, SIOCGSTAMPNS, &ts) >= 0) triple_timestamp_from_realtime(&n->timestamp, timespec_load(&ts)); else triple_timestamp_get(&n->timestamp); return lldp_handle_datagram(lldp, n); }
int sysview_seat_new(sysview_seat **out, sysview_context *c, const char *name) { _cleanup_(sysview_seat_freep) sysview_seat *seat = NULL; int r; assert_return(c, -EINVAL); assert_return(name, -EINVAL); seat = new0(sysview_seat, 1); if (!seat) return -ENOMEM; seat->context = c; seat->name = strdup(name); if (!seat->name) return -ENOMEM; r = sd_bus_path_encode("/org/freedesktop/login1/seat", seat->name, &seat->path); if (r < 0) return r; seat->session_map = hashmap_new(&string_hash_ops); if (!seat->session_map) return -ENOMEM; seat->device_map = hashmap_new(&string_hash_ops); if (!seat->device_map) return -ENOMEM; r = hashmap_put(c->seat_map, seat->name, seat); if (r < 0) return r; if (out) *out = seat; seat = NULL; return 0; }
int loopback_setup(void) { _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; int r; r = sd_netlink_open(&rtnl); if (r < 0) return r; r = start_loopback(rtnl); if (r < 0) { /* If we lack the permissions to configure the * loopback device, but we find it to be already * configured, let's exit cleanly, in order to * supported unprivileged containers. */ if (r == -EPERM && check_loopback(rtnl)) return 0; return log_warning_errno(r, "Failed to configure loopback device: %m"); } return 0; }
int main(int argc, char *argv[]) { _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); log_parse_environment(); log_open(); r = parse_argv(argc, argv); if (r <= 0) goto finish; r = bus_connect_transport(arg_transport, arg_host, false, &bus); if (r < 0) { log_error_errno(r, "Failed to create bus connection: %m"); goto finish; } r = hostnamectl_main(bus, argc, argv); finish: return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }
static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { _cleanup_(link_unrefp) Link *link = userdata; int r; assert(link); r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) { log_link_error_errno(link, r, "Could not set DHCPv4 address: %m"); link_enter_failed(link); } else if (r >= 0) manager_rtnl_process_address(rtnl, m, link->manager); link_set_dhcp_routes(link); if (link->dhcp4_messages == 0) { link->dhcp4_configured = true; link_check_ready(link); } return 1; }
int parse_acl(char *text, acl_t *acl_access, acl_t *acl_default, bool want_mask) { _cleanup_free_ char **a = NULL, **d = NULL; /* strings are not be freed */ _cleanup_strv_free_ char **split; char **entry; int r = -EINVAL; _cleanup_(acl_freep) acl_t a_acl = NULL, d_acl = NULL; split = strv_split(text, ","); if (!split) return log_oom(); STRV_FOREACH(entry, split) { char *p; p = startswith(*entry, "default:"); if (!p) p = startswith(*entry, "d:"); if (p) r = strv_push(&d, p); else r = strv_push(&a, *entry); }
_public_ int sd_hwdb_new(sd_hwdb **ret) { _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL; const char *hwdb_bin_path; const char sig[] = HWDB_SIG; assert_return(ret, -EINVAL); hwdb = new0(sd_hwdb, 1); if (!hwdb) return -ENOMEM; hwdb->n_ref = REFCNT_INIT; /* find hwdb.bin in hwdb_bin_paths */ NULSTR_FOREACH(hwdb_bin_path, hwdb_bin_paths) { hwdb->f = fopen(hwdb_bin_path, "re"); if (hwdb->f) break; else if (errno == ENOENT) continue; else return log_debug_errno(errno, "Failed to open %s: %m", hwdb_bin_path); }
static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { _cleanup_(link_unrefp) Link *link = userdata; int r; assert(link); assert(link->dhcp4_messages > 0); link->dhcp4_messages--; r = sd_netlink_message_get_errno(m); if (r < 0 && r != -EEXIST) { log_link_error_errno(link, r, "Could not set DHCPv4 route: %m"); link_enter_failed(link); } if (link->dhcp4_messages == 0) { link->dhcp4_configured = true; link_check_ready(link); } return 1; }
int main(int argc, char *argv[]) { _cleanup_(sd_event_unrefp) sd_event *e; test_setup_logging(LOG_DEBUG); assert_se(sd_event_new(&e) >= 0); test_request_basic(e); test_request_anonymize(e); test_checksum(); test_discover_message(e); test_addr_acq(e); #if VALGRIND /* Make sure the async_close thread has finished. * valgrind would report some of the phread_* structures * as not cleaned up properly. */ sleep(1); #endif return 0; }
static int check_good_user(sd_bus_message *m, uid_t good_user) { _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; uid_t sender_uid; int r; assert(m); if (good_user == UID_INVALID) return 0; r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds); if (r < 0) return r; /* Don't trust augmented credentials for authorization */ assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM); r = sd_bus_creds_get_euid(creds, &sender_uid); if (r < 0) return r; return sender_uid == good_user; }
_public_ int sd_bus_call_method_async( sd_bus *bus, sd_bus_slot **slot, const char *destination, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, ...) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; int r; assert_return(bus, -EINVAL); assert_return(bus = bus_resolve(bus), -ENOPKG); assert_return(!bus_pid_changed(bus), -ECHILD); if (!BUS_IS_OPEN(bus->state)) return -ENOTCONN; r = sd_bus_message_new_method_call(bus, &m, destination, path, interface, member); if (r < 0) return r; if (!isempty(types)) { va_list ap; va_start(ap, types); r = sd_bus_message_appendv(m, types, ap); va_end(ap); if (r < 0) return r; } return sd_bus_call_async(bus, slot, m, callback, userdata, 0); }
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { _cleanup_(sd_dhcp_server_unrefp) sd_dhcp_server *server = NULL; struct in_addr address = {.s_addr = htobe32(UINT32_C(10) << 24 | UINT32_C(1))}; static const uint8_t chaddr[] = {3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3}; uint8_t *client_id; DHCPLease *lease; int pool_offset; if (size < sizeof(DHCPMessage)) return 0; assert_se(sd_dhcp_server_new(&server, 1) >= 0); server->fd = open("/dev/null", O_RDWR|O_CLOEXEC|O_NOCTTY); assert_se(server->fd >= 0); assert_se(sd_dhcp_server_configure_pool(server, &address, 24, 0, 0) >= 0); /* add a lease to the pool to expose additional code paths */ client_id = malloc(2); assert_se(client_id); client_id[0] = 2; client_id[1] = 2; lease = new0(DHCPLease, 1); assert_se(lease); lease->client_id.length = 2; lease->client_id.data = client_id; lease->address = htobe32(UINT32_C(10) << 24 | UINT32_C(2)); lease->gateway = htobe32(UINT32_C(10) << 24 | UINT32_C(1)); lease->expiration = UINT64_MAX; memcpy(lease->chaddr, chaddr, 16); pool_offset = get_pool_offset(server, lease->address); server->bound_leases[pool_offset] = lease; assert_se(hashmap_put(server->leases_by_client_id, &lease->client_id, lease) >= 0); (void) dhcp_server_handle_message(server, (DHCPMessage*)data, size); return 0; }