Hi all,

I am having a problem authenticating a user/password combination with
Suse Linux 10. The same code that works on other Linux versions fails,
pam_authenticate() always returns "Authentication failed". I know the
combination is correct, as I can "su" with it. The program is running
as root. The system is a default installation with no modifications to
the PAM. So I wonder if there is something peculiar with PAM on Sus
Linux 10. Can't find anything about it on the web. Any ideas would be
appreciated !
Code of the little test program follows below.

TIA,

Chris Breemer


#include
#include
#include

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

printf("pamconv : %d items of size %d\n", num_msg, sizeof(struct
pam_response));
reply = (struct pam_response *) calloc(num_msg, sizeof(struct
pam_response));
if ( !reply )
{
printf("pamconv : ERROR: calloc() failed !\n");
return -1; /* PAM_CONV_ERROR; */
}

for (count=0; count < num_msg; ++count)
{
switch (msgm[count]->msg_style)
{
case PAM_PROMPT_ECHO_OFF:
case PAM_PROMPT_ECHO_ON:
printf("pamconv : '%s'\n", appdata_ptr);
reply[count].resp_retcode = 0;
reply[count].resp = strdup(appdata_ptr);
break;
}
}
*response = reply;
return PAM_SUCCESS;
}



int main (void)
{
char user[81];
char pass[81];
int ret;
int uid;

pam_handle_t *pamh = NULL;
struct pam_conv conv;

uid = getuid();
printf("username: ");
fgets((char*)user, 80, stdin);
user[strlen(user)-1] = 0;

printf("password: ");
fgets((char*)pass, 80, stdin);
pass[strlen(pass)-1] = 0;

printf("PAM Authenticating username '%s', password '%s'\n", user,
pass);
printf("Current user id = %d (%s)\n", uid, uid ? "NON-ROOT" :
"ROOT");

if ( !user || !*user )
{
printf("Null or zero-length username, authentication
FAILED.\n");
return 0;
}

if ( !pass || !*pass )
{
printf("Null or zero-length password, authentication
FAILED.\n");
return 0;
}

conv.appdata_ptr = (void *)pass;
conv.conv = pamconv;

ret = pam_start("system-auth", user, &conv, &pamh);
printf("pam_start message: '%s'\n", pam_strerror(pamh, ret));
if ( ret != PAM_SUCCESS )
{
printf("pam_start() failed, retcode = %d\n", ret);
return 0;
}

ret = pam_authenticate(pamh, 0);
printf("pam_authenticate message: '%s'\n", pam_strerror(pamh,
ret));
switch (ret)
{
case PAM_SUCCESS:
printf("User '%s' succesfully authenticated\n", user);
break;

case PAM_AUTH_ERR:
printf("User '%s' authentication failed\n", user);
(void)pam_end(pamh, ret);
return 0;

default:
printf("User '%s' pam_authenticate() failed, returncode %d
\n", user, ret);
(void)pam_end(pamh, ret);
return 0;
}

ret = pam_acct_mgmt(pamh, 0); /* permitted access? */
printf("pam_acct_mgmt: '%s'\n", pam_strerror(pamh, ret));

switch (ret)
{
case PAM_SUCCESS:
printf("User '%s' is permitted account access\n", user);
break;

case PAM_AUTH_ERR:
printf("User '%s' has no account permission\n", user);
(void)pam_end(pamh, ret);
return 0;

default:
printf("User '%s' has no account permission,
pam_acct_mgmt() returned %d\n", user,
ret);
return 0;
}

ret = pam_end(pamh, ret);
printf("pam_end: '%s'\n", pam_strerror(pamh, ret));
if ( ret != PAM_SUCCESS )
{
printf("User '%s' not authorized, pam_end() returned %d\n",
user, ret);
return 0;
}

printf("User/password authenticationt OK !\n");
return 0;
}