This affects 3.0alpha19 and all previous versions of pam_winbind.so
AFAICS

Long running PAM clients can cause PAM to repeatedly load and unload
pam_winbind.so. When this happens the client application will leak
file descriptors if a request was made to winbindd while the library
was loaded.

The problem occurs because pam_winbind.c never closes the winbindd
socket. When pam_winbind.so is loaded for the life of the application
this doesn't cause an FD leak as the wb_common routines keep the
socket file descriptor in winbindd_fd and reuse it.

However the socket is not closed when the shared library is unloaded,
if PAM then reloads pam_winbind. a new copy of winbindd_fd is created
with an initial value of -1 causing a new connection to be established
to winbindd.

One such PAM client is the Cyrus saslauthd, which I use together with
pam_winbind to authenticate IMAP logins. Saslauthd and winbindd wound
up running out of file descriptors every 12-24 hours.

The following patch fixes the problem on Linux but is gcc specific.
Unfortunately I don't have any other compilers to try.


Index: pam_winbind.c
===================================================================
RCS file: /cvsroot/samba/source/nsswitch/pam_winbind.c,v
retrieving revision 1.14
diff -c -r1.14 pam_winbind.c
*** pam_winbind.c       24 Jul 2002 03:13:43 -0000      1.14
--- pam_winbind.c       29 Aug 2002 11:37:01 -0000
***************
*** 15,20 ****
--- 15,21 ----
  void init_request(struct winbindd_request *req,int rq_type);
  int write_sock(void *buffer, int count);
  int read_reply(struct winbindd_response *response);
+ int close_sock(void);
  
  /* data tokens */
  
***************
*** 468,473 ****
--- 469,475 ----
  
      /* Verify the username */
      retval = valid_user(username);
+ 
      switch (retval) {
        case -1:
            /* some sort of system error. The log was already printed */
***************
*** 673,678 ****
--- 675,687 ----
        }
        
        return retval;
+ }
+ 
+ void __attribute__ ((destructor))  unload () 
+ {
+       /* Make sure socket is closed on unload of dll, some apps use PAM in
+          a manner which leaks FDs otherwise */
+       close_sock();
  }
  
  #ifdef PAM_STATIC
Index: wb_common.c
===================================================================
RCS file: /cvsroot/samba/source/nsswitch/wb_common.c,v
retrieving revision 1.17
diff -c -r1.17 wb_common.c
*** wb_common.c 17 Aug 2002 05:26:58 -0000      1.17
--- wb_common.c 29 Aug 2002 11:37:01 -0000
***************
*** 75,81 ****
  
  /* Close established socket */
  
! static void close_sock(void)
  {
        if (winbindd_fd != -1) {
                close(winbindd_fd);
--- 75,81 ----
  
  /* Close established socket */
  
! void close_sock(void)
  {
        if (winbindd_fd != -1) {
                close(winbindd_fd);


Reply via email to