pam application doesn't release sockets

Evgeny Tarasov etarasov.ekb at gmail.com
Mon Jan 24 18:59:24 UTC 2011


Hello, list!

I encountered with some problem using pam library while writing pam 
enabled application.
The program doesn't release some socket after each authentification.

Here is the code:

/*
  * This is a slightly modified example from
  * The Linux-PAM Application Developers' Guide
  *
  * some code was taken from the paper (russian)
  * http://www.opennet.ru/base/net/pam_linux.txt.html
  * ---------------------------------------------

   Original program was contributed by Shane Watts
   [modifications by AGM and kukuk]

   You need to add the following (or equivalent) to the
   /etc/pam.d/check_user file:
   # check authorization
   auth       required     pam_unix.so
   account    required     pam_unix.so
  */

#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <stdio.h>

// Put here real login with it's password
char username[80] = "myuser";
char password[80] = "mypassword";

static int custom_conv(int num_msg, const struct pam_message **msgm,
                       struct pam_response **response, void *appdata_ptr)
{
     struct pam_response *reply;
     int count;

     if (num_msg <= 0)
         return PAM_CONV_ERR;

     reply = (struct pam_response *) calloc(num_msg,
                                            sizeof(struct pam_response));
     if (reply == NULL) {
         return PAM_CONV_ERR;
     }

     for (count=0; count < num_msg; ++count) {
         printf("%s  %d\n",msgm[count]->msg, msgm[count]->msg_style);
         reply[count].resp_retcode = 0;
         reply[count].resp = strdup(password);
     }

     *response = reply;
     reply = NULL;

     return PAM_SUCCESS;
}

int main(int argc, char *argv[])
{
     int retval;
     while (1)
     {
         struct pam_conv conv;
         pam_handle_t *pamh=NULL;

         conv.conv = custom_conv;
         conv.appdata_ptr = NULL;

         retval = pam_start("check_user", username, &conv, &pamh);
         printf("pam_start returned %d\n", retval);

         if (retval == PAM_SUCCESS)
             retval = pam_authenticate(pamh, 0);    /* is user really 
user? */
         printf("pam_authenticate returned %d\n", retval);

         if (retval == PAM_SUCCESS)
             retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
         printf("pam_acct_mgmt returned %d\n", retval);

         /* This is where we have been authorized or not. */

         if (retval == PAM_SUCCESS) {
             fprintf(stdout, "Authenticated\n");
         } else {
             fprintf(stdout, "Not Authenticated\n");
         }

         if (pam_end(pamh,retval) != PAM_SUCCESS) {     /* close 
Linux-PAM */
             pamh = NULL;
             fprintf(stderr, "check_user: failed to release 
authenticator\n");
             exit(1);
         }
         char c;
         printf("please hit enter\n");
         c = getchar();
     }
     return ( retval == PAM_SUCCESS ? 0:1 );       /* indicate success */
}

I compile the program with the command:

$ gcc -lpam test.c

Then I run the program under root:

$ sudo ./a.out
[sudo] password for evgeny:
pam_start returned 0
Password:   1
pam_authenticate returned 0
pam_acct_mgmt returned 0
Authenticated
please hit enter

pam_start returned 0
Password:   1
pam_authenticate returned 0
pam_acct_mgmt returned 0
Authenticated
please hit enter

pam_start returned 0
Password:   1
pam_authenticate returned 0
pam_acct_mgmt returned 0
Authenticated
please hit enter

After that I check open file descriptors for the process (under root):

# lsof -c a.out
lsof: WARNING: can't stat() fuse.gvfs-fuse-daemon file system 
/home/evgeny/.gvfs
       Output information may be incomplete.
COMMAND   PID USER   FD   TYPE     DEVICE SIZE/OFF     NODE NAME
a.out   31532 root  cwd    DIR      253,5     4096    11644 
/home/evgeny/pamtest
a.out   31532 root  rtd    DIR      253,2     4096        2 /
a.out   31532 root  txt    REG      253,5     7024    12165 
/home/evgeny/pamtest/a.out
a.out   31532 root  mem    REG      253,2    58536   295806 
/lib/libnss_files-2.12.2.so
a.out   31532 root  mem    REG      253,2   141532   260241 
/lib/ld-2.12.2.so
a.out   31532 root  mem    REG      253,2  1851728   283873 
/lib/libc-2.12.2.so
a.out   31532 root  mem    REG      253,2    19788   316351 
/lib/libdl-2.12.2.so
a.out   31532 root  mem    REG      253,2   133136   340215 
/lib/libpthread-2.12.2.so
a.out   31532 root  mem    REG      253,2    41728   340216 
/lib/librt-2.12.2.so
a.out   31532 root  mem    REG      253,2    51160   371616 
/lib/libpam.so.0.82.2
a.out   31532 root  mem    REG      253,2    40296   371610 
/lib/libcrypt-2.12.2.so
a.out   31532 root  mem    REG      253,2   287388   338074 
/lib/libfreebl3.so
a.out   31532 root  mem    REG      253,2    93248   371615 
/lib/libaudit.so.1.0.0
a.out   31532 root    0u   CHR      136,9      0t0       12 /dev/pts/9
a.out   31532 root    1u   CHR      136,9      0t0       12 /dev/pts/9
a.out   31532 root    2u   CHR      136,9      0t0       12 /dev/pts/9
a.out   31532 root    3u  unix 0xe19d8000      0t0 14146583 socket
a.out   31532 root    4u  FIFO        0,8      0t0 14146586 pipe
a.out   31532 root    5r  FIFO        0,8      0t0 14146586 pipe
a.out   31532 root    6w  unix 0xf657c000      0t0 14146592 socket
a.out   31532 root    7r  FIFO        0,8      0t0 14146589 pipe
a.out   31532 root    8w  FIFO        0,8      0t0 14146589 pipe
a.out   31532 root    9r  FIFO        0,8      0t0 14146594 pipe
a.out   31532 root   10r  FIFO        0,8      0t0 14146594 pipe
a.out   31532 root   11w  unix 0xd4c68600      0t0 14146600 socket
a.out   31532 root   12u  FIFO        0,8      0t0 14146597 pipe
a.out   31532 root   13w  FIFO        0,8      0t0 14146597 pipe
a.out   31532 root   14r  FIFO        0,8      0t0 14146602 pipe
a.out   31532 root   15w  FIFO        0,8      0t0 14146602 pipe
a.out   31532 root   17r  FIFO        0,8      0t0 14146605 pipe
a.out   31532 root   18w  FIFO        0,8      0t0 14146605 pipe

There is always one open socket for each authentication attempt (100 
after 100 attempts) and this sockets will be never closed.

The version of libpam I'm using:

$ yum info pam-devel
Name        : pam-devel
Arch        : i686
Version     : 1.1.1
Release     : 6.fc13
Size        : 548 k
Repository : installed
 From repo   : updates

Please help me to figure out the cause of the problem. It seems I forgot 
some finalising stuff, but `pam_end` in it's place. Maybe there is 
something else?

Thanks in advance

Best regards,  Evgeny Tarasov




More information about the Pam-list mailing list