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) {