From 6b21f0cf45ea2a8cd5926393a4c056b3a716c8af Mon Sep 17 00:00:00 2001 From: lennart Date: Sat, 19 Nov 2005 18:19:39 +0000 Subject: initial commit git-svn-id: svn+ssh://rootserver/home/lennart/svn/private/projects/nss-myhostname@83 bf9bc1cc-28ce-0310-abfb-9041aa761afb --- Makefile | 13 +++++ nss-myhostname.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 Makefile create mode 100644 nss-myhostname.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9301fab --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +CFLAGS=-Wall -pipe -W -O2 -Wextra -Wno-unused-parameter + +libnss_myhostname.so.2: nss-myhostname.o + $(CC) -shared -o $@ -Wl,-soname,$@ $^ + strip $@ + +install: + install -D -g root -m 644 -o root -s -v libnss_myhostname.so.2 /usr/lib/libnss_myhostname.so.2 + +clean: + rm -f *.o *~ libnss_myhostname.so.2 + +.PHONY: clean diff --git a/nss-myhostname.c b/nss-myhostname.c new file mode 100644 index 0000000..a459fd0 --- /dev/null +++ b/nss-myhostname.c @@ -0,0 +1,164 @@ +/* + * This file is part of nss-myhostname. + * + * nss-myhostname is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * nss-myhostname is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with nss-myhostname; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOCALADDRESS (htonl(0x7F0002)) + +static enum nss_status fill_in_hostent( + const char *hn, + struct hostent *result, + char *buffer, + size_t buflen, + int *errnop, + int *h_errnop) { + + size_t l, idx; + char *r_addr, *r_name, *r_aliases, *r_addr_list; + + l = strlen(hn); + if (buflen < l+1+sizeof(char*)+4+sizeof(char*)*2) { + *errnop = ENOMEM; + *h_errnop = NO_RECOVERY; + return NSS_STATUS_TRYAGAIN; + } + + r_name = buffer; + strcpy(buffer, hn); + + idx = l+1; + + *(char**) (buffer + idx) = NULL; + r_aliases = buffer + idx; + idx += sizeof(char*); + + r_addr = buffer + idx; + *(uint32_t*) &buffer[idx] = LOCALADDRESS; + idx += 4; + + r_addr_list = buffer + idx; + * (char**) (buffer + idx) = r_addr; + * (((char**) (buffer + idx)) +1) = NULL; + + result->h_name = r_name; + result->h_aliases = (char**) r_aliases; + result->h_addrtype = AF_INET; + result->h_length = 4; + result->h_addr_list = (char**) r_addr_list; + + return NSS_STATUS_SUCCESS; +} + +enum nss_status _nss_hostname_gethostbyname2_r( + const char *name, + int af, + struct hostent * result, + char *buffer, + size_t buflen, + int *errnop, + int *h_errnop) { + + char hn[HOST_NAME_MAX+1]; + + assert(errnop); + assert(h_errnop); + + if (af == AF_UNSPEC) + af = AF_INET; + + if (af != AF_INET) { + *errnop = ENOENT; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } + + if (gethostname(hn, sizeof(hn)-1) < 0) { + *errnop = errno; + *h_errnop = NO_RECOVERY; + return NSS_STATUS_TRYAGAIN; + } + + hn[sizeof(hn)-1] = 0; + + if (strcasecmp(name, hn) != 0) { + *errnop = ENOENT; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } + + return fill_in_hostent(hn, result, buffer, buflen, errnop, h_errnop); +} + +enum nss_status _nss_hostname_gethostbyname_r ( + const char *name, + struct hostent *result, + char *buffer, + size_t buflen, + int *errnop, + int *h_errnop) { + + return _nss_hostname_gethostbyname2_r( + name, + AF_UNSPEC, + result, + buffer, + buflen, + errnop, + h_errnop); +} + +enum nss_status _nss_hostname_gethostbyaddr_r( + const void* addr, + int len, + int af, + struct hostent *result, + char *buffer, + size_t buflen, + int *errnop, + int *h_errnop) { + + char hn[HOST_NAME_MAX+1]; + + assert(errnop); + assert(h_errnop); + + if (af != AF_INET || len != 4 || (*(uint32_t*) addr) != LOCALADDRESS) { + *errnop = ENOENT; + *h_errnop = HOST_NOT_FOUND; + return NSS_STATUS_NOTFOUND; + } + + if (gethostname(hn, sizeof(hn)-1) < 0) { + *errnop = errno; + *h_errnop = NO_RECOVERY; + return NSS_STATUS_TRYAGAIN; + } + + hn[sizeof(hn)-1] = 0; + + return fill_in_hostent(hn, result, buffer, buflen, errnop, h_errnop); +} -- cgit