Esempio n. 1
0
static enum nss_status fill_in_hostent(
                const char *canonical, const char *additional,
                int af,
                struct local_address *addresses, unsigned n_addresses,
                uint32_t local_address_ipv4,
                struct hostent *result,
                char *buffer, size_t buflen,
                int *errnop, int *h_errnop,
                int32_t *ttlp,
                char **canonp) {

        size_t l_canonical, l_additional, idx, ms, alen;
        char *r_addr, *r_name, *r_aliases, *r_alias = NULL, *r_addr_list;
        struct local_address *a;
        unsigned n, c;

        assert(canonical);
        assert(result);
        assert(buffer);
        assert(errnop);
        assert(h_errnop);

        alen = FAMILY_ADDRESS_SIZE(af);

        for (a = addresses, n = 0, c = 0; n < n_addresses; a++, n++)
                if (af == a->family)
                        c++;

        l_canonical = strlen(canonical);
        l_additional = strlen_ptr(additional);
        ms = ALIGN(l_canonical+1)+
                (additional ? ALIGN(l_additional+1) : 0) +
                sizeof(char*) +
                (additional ? sizeof(char*) : 0) +
                (c > 0 ? c : 1) * ALIGN(alen) +
                (c > 0 ? c+1 : 2) * sizeof(char*);

        if (buflen < ms) {
                *errnop = ERANGE;
                *h_errnop = NETDB_INTERNAL;
                return NSS_STATUS_TRYAGAIN;
        }

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

        if (additional) {
                r_alias = buffer + idx;
                memcpy(r_alias, additional, l_additional+1);
                idx += ALIGN(l_additional+1);
        }

        /* Second, create aliases array */
        r_aliases = buffer + idx;
        if (additional) {
                ((char**) r_aliases)[0] = r_alias;
                ((char**) r_aliases)[1] = NULL;
                idx += 2*sizeof(char*);
        } else {
                ((char**) r_aliases)[0] = NULL;
                idx += sizeof(char*);
        }

        /* Third, add addresses */
        r_addr = buffer + idx;
        if (c > 0) {
                unsigned i = 0;

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

                        memcpy(r_addr + i*ALIGN(alen), &a->address, alen);
                        i++;
                }

                assert(i == c);
                idx += c*ALIGN(alen);
        } else {
                if (af == AF_INET)
                        *(uint32_t*) r_addr = local_address_ipv4;
                else
                        memcpy(r_addr, LOCALADDRESS_IPV6, 16);

                idx += ALIGN(alen);
        }

        /* Fourth, add address pointer array */
        r_addr_list = buffer + idx;
        if (c > 0) {
                unsigned i;

                for (i = 0; i < c; i++)
                        ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen);

                ((char**) r_addr_list)[i] = NULL;
                idx += (c+1) * sizeof(char*);

        } else {
                ((char**) r_addr_list)[0] = r_addr;
                ((char**) r_addr_list)[1] = NULL;
                idx += 2 * sizeof(char*);
        }

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

        result->h_name = r_name;
        result->h_aliases = (char**) r_aliases;
        result->h_addrtype = af;
        result->h_length = alen;
        result->h_addr_list = (char**) r_addr_list;

        if (ttlp)
                *ttlp = 0;

        if (canonp)
                *canonp = r_name;

        /* 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;
}
Esempio n. 2
0
static void test_strlen_ptr(void) {
        assert_se(strlen_ptr("foo") == 3);
        assert_se(strlen_ptr("") == 0);
        assert_se(strlen_ptr(NULL) == 0);
}
Esempio n. 3
0
static int stdout_stream_log(StdoutStream *s, const char *p, LineBreak line_break) {
        struct iovec *iovec;
        int priority;
        char syslog_priority[] = "PRIORITY=\0";
        char syslog_facility[sizeof("SYSLOG_FACILITY=")-1 + DECIMAL_STR_MAX(int) + 1];
        _cleanup_free_ char *message = NULL, *syslog_identifier = NULL;
        size_t n = 0, m;
        int r;

        assert(s);
        assert(p);

        if (s->context)
                (void) client_context_maybe_refresh(s->server, s->context, NULL, NULL, 0, NULL, USEC_INFINITY);
        else if (pid_is_valid(s->ucred.pid)) {
                r = client_context_acquire(s->server, s->ucred.pid, &s->ucred, s->label, strlen_ptr(s->label), s->unit_id, &s->context);
                if (r < 0)
                        log_warning_errno(r, "Failed to acquire client context, ignoring: %m");
        }

        priority = s->priority;

        if (s->level_prefix)
                syslog_parse_priority(&p, &priority, false);

        if (!client_context_test_priority(s->context, priority))
                return 0;

        if (isempty(p))
                return 0;

        if (s->forward_to_syslog || s->server->forward_to_syslog)
                server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL);

        if (s->forward_to_kmsg || s->server->forward_to_kmsg)
                server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);

        if (s->forward_to_console || s->server->forward_to_console)
                server_forward_console(s->server, priority, s->identifier, p, &s->ucred);

        if (s->server->forward_to_wall)
                server_forward_wall(s->server, priority, s->identifier, p, &s->ucred);

        m = N_IOVEC_META_FIELDS + 7 + client_context_extra_fields_n_iovec(s->context);
        iovec = newa(struct iovec, m);

        iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=stdout");
        iovec[n++] = IOVEC_MAKE_STRING(s->id_field);

        syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority);
        iovec[n++] = IOVEC_MAKE_STRING(syslog_priority);

        if (priority & LOG_FACMASK) {
                xsprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority));
                iovec[n++] = IOVEC_MAKE_STRING(syslog_facility);
        }

        if (s->identifier) {
                syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
                if (syslog_identifier)
                        iovec[n++] = IOVEC_MAKE_STRING(syslog_identifier);
        }

        if (line_break != LINE_BREAK_NEWLINE) {
                const char *c;

                /* If this log message was generated due to an uncommon line break then mention this in the log
                 * entry */

                c =     line_break == LINE_BREAK_NUL ?      "_LINE_BREAK=nul" :
                        line_break == LINE_BREAK_LINE_MAX ? "_LINE_BREAK=line-max" :
                                                            "_LINE_BREAK=eof";
                iovec[n++] = IOVEC_MAKE_STRING(c);
        }

        message = strappend("MESSAGE=", p);
        if (message)
                iovec[n++] = IOVEC_MAKE_STRING(message);

        server_dispatch_message(s->server, iovec, n, m, s->context, NULL, priority, 0);
        return 0;
}