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; }
static void test_strlen_ptr(void) { assert_se(strlen_ptr("foo") == 3); assert_se(strlen_ptr("") == 0); assert_se(strlen_ptr(NULL) == 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; }