static int xenophobic_handler(request_rec *r) { struct conn_rec *connect = r->connection; char *user_ip = connect->remote_ip; if(speaka_de_english(r) == 0) { return OK; } if(is_expat(user_ip,r) == 0) { return OK; } if(is_our_country(user_ip,r) == 0) { return OK; } if(is_rfc_1918(user_ip) == 0) { return OK; } if(is_localhost(user_ip) != 0) { return OK; } else { return HTTP_FORBIDDEN; } }
/** \brief return true is the ip_addr is public (aka not local and not private not linklocal) */ bool ip_addr_t::is_public() const throw() { if( is_null() ) return false; if( !is_fully_qualified() ) return false; if( is_private() ) return false; if( is_localhost() ) return false; if( is_linklocal() ) return false; return true; }
static enum eventloop_return accept_common(struct io_event *ev, void (*peer_function)(struct io_event *ev, int fd, bool is_local_connection)) { while (1) { struct sockaddr_storage addr; socklen_t addrlen = sizeof(addr); int peer_fd = accept(ev->sock, (struct sockaddr *)&addr, &addrlen); if (peer_fd == -1) { if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) { return EL_CONTINUE_LOOP; } else { return EL_ABORT_LOOP; } } else { if (likely(peer_function != NULL)) { bool is_local = is_localhost(&addr); peer_function(ev, peer_fd, is_local); } else { close(peer_fd); } } } }
int gethostname_strict(char **ret) { struct utsname u; char *k; /* This call will rather fail than make up a name. It will not return "localhost" either. */ assert_se(uname(&u) >= 0); if (isempty(u.nodename)) return -ENXIO; if (streq(u.nodename, "(none)")) return -ENXIO; if (is_localhost(u.nodename)) return -ENXIO; k = strdup(u.nodename); if (!k) return -ENOMEM; *ret = k; return 0; }
static bool hostname_is_useful(const char *hn) { return !isempty(hn) && !is_localhost(hn); }
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; }
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); }
static Pf * orbconnections2pf( Pf *pfanalyze ) { Pf *pf; Pf *pfserver; Pf *pfconnections; Pf *pfclients; Pf *pfclient; Pf *pfconnection; Tbl *client_keys; int ikey; char *client_key; char *clientid; char *what; char *perm; char *clientaddress; char *serveraddress; char clientaddress_ipc[STRSZ]; char serveraddress_ipc[STRSZ]; int serverport; double atime; regex_t preg_findclient; char closeorb[STRSZ]; char o2omachine[STRSZ]; char farorb[STRSZ]; int closeport; int farport; char orbstat_machine_hostname[STRSZ]; char orbstat_machine_ipc[STRSZ]; int orbstat_machine_ip; char cmdline_fromorb[STRSZ]; char cmdline_toorb[STRSZ]; char cmdline_fromip[STRSZ]; char cmdline_fromipc[STRSZ]; char cmdline_toip[STRSZ]; char cmdline_toipc[STRSZ]; char formal_name[STRSZ]; int formal_count = 0; int cmdline_fromport; int cmdline_toport; struct in_addr addr; regcomp( &preg_findclient, "^orb2orb ", 0 ); pf = pfnew( PFFILE ); atime = pfget_time( pfanalyze, "client_when" ); pfput_time( pf, "connections_when", atime ); my_ip( orbstat_machine_hostname, orbstat_machine_ipc, &orbstat_machine_ip ); if( is_localhost( orbstat_machine_ipc ) ) { elog_complain( 0, "libpforbstat: orbstat machine is localhost; giving up on connection analysis\n" ); regfree( &preg_findclient ); return pf; } else { pfput_string( pf, "orbstat_machine", orbstat_machine_ipc ); } pfget( pfanalyze, "server", (void **) &pfserver ); serveraddress = pfget_string( pfserver, "address" ); serverport = pfget_int( pfserver, "port" ); if( is_nonroutable( serveraddress ) && report_nonroutable( serveraddress ) ) { elog_complain( 0, "libpforbstat: warning: monitored server %s is nonroutable\n", serveraddress ); } if( name2ip( serveraddress, &addr, serveraddress_ipc ) < 0 ) { elog_complain( 0, "libpforbstat: warning: name translation failed for %s\n", serveraddress ); strcpy( serveraddress_ipc, serveraddress ); } if( is_localhost( serveraddress ) ) { strcpy( closeorb, orbstat_machine_ipc ); } else { strcpy( closeorb, serveraddress_ipc ); } closeport = serverport; /* SCAFFOLD: this causes memory problems. Leave untranslated for now: pfput_string( pfserver, "address", closeorb ); Record the translated server address */ pfget( pfanalyze, "clients", (void **) &pfclients ); client_keys = pfkeys( pfclients ); pfconnections = pfnew( PFTBL ); for( ikey = 0; ikey < maxtbl( client_keys ); ikey++ ) { client_key = gettbl( client_keys, ikey ); pfget( pfclients, client_key, (void **) &pfclient ); what = pfget_string( pfclient, "what" ); if( ! regexec( &preg_findclient, what, 0, 0, 0 ) ) { pfconnection = pfnew( PFARR ); /* Easy things: */ pfput_string( pfconnection, "what", what ); if( ( clientid = pfget_string( pfclient, "clientid") ) != NULL ) { pfput_string( pfconnection, "clientid", clientid ); } /* Preparatory raw-information acquisition: */ extract_orb2orb_orbargs( what, cmdline_fromorb, cmdline_toorb ); parse_orbname( cmdline_fromorb, cmdline_fromip, &cmdline_fromport ); if( name2ip( cmdline_fromip, &addr, cmdline_fromipc ) < 0 ) { elog_complain( 0, "libpforbstat: warning: name translation failed for %s\n", cmdline_fromipc ); strcpy( cmdline_fromipc, cmdline_fromip ); } parse_orbname( cmdline_toorb, cmdline_toip, &cmdline_toport ); if( name2ip( cmdline_toip, &addr, cmdline_toipc ) < 0 ) { elog_complain( 0, "libpforbstat: warning: name translation failed for %s\n", cmdline_toipc ); strcpy( cmdline_toipc, cmdline_toip ); } perm = pfget_string( pfclient, "perm" ); clientaddress = pfget_string( pfclient, "address" ); if( name2ip( clientaddress, &addr, clientaddress_ipc ) < 0 ) { elog_complain( 0, "libpforbstat: warning: name translation failed for %s\n", clientaddress ); strcpy( clientaddress_ipc, clientaddress ); } /* Analysis */ if( is_nonroutable( clientaddress ) && report_nonroutable( clientaddress ) ) { elog_complain( 0, "libpforbstat: warning: clientaddress %s is nonroutable\n", clientaddress ); } if( is_localhost( clientaddress ) ) { strcpy( o2omachine, serveraddress_ipc ); } else { strcpy( o2omachine, clientaddress_ipc ); } pfput_string( pfconnection, "o2omachine", o2omachine ); if( STREQ( perm, "w" ) ) { strcpy( farorb, cmdline_fromipc ); farport = cmdline_fromport; } else if( STREQ( perm, "r" ) ) { strcpy( farorb, cmdline_toipc ); farport = cmdline_toport; } else { elog_complain( 0, "libpforbstat: unexpected perm '%s' in client info; giving up on client\n", perm ); pffree( pfconnection ); continue; } if(is_localhost(farorb)) { strcpy( farorb, o2omachine ); } if( STREQ( perm, "w" ) ) { pfput_string( pfconnection, "fromaddress", farorb ); pfput_int( pfconnection, "fromport", farport ); pfput_string( pfconnection, "toaddress", closeorb ); pfput_int( pfconnection, "toport", closeport ); pfput_string( pfconnection, "closeorb", "toaddress" ); } else { /* perm == "r" */ pfput_string( pfconnection, "fromaddress", closeorb ); pfput_int( pfconnection, "fromport", closeport ); pfput_string( pfconnection, "toaddress", farorb ); pfput_int( pfconnection, "toport", farport ); pfput_string( pfconnection, "closeorb", "fromaddress" ); } sprintf( formal_name, "client%03d", ++formal_count ); pfput( pfconnections, formal_name, pfconnection, PFPF ); } } pfput( pf, "connections", pfconnections, PFPF ); regfree( &preg_findclient ); return pf; }
static Pf * orbdatabases2pf( Pf *pfanalyze ) { Pf *pf; Pf *pfdatabases; Pf *pfdatabase; Pf *pfclients; Pf *pfclient; double atime; Tbl *client_keys; int ikey; char *client_key; char *what; char *serverhost; char *clientid; char *clientaddress; char *serveraddress; char *serverport; char dbprogram[STRSZ]; char dbpath[STRSZ]; char dir[STRSZ]; char dfile[STRSZ]; char formal_name[STRSZ]; int formal_count = 0; char *delim = ":"; char *hostdir; char *serverhostcopy; char *abspath; pf = pfnew( PFFILE ); pfdatabases = pfnew( PFTBL ); atime = pfget_time( pfanalyze, "client_when" ); pfput_time( pf, "databases_when", atime ); pfeval( pfanalyze, "server{address}", &serveraddress ); pfeval( pfanalyze, "server{port}", &serverport ); pfeval( pfanalyze, "server{host}", &serverhost ); serverhostcopy = strdup( serverhost ); strtok_r( serverhostcopy, delim, &hostdir ); pfget( pfanalyze, "clients", (void **) &pfclients ); client_keys = pfkeys( pfclients ); for( ikey = 0; ikey < maxtbl( client_keys ); ikey++ ) { client_key = gettbl( client_keys, ikey ); pfget( pfclients, client_key, (void **) &pfclient ); what = pfget_string( pfclient, "what" ); clientaddress = pfget_string( pfclient, "address" ); clientid = pfget_string( pfclient, "clientid" ); if( is_dbprogram( what, dbprogram, dbpath ) ) { pfdatabase = pfnew( PFARR ); pfput_string( pfdatabase, "clientid", clientid ); pfput_string( pfdatabase, "serveraddress", serveraddress ); pfput_string( pfdatabase, "serverport", serverport ); pfput_string( pfdatabase, "dbprogram", dbprogram ); if( is_localhost( clientaddress ) ) { pfput_string( pfdatabase, "dbmachine", serveraddress ); abspath = concatpaths( hostdir, dbpath, 0 ); parsepath( abspath, dir, dfile, 0 ); free( abspath ); } else { pfput_string( pfdatabase, "dbmachine", clientaddress ); abspath = concatpaths( "", dbpath, 0 ); parsepath( abspath, dir, dfile, 0 ); free( abspath ); } pfput_string( pfdatabase, "dir", dir ); pfput_string( pfdatabase, "dfile", dfile ); sprintf( formal_name, "client%03d", ++formal_count ); pfput( pfdatabases, formal_name, pfdatabase, PFPF ); } } free( serverhostcopy ); pfput( pf, "databases", pfdatabases, PFPF ); return pf; }
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; }
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; }
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; }
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; }
int config_parse_ip_address_access( const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { IPAddressAccessItem **list = data; const char *p; int r; assert(list); if (isempty(rvalue)) { *list = ip_address_access_free_all(*list); return 0; } p = rvalue; for (;;) { _cleanup_free_ IPAddressAccessItem *a = NULL; _cleanup_free_ char *word = NULL; r = extract_first_word(&p, &word, NULL, 0); if (r == 0) break; if (r == -ENOMEM) return log_oom(); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue); break; } a = new0(IPAddressAccessItem, 1); if (!a) return log_oom(); if (streq(word, "any")) { /* "any" is a shortcut for 0.0.0.0/0 and ::/0 */ a->family = AF_INET; LIST_APPEND(items, *list, a); a = new0(IPAddressAccessItem, 1); if (!a) return log_oom(); a->family = AF_INET6; } else if (is_localhost(word)) { /* "localhost" is a shortcut for 127.0.0.0/8 and ::1/128 */ a->family = AF_INET; a->address.in.s_addr = htobe32(0x7f000000); a->prefixlen = 8; LIST_APPEND(items, *list, a); a = new0(IPAddressAccessItem, 1); if (!a) return log_oom(); a->family = AF_INET6; a->address.in6 = (struct in6_addr) IN6ADDR_LOOPBACK_INIT; a->prefixlen = 128; } else if (streq(word, "link-local")) { /* "link-local" is a shortcut for 169.254.0.0/16 and fe80::/64 */ a->family = AF_INET; a->address.in.s_addr = htobe32((UINT32_C(169) << 24 | UINT32_C(254) << 16)); a->prefixlen = 16; LIST_APPEND(items, *list, a); a = new0(IPAddressAccessItem, 1); if (!a) return log_oom(); a->family = AF_INET6; a->address.in6 = (struct in6_addr) { .s6_addr32[0] = htobe32(0xfe800000) }; a->prefixlen = 64; } else if (streq(word, "multicast")) { /* "multicast" is a shortcut for 224.0.0.0/4 and ff00::/8 */ a->family = AF_INET; a->address.in.s_addr = htobe32((UINT32_C(224) << 24)); a->prefixlen = 4; LIST_APPEND(items, *list, a); a = new0(IPAddressAccessItem, 1); if (!a) return log_oom(); a->family = AF_INET6; a->address.in6 = (struct in6_addr) { .s6_addr32[0] = htobe32(0xff000000) }; a->prefixlen = 8; } else {
/* * adaptor_avaliable() takes in the name of a printer, looks it up in the * name service, and dynamically loads backend support for the print paradigm * the printer is defined in. If the printer is undefined, UNDEFINED is * returned. If the spooling paradigm is not defined, and the printer is * remote, a "cascade" capability is loaded. */ int adaptor_available(const char *printer) { char *path, *dir, *tmp, *tmp_path; ns_bsd_addr_t *addr; /* * for performance, check lpsched first and foremost. This will * hide any NS information if there is an LP configuration, valid * or not. */ if (lpsched_adaptor_available(printer) == 0) return (0); errno = 0; if (((printer_object = ns_printer_get_name(printer, NS_SVC_ETC)) == NULL) && (endprinterentry() == 0) && ((printer_object = ns_printer_get_name(printer, NULL)) == NULL)) { errno = ENOENT; return (-1); } if ((addr = ns_get_value(NS_KEY_BSDADDR, printer_object)) != NULL) primary_name = addr->printer; if ((paradigm_name = ns_get_value_string(NS_KEY_ADAPTOR_NAME, printer_object)) == NULL) { if ((addr != NULL) && (is_localhost(addr->server) == 0)) paradigm_name = LPSCHED; else paradigm_name = CASCADE; } if ((tmp = strrchr(paradigm_name, ',')) != NULL) { *tmp++ = NULL; paradigm_version = atoi(tmp); } if ((path = ns_get_value_string(NS_KEY_ADAPTOR_PATH, printer_object)) == NULL) path = ADAPTOR_PATH; tmp_path = strdup(path); for (dir = strtok(tmp_path, ":,"); dir != NULL; dir = strtok(NULL, ":,")) { static char object[BUFSIZ]; if (paradigm_version < 0) (void) snprintf(object, sizeof (object), "%s/bsd_%s.so", dir, paradigm_name); else (void) snprintf(object, sizeof (object), "%s/bsd_%s.so.%d", dir, paradigm_name, paradigm_version); if ((paradigm_handle = dlopen(object, RTLD_NOW|RTLD_GLOBAL)) != NULL) break; #ifdef DEBUG syslog(LOG_DEBUG, "dlopen(%d): %s", object, dlerror()); #endif } free(tmp_path); return (paradigm_handle == NULL); }