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