ssh를 통해 입력한 사용자의 사용자 이름과 비밀번호를 얻으려고 하는데 등록된 사용자와 등록되지 않은 사용자(Ubuntu 사용자)의 비밀번호만 볼 수 있고 "INC"라는 문자열이 표시됩니다. Ubuntu 인증을 대체하고 사용자가 내 데이터베이스를 통해 합법적인지 테스트하고 그렇다면 기본 사용자와 비밀번호를 리디렉션하려고 합니다. 내 코드:
int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
const char *user = NULL;
const char * password=NULL;
int pgu_ret, snp_ret, a_ret,retVal=0;
int i =0,pam_err=0;
FILE * fp =fopen("/var/log/test_pam_debug.txt","a");
fprintf(fp,"pam_sm_authenticate function start \n");
pgu_ret = pam_get_user(pamh, &user, NULL);
if (pgu_ret != PAM_SUCCESS || user == NULL) {
fprintf(fp,"pam_sm_authenticate get user failed \n");
fclose(fp);
return(PAM_IGNORE);
}
else
fprintf(fp,"pam_sm_authenticate user :%s \n",user);
/* get this user's authentication token */
retVal = pam_get_authtok(pamh, PAM_AUTHTOK, &password , NULL);
if (retVal != PAM_SUCCESS) {
if (retVal != PAM_CONV_AGAIN)
{
fprintf(fp,"auth could not identify password for [%s]\n", user);
}
else
{
fprintf(fp,"conversation function is not ready yet \n");
}
fclose(fp);
fprintf(fp,"retVal : %d \n ",retVal);
return(retVal);
}
else if(password)
fprintf(fp,"user=%s, password=[%s]\n", user,password);
/*TODO : here i will check the user && pasword via db in if so continue else return PAM_USER_UNKNOWN*/
if ((pam_err = pam_set_item(pamh, PAM_RUSER, "default_user")) != PAM_SUCCESS)
{ printf("\n pam_set_item( pamh, PAM_RUSER, rad) error msg : %s and return code : %d \n ", pam_strerror(pamh, pam_err),pam_err);
fclose(fp);
return(PAM_USER_UNKNOWN);
}
if ((pam_err = pam_set_item(pamh, PAM_AUTHTOK, "default_userPwd")) != PAM_SUCCESS)
{
printf("\n pam_set_item( pamh, PAM_AUTHTOK, rad123) error msg : %s and return code : %d \n ", pam_strerror(pamh, pam_err),pam_err);
fclose(fp);
return(PAM_CRED_INSUFFICIENT);
}
fclose(fp);
return(PAM_SUCCESS);
}
적절한 인증을 .so
위해 이것을 컴파일 하고 추가했습니다./etc/pam.d/sshd
/lib/x86_64-linux-gnu/security/pam_test.so
지문이 찍혀 있어요/var/log/test_pam_debug.txt
user=wewe, password=[ ]
알 수 없거나 때로는
2.. user=jhjh, password=[ IN]
알려진 사용자의 경우 사용자의 비밀번호를 인쇄합니다(사용자가 입력한 비밀번호가 아니며 변경할 수 없는 것 같습니다).
답변1
발견된 문제점은 다음과 같습니다.https://www.linuxquestions.org/questions/programming-9/can%27t-get-auth-token-for-non-local-users-with-pam-module-945164/
기본적으로 문제는 알 수 없는 사용자로부터 비밀번호를 얻을 수 없다는 것입니다. \b\n\r\177INCORRECT
Linux PAM은 시스템 데이터베이스(서비스 스위치 이름 지정, man nsswitch.conf 참조)에서 사용자에 대한 정보를 얻을 수 없는 경우 비밀번호를 대체합니다. 가능한 해결 방법은 getpawn을 사용하여 사용자가 존재하는지 확인하는 것입니다. 예:
/* The actual pam functions are merely wrappers around succeed_if */
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
const char * password=NULL;
struct passwd *pwd;
const char *user;
int pam_err=0;
/* identify user */
pam_err = pam_get_user(pamh, &user, NULL);
if (pam_err != PAM_SUCCESS)
{
return (pam_err);
}
if ((pwd = getpwnam(user)) == NULL)
{
return (PAM_USER_UNKNOWN);
}
/* note : if user is not defined password return will be "^H$^M^?INCORRECT^@" */
pam_err = pam_get_authtok(pamh, PAM_AUTHTOK, &password , NULL);
if (pam_err!=PAM_SUCCESS)
{
return (pam_err);
}
/* here add personal auhtentication */
pam_err = isAuthenticate((char *)user,(char *)password);
if (pam_err != PAM_OK)
{
return (PAM_AUTH_ERR);
}
return (PAM_SUCCESS);
}