diff options
| -rw-r--r-- | source3/include/includes.h | 2 | ||||
| -rw-r--r-- | source3/include/smb.h | 2 | ||||
| -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 | 
8 files changed, 96 insertions, 39 deletions
diff --git a/source3/include/includes.h b/source3/include/includes.h index dacac356e3..eaa0d25239 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -762,6 +762,8 @@ extern int errno;  #include "mangle.h" +#include "nsswitch/winbind_client.h" +  /*   * Type for wide character dirent structure.   * Only d_name is defined by POSIX. diff --git a/source3/include/smb.h b/source3/include/smb.h index 2ee2f0cb72..a1b3faa343 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1623,8 +1623,6 @@ struct unix_error_map {  #define SAFE_NETBIOS_CHARS ". -_" -#include "nsswitch/winbindd_nss.h" -  /* generic iconv conversion structure */  typedef struct {  	size_t (*direct)(void *cd, char **inbuf, size_t *inbytesleft, 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>  | 
