Author: vlendec
Date: 2007-03-19 21:04:56 +0000 (Mon, 19 Mar 2007)
New Revision: 21878

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=21878

Log:
Fix a bug with smbd serving a windows terminal server: If winbind decides smbd
to be idle it might happen that smbd needs to do a winbind operation (for
example sid2name) as non-root. This then fails to get the privileged
pipe. When later on on the same connection another authentication request
comes in, we try to do the CRAP auth via the non-privileged pipe.

This adds a winbindd_priv_request_response() request that kills the existing
winbind pipe connection if it's not privileged.

Volker

Modified:
   branches/SAMBA_3_0/source/auth/auth_winbind.c
   branches/SAMBA_3_0/source/nsswitch/pam_winbind.c
   branches/SAMBA_3_0/source/nsswitch/wb_common.c
   branches/SAMBA_3_0/source/nsswitch/winbind_client.h
   branches/SAMBA_3_0/source/nsswitch/winbind_nss_irix.c
   branches/SAMBA_3_0_25/source/auth/auth_winbind.c
   branches/SAMBA_3_0_25/source/nsswitch/pam_winbind.c
   branches/SAMBA_3_0_25/source/nsswitch/wb_common.c
   branches/SAMBA_3_0_25/source/nsswitch/winbind_client.h
   branches/SAMBA_3_0_25/source/nsswitch/winbind_nss_irix.c


Changeset:
Modified: branches/SAMBA_3_0/source/auth/auth_winbind.c
===================================================================
--- branches/SAMBA_3_0/source/auth/auth_winbind.c       2007-03-19 21:03:30 UTC 
(rev 21877)
+++ branches/SAMBA_3_0/source/auth/auth_winbind.c       2007-03-19 21:04:56 UTC 
(rev 21878)
@@ -108,7 +108,8 @@
 
        /* we are contacting the privileged pipe */
        become_root();
-       result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, 
&response);
+       result = winbindd_priv_request_response(WINBINDD_PAM_AUTH_CRAP,
+                                               &request, &response);
        unbecome_root();
 
        if ( result == NSS_STATUS_UNAVAIL )  {

Modified: branches/SAMBA_3_0/source/nsswitch/pam_winbind.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/pam_winbind.c    2007-03-19 21:03:30 UTC 
(rev 21877)
+++ branches/SAMBA_3_0/source/nsswitch/pam_winbind.c    2007-03-19 21:04:56 UTC 
(rev 21878)
@@ -436,7 +436,7 @@
        /* Fill in request and send down pipe */
        init_request(request, req_type);
        
-       if (write_sock(request, sizeof(*request), 0) == -1) {
+       if (write_sock(request, sizeof(*request), 0, 1) == -1) {
                _pam_log(pamh, ctrl, LOG_ERR, "pam_winbind_request: write to 
socket failed!");
                close_sock();
                return PAM_SERVICE_ERR;

Modified: branches/SAMBA_3_0/source/nsswitch/wb_common.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/wb_common.c      2007-03-19 21:03:30 UTC 
(rev 21877)
+++ branches/SAMBA_3_0/source/nsswitch/wb_common.c      2007-03-19 21:04:56 UTC 
(rev 21878)
@@ -33,6 +33,7 @@
 /* Global variables.  These are effectively the client state information */
 
 int winbindd_fd = -1;           /* fd for winbindd socket */
+static int is_privileged = 0;
 
 /* Free a response structure */
 
@@ -287,7 +288,7 @@
 
 /* Connect to winbindd socket */
 
-static int winbind_open_pipe_sock(int recursing)
+static int winbind_open_pipe_sock(int recursing, int need_priv)
 {
 #ifdef HAVE_UNIXSOCKET
        static pid_t our_pid;
@@ -300,6 +301,10 @@
                close_sock();
                our_pid = getpid();
        }
+
+       if ((need_priv != 0) && (is_privileged == 0)) {
+               close_sock();
+       }
        
        if (winbindd_fd != -1) {
                return winbindd_fd;
@@ -313,6 +318,8 @@
                return -1;
        }
 
+       is_privileged = 0;
+
        /* version-check the socket */
 
        request.flags = WBFLAG_RECURSE;
@@ -329,9 +336,14 @@
                if ((fd = winbind_named_pipe_sock((char 
*)response.extra_data.data)) != -1) {
                        close(winbindd_fd);
                        winbindd_fd = fd;
+                       is_privileged = 1;
                }
        }
 
+       if ((need_priv != 0) && (is_privileged == 0)) {
+               return -1;
+       }
+
        SAFE_FREE(response.extra_data.data);
 
        return winbindd_fd;
@@ -342,7 +354,7 @@
 
 /* Write data to winbindd socket */
 
-int write_sock(void *buffer, int count, int recursing)
+int write_sock(void *buffer, int count, int recursing, int need_priv)
 {
        int result, nwritten;
        
@@ -350,7 +362,7 @@
        
  restart:
        
-       if (winbind_open_pipe_sock(recursing) == -1) {
+       if (winbind_open_pipe_sock(recursing, need_priv) == -1) {
                return -1;
        }
        
@@ -536,7 +548,8 @@
  * send simple types of requests 
  */
 
-NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request 
*request)
+NSS_STATUS winbindd_send_request(int req_type, int need_priv,
+                                struct winbindd_request *request)
 {
        struct winbindd_request lrequest;
 
@@ -555,12 +568,14 @@
 
        init_request(request, req_type);
        
-       if (write_sock(request, sizeof(*request), request->flags & 
WBFLAG_RECURSE) == -1) {
+       if (write_sock(request, sizeof(*request),
+                      request->flags & WBFLAG_RECURSE, need_priv) == -1) {
                return NSS_STATUS_UNAVAIL;
        }
 
        if ((request->extra_len != 0) &&
-           (write_sock(request->extra_data.data, request->extra_len, 
request->flags & WBFLAG_RECURSE) == -1)) {
+           (write_sock(request->extra_data.data, request->extra_len,
+                       request->flags & WBFLAG_RECURSE, need_priv) == -1)) {
                return NSS_STATUS_UNAVAIL;
        }
        
@@ -610,7 +625,7 @@
        int count = 0;
 
        while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) {
-               status = winbindd_send_request(req_type, request);
+               status = winbindd_send_request(req_type, 0, request);
                if (status != NSS_STATUS_SUCCESS) 
                        return(status);
                status = winbindd_get_response(response);
@@ -620,6 +635,24 @@
        return status;
 }
 
+NSS_STATUS winbindd_priv_request_response(int req_type, 
+                                         struct winbindd_request *request,
+                                         struct winbindd_response *response)
+{
+       NSS_STATUS status = NSS_STATUS_UNAVAIL;
+       int count = 0;
+
+       while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) {
+               status = winbindd_send_request(req_type, 1, request);
+               if (status != NSS_STATUS_SUCCESS) 
+                       return(status);
+               status = winbindd_get_response(response);
+               count += 1;
+       }
+
+       return status;
+}
+
 /*************************************************************************
  A couple of simple functions to disable winbindd lookups and re-
  enable them

Modified: branches/SAMBA_3_0/source/nsswitch/winbind_client.h
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbind_client.h 2007-03-19 21:03:30 UTC 
(rev 21877)
+++ branches/SAMBA_3_0/source/nsswitch/winbind_client.h 2007-03-19 21:04:56 UTC 
(rev 21878)
@@ -2,13 +2,16 @@
 #include "winbindd_nss.h"
 
 void init_request(struct winbindd_request *req,int rq_type);
-NSS_STATUS winbindd_send_request(int req_type,
+NSS_STATUS winbindd_send_request(int req_type, int need_priv,
                                 struct winbindd_request *request);
 NSS_STATUS winbindd_get_response(struct winbindd_response *response);
 NSS_STATUS winbindd_request_response(int req_type, 
                            struct winbindd_request *request,
                            struct winbindd_response *response);
-int write_sock(void *buffer, int count, int recursing);
+NSS_STATUS winbindd_priv_request_response(int req_type, 
+                                         struct winbindd_request *request,
+                                         struct winbindd_response *response);
+int write_sock(void *buffer, int count, int recursing, int need_priv);
 int read_reply(struct winbindd_response *response);
 void close_sock(void);
 void free_response(struct winbindd_response *response);

Modified: branches/SAMBA_3_0/source/nsswitch/winbind_nss_irix.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/winbind_nss_irix.c       2007-03-19 
21:03:30 UTC (rev 21877)
+++ branches/SAMBA_3_0/source/nsswitch/winbind_nss_irix.c       2007-03-19 
21:04:56 UTC (rev 21878)
@@ -454,7 +454,7 @@
        nsd_logprintf(NSD_LOG_MIN,
                "send_next_request (winbind) %d, timeout = %d sec\n",
                        rq->f_cmd_data, timeout);
-       status = winbindd_send_request((int)rq->f_cmd_data,request);
+       status = winbindd_send_request((int)rq->f_cmd_data,request,0);
        SAFE_FREE(request);
 
        if (status != NSS_STATUS_SUCCESS) {

Modified: branches/SAMBA_3_0_25/source/auth/auth_winbind.c
===================================================================
--- branches/SAMBA_3_0_25/source/auth/auth_winbind.c    2007-03-19 21:03:30 UTC 
(rev 21877)
+++ branches/SAMBA_3_0_25/source/auth/auth_winbind.c    2007-03-19 21:04:56 UTC 
(rev 21878)
@@ -108,7 +108,8 @@
 
        /* we are contacting the privileged pipe */
        become_root();
-       result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, 
&response);
+       result = winbindd_priv_request_response(WINBINDD_PAM_AUTH_CRAP,
+                                               &request, &response);
        unbecome_root();
 
        if ( result == NSS_STATUS_UNAVAIL )  {

Modified: branches/SAMBA_3_0_25/source/nsswitch/pam_winbind.c
===================================================================
--- branches/SAMBA_3_0_25/source/nsswitch/pam_winbind.c 2007-03-19 21:03:30 UTC 
(rev 21877)
+++ branches/SAMBA_3_0_25/source/nsswitch/pam_winbind.c 2007-03-19 21:04:56 UTC 
(rev 21878)
@@ -436,7 +436,7 @@
        /* Fill in request and send down pipe */
        init_request(request, req_type);
        
-       if (write_sock(request, sizeof(*request), 0) == -1) {
+       if (write_sock(request, sizeof(*request), 0, 1) == -1) {
                _pam_log(pamh, ctrl, LOG_ERR, "pam_winbind_request: write to 
socket failed!");
                close_sock();
                return PAM_SERVICE_ERR;

Modified: branches/SAMBA_3_0_25/source/nsswitch/wb_common.c
===================================================================
--- branches/SAMBA_3_0_25/source/nsswitch/wb_common.c   2007-03-19 21:03:30 UTC 
(rev 21877)
+++ branches/SAMBA_3_0_25/source/nsswitch/wb_common.c   2007-03-19 21:04:56 UTC 
(rev 21878)
@@ -33,6 +33,7 @@
 /* Global variables.  These are effectively the client state information */
 
 int winbindd_fd = -1;           /* fd for winbindd socket */
+static int is_privileged = 0;
 
 /* Free a response structure */
 
@@ -287,7 +288,7 @@
 
 /* Connect to winbindd socket */
 
-static int winbind_open_pipe_sock(int recursing)
+static int winbind_open_pipe_sock(int recursing, int need_priv)
 {
 #ifdef HAVE_UNIXSOCKET
        static pid_t our_pid;
@@ -300,6 +301,10 @@
                close_sock();
                our_pid = getpid();
        }
+
+       if ((need_priv != 0) && (is_privileged == 0)) {
+               close_sock();
+       }
        
        if (winbindd_fd != -1) {
                return winbindd_fd;
@@ -313,6 +318,8 @@
                return -1;
        }
 
+       is_privileged = 0;
+
        /* version-check the socket */
 
        request.flags = WBFLAG_RECURSE;
@@ -329,9 +336,14 @@
                if ((fd = winbind_named_pipe_sock((char 
*)response.extra_data.data)) != -1) {
                        close(winbindd_fd);
                        winbindd_fd = fd;
+                       is_privileged = 1;
                }
        }
 
+       if ((need_priv != 0) && (is_privileged == 0)) {
+               return -1;
+       }
+
        SAFE_FREE(response.extra_data.data);
 
        return winbindd_fd;
@@ -342,7 +354,7 @@
 
 /* Write data to winbindd socket */
 
-int write_sock(void *buffer, int count, int recursing)
+int write_sock(void *buffer, int count, int recursing, int need_priv)
 {
        int result, nwritten;
        
@@ -350,7 +362,7 @@
        
  restart:
        
-       if (winbind_open_pipe_sock(recursing) == -1) {
+       if (winbind_open_pipe_sock(recursing, need_priv) == -1) {
                return -1;
        }
        
@@ -536,7 +548,8 @@
  * send simple types of requests 
  */
 
-NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request 
*request)
+NSS_STATUS winbindd_send_request(int req_type, int need_priv,
+                                struct winbindd_request *request)
 {
        struct winbindd_request lrequest;
 
@@ -555,12 +568,14 @@
 
        init_request(request, req_type);
        
-       if (write_sock(request, sizeof(*request), request->flags & 
WBFLAG_RECURSE) == -1) {
+       if (write_sock(request, sizeof(*request),
+                      request->flags & WBFLAG_RECURSE, need_priv) == -1) {
                return NSS_STATUS_UNAVAIL;
        }
 
        if ((request->extra_len != 0) &&
-           (write_sock(request->extra_data.data, request->extra_len, 
request->flags & WBFLAG_RECURSE) == -1)) {
+           (write_sock(request->extra_data.data, request->extra_len,
+                       request->flags & WBFLAG_RECURSE, need_priv) == -1)) {
                return NSS_STATUS_UNAVAIL;
        }
        
@@ -610,7 +625,7 @@
        int count = 0;
 
        while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) {
-               status = winbindd_send_request(req_type, request);
+               status = winbindd_send_request(req_type, 0, request);
                if (status != NSS_STATUS_SUCCESS) 
                        return(status);
                status = winbindd_get_response(response);
@@ -620,6 +635,24 @@
        return status;
 }
 
+NSS_STATUS winbindd_priv_request_response(int req_type, 
+                                         struct winbindd_request *request,
+                                         struct winbindd_response *response)
+{
+       NSS_STATUS status = NSS_STATUS_UNAVAIL;
+       int count = 0;
+
+       while ((status == NSS_STATUS_UNAVAIL) && (count < 10)) {
+               status = winbindd_send_request(req_type, 1, request);
+               if (status != NSS_STATUS_SUCCESS) 
+                       return(status);
+               status = winbindd_get_response(response);
+               count += 1;
+       }
+
+       return status;
+}
+
 /*************************************************************************
  A couple of simple functions to disable winbindd lookups and re-
  enable them

Modified: branches/SAMBA_3_0_25/source/nsswitch/winbind_client.h
===================================================================
--- branches/SAMBA_3_0_25/source/nsswitch/winbind_client.h      2007-03-19 
21:03:30 UTC (rev 21877)
+++ branches/SAMBA_3_0_25/source/nsswitch/winbind_client.h      2007-03-19 
21:04:56 UTC (rev 21878)
@@ -2,13 +2,16 @@
 #include "winbindd_nss.h"
 
 void init_request(struct winbindd_request *req,int rq_type);
-NSS_STATUS winbindd_send_request(int req_type,
+NSS_STATUS winbindd_send_request(int req_type, int need_priv,
                                 struct winbindd_request *request);
 NSS_STATUS winbindd_get_response(struct winbindd_response *response);
 NSS_STATUS winbindd_request_response(int req_type, 
                            struct winbindd_request *request,
                            struct winbindd_response *response);
-int write_sock(void *buffer, int count, int recursing);
+NSS_STATUS winbindd_priv_request_response(int req_type, 
+                                         struct winbindd_request *request,
+                                         struct winbindd_response *response);
+int write_sock(void *buffer, int count, int recursing, int need_priv);
 int read_reply(struct winbindd_response *response);
 void close_sock(void);
 void free_response(struct winbindd_response *response);

Modified: branches/SAMBA_3_0_25/source/nsswitch/winbind_nss_irix.c
===================================================================
--- branches/SAMBA_3_0_25/source/nsswitch/winbind_nss_irix.c    2007-03-19 
21:03:30 UTC (rev 21877)
+++ branches/SAMBA_3_0_25/source/nsswitch/winbind_nss_irix.c    2007-03-19 
21:04:56 UTC (rev 21878)
@@ -454,7 +454,7 @@
        nsd_logprintf(NSD_LOG_MIN,
                "send_next_request (winbind) %d, timeout = %d sec\n",
                        rq->f_cmd_data, timeout);
-       status = winbindd_send_request((int)rq->f_cmd_data,request);
+       status = winbindd_send_request((int)rq->f_cmd_data,request,0);
        SAFE_FREE(request);
 
        if (status != NSS_STATUS_SUCCESS) {

Reply via email to