diff options
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/pam_winbind.c | 21 | ||||
-rw-r--r-- | source3/nsswitch/pam_winbind.h | 3 | ||||
-rw-r--r-- | source3/nsswitch/wb_common.c | 73 | ||||
-rw-r--r-- | source3/nsswitch/wbinfo.c | 12 | ||||
-rw-r--r-- | source3/nsswitch/winbind_nss.c | 14 | ||||
-rw-r--r-- | source3/nsswitch/winbind_nss_config.h | 8 |
6 files changed, 94 insertions, 37 deletions
diff --git a/source3/nsswitch/pam_winbind.c b/source3/nsswitch/pam_winbind.c index 29ceca4e79..f95caefb4c 100644 --- a/source3/nsswitch/pam_winbind.c +++ b/source3/nsswitch/pam_winbind.c @@ -11,11 +11,6 @@ #include "pam_winbind.h" -/* prototypes from common.c */ -void init_request(struct winbindd_request *req,int rq_type); -int write_sock(void *buffer, int count); -int read_reply(struct winbindd_response *response); - /* data tokens */ #define MAX_PASSWD_TRIES 3 @@ -99,24 +94,30 @@ static int _make_remark(pam_handle_t * pamh, int type, const char *text) return retval; } -static int winbind_request(enum winbindd_cmd req_type, - struct winbindd_request *request, - struct winbindd_response *response) +static int pam_winbind_request(enum winbindd_cmd req_type, + struct winbindd_request *request, + struct winbindd_response *response) { + /* Fill in request and send down pipe */ init_request(request, req_type); if (write_sock(request, sizeof(*request)) == -1) { _pam_log(LOG_ERR, "write to socket failed!"); + close_sock(); return PAM_SERVICE_ERR; } /* Wait for reply */ if (read_reply(response) == -1) { _pam_log(LOG_ERR, "read from socket failed!"); + close_sock(); return PAM_SERVICE_ERR; } + /* We are done with the socket - close it and avoid mischeif */ + close_sock(); + /* Copy reply data from socket */ if (response->result != WINBINDD_OK) { if (response->data.auth.pam_error != PAM_SUCCESS) { @@ -148,7 +149,7 @@ static int winbind_auth_request(const char *user, const char *pass, int ctrl) strncpy(request.data.auth.pass, pass, sizeof(request.data.auth.pass)-1); - retval = winbind_request(WINBINDD_PAM_AUTH, &request, &response); + retval = pam_winbind_request(WINBINDD_PAM_AUTH, &request, &response); switch (retval) { case PAM_AUTH_ERR: @@ -217,7 +218,7 @@ static int winbind_chauthtok_request(const char *user, const char *oldpass, request.data.chauthtok.newpass[0] = '\0'; } - return winbind_request(WINBINDD_PAM_CHAUTHTOK, &request, &response); + return pam_winbind_request(WINBINDD_PAM_CHAUTHTOK, &request, &response); } /* diff --git a/source3/nsswitch/pam_winbind.h b/source3/nsswitch/pam_winbind.h index 9897249e16..fae635d806 100644 --- a/source3/nsswitch/pam_winbind.h +++ b/source3/nsswitch/pam_winbind.h @@ -90,5 +90,4 @@ do { \ #define on(x, y) (x & y) #define off(x, y) (!(x & y)) -#include "winbind_nss_config.h" -#include "winbindd_nss.h" +#include "winbind_client.h" diff --git a/source3/nsswitch/wb_common.c b/source3/nsswitch/wb_common.c index 9bc9faafb5..0d1be4d5d1 100644 --- a/source3/nsswitch/wb_common.c +++ b/source3/nsswitch/wb_common.c @@ -5,6 +5,8 @@ Copyright (C) Tim Potter 2000 Copyright (C) Andrew Tridgell 2000 + Copyright (C) Andrew Bartlett 2002 + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -75,7 +77,7 @@ void init_response(struct winbindd_response *response) /* Close established socket */ -static void close_sock(void) +void close_sock(void) { if (winbindd_fd != -1) { close(winbindd_fd); @@ -83,6 +85,64 @@ static void close_sock(void) } } +/* Make sure socket handle isn't stdin, stdout or stderr */ +#define RECURSION_LIMIT 3 + +static int make_nonstd_fd_internals(int fd, int limit /* Recursion limiter */) +{ + int new_fd; + if (fd >= 0 && fd <= 2) { +#ifdef F_DUPFD + if ((new_fd = fcntl(fd, F_DUPFD, 3)) == -1) { + return -1; + } + /* Parinoia */ + if (new_fd < 3) { + return -1; + } + close(fd); + return new_fd; +#else + if (limit <= 0) + return -1; + + new_fd = dup(fd); + if (new_fd == -1) + return -1; + + /* use the program stack to hold our list of FDs to close */ + new_fd = make_nonstd_fd_internals(new_fd, limit - 1); + close(fd); + return new_fd; +#endif + } + return fd; +} + +static int make_safe_fd(int fd) +{ + int result, flags; + int new_fd = make_nonstd_fd_internals(fd, RECURSION_LIMIT); + if (new_fd == -1) { + close(fd); + return -1; + } + /* Socket should be closed on exec() */ + +#ifdef FD_CLOEXEC + result = flags = fcntl(new_fd, F_GETFD, 0); + if (flags >= 0) { + flags |= FD_CLOEXEC; + result = fcntl( new_fd, F_SETFD, flags ); + } + if (result < 0) { + close(new_fd); + return -1; + } +#endif + return new_fd; +} + /* Connect to winbindd socket */ int winbind_open_pipe_sock(void) @@ -91,6 +151,7 @@ int winbind_open_pipe_sock(void) static pid_t our_pid; struct stat st; pstring path; + int fd; if (our_pid != getpid()) { close_sock(); @@ -144,9 +205,13 @@ int winbind_open_pipe_sock(void) /* Connect to socket */ - if ((winbindd_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { return -1; } + + if ((winbindd_fd = make_safe_fd( fd)) == -1) { + return winbindd_fd; + } if (connect(winbindd_fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) { @@ -366,8 +431,8 @@ NSS_STATUS winbindd_get_response(struct winbindd_response *response) /* Handle simple types of requests */ NSS_STATUS winbindd_request(int req_type, - struct winbindd_request *request, - struct winbindd_response *response) + struct winbindd_request *request, + struct winbindd_response *response) { NSS_STATUS status; diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index d7d70b9e52..a0fdd033d7 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -28,11 +28,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND -/* Prototypes from common.h */ - -NSS_STATUS winbindd_request(int req_type, - struct winbindd_request *request, - struct winbindd_response *response); +extern int winbindd_fd; static char winbind_separator(void) { @@ -608,13 +604,13 @@ static BOOL wbinfo_set_auth_user(char *username) static BOOL wbinfo_ping(void) { NSS_STATUS result; - + result = winbindd_request(WINBINDD_PING, NULL, NULL); /* Display response */ - d_printf("'ping' to winbindd %s\n", - (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed"); + d_printf("'ping' to winbindd %s on fd %d\n", + (result == NSS_STATUS_SUCCESS) ? "succeeded" : "failed", winbindd_fd); return result == NSS_STATUS_SUCCESS; } diff --git a/source3/nsswitch/winbind_nss.c b/source3/nsswitch/winbind_nss.c index 594b5fbadb..0b4c0ce1d0 100644 --- a/source3/nsswitch/winbind_nss.c +++ b/source3/nsswitch/winbind_nss.c @@ -21,8 +21,7 @@ Boston, MA 02111-1307, USA. */ -#include "winbind_nss_config.h" -#include "winbindd_nss.h" +#include "winbind_client.h" #ifdef HAVE_NS_API_H #undef VOLATILE @@ -37,17 +36,6 @@ extern int winbindd_fd; -void init_request(struct winbindd_request *req,int rq_type); -NSS_STATUS winbindd_send_request(int req_type, - struct winbindd_request *request); -NSS_STATUS winbindd_get_response(struct winbindd_response *response); -NSS_STATUS winbindd_request(int req_type, - struct winbindd_request *request, - struct winbindd_response *response); -int winbind_open_pipe_sock(void); -int write_sock(void *buffer, int count); -int read_reply(struct winbindd_response *response); -void free_response(struct winbindd_response *response); #ifdef HAVE_NS_API_H /* IRIX version */ diff --git a/source3/nsswitch/winbind_nss_config.h b/source3/nsswitch/winbind_nss_config.h index 00cd5c12e4..d9a9b8aaae 100644 --- a/source3/nsswitch/winbind_nss_config.h +++ b/source3/nsswitch/winbind_nss_config.h @@ -62,6 +62,14 @@ #include <string.h> #endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#else +#ifdef HAVE_SYS_FCNTL_H +#include <sys/fcntl.h> +#endif +#endif + #include <sys/types.h> #include <sys/stat.h> #include <errno.h> |