s3:smbd/durable: remove an extra blank line from vfs_default_durable_reconnect()
[samba.git] / nsswitch / wb_common.c
index d0dfcb8bbfb67326d82f2736b8110b3a9baf8688..c56a76f82612b1017853b2734261636e67cadf94 100644 (file)
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#define UID_WRAPPER_NOT_REPLACE
+
+#include "replace.h"
+#include "system/select.h"
 #include "winbind_client.h"
 
 /* Global variables.  These are effectively the client state information */
@@ -41,7 +45,8 @@ void winbindd_free_response(struct winbindd_response *response)
 
 /* Initialise a request structure */
 
-void winbindd_init_request(struct winbindd_request *request, int request_type)
+static void winbindd_init_request(struct winbindd_request *request,
+                                 int request_type)
 {
        request->length = sizeof(struct winbindd_request);
 
@@ -61,7 +66,10 @@ static void init_response(struct winbindd_response *response)
 
 /* Close established socket */
 
-void winbind_close_sock(void)
+#if HAVE_FUNCTION_ATTRIBUTE_DESTRUCTOR
+__attribute__((destructor))
+#endif
+static void winbind_close_sock(void)
 {
        if (winbindd_fd != -1) {
                close(winbindd_fd);
@@ -229,8 +237,7 @@ static int winbind_named_pipe_sock(const char *dir)
 
        for (wait_time = 0; connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1;
                        wait_time += slept) {
-               struct timeval tv;
-               fd_set w_fds;
+               struct pollfd pfd;
                int ret;
                int connect_errno = 0;
                socklen_t errnosize;
@@ -240,12 +247,10 @@ static int winbind_named_pipe_sock(const char *dir)
 
                switch (errno) {
                        case EINPROGRESS:
-                               FD_ZERO(&w_fds);
-                               FD_SET(fd, &w_fds);
-                               tv.tv_sec = CONNECT_TIMEOUT - wait_time;
-                               tv.tv_usec = 0;
+                               pfd.fd = fd;
+                               pfd.events = POLLOUT;
 
-                               ret = select(fd + 1, NULL, &w_fds, NULL, &tv);
+                               ret = poll(&pfd, 1, (CONNECT_TIMEOUT - wait_time) * 1000);
 
                                if (ret > 0) {
                                        errnosize = sizeof(connect_errno);
@@ -363,15 +368,17 @@ static int winbind_open_pipe_sock(int recursing, int need_priv)
 
 /* Write data to winbindd socket */
 
-int winbind_write_sock(void *buffer, int count, int recursing, int need_priv)
+static int winbind_write_sock(void *buffer, int count, int recursing,
+                             int need_priv)
 {
-       int result, nwritten;
+       int fd, result, nwritten;
 
        /* Open connection to winbind daemon */
 
  restart:
 
-       if (winbind_open_pipe_sock(recursing, need_priv) == -1) {
+       fd = winbind_open_pipe_sock(recursing, need_priv);
+       if (fd == -1) {
                errno = ENOENT;
                return -1;
        }
@@ -381,48 +388,45 @@ int winbind_write_sock(void *buffer, int count, int recursing, int need_priv)
        nwritten = 0;
 
        while(nwritten < count) {
-               struct timeval tv;
-               fd_set r_fds;
+               struct pollfd pfd;
+               int ret;
 
                /* Catch pipe close on other end by checking if a read()
-                  call would not block by calling select(). */
+                  call would not block by calling poll(). */
 
-               FD_ZERO(&r_fds);
-               FD_SET(winbindd_fd, &r_fds);
-               ZERO_STRUCT(tv);
+               pfd.fd = fd;
+               pfd.events = POLLIN|POLLHUP;
 
-               if (select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv) == -1) {
+               ret = poll(&pfd, 1, 0);
+               if (ret == -1) {
                        winbind_close_sock();
-                       return -1;                   /* Select error */
+                       return -1;                   /* poll error */
                }
 
                /* Write should be OK if fd not available for reading */
 
-               if (!FD_ISSET(winbindd_fd, &r_fds)) {
-
-                       /* Do the write */
+               if ((ret == 1) && (pfd.revents & (POLLIN|POLLHUP|POLLERR))) {
 
-                       result = write(winbindd_fd,
-                                      (char *)buffer + nwritten,
-                                      count - nwritten);
-
-                       if ((result == -1) || (result == 0)) {
+                       /* Pipe has closed on remote end */
 
-                               /* Write failed */
+                       winbind_close_sock();
+                       goto restart;
+               }
 
-                               winbind_close_sock();
-                               return -1;
-                       }
+               /* Do the write */
 
-                       nwritten += result;
+               result = write(fd, (char *)buffer + nwritten,
+                              count - nwritten);
 
-               } else {
+               if ((result == -1) || (result == 0)) {
 
-                       /* Pipe has closed on remote end */
+                       /* Write failed */
 
                        winbind_close_sock();
-                       goto restart;
+                       return -1;
                }
+
+               nwritten += result;
        }
 
        return nwritten;
@@ -430,35 +434,37 @@ int winbind_write_sock(void *buffer, int count, int recursing, int need_priv)
 
 /* Read data from winbindd socket */
 
-int winbind_read_sock(void *buffer, int count)
+static int winbind_read_sock(void *buffer, int count)
 {
+       int fd;
        int nread = 0;
-       int total_time = 0, selret;
+       int total_time = 0;
 
-       if (winbindd_fd == -1) {
+       fd = winbind_open_pipe_sock(false, false);
+       if (fd == -1) {
                return -1;
        }
 
        /* Read data from socket */
        while(nread < count) {
-               struct timeval tv;
-               fd_set r_fds;
+               struct pollfd pfd;
+               int ret;
 
                /* Catch pipe close on other end by checking if a read()
-                  call would not block by calling select(). */
+                  call would not block by calling poll(). */
+
+               pfd.fd = fd;
+               pfd.events = POLLIN|POLLHUP;
 
-               FD_ZERO(&r_fds);
-               FD_SET(winbindd_fd, &r_fds);
-               ZERO_STRUCT(tv);
                /* Wait for 5 seconds for a reply. May need to parameterise this... */
-               tv.tv_sec = 5;
 
-               if ((selret = select(winbindd_fd + 1, &r_fds, NULL, NULL, &tv)) == -1) {
+               ret = poll(&pfd, 1, 5000);
+               if (ret == -1) {
                        winbind_close_sock();
-                       return -1;                   /* Select error */
+                       return -1;                   /* poll error */
                }
 
-               if (selret == 0) {
+               if (ret == 0) {
                        /* Not ready for read yet... */
                        if (total_time >= 30) {
                                /* Timeout */
@@ -469,11 +475,11 @@ int winbind_read_sock(void *buffer, int count)
                        continue;
                }
 
-               if (FD_ISSET(winbindd_fd, &r_fds)) {
+               if ((ret == 1) && (pfd.revents & (POLLIN|POLLHUP|POLLERR))) {
 
                        /* Do the Read */
 
-                       int result = read(winbindd_fd, (char *)buffer + nread,
+                       int result = read(fd, (char *)buffer + nread,
                              count - nread);
 
                        if ((result == -1) || (result == 0)) {
@@ -496,7 +502,7 @@ int winbind_read_sock(void *buffer, int count)
 
 /* Read reply */
 
-int winbindd_read_reply(struct winbindd_response *response)
+static int winbindd_read_reply(struct winbindd_response *response)
 {
        int result1, result2 = 0;
 
@@ -512,6 +518,10 @@ int winbindd_read_reply(struct winbindd_response *response)
                return -1;
        }
 
+       if (response->length < sizeof(struct winbindd_response)) {
+               return -1;
+       }
+
        /* We actually send the pointer value of the extra_data field from
           the server.  This has no meaning in the client's address space
           so we clear it out. */
@@ -665,26 +675,3 @@ NSS_STATUS winbindd_priv_request_response(int req_type,
 
        return status;
 }
-
-/*************************************************************************
- ************************************************************************/
-
-const char *nss_err_str(NSS_STATUS ret)
-{
-       switch (ret) {
-               case NSS_STATUS_TRYAGAIN:
-                       return "NSS_STATUS_TRYAGAIN";
-               case NSS_STATUS_SUCCESS:
-                       return "NSS_STATUS_SUCCESS";
-               case NSS_STATUS_NOTFOUND:
-                       return "NSS_STATUS_NOTFOUND";
-               case NSS_STATUS_UNAVAIL:
-                       return "NSS_STATUS_UNAVAIL";
-#ifdef NSS_STATUS_RETURN
-               case NSS_STATUS_RETURN:
-                       return "NSS_STATUS_RETURN";
-#endif
-               default:
-                       return "UNKNOWN RETURN CODE!!!!!!!";
-       }
-}