1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-23 00:23:53 +03:00

Winbind client-side cleanups.

The global winbind file descriptor can cause havoc in some situations -
particulary when it becomes 0, 1 or 2.  This patch (based on some very nice
work by Hannes Schmidt <mail@schmidt-net.via.t-online.de>) starts to recitfy
the problem by ensuring that the close-on-exec flag is set, and that we move
above 3 in the file descriptor table.

I've also decided that the PAM module can close it's pipe handle on every
request - this isn't performance-critical code.

The next step is to do the same for nss_winbind.  (But things like getent()
might get in our way there).

This also cleans up some function prototypes, puts them in just one place.

Andrew Bartlett
This commit is contained in:
Andrew Bartlett
-
parent 29b4b9a2b5
commit 442eb39657
8 changed files with 96 additions and 39 deletions

View File

@@ -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.

View File

@@ -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,

View File

@@ -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,
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);
}
/*

View File

@@ -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"

View File

@@ -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,10 +205,14 @@ 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) {
close_sock();

View File

@@ -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)
{
@@ -613,8 +609,8 @@ static BOOL wbinfo_ping(void)
/* 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;
}

View File

@@ -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 */

View File

@@ -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>