static void test_condition_test_host(void) {
        Condition *condition;
        sd_id128_t id;
        int r;
        char sid[SD_ID128_STRING_MAX];
        _cleanup_free_ char *hostname = NULL;

        r = sd_id128_get_machine(&id);
        assert_se(r >= 0);
        assert_se(sd_id128_to_string(id, sid));

        condition = condition_new(CONDITION_HOST, sid, false, false);
        assert_se(condition_test(condition));
        condition_free(condition);

        condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false);
        assert_se(!condition_test(condition));
        condition_free(condition);

        condition = condition_new(CONDITION_HOST, sid, false, true);
        assert_se(!condition_test(condition));
        condition_free(condition);

        hostname = gethostname_malloc();
        assert_se(hostname);

        condition = condition_new(CONDITION_HOST, hostname, false, false);
        assert_se(condition_test(condition));
        condition_free(condition);
}
Beispiel #2
0
static int context_read_data(Context *c) {
        int r;
        struct utsname u;

        assert(c);

        context_reset(c);

        assert_se(uname(&u) >= 0);
        c->data[PROP_KERNEL_NAME] = strdup(u.sysname);
        c->data[PROP_KERNEL_RELEASE] = strdup(u.release);
        c->data[PROP_KERNEL_VERSION] = strdup(u.version);
        if (!c->data[PROP_KERNEL_NAME] || !c->data[PROP_KERNEL_RELEASE] ||
            !c->data[PROP_KERNEL_VERSION])
                return -ENOMEM;

        c->data[PROP_HOSTNAME] = gethostname_malloc();
        if (!c->data[PROP_HOSTNAME])
                return -ENOMEM;

        r = read_etc_hostname(NULL, &c->data[PROP_STATIC_HOSTNAME]);
        if (r < 0 && r != -ENOENT)
                return r;

        r = parse_env_file(NULL, "/etc/machine-info",
                           "PRETTY_HOSTNAME", &c->data[PROP_PRETTY_HOSTNAME],
                           "ICON_NAME", &c->data[PROP_ICON_NAME],
                           "CHASSIS", &c->data[PROP_CHASSIS],
                           "DEPLOYMENT", &c->data[PROP_DEPLOYMENT],
                           "LOCATION", &c->data[PROP_LOCATION]);
        if (r < 0 && r != -ENOENT)
                return r;

        r = parse_os_release(NULL,
                             "PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME],
                             "CPE_NAME", &c->data[PROP_OS_CPE_NAME],
                             "HOME_URL", &c->data[PROP_HOME_URL],
                             NULL);
        if (r < 0 && r != -ENOENT)
                return r;

        r = id128_read("/sys/class/dmi/id/product_uuid", ID128_UUID, &c->uuid);
        if (r < 0)
                log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
                               "Failed to read product UUID, ignoring: %m");
        else if (sd_id128_is_null(c->uuid) || sd_id128_is_allf(c->uuid))
                log_debug("DMI product UUID " SD_ID128_FORMAT_STR " is all 0x00 or all 0xFF, ignoring.", SD_ID128_FORMAT_VAL(c->uuid));
        else
                c->has_uuid = true;

        return 0;
}
Beispiel #3
0
static int context_read_data(Context *c) {
        int r;
        struct utsname u;

        assert(c);

        context_reset(c);

        assert_se(uname(&u) >= 0);
        c->data[PROP_KERNEL_NAME] = strdup(u.sysname);
        c->data[PROP_KERNEL_RELEASE] = strdup(u.release);
        c->data[PROP_KERNEL_VERSION] = strdup(u.version);
        if (!c->data[PROP_KERNEL_NAME] || !c->data[PROP_KERNEL_RELEASE] ||
            !c->data[PROP_KERNEL_VERSION])
                return -ENOMEM;

        c->data[PROP_HOSTNAME] = gethostname_malloc();
        if (!c->data[PROP_HOSTNAME])
                return -ENOMEM;

        r = read_one_line_file("/etc/hostname", &c->data[PROP_STATIC_HOSTNAME]);
        if (r < 0 && r != -ENOENT)
                return r;

        r = parse_env_file("/etc/machine-info", NEWLINE,
                           "PRETTY_HOSTNAME", &c->data[PROP_PRETTY_HOSTNAME],
                           "ICON_NAME", &c->data[PROP_ICON_NAME],
                           "CHASSIS", &c->data[PROP_CHASSIS],
                           "DEPLOYMENT", &c->data[PROP_DEPLOYMENT],
                           "LOCATION", &c->data[PROP_LOCATION],
                           NULL);
        if (r < 0 && r != -ENOENT)
                return r;

        r = parse_env_file("/etc/os-release", NEWLINE,
                           "PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME],
                           "CPE_NAME", &c->data[PROP_OS_CPE_NAME],
                           NULL);
        if (r == -ENOENT) {
                r = parse_env_file("/usr/lib/os-release", NEWLINE,
                                   "PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME],
                                   "CPE_NAME", &c->data[PROP_OS_CPE_NAME],
                                   NULL);
        }

        if (r < 0 && r != -ENOENT)
                return r;

        return 0;
}
Beispiel #4
0
static int condition_test_host(Condition *c) {
        _cleanup_free_ char *h = NULL;
        sd_id128_t x, y;
        int r;

        assert(c);
        assert(c->parameter);
        assert(c->type == CONDITION_HOST);

        if (sd_id128_from_string(c->parameter, &x) >= 0) {

                r = sd_id128_get_machine(&y);
                if (r < 0)
                        return r;

                return sd_id128_equal(x, y);
        }

        h = gethostname_malloc();
        if (!h)
                return -ENOMEM;

        return fnmatch(c->parameter, h, FNM_CASEFOLD) == 0;
}
Beispiel #5
0
enum nss_status _nss_myhostname_gethostbyname4_r(
                const char *name,
                struct gaih_addrtuple **pat,
                char *buffer, size_t buflen,
                int *errnop, int *h_errnop,
                int32_t *ttlp) {

        struct gaih_addrtuple *r_tuple, *r_tuple_prev = NULL;
        _cleanup_free_ struct local_address *addresses = NULL;
        _cleanup_free_ char *hn = NULL;
        const char *canonical = NULL;
        int n_addresses = 0, lo_ifi;
        uint32_t local_address_ipv4;
        struct local_address *a;
        size_t l, idx, ms;
        char *r_name;
        unsigned n;

        assert(name);
        assert(pat);
        assert(buffer);
        assert(errnop);
        assert(h_errnop);

        if (is_localhost(name)) {
                /* We respond to 'localhost', so that /etc/hosts
                 * is optional */

                canonical = "localhost";
                local_address_ipv4 = htonl(INADDR_LOOPBACK);

        } else if (is_gateway_hostname(name)) {

                n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
                if (n_addresses <= 0) {
                        *errnop = ENOENT;
                        *h_errnop = HOST_NOT_FOUND;
                        return NSS_STATUS_NOTFOUND;
                }

                canonical = "gateway";

        } else {
                hn = gethostname_malloc();
                if (!hn) {
                        *errnop = ENOMEM;
                        *h_errnop = NO_RECOVERY;
                        return NSS_STATUS_TRYAGAIN;
                }

                /* We respond to our local host name, our our hostname suffixed with a single dot. */
                if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
                        *errnop = ENOENT;
                        *h_errnop = HOST_NOT_FOUND;
                        return NSS_STATUS_NOTFOUND;
                }

                n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
                if (n_addresses < 0)
                        n_addresses = 0;

                canonical = hn;
                local_address_ipv4 = LOCALADDRESS_IPV4;
        }

        /* If this call fails we fill in 0 as scope. Which is fine */
        lo_ifi = n_addresses <= 0 ? LOOPBACK_IFINDEX : 0;

        l = strlen(canonical);
        ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2);
        if (buflen < ms) {
                *errnop = ENOMEM;
                *h_errnop = NO_RECOVERY;
                return NSS_STATUS_TRYAGAIN;
        }

        /* First, fill in hostname */
        r_name = buffer;
        memcpy(r_name, canonical, l+1);
        idx = ALIGN(l+1);

        if (n_addresses <= 0) {
                /* Second, fill in IPv6 tuple */
                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                r_tuple->next = r_tuple_prev;
                r_tuple->name = r_name;
                r_tuple->family = AF_INET6;
                memcpy(r_tuple->addr, LOCALADDRESS_IPV6, 16);
                r_tuple->scopeid = (uint32_t) lo_ifi;

                idx += ALIGN(sizeof(struct gaih_addrtuple));
                r_tuple_prev = r_tuple;

                /* Third, fill in IPv4 tuple */
                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                r_tuple->next = r_tuple_prev;
                r_tuple->name = r_name;
                r_tuple->family = AF_INET;
                *(uint32_t*) r_tuple->addr = local_address_ipv4;
                r_tuple->scopeid = (uint32_t) lo_ifi;

                idx += ALIGN(sizeof(struct gaih_addrtuple));
                r_tuple_prev = r_tuple;
        }

        /* Fourth, fill actual addresses in, but in backwards order */
        for (a = addresses + n_addresses - 1, n = 0; (int) n < n_addresses; n++, a--) {
                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                r_tuple->next = r_tuple_prev;
                r_tuple->name = r_name;
                r_tuple->family = a->family;
                r_tuple->scopeid = a->ifindex;
                memcpy(r_tuple->addr, &a->address, 16);

                idx += ALIGN(sizeof(struct gaih_addrtuple));
                r_tuple_prev = r_tuple;
        }

        /* Verify the size matches */
        assert(idx == ms);

        /* Nscd expects us to store the first record in **pat. */
        if (*pat)
                **pat = *r_tuple_prev;
        else
                *pat = r_tuple_prev;

        if (ttlp)
                *ttlp = 0;

        /* Explicitly reset all error variables */
        *errnop = 0;
        *h_errnop = NETDB_SUCCESS;
        h_errno = 0;

        return NSS_STATUS_SUCCESS;
}
Beispiel #6
0
enum nss_status _nss_myhostname_gethostbyaddr2_r(
                const void* addr, socklen_t len,
                int af,
                struct hostent *host,
                char *buffer, size_t buflen,
                int *errnop, int *h_errnop,
                int32_t *ttlp) {

        const char *canonical = NULL, *additional = NULL;
        uint32_t local_address_ipv4 = LOCALADDRESS_IPV4;
        _cleanup_free_ struct local_address *addresses = NULL;
        _cleanup_free_ char *hn = NULL;
        int n_addresses = 0;
        struct local_address *a;
        bool additional_from_hostname = false;
        unsigned n;

        assert(addr);
        assert(host);
        assert(buffer);
        assert(errnop);
        assert(h_errnop);

        if (!IN_SET(af, AF_INET, AF_INET6)) {
                *errnop = EAFNOSUPPORT;
                *h_errnop = NO_DATA;
                return NSS_STATUS_UNAVAIL;
        }

        if (len != FAMILY_ADDRESS_SIZE(af)) {
                *errnop = EINVAL;
                *h_errnop = NO_RECOVERY;
                return NSS_STATUS_UNAVAIL;
        }

        if (af == AF_INET) {
                if ((*(uint32_t*) addr) == LOCALADDRESS_IPV4)
                        goto found;

                if ((*(uint32_t*) addr) == htonl(INADDR_LOOPBACK)) {
                        canonical = "localhost";
                        local_address_ipv4 = htonl(INADDR_LOOPBACK);
                        goto found;
                }

        } else {
                assert(af == AF_INET6);

                if (memcmp(addr, LOCALADDRESS_IPV6, 16) == 0) {
                        canonical = "localhost";
                        additional_from_hostname = true;
                        goto found;
                }
        }

        n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
        if (n_addresses > 0) {
                for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
                        if (af != a->family)
                                continue;

                        if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0)
                                goto found;
                }
        }

        addresses = mfree(addresses);

        n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
        if (n_addresses > 0) {
                for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
                        if (af != a->family)
                                continue;

                        if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0) {
                                canonical = "gateway";
                                goto found;
                        }
                }
        }

        *errnop = ENOENT;
        *h_errnop = HOST_NOT_FOUND;

        return NSS_STATUS_NOTFOUND;

found:
        if (!canonical || (!additional && additional_from_hostname)) {
                hn = gethostname_malloc();
                if (!hn) {
                        *errnop = ENOMEM;
                        *h_errnop = NO_RECOVERY;
                        return NSS_STATUS_TRYAGAIN;
                }

                if (!canonical)
                        canonical = hn;

                if (!additional && additional_from_hostname)
                        additional = hn;
        }

        return fill_in_hostent(
                        canonical, additional,
                        af,
                        addresses, n_addresses,
                        local_address_ipv4,
                        host,
                        buffer, buflen,
                        errnop, h_errnop,
                        ttlp,
                        NULL);
}
Beispiel #7
0
enum nss_status _nss_myhostname_gethostbyname3_r(
                const char *name,
                int af,
                struct hostent *host,
                char *buffer, size_t buflen,
                int *errnop, int *h_errnop,
                int32_t *ttlp,
                char **canonp) {

        _cleanup_free_ struct local_address *addresses = NULL;
        const char *canonical, *additional = NULL;
        _cleanup_free_ char *hn = NULL;
        uint32_t local_address_ipv4 = 0;
        int n_addresses = 0;

        assert(name);
        assert(host);
        assert(buffer);
        assert(errnop);
        assert(h_errnop);

        if (af == AF_UNSPEC)
                af = AF_INET;

        if (af != AF_INET && af != AF_INET6) {
                *errnop = EAFNOSUPPORT;
                *h_errnop = NO_DATA;
                return NSS_STATUS_UNAVAIL;
        }

        if (is_localhost(name)) {
                canonical = "localhost";
                local_address_ipv4 = htonl(INADDR_LOOPBACK);

        } else if (is_gateway_hostname(name)) {

                n_addresses = local_gateways(NULL, 0, af, &addresses);
                if (n_addresses <= 0) {
                        *errnop = ENOENT;
                        *h_errnop = HOST_NOT_FOUND;
                        return NSS_STATUS_NOTFOUND;
                }

                canonical = "gateway";

        } else {
                hn = gethostname_malloc();
                if (!hn) {
                        *errnop = ENOMEM;
                        *h_errnop = NO_RECOVERY;
                        return NSS_STATUS_TRYAGAIN;
                }

                if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
                        *errnop = ENOENT;
                        *h_errnop = HOST_NOT_FOUND;
                        return NSS_STATUS_NOTFOUND;
                }

                n_addresses = local_addresses(NULL, 0, af, &addresses);
                if (n_addresses < 0)
                        n_addresses = 0;

                canonical = hn;
                additional = n_addresses <= 0 && af == AF_INET6 ? "localhost" : NULL;
                local_address_ipv4 = LOCALADDRESS_IPV4;
        }

        return fill_in_hostent(
                        canonical, additional,
                        af,
                        addresses, n_addresses,
                        local_address_ipv4,
                        host,
                        buffer, buflen,
                        errnop, h_errnop,
                        ttlp,
                        canonp);
}
Beispiel #8
0
static void test_install_printf(void) {
        char    name[] = "name.service",
                path[] = "/run/systemd/system/name.service";
        UnitFileInstallInfo i = { .name = name, .path = path, };
        UnitFileInstallInfo i2 = { .name= name, .path = path, };
        char    name3[] = "*****@*****.**",
                path3[] = "/run/systemd/system/name.service";
        UnitFileInstallInfo i3 = { .name = name3, .path = path3, };
        UnitFileInstallInfo i4 = { .name = name3, .path = path3, };

        _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *uid = NULL, *user = NULL;

        assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
        assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
        assert_se((host = gethostname_malloc()));
        assert_se((user = uid_to_name(getuid())));
        assert_se(asprintf(&uid, UID_FMT, getuid()) >= 0);

#define expect(src, pattern, result)                                    \
        do {                                                            \
                _cleanup_free_ char *t = NULL;                          \
                _cleanup_free_ char                                     \
                        *d1 = strdup(i.name),                           \
                        *d2 = strdup(i.path);                           \
                assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \
                memzero(i.name, strlen(i.name));                        \
                memzero(i.path, strlen(i.path));                        \
                assert_se(d1 && d2);                                    \
                if (result) {                                           \
                        printf("%s\n", t);                              \
                        assert_se(streq(t, result));                    \
                } else assert_se(t == NULL);                            \
                strcpy(i.name, d1);                                     \
                strcpy(i.path, d2);                                     \
        } while (false)

        expect(i, "%n", "name.service");
        expect(i, "%N", "name");
        expect(i, "%p", "name");
        expect(i, "%i", "");
        expect(i, "%u", user);
        expect(i, "%U", uid);

        expect(i, "%m", mid);
        expect(i, "%b", bid);
        expect(i, "%H", host);

        expect(i2, "%u", user);
        expect(i2, "%U", uid);

        expect(i3, "%n", "*****@*****.**");
        expect(i3, "%N", "name@inst");
        expect(i3, "%p", "name");
        expect(i3, "%u", user);
        expect(i3, "%U", uid);

        expect(i3, "%m", mid);
        expect(i3, "%b", bid);
        expect(i3, "%H", host);

        expect(i4, "%u", user);
        expect(i4, "%U", uid);
}
Beispiel #9
0
int dhcp4_configure(Link *link) {
        int r;

        assert(link);
        assert(link->network);
        assert(link->network->dhcp & ADDRESS_FAMILY_IPV4);

        r = sd_dhcp_client_new(&link->dhcp_client);
        if (r < 0)
                return r;

        r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_mac(link->dhcp_client,
                                   (const uint8_t *) &link->mac,
                                   sizeof (link->mac), ARPHRD_ETHER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
                                                 link->network->dhcp_broadcast);
        if (r < 0)
                return r;

        if (link->mtu) {
                r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_mtu) {
             r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                   DHCP_OPTION_INTERFACE_MTU);
             if (r < 0)
                return r;
        }

        if (link->network->dhcp_routes) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      DHCP_OPTION_STATIC_ROUTE);
                if (r < 0)
                        return r;
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_sendhost) {
                _cleanup_free_ char *hostname = NULL;
                const char *hn = NULL;

                if (!link->network->hostname)  {
                        hostname = gethostname_malloc();
                        if (!hostname)
                                return -ENOMEM;

                        hn = hostname;
                } else
                        hn = link->network->hostname;

                if (!is_localhost(hn)) {
                        r = sd_dhcp_client_set_hostname(link->dhcp_client, hn);
                        if (r < 0)
                                return r;
                }
        }

        if (link->network->dhcp_vendor_class_identifier) {
                r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
                                                               link->network->dhcp_vendor_class_identifier);
                if (r < 0)
                        return r;
        }

        switch (link->network->dhcp_client_identifier) {
        case DHCP_CLIENT_ID_DUID:
                /* Library defaults to this. */
                break;
        case DHCP_CLIENT_ID_MAC:
                r = sd_dhcp_client_set_client_id(link->dhcp_client,
                                                 ARPHRD_ETHER,
                                                 (const uint8_t *) &link->mac,
                                                 sizeof (link->mac));
                if (r < 0)
                        return r;
                break;
        default:
                assert_not_reached("Unknown client identifier type.");
        }

        return 0;
}
Beispiel #10
0
static int test_unit_printf(void) {
        Manager *m;
        Unit *u, *u2;
        int r;

        _cleanup_free_ char *mid, *bid, *host, *root_uid;
        struct passwd *root;

        assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
        assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
        assert_se((host = gethostname_malloc()));

        assert_se((root = getpwnam("root")));
        assert_se(asprintf(&root_uid, "%d", (int) root->pw_uid) > 0);

        r = manager_new(SYSTEMD_USER, &m);
        if (r == -EPERM || r == -EACCES || r == -EADDRINUSE) {
                puts("manager_new: Permission denied. Skipping test.");
                return EXIT_TEST_SKIP;
        }
        assert(r == 0);

#define expect(unit, pattern, expected)                                 \
        {                                                               \
                char *e;                                                \
                _cleanup_free_ char *t;                                 \
                assert_se(unit_full_printf(unit, pattern, &t) >= 0);    \
                printf("result: %s\nexpect: %s\n", t, expected);        \
                if ((e = endswith(expected, "*")))                      \
                        assert(strncmp(t, e, e-expected));              \
                else                                                    \
                        assert(streq(t, expected));                     \
        }

        assert_se(setenv("USER", "root", 1) == 0);
        assert_se(setenv("HOME", "/root", 1) == 0);

        assert_se(u = unit_new(m, sizeof(Service)));
        assert_se(unit_add_name(u, "blah.service") == 0);
        assert_se(unit_add_name(u, "blah.service") == 0);

        /* general tests */
        expect(u, "%%", "%");
        expect(u, "%%s", "%s");
        expect(u, "%", "");    // REALLY?

        /* normal unit */
        expect(u, "%n", "blah.service");
        expect(u, "%N", "blah");
        expect(u, "%p", "blah");
        expect(u, "%P", "blah");
        expect(u, "%i", "");
        expect(u, "%I", "");
        expect(u, "%u", root->pw_name);
        expect(u, "%U", root_uid);
        expect(u, "%h", root->pw_dir);
        expect(u, "%s", "/bin/sh");
        expect(u, "%m", mid);
        expect(u, "%b", bid);
        expect(u, "%H", host);
        expect(u, "%t", "/run/user/*");

        /* templated */
        assert_se(u2 = unit_new(m, sizeof(Service)));
        assert_se(unit_add_name(u2, "*****@*****.**") == 0);
        assert_se(unit_add_name(u2, "*****@*****.**") == 0);

        expect(u2, "%n", "*****@*****.**");
        expect(u2, "%N", "blah@foo-foo");
        expect(u2, "%p", "blah");
        expect(u2, "%P", "blah");
        expect(u2, "%i", "foo-foo");
        expect(u2, "%I", "foo/foo");
        expect(u2, "%u", root->pw_name);
        expect(u2, "%U", root_uid);
        expect(u2, "%h", root->pw_dir);
        expect(u2, "%s", "/bin/sh");
        expect(u2, "%m", mid);
        expect(u2, "%b", bid);
        expect(u2, "%H", host);
        expect(u2, "%t", "/run/user/*");

        manager_free(m);

        return 0;
}
Beispiel #11
0
static void test_install_printf(void) {
        char    name[] = "name.service",
                path[] = "/run/systemd/system/name.service",
                user[] = "xxxx-no-such-user";
        InstallInfo i = {name, path, user};
        InstallInfo i2 = {name, path, NULL};
        char    name3[] = "*****@*****.**",
                path3[] = "/run/systemd/system/name.service";
        InstallInfo i3 = {name3, path3, user};
        InstallInfo i4 = {name3, path3, NULL};

        _cleanup_free_ char *mid, *bid, *host;

        assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
        assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
        assert_se((host = gethostname_malloc()));

#define expect(src, pattern, result)                                    \
        do {                                                            \
                _cleanup_free_ char *t = NULL;                          \
                _cleanup_free_ char                                     \
                        *d1 = strdup(i.name),                           \
                        *d2 = strdup(i.path),                           \
                        *d3 = strdup(i.user);                           \
                assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \
                memzero(i.name, strlen(i.name));                        \
                memzero(i.path, strlen(i.path));                        \
                memzero(i.user, strlen(i.user));                        \
                assert_se(d1 && d2 && d3);                                 \
                if (result) {                                           \
                        printf("%s\n", t);                              \
                        assert_se(streq(t, result));                       \
                } else assert_se(t == NULL);                               \
                strcpy(i.name, d1);                                     \
                strcpy(i.path, d2);                                     \
                strcpy(i.user, d3);                                     \
        } while(false)

        assert_se(setenv("USER", "root", 1) == 0);

        expect(i, "%n", "name.service");
        expect(i, "%N", "name");
        expect(i, "%p", "name");
        expect(i, "%i", "");
        expect(i, "%u", "xxxx-no-such-user");

        DISABLE_WARNING_NONNULL;
        expect(i, "%U", NULL);
        REENABLE_WARNING;

        expect(i, "%m", mid);
        expect(i, "%b", bid);
        expect(i, "%H", host);

        expect(i2, "%u", "root");
        expect(i2, "%U", "0");

        expect(i3, "%n", "*****@*****.**");
        expect(i3, "%N", "name@inst");
        expect(i3, "%p", "name");
        expect(i3, "%u", "xxxx-no-such-user");

        DISABLE_WARNING_NONNULL;
        expect(i3, "%U", NULL);
        REENABLE_WARNING;

        expect(i3, "%m", mid);
        expect(i3, "%b", bid);
        expect(i3, "%H", host);

        expect(i4, "%u", "root");
        expect(i4, "%U", "0");
}
Beispiel #12
0
int dhcp4_configure(Link *link) {
        int r;

        assert(link);
        assert(link->network);
        assert(link->network->dhcp & ADDRESS_FAMILY_IPV4);

        if (!link->dhcp_client) {
                r = sd_dhcp_client_new(&link->dhcp_client);
                if (r < 0)
                        return r;
        }

        r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_mac(link->dhcp_client,
                                   (const uint8_t *) &link->mac,
                                   sizeof (link->mac), ARPHRD_ETHER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
                                                 link->network->dhcp_broadcast);
        if (r < 0)
                return r;

        if (link->mtu) {
                r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_use_mtu) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_INTERFACE_MTU);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_use_routes) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_STATIC_ROUTE);
                if (r < 0)
                        return r;
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
                if (r < 0)
                        return r;
        }

        /* Always acquire the timezone and NTP */
        r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE);
        if (r < 0)
                return r;

        if (link->network->dhcp_send_hostname) {
                _cleanup_free_ char *hostname = NULL;
                const char *hn = NULL;

                if (!link->network->dhcp_hostname) {
                        hostname = gethostname_malloc();
                        if (!hostname)
                                return -ENOMEM;

                        hn = hostname;
                } else
                        hn = link->network->dhcp_hostname;

                if (!is_localhost(hn)) {
                        r = sd_dhcp_client_set_hostname(link->dhcp_client, hn);
                        if (r < 0)
                                return r;
                }
        }

        if (link->network->dhcp_vendor_class_identifier) {
                r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
                                                               link->network->dhcp_vendor_class_identifier);
                if (r < 0)
                        return r;
        }

        switch (link->network->dhcp_client_identifier) {
        case DHCP_CLIENT_ID_DUID:
                /* If configured, apply user specified DUID and/or IAID */
                r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
                                                 link->network->iaid_value,
                                                 link->manager->dhcp_duid_len,
                                                 &link->manager->dhcp_duid);
                if (r < 0)
                        return r;
                break;
        case DHCP_CLIENT_ID_MAC:
                r = sd_dhcp_client_set_client_id(link->dhcp_client,
                                                 ARPHRD_ETHER,
                                                 (const uint8_t *) &link->mac,
                                                 sizeof (link->mac));
                if (r < 0)
                        return r;
                break;
        default:
                assert_not_reached("Unknown client identifier type.");
        }

        return 0;
}
Beispiel #13
0
int dhcp4_configure(Link *link) {
        int r;

        assert(link);
        assert(link->network);
        assert(IN_SET(link->network->dhcp, DHCP_SUPPORT_BOTH, DHCP_SUPPORT_V4));

        r = sd_dhcp_client_new(&link->dhcp_client);
        if (r < 0)
                return r;

        r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_mac(link->dhcp_client,
                                   (const uint8_t *) &link->mac,
                                   sizeof (link->mac), ARPHRD_ETHER);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link);
        if (r < 0)
                return r;

        r = sd_dhcp_client_set_request_broadcast(link->dhcp_client,
                                                 link->network->dhcp_broadcast);
        if (r < 0)
                return r;

        if (link->mtu) {
                r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu);
                if (r < 0)
                        return r;
        }

        if (link->network->dhcp_mtu) {
             r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                   DHCP_OPTION_INTERFACE_MTU);
             if (r < 0)
                return r;
        }

        if (link->network->dhcp_routes) {
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      DHCP_OPTION_STATIC_ROUTE);
                if (r < 0)
                        return r;
                r = sd_dhcp_client_set_request_option(link->dhcp_client,
                                                      DHCP_OPTION_CLASSLESS_STATIC_ROUTE);
                        if (r < 0)
                                return r;
        }

        if (link->network->dhcp_sendhost) {
                _cleanup_free_ char *hostname = NULL;

                hostname = gethostname_malloc();
                if (!hostname)
                        return -ENOMEM;

                if (!is_localhost(hostname)) {
                        r = sd_dhcp_client_set_hostname(link->dhcp_client,
                                                        hostname);
                        if (r < 0)
                                return r;
                }
        }

        if (link->network->dhcp_vendor_class_identifier) {
                r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client,
                                                               link->network->dhcp_vendor_class_identifier);
                if (r < 0)
                        return r;
        }

        return 0;
}
Beispiel #14
0
enum nss_status _nss_myhostname_gethostbyname4_r(
                const char *name,
                struct gaih_addrtuple **pat,
                char *buffer, size_t buflen,
                int *errnop, int *h_errnop,
                int32_t *ttlp) {

        struct gaih_addrtuple *r_tuple, *r_tuple_prev = NULL;
        _cleanup_free_ struct local_address *addresses = NULL;
        _cleanup_free_ char *hn = NULL;
        const char *canonical = NULL;
        int n_addresses = 0;
        uint32_t local_address_ipv4;
        struct local_address *a;
        size_t l, idx, ms;
        char *r_name;
        unsigned n;

        PROTECT_ERRNO;
        BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);

        assert(name);
        assert(pat);
        assert(buffer);
        assert(errnop);
        assert(h_errnop);

        if (is_localhost(name)) {
                /* We respond to 'localhost', so that /etc/hosts
                 * is optional */

                canonical = "localhost";
                local_address_ipv4 = htobe32(INADDR_LOOPBACK);

        } else if (is_gateway_hostname(name)) {

                n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
                if (n_addresses <= 0) {
                        *h_errnop = HOST_NOT_FOUND;
                        return NSS_STATUS_NOTFOUND;
                }

                canonical = "_gateway";

        } else {
                hn = gethostname_malloc();
                if (!hn) {
                        *errnop = ENOMEM;
                        *h_errnop = NO_RECOVERY;
                        return NSS_STATUS_TRYAGAIN;
                }

                /* We respond to our local host name, our hostname suffixed with a single dot. */
                if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) {
                        *h_errnop = HOST_NOT_FOUND;
                        return NSS_STATUS_NOTFOUND;
                }

                n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
                if (n_addresses < 0)
                        n_addresses = 0;

                canonical = hn;
                local_address_ipv4 = LOCALADDRESS_IPV4;
        }

        l = strlen(canonical);
        ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2);
        if (buflen < ms) {
                *errnop = ERANGE;
                *h_errnop = NETDB_INTERNAL;
                return NSS_STATUS_TRYAGAIN;
        }

        /* First, fill in hostname */
        r_name = buffer;
        memcpy(r_name, canonical, l+1);
        idx = ALIGN(l+1);

        assert(n_addresses >= 0);
        if (n_addresses == 0) {
                /* Second, fill in IPv6 tuple */
                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                r_tuple->next = r_tuple_prev;
                r_tuple->name = r_name;
                r_tuple->family = AF_INET6;
                memcpy(r_tuple->addr, LOCALADDRESS_IPV6, 16);
                r_tuple->scopeid = 0;

                idx += ALIGN(sizeof(struct gaih_addrtuple));
                r_tuple_prev = r_tuple;

                /* Third, fill in IPv4 tuple */
                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                r_tuple->next = r_tuple_prev;
                r_tuple->name = r_name;
                r_tuple->family = AF_INET;
                *(uint32_t*) r_tuple->addr = local_address_ipv4;
                r_tuple->scopeid = 0;

                idx += ALIGN(sizeof(struct gaih_addrtuple));
                r_tuple_prev = r_tuple;
        }

        /* Fourth, fill actual addresses in, but in backwards order */
        for (a = addresses + n_addresses - 1, n = 0; (int) n < n_addresses; n++, a--) {
                r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                r_tuple->next = r_tuple_prev;
                r_tuple->name = r_name;
                r_tuple->family = a->family;
                r_tuple->scopeid = a->family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&a->address.in6) ? a->ifindex : 0;
                memcpy(r_tuple->addr, &a->address, 16);

                idx += ALIGN(sizeof(struct gaih_addrtuple));
                r_tuple_prev = r_tuple;
        }

        /* Verify the size matches */
        assert(idx == ms);

        /* Nscd expects us to store the first record in **pat. */
        if (*pat)
                **pat = *r_tuple_prev;
        else
                *pat = r_tuple_prev;

        if (ttlp)
                *ttlp = 0;

        /* Explicitly reset both *h_errnop and h_errno to work around
         * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
        *h_errnop = NETDB_SUCCESS;
        h_errno = 0;

        return NSS_STATUS_SUCCESS;
}
Beispiel #15
0
static int test_unit_printf(void) {
        Manager *m = NULL;
        Unit *u, *u2;
        int r;

        _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *uid = NULL, *user = NULL, *shell = NULL, *home = NULL;

        assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
        assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
        assert_se(host = gethostname_malloc());
        assert_se(user = getusername_malloc());
        assert_se(asprintf(&uid, UID_FMT, getuid()));
        assert_se(get_home_dir(&home) >= 0);
        assert_se(get_shell(&shell) >= 0);

        r = manager_new(UNIT_FILE_USER, true, &m);
        if (r == -EPERM || r == -EACCES || r == -EADDRINUSE) {
                puts("manager_new: Permission denied. Skipping test.");
                return EXIT_TEST_SKIP;
        }
        assert_se(r == 0);

#define expect(unit, pattern, expected)                                 \
        {                                                               \
                char *e;                                                \
                _cleanup_free_ char *t = NULL;                          \
                assert_se(unit_full_printf(unit, pattern, &t) >= 0);    \
                printf("result: %s\nexpect: %s\n", t, expected);        \
                if ((e = endswith(expected, "*")))                      \
                        assert_se(strncmp(t, e, e-expected));              \
                else                                                    \
                        assert_se(streq(t, expected));                     \
        }

        assert_se(setenv("XDG_RUNTIME_DIR", "/run/user/1/", 1) == 0);

        assert_se(u = unit_new(m, sizeof(Service)));
        assert_se(unit_add_name(u, "blah.service") == 0);
        assert_se(unit_add_name(u, "blah.service") == 0);

        /* general tests */
        expect(u, "%%", "%");
        expect(u, "%%s", "%s");
        expect(u, "%", "");    // REALLY?

        /* normal unit */
        expect(u, "%n", "blah.service");
        expect(u, "%f", "/blah");
        expect(u, "%N", "blah");
        expect(u, "%p", "blah");
        expect(u, "%P", "blah");
        expect(u, "%i", "");
        expect(u, "%u", user);
        expect(u, "%U", uid);
        expect(u, "%h", home);
        expect(u, "%m", mid);
        expect(u, "%b", bid);
        expect(u, "%H", host);
        expect(u, "%t", "/run/user/*");

        /* templated */
        assert_se(u2 = unit_new(m, sizeof(Service)));
        assert_se(unit_add_name(u2, "*****@*****.**") == 0);
        assert_se(unit_add_name(u2, "*****@*****.**") == 0);

        expect(u2, "%n", "*****@*****.**");
        expect(u2, "%N", "blah@foo-foo");
        expect(u2, "%f", "/foo/foo");
        expect(u2, "%p", "blah");
        expect(u2, "%P", "blah");
        expect(u2, "%i", "foo-foo");
        expect(u2, "%I", "foo/foo");
        expect(u2, "%u", user);
        expect(u2, "%U", uid);
        expect(u2, "%h", home);
        expect(u2, "%m", mid);
        expect(u2, "%b", bid);
        expect(u2, "%H", host);
        expect(u2, "%t", "/run/user/*");

        manager_free(m);
#undef expect

        return 0;
}