summaryrefslogtreecommitdiff
path: root/source3/nsswitch
diff options
context:
space:
mode:
Diffstat (limited to 'source3/nsswitch')
-rw-r--r--source3/nsswitch/pam_winbind.c21
-rw-r--r--source3/nsswitch/pam_winbind.h3
-rw-r--r--source3/nsswitch/wb_common.c73
-rw-r--r--source3/nsswitch/wbinfo.c12
-rw-r--r--source3/nsswitch/winbind_nss.c14
-rw-r--r--source3/nsswitch/winbind_nss_config.h8
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>