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
_______________________________________________
Pam-list mailing list
Pam-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/pam-list