diff --git a/Makefile b/Makefile index a1ab586..8ff1dee 100644 --- a/Makefile +++ b/Makefile @@ -33,15 +33,13 @@ get_shadow_line.o: get_shadow_line.c get_shadow_line.h common.h gcc $(CFLAGS) -c -fPIC -o get_shadow_line.o get_shadow_line.c libnss_mxshadow.so.2: libnss_mxshadow.c get_shadow_line.c common.h - gcc $(CFLAGS) -shared -o libnss_mxshadow.so.2 -Wl,-soname,libnss_mxshadow.so.2 -fPIC libnss_mxshadow.c get_shadow_line.c -lssl -lcrypto -test_server: test_server.o get_shadow_line.o - gcc $(CFLAGS) -o test_server test_server.o get_shadow_line.o -lssl -lcrypto + gcc $(CFLAGS) -shared -o libnss_mxshadow.so.2 -Wl,-soname,libnss_mxshadow.so.2,-unresolved-symbols=report-all -fPIC libnss_mxshadow.c get_shadow_line.c -l:libssl.a -l:libcrypto.a -lpthread -ldl -mxshadowsrv: mxshadowsrv.o - gcc $(CFLAGS) -o mxshadowsrv mxshadowsrv.o -l:libssl.a -l:libcrypto.a -lpthread -ldl +test_server: test_server.c get_shadow_line.c common.h get_shadow_line.h + gcc $(CFLAGS) -o test_server test_server.c get_shadow_line.c -l:libssl.a -l:libcrypto.a -lpthread -ldl -mxshadowsrv.o: mxshadowsrv.c common.h -test_server.o: test_server.c common.h get_shadow_line.h +mxshadowsrv: mxshadowsrv.c common.h + gcc $(CFLAGS) -o mxshadowsrv mxshadowsrv.c -l:libssl.a -l:libcrypto.a -lpthread -ldl clean: @rm *.o libnss_mxshadow.so.2 mxshadowsrv test_server test_query_shadow >/dev/null || true diff --git a/common.h b/common.h index 259ff7a..db41a92 100644 --- a/common.h +++ b/common.h @@ -6,13 +6,13 @@ #define _cleanup_(x) __attribute__((cleanup(x))) -static void free_ssl_ctx(SSL_CTX **ctxp) { +static void __attribute__((unused)) free_ssl_ctx(SSL_CTX **ctxp) { if (*ctxp) { SSL_CTX_free(*ctxp); } } -static void free_ssl(SSL **sslp) { +static void __attribute__((unused)) free_ssl(SSL **sslp) { if (*sslp) { SSL_free(*sslp); } @@ -36,7 +36,7 @@ static void __attribute__((unused)) free_string(char **ptr) { } } -static void psslerror(char *str) { +static void __attribute__((unused)) psslerror(char *str) { fprintf(stderr, "%s\n", str); ERR_print_errors_fp(stderr); } diff --git a/get_shadow_line.c b/get_shadow_line.c index 2c289ab..25bd55f 100644 --- a/get_shadow_line.c +++ b/get_shadow_line.c @@ -76,7 +76,9 @@ static int connect_with_timeout(int sockfd, struct sockaddr *addr, socklen_t add return status; } -int get_shadow_line_from_server(char *user, char *buf, size_t buflen) { +#define BUFLEN_SPWD (1024) + +int get_shadow_line(char *user, char **line) { struct sockaddr_in sockaddr; bzero(&sockaddr, sizeof(sockaddr)); @@ -112,17 +114,21 @@ int get_shadow_line_from_server(char *user, char *buf, size_t buflen) { return -1; } - len = ssl_read_with_timeout(ssl, sock, buf, buflen, 1000); + char *buffer _cleanup_(free_string) = malloc(BUFLEN_SPWD); + if (buffer == NULL) + return -1; + + len = ssl_read_with_timeout(ssl, sock, buffer, BUFLEN_SPWD, 1000); if (len<0) return -1; SSL_shutdown(ssl); - if (len == buflen) { - fprintf(stderr, "%s: buffer to small", __func__); - errno = ERANGE; // as getspent + if (len == BUFLEN_SPWD) { + /* we don't expect reply lines longer than BUFLEN_SPWD. If we get one, regard this as a protocol error */ + errno = EPROTO; return -1; } - buf[len] = '\0'; + buffer[len] = '\0'; + *line = buffer; + buffer = NULL; return 0; } - - diff --git a/get_shadow_line.h b/get_shadow_line.h index 3942baf..3c0811d 100644 --- a/get_shadow_line.h +++ b/get_shadow_line.h @@ -1,6 +1,6 @@ #ifndef _GET_SHADOW_LINE_H #define _GET_SHADOW_LINE_H -int get_shadow_line_from_server(char *user, char *buf, size_t buflen); +int get_shadow_line(char *user, char **line); #endif /* _GET_SHADOW_LINE_H */ diff --git a/libnss_mxshadow.c b/libnss_mxshadow.c index 5660af6..09a6e1d 100644 --- a/libnss_mxshadow.c +++ b/libnss_mxshadow.c @@ -1,46 +1,29 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include "get_shadow_line.h" - -static long int atol_or_minus1(char *p) { - return *p == '\0' ? -1 : atol(p); -} - -static unsigned long int atoul_or_minus1(char *p) { - return *p == '\0' ? (unsigned long int) -1 : strtoul(p, NULL, 10); -} +#include "common.h" enum nss_status _nss_mxshadow_getspnam_r(const char *name, struct spwd *spwd, char *buffer, size_t buflen, int *errnop) { - int status = get_shadow_line_from_server((char *)name, buffer, buflen); + char *line _cleanup_(free_string) = NULL; + + int status = get_shadow_line((char *)name, &line); if (status == -1) { - perror(__func__); + *errnop = errno; return NSS_STATUS_UNAVAIL; } - if (buffer[0] == '\0') + if (line[0] == '\0') { + errno = ENOENT; + *errnop = errno; return NSS_STATUS_NOTFOUND; - - char *p; - - p = strsep(&buffer, ":"); if (p == NULL) return NSS_STATUS_NOTFOUND; spwd->sp_namp = p; - p = strsep(&buffer, ":"); if (p == NULL) return NSS_STATUS_NOTFOUND; spwd->sp_pwdp = p; - p = strsep(&buffer, ":"); if (p == NULL) return NSS_STATUS_NOTFOUND; spwd->sp_lstchg = atol_or_minus1(p); - p = strsep(&buffer, ":"); if (p == NULL) return NSS_STATUS_NOTFOUND; spwd->sp_min = atol_or_minus1(p); - p = strsep(&buffer, ":"); if (p == NULL) return NSS_STATUS_NOTFOUND; spwd->sp_max = atol_or_minus1(p); - p = strsep(&buffer, ":"); if (p == NULL) return NSS_STATUS_NOTFOUND; spwd->sp_warn = atol_or_minus1(p); - p = strsep(&buffer, ":"); if (p == NULL) return NSS_STATUS_NOTFOUND; spwd->sp_inact = atol_or_minus1(p); - p = strsep(&buffer, ":"); if (p == NULL) return NSS_STATUS_NOTFOUND; spwd->sp_expire = atol_or_minus1(p); - p = strsep(&buffer, ":"); if (p == NULL) return NSS_STATUS_NOTFOUND; spwd->sp_flag = atoul_or_minus1(p); + } + struct spwd *spbufp; + status = sgetspent_r(line, spwd, buffer, buflen, &spbufp); + if (status == -1) { + *errnop = errno; + return NSS_STATUS_UNAVAIL; + } return NSS_STATUS_SUCCESS; } diff --git a/test_server.c b/test_server.c index 9128212..7548432 100644 --- a/test_server.c +++ b/test_server.c @@ -1,4 +1,5 @@ #include +#include #include "get_shadow_line.h" @@ -7,11 +8,12 @@ int main(int argc, char **argv) { fprintf(stderr, "usage: %s username\n", argv[0]); return 1; } - char buf[1024]; - int status = get_shadow_line_from_server(argv[1], buf, sizeof(buf)); + char *line; + int status = get_shadow_line(argv[1], &line); if (status == -1) return 1; - if (buf[0]) { - printf("%s\n", buf); + if (line[0]) { + printf("%s\n", line); } + free(line); }