3.1. 응용에서 기대할 수 있는 것

3.1.1. PAM 트랜잭션 초기화하기

#include <security/pam_appl.h>
int pam_start(service_name,  
 user,  
 pam_conversation,  
 pamh); 
const char *service_name;
const char *user;
const struct pam_conv *pam_conversation;
pam_handle_t **pamh;
 
int pam_start_confdir(service_name,  
 user,  
 pam_conversation,  
 confdir,  
 pamh); 
const char *service_name;
const char *user;
const struct pam_conv *pam_conversation;
const char *confdir;
pam_handle_t **pamh;
 

3.1.1.1. 설명

pam_start 함수는 PAM 문맥을 만들고 PAM 트랜잭션을 초기화한다. 응용에서 처음으로 호출해야 하는 PAM 함수다. 핸들이 나타내는 구조체에 트랜잭션 상태가 모두 담기게 되므로 동시에 여러 트랜잭션을 만들 수도 있다. 하지만 한 핸들을 여러 트랜잭션에 사용하는 건 불가능하다. 새 문맥마다 새 핸들이 필요하다.

service_name 인자는 신청할 서비스 이름을 나타내며 새 문맥에 PAM_SERVICE 항목으로 저장된다. /etc/pam.d/service_name 파일에서, 또는 그 파일이 존재하지 않으면 /etc/pam.conf 파일에서 서비스 정책을 읽어 들이게 된다.

user 인자는 대상 사용자의 이름을 나타내며 PAM_USER 항목으로 저장된다. 이 인자가 NULL이면 모듈에서 필요시 이 항목을 묻게 된다.

pam_conversation 인자는 사용할 대화 함수를 기술하는 struct pam_conv를 가리킨다. 응용에서 제공하는 이 함수를 통해 적재된 모듈과 응용이 직접 소통한다.

성공 반환(PAM_SUCCESS) 시 pamh의 내용물이 PAM 문맥을 담은 핸들이 되며, 이를 이후 PAM 함수 호출에 쓰게 된다. 오류 발생 시 pamh의 내용물은 규정돼 있지 않다.

pam_handle_t는 내부가 감춰진 구조체이며 응용에서 그 구조체 안의 정보를 직접 읽으려고 해선 안 된다. 대신 PAM 라이브러리에서 pam_set_item(3)pam_get_item(3) 함수를 제공한다. pam_end를 호출하기 전에는 PAM 핸들을 다른 인증에 동시에 사용할 수 없다.

pam_start_confdir 함수는 pam_start 함수처럼 동작하되 confdir 인자에 디렉터리 경로를 설정해서 서비스 정책 파일 기본 경로(/etc/pam.d)를 바꿀 수 있다. confdir이 NULL이면 pam_start와 똑같이 동작한다.

3.1.1.2. 반환 값

PAM_ABORT

일반 오류.

PAM_BUF_ERR

메모리 버퍼 오류.

PAM_SUCCESS

트랜잭션이 성공적으로 시작됐음.

PAM_SYSTEM_ERR

시스템 오류. 예를 들어 데이터에 대한 포인터가 아니라 NULL 포인터를 줬음.

3.1.2. PAM 트랜잭션 종결하기

#include <security/pam_appl.h>
int pam_end(pamh,  
 pam_status); 
pam_handle_t *pamh;
int pam_status;
 

3.1.2.1. 설명

pam_end 함수는 PAM 트랜잭션을 종결한다. PAM 문맥에서 응용이 호출해야 하는 마지막 함수다. 반환 후에는 pamh 핸들이 더 이상 유효하지 않으며 그 핸들에 연계된 모든 메모리가 유효하지 않게 된다.

pam_status 인자는 최근 PAM 라이브러리 호출에서 응용으로 반환한 값으로 설정해야 한다.

pam_status의 값을 모듈별 콜백 함수 cleanup()에 인자로 사용한다. (pam_set_data(3)pam_get_data(3) 참고.) 이런 방식으로 종료 과정의 성공/실패를 모듈에서 알게 되고, 그 모듈에 적합한 최종 작업이 있으면 마지막으로 수행할 수 있게 된다. 이 인자에 PAM_DATA_SILENT를 논리 OR 해서 그 호출을 모듈에서 너무 심각하게 다룰 필요는 없다고 표시할 수 있다. 일반적으로는 fork(2) 된 프로세스에서 라이브러리 종료를 하고 있으며 현재 프로세스 공간 밖에 존재하는 것들(파일 등)을 정리하는 건 부모가 맡을 것이라는 의미다.

이 함수에선 pam_set_item(3)pam_get_item(3) 함수와 관련된 모든 항목의 메모리를 free한다. 그런 객체들과 연관된 포인터가 pam_end 호출 후에는 더는 유효하지 않게 된다.

3.1.2.2. 반환 값

PAM_SUCCESS

트랜잭션이 성공적으로 종결되었음.

PAM_SYSTEM_ERR

시스템 오류. 예를 들어 PAM 핸들로 NULL 포인터를 줬거나 모듈에서 함수를 호출했음.

3.1.3. PAM 항목 설정하기

#include <security/pam_modules.h>
int pam_set_item(pamh,  
 item_type,  
 item); 
pam_handle_t *pamh;
int item_type;
const void *item;
 

3.1.3.1. 설명

pam_set_item 함수를 사용해 응용과 PAM 서비스 모듈에서 item_type이 나타내는 PAM 정보에 접근해 값을 갱신할 수 있다. 이를 위해 item 인자가 가리키는 객체의 사본을 만든다. 다음 item_type을 지원한다.

PAM_SERVICE

서비스 이름. (PAM 함수들에서 프로그램을 인증하는 데 이용할 PAM 스택을 나타낸다.)

PAM_USER

사용자 이름. 그 신원으로 서비스가 제공된다. 즉, 인증 후에 PAM_USER는 서비스를 이용하게 된 로컬 개체를 나타낸다. 참고로 PAM 스택의 모듈에서 이 값을 뭔가(예: "anonymous")에서 다른 뭔가(예: "guest119")로 매핑할 수 있다. 그러므로 응용에선 PAM 함수를 호출한 다음에 PAM_USER의 값을 확인해 봐야 한다.

PAM_USER_PROMPT

사용자 이름을 물을 때 보일 문자열. 이 문자열의 기본값은 "login: "의 지역화 버전이다.

PAM_TTY

터미널 이름. 장치 파일이면 앞에 /dev/가 붙는다. X 기반의 그래픽 응용에서 이 항목의 값은 $DISPLAY 변수여야 한다.

PAM_RUSER

요청하는 사용자의 이름. 지역에서 요청하는 사용자면 지역의 이름이고 원격에서 요청하는 사용자면 원격의 사용자 이름.

일반적으로 응용 내지 모듈에서는 강력하게 인증된 쪽을 (원격 계정보다는 로컬 계정을) 값으로 제공하려 하게 된다. 이 값의 신뢰성은 응용에 결부된 실제 인증 스택에 따라 정해지고, 그래서 궁극적으로 시스템 관리자에게 달려 있다.

PAM_RUSER@PAM_RHOST가 항상 요청하는 사용자를 나타낼 것이다. 일부 경우에선 PAM_RUSER가 비어 있을 수 있다. 그 경우는 요청하는 개체가 누구인지 분명하지 않은 것이다.

PAM_RHOST

요청하는 호스트의 이름 (PAM_RUSER 개체가 서비스를 요청하고 있는 머신의 호스트명). 즉 PAM_RUSER@PAM_RHOST가 요청하는 사용자를 나타낸다. 일부 응용에서는 PAM_RHOST가 NULL일 수 있다. 그 경우는 인증 요청이 어디서 오는 것인지 분명하지 않은 것이다.

PAM_AUTHTOK

인증 토큰 (보통은 패스워드). pam_sm_authenticate(3)pam_sm_chauthtok(3)을 제외한 모듈 함수들에선 이 토큰을 무시해야 한다. 앞쪽 함수에선 한 모듈에서 다른 모듈로 최신 인증 토큰을 전달하는 데 쓴다. 뒤쪽 함수에선 다른 용도로 쓰는데, 현재 활성인 인증 토큰을 담는다.

PAM_OLDAUTHTOK

이전 인증 토큰. pam_sm_chauthtok(3)을 제외한 모듈 함수들에선 이 토큰을 무시해야 한다.

PAM_CONV

pam_conv 구조체. pam_conv(3) 참고.

다음 추가 항목들은 Linux-PAM 한정이므로 이식 가능한 응용에선 쓰지 말아야 한다.

PAM_FAIL_DELAY

실패 시 지연 공통 동작 방식을 바꾸기 위한 함수 포인터. pam_fail_delay(3) 참고.

PAM_XDISPLAY

X 디스플레이 이름. X 기반의 그래픽 응용에서 이 항목의 값은 $DISPLAY 변수여야 한다. PAM_TTY와 독립적으로 디스플레이 이름을 전달하는 데 이 값을 쓸 수 있다.

PAM_XAUTHDATA

필요시 PAM_XDISPLAY에 지정된 디스플레이로 연결하기 위해 필요한 X 인증 데이터를 담은 구조체에 대한 포인터. pam_xauth_data(3) 참고.

PAM_AUTHTOK_TYPE

기본적으로 모듈에서 패스워드를 요청할 때 "New UNIX password: " 및 "Retype UNIX passwords: " 프롬프트를 쓴다. 여기서 단어 UNIX를 이 항목으로 바꿀 수 있으며, 기본은 비어 있다. pam_get_authtok(3)에서 이 항목을 사용한다.

PAM_CONV와 PAM_FAIL_DELAY를 제외한 모든 item_type에서 item은 <NUL> 종료 문자열에 대한 포인터다. PAM_CONV에서 item은 초기화된 pam_conv 구조체를 가리킨다. PAM_FAIL_DELAY의 경우 itemvoid (*delay_fn)(int retval, unsigned usec_delay, void *appdata_ptr) 함수 포인터다.

PAM_AUTHOK과 PAM_OLDAUTHTOK 모두 응용으로 반환하기 전에 재설정된다. 즉 응용에서는 인증 토큰에 접근할 수 없다.

3.1.3.2. 반환 값

PAM_BAD_ITEM

정의돼 있지 않거나 접근 불가능한 항목을 설정하려 했음.

PAM_BUF_ERR

메모리 버퍼 오류.

PAM_SUCCESS

데이터가 성공적으로 갱신되었음.

PAM_SYSTEM_ERR

첫 번째 인자로 준 pam_handle_t 인자가 유효하지 않음.

3.1.4. PAM 항목 얻기

#include <security/pam_modules.h>
int pam_get_item(pamh,  
 item_type,  
 item); 
const pam_handle_t *pamh;
int item_type;
const void **item;
 

3.1.4.1. 설명

pam_get_item 함수를 사용해 응용과 PAM 서비스 모듈에서 item_type이 나타내는 PAM 정보에 접근해 값을 가져올 수 있다. 성공 반환 시 item이 해당 항목의 값에 대한 포인터를 담고 있다. 참고로 실제 데이터에 대한 포인터이므로 free() 하거나 덮어 쓰면 안 된다. item_type으로 다음 값들을 지원한다.

PAM_SERVICE

서비스 이름. (PAM 함수들에서 프로그램을 인증하는 데 이용할 PAM 스택을 나타낸다.)

PAM_USER

사용자 이름. 그 신원으로 서비스가 제공된다. 즉, 인증 후에 PAM_USER는 서비스를 이용하게 된 로컬 개체를 나타낸다. 참고로 PAM 스택의 모듈에서 이 값을 뭔가(예: "anonymous")에서 다른 뭔가(예: "guest119")로 매핑할 수 있다. 그러므로 응용에선 PAM 함수를 호출한 다음에 PAM_USER의 값을 확인해 봐야 한다.

PAM_USER_PROMPT

사용자 이름을 물을 때 보일 문자열. 이 문자열의 기본값은 "login: "의 지역화 버전이다.

PAM_TTY

터미널 이름. 장치 파일이면 앞에 /dev/가 붙는다. X 기반의 그래픽 응용에서 이 항목의 값은 $DISPLAY 변수여야 한다.

PAM_RUSER

요청하는 사용자의 이름. 로컬에서 요청하는 사용자면 로컬의 이름이고 원격에서 요청하는 사용자면 원격의 사용자 이름.

일반적으로 응용 내지 모듈에서는 강력하게 인증된 쪽을 (원격 계정보다는 로컬 계정을) 값으로 제공하려 하게 된다. 이 값의 신뢰성은 응용에 결부된 실제 인증 스택에 따라 정해지고, 그래서 궁극적으로 시스템 관리자에게 달려 있다.

PAM_RUSER@PAM_RHOST가 항상 요청하는 사용자를 나타내게 된다. 일부 경우에는 PAM_RUSER가 NULL일 수 있다. 그 경우는 요청하는 개체가 누구인지 분명하지 않은 것이다.

PAM_RHOST

요청하는 호스트의 이름 (PAM_RUSER 개체가 서비스를 요청하고 있는 머신의 호스트명). 즉 PAM_RUSER@PAM_RHOST가 요청하는 사용자를 나타낸다. 일부 응용에서는 PAM_RHOST가 NULL일 수 있다. 그 경우는 인증 요청이 어디서 오는 것인지 분명하지 않은 것이다.

PAM_AUTHTOK

인증 토큰 (보통은 패스워드). pam_sm_authenticate(3)pam_sm_chauthtok(3)을 제외한 다른 모듈 함수에선 이 토큰을 무시해야 한다. 앞쪽 함수에선 한 모듈에서 다른 모듈로 최신 인증 토큰을 전달하는 데 쓴다. 뒤쪽 함수에선 다른 용도로 쓰는데, 현재 활성인 인증 토큰을 담는다.

PAM_OLDAUTHTOK

이전 인증 토큰. pam_sm_chauthtok(3)을 제외한 다른 모듈 함수에선 이 토큰을 무시해야 한다.

PAM_CONV

pam_conv 구조체. pam_conv(3) 참고.

다음 추가 항목들은 Linux-PAM 한정이므로 이식 가능한 응용에선 쓰지 말아야 한다.

PAM_FAIL_DELAY

실패 시 지연 공통 동작 방식을 바꾸기 위한 함수 포인터. pam_fail_delay(3) 참고.

PAM_XDISPLAY

X 디스플레이 이름. X 기반의 그래픽 응용에서 이 항목의 값은 $DISPLAY 변수여야 한다. PAM_TTY와 독립적으로 디스플레이 이름을 전달하는 데 이 값을 쓸 수 있다.

PAM_XAUTHDATA

필요시 PAM_XDISPLAY에 지정된 디스플레이로 연결하기 위해 필요한 X 인증 데이터를 담은 구조체에 대한 포인터. pam_xauth_data(3) 참고.

PAM_AUTHTOK_TYPE

기본적으로 모듈에서 패스워드를 요청할 때 "New UNIX password: " 및 "Retype UNIX passwords: " 프롬프트를 쓴다. 여기서 단어 UNIX를 이 항목으로 바꿀 수 있으며, 기본은 비어 있다. pam_get_authtok(3)에서 이 항목을 사용한다.

서비스 모듈에서 사용자의 이름을 얻고 싶으면 이 함수를 쓰지 말고 pam_get_user(3) 호출을 수행해야 한다.

서비스 모듈에서만 PAM_AUTHTOK 및 PAM_OLDAUTHTOK으로 인증 토큰을 읽을 권한이 있다.

3.1.4.2. 반환 값

PAM_BAD_ITEM

정의돼 있지 않거나 접근 불가능한 항목을 설정하려 했음.

PAM_BUF_ERR

메모리 버퍼 오류.

PAM_PERM_DENIED

item의 값이 NULL임.

PAM_SUCCESS

데이터가 성공적으로 갱신되었음.

PAM_SYSTEM_ERR

첫 번째 인자로 준 pam_handle_t 인자가 유효하지 않음.

3.1.5. PAM 오류 코드 서술 문자열

#include <security/pam_appl.h>
const char *pam_strerror(pamh,  
 errnum); 
pam_handle_t *pamh;
int errnum;
 

3.1.5.1. 설명

pam_strerror 함수는 인자 errnum로 준 오류 코드를 설명하는 문자열에 대한 포인터를 반환한다. 가능한 경우 현재 로캘의 LC_MESSAGES 부분을 사용해 적절한 언어를 선택한다. 응용에서 그 문자열을 변경해선 안 된다. 어떤 라이브러리 함수에서도 그 문자열을 변경하지 않을 것이다.

3.1.5.2. 반환 값

이 함수는 항상 문자열 포인터를 반환한다.

3.1.6. 실패 시 지연 요청하기

#include <security/pam_appl.h>
int pam_fail_delay(pamh,  
 usec); 
pam_handle_t *pamh;
unsigned int usec;
 

3.1.6.1. 설명

pam_fail_delay 함수는 응용이나 모듈에서 usec 마이크로초의 최소 지연 시간을 제안할 수 있는 방법을 제공한다. 이 함수로 요청한 가장 긴 시간이 기록된다. pam_authenticate(3)가 실패하면 응용으로 실패를 반환하는 동작이 그 가장 긴 값 정도의 (50%까지의) 난수 분포 시간만큼 지연된다.

성공 여부와 무관하게 PAM 서비스 모듈에서 응용으로 제어가 반환될 때 지연 시간이 기본값 0으로 재설정된다. 인증 모듈들이 호출된 후이자 서비스 응용으로 제어가 반환되기는 전에 지연이 이뤄진다.

이 함수를 쓸 때 프로그래머는 다음처럼 이용 가능 여부를 확인해야 한다.

#ifdef HAVE_PAM_FAIL_DELAY
    ....
#endif /* HAVE_PAM_FAIL_DELAY */
      

이벤트 주도 방식으로 작성된 단일 스레드 응용에서는 이렇게 지연을 만드는 게 바람직하지 않을 수도 있다. 응용에서 어떤 다른 방식으로 지연을 처리하고 싶을 수 있다. 예를 들어 단일 이벤트 루프에서 여러 인증 요청을 처리하는 단일 스레드 서버라면 응용의 타이머가 만료될 때까지 해당 연결에 차단 표시만 해 두고 싶을 수 있다. 그런 이유로 지연 함수를 PAM_FAIL_DELAY 항목으로 교체할 수 있다. pam_get_item(3)pam_set_item(3)으로 질의하고 설정할 수 있다. 설정하는 값은 다음 원형의 함수 포인터여야 한다.

void (*delay_fn)(int retval, unsigned usec_delay, void *appdata_ptr);
      

인자 retval은 모듈 스택의 반환 코드이고, usec_delay는 libpam에서 요청하는 마이크로초 단위 지연 시간이다. 그리고 appdata_ptr은 현재 pamh에 응용에서 연계시켜 둔 값이다. 이 마지막 인자는 pam_start(3)를 호출할 때, 또는 명시적으로 pam_set_item(3)를 호출해서 응용에서 설정해 둔 값이다.

참고로 PAM_FAIL_DELAY 항목은 기본적으로 NULL로 설정돼 있다. 이는 인증이 실패하고 지연이 제안됐을 때 위에서 설명한 것처럼 PAM에서 임이 길이로 지연을 수행한다는 뜻이다. 인증 실패 시 PAM 라이브러리에서 지연을 수행하는 걸 응용에서 원치 않는다면 아무것도 실행하지 않는 자체 지연 함수를 정의하고 PAM_FAIL_DELAY 항목이 그 함수를 가리키게 설정해야 한다.

3.1.6.2. 반환 값

PAM_SUCCESS

지연 시간이 성공적으로 조정되었음.

PAM_SYSTEM_ERR

PAM 핸들로 NULL 포인터를 줬음.

3.1.7. 사용자 인증하기

#include <security/pam_appl.h>
int pam_authenticate(pamh,  
 flags); 
pam_handle_t *pamh;
int flags;
 

3.1.7.1. 설명

pam_authenticate 함수를 이용해 사용자를 인증한다. 사용자는 인증 서비스에 따라 인증 토큰을 제공해야 하는데, 일반적으로 패스워드이지만 지문 같은 게 될 수도 있다.

PAM 서비스 모듈에서 사용자에게 대화 메커니즘을 통해 사용자명 입력을 요청할 수도 있다. (pam_start(3)pam_conv(3) 참고.) 인증된 사용자의 이름이 PAM 항목 PAM_USER가 된다. pam_get_item(3) 호출로 그 항목을 얻을 수 있다.

pamh 인자는 앞선 pam_start() 호출로 얻은 인증 핸들이다. flags 인자는 다음 값을 0개 이상 조합한 것이다.

PAM_SILENT

어떤 메시지도 찍지 않기.

PAM_DISALLOW_NULL_AUTHTOK

사용자에게 등록된 인증 토큰이 없으면 PAM 모듈 서비스가 PAM_AUTH_ERR를 반환해야 한다.

3.1.7.2. 반환 값

PAM_ABORT

응용에서 즉시 pam_end(3)를 호출하고 종료해야 함.

PAM_AUTH_ERR

사용자가 인증되지 않았음.

PAM_CRED_INSUFFICIENT

어떤 이유로 사용자를 인증하기 위한 크리덴셜이 충분치 않다.

PAM_AUTHINFO_UNAVAIL

모듈에서 인증 정보에 접근할 수 없었다. 네트워크나 하드웨어 장애 등이 원인일 수 있다.

PAM_MAXTRIES

인증 모듈들 중 하나 이상에서 사용자 인증 시도 최대 횟수에 도달했다. 재시도 하지 말 것.

PAM_SUCCESS

사용자가 성공적으로 인증됐음.

PAM_USER_UNKNOWN

인증 서비스에서 알지 못하는 사용자.

3.1.8. 사용자 크리덴셜 설정하기

#include <security/pam_appl.h>
int pam_setcred(pamh,  
 flags); 
pam_handle_t *pamh;
int flags;
 

3.1.8.1. 설명

pam_setcred 함수를 이용해 사용자의 크리덴셜을 설정하고, 관리하고, 삭제한다. 사용자를 인증한 후에 (pam_open_session(3)으로) 사용자 세션을 열기 전에 호출해서 크리덴셜을 설정해야 한다. (pam_close_session(3)으로) 세션을 닫은 후에 크리덴셜을 삭제해야 한다.

크리덴셜이란 사용자가 소유한 뭔가이다. 커베로스 티켓 같은 어떤 소유물일 수도 있고 해당 사용자의 유일성을 구성하는 보조 그룹 멤버십일 수도 있다. 리눅스 시스템의 사용자 UIDGID도 크리덴셜이다. 하지만 이 속성들은 (사용자가 소속된 기본 추가 그룹들과 더불어) PAM이 아니라 응용에서 직접 설정해야 하는 크리덴셜이라고 결정됐다. 그런 크리덴셜들은 이 함수 호출 전에 응용에서 설정해야 한다. 예를 들어 initgroups(2)를 (또는 동등한 동작을) 수행해야 한다.

유효한 flags는 다음 중 하나이며, PAM_SILENT를 논리 OR 할 수도 있다.

PAM_ESTABLISH_CRED

사용자의 크리덴셜 설정.

PAM_DELETE_CRED

사용자의 크리덴셜 삭제.

PAM_REINITIALIZE_CRED

사용자의 크리덴셜 전체 재설정.

PAM_REFRESH_CRED

기존 크리덴셜의 수명 연장.

3.1.8.2. 반환 값

PAM_BUF_ERR

메모리 버퍼 오류.

PAM_CRED_ERR

사용자 크리덴셜을 설정하는 데 실패했음.

PAM_CRED_EXPIRED

사용자 크리덴셜이 만료되었음.

PAM_CRED_UNAVAIL

사용자 크리덴셜을 가져오는 데 실패했음.

PAM_SUCCESS

데이터가 성공적으로 저장되었음.

PAM_SYSTEM_ERR

PAM 핸들로 NULL 포인터를 줬거나, 모듈에서 함수를 호출했거나, 다른 시스템 오류가 발생했음.

PAM_USER_UNKNOWN

인증 모듈에서 알지 못하는 사용자.

3.1.9. 계정 유효성 관리하기

#include <security/pam_appl.h>
int pam_acct_mgmt(pamh,  
 flags); 
pam_handle_t *pamh;
int flags;
 

3.1.9.1. 설명

pam_acct_mgmt 함수를 이용해 사용자의 계정이 유효한지 알아낸다. 인증 토큰과 계정의 만료 여부를 확인하고 접근 제약 조건을 검사한다. 보통 사용자 인증이 끝난 후에 호출한다.

pamh 인자는 앞선 pam_start() 호출로 얻은 인증 핸들이다. flags 인자는 다음 값을 0개 이상 조합한 것이다.

PAM_SILENT

어떤 메시지도 찍지 않기.

PAM_DISALLOW_NULL_AUTHTOK

사용자에게 인증 토큰이 없으면 PAM 모듈 서비스가 PAM_NEW_AUTHTOK_REQD를 반환해야 한다.

3.1.9.2. 반환 값

PAM_ACCT_EXPIRED

사용자 계정이 만료되었음.

PAM_AUTH_ERR

인증 실패.

PAM_NEW_AUTHTOK_REQD

사용자 계정이 유효하지만 인증 토큰이 만료됐다. 이 반환 값에 대한 올바른 대응은 사용자가 pam_chauthtok() 함수를 성공적으로 거친 후에 서비스를 받을 수 있게 하는 것이다. 어떤 응용에서는 이렇게 하는 게 불가능할 수도 있다. 그런 경우에는 사용자가 자기 패스워드를 갱신할 수 있게 될 때까지 접근을 거부해야 한다.

PAM_PERM_DENIED

권한 거부됨.

PAM_SUCCESS

인증 토큰이 성공적으로 갱신되었음.

PAM_USER_UNKNOWN

패스워드 서비스에서 알지 못하는 사용자.

3.1.10. 인증 토큰 갱신하기

#include <security/pam_appl.h>
int pam_chauthtok(pamh,  
 flags); 
pam_handle_t *pamh;
int flags;
 

3.1.10.1. 설명

pam_chauthtok 함수를 이용해 (pamh 핸들에 결속된 상태가 나타내는) 해당 사용자의 인증 토큰을 바꾼다.

pamh 인자는 앞선 pam_start() 호출로 얻은 인증 핸들이다. flags 인자는 다음 값을 0개 이상 조합한 것이다.

PAM_SILENT

어떤 메시지도 찍지 않기.

PAM_CHANGE_EXPIRED_AUTHTOK

사용자의 인증 토큰(패스워드)이 만료된 경우에만 바꿔야 한다고 모듈에게 알린다. 응용에서 이 인자를 주지 않으면 항상 인증 토큰을 바꿔야 한다고 요구하는 것이다.

3.1.10.2. 반환 값

PAM_AUTHTOK_ERR

어느 모듈에서 새 인증 토큰을 얻을 수 없었음.

PAM_AUTHTOK_RECOVERY_ERR

어느 모듈에서 이전 인증 토큰을 얻을 수 없었음.

PAM_AUTHTOK_LOCK_BUSY

인증 토큰이 현재 잠겨 있어서 하나 이상의 모듈에서 인증 토큰을 변경할 수 없었음.

PAM_AUTHTOK_DISABLE_AGING

적어도 한 모듈에서 인증 토큰 만료 동작이 꺼져 있다.

PAM_PERM_DENIED

권한 거부됨.

PAM_SUCCESS

인증 토큰이 성공적으로 갱신되었음.

PAM_TRY_AGAIN

모든 모듈이 인증 토큰(들)을 갱신할 수 있는 처지에 있지는 않았다. 그 경우 사용자의 어떤 인증 토큰도 갱신되지 않는다.

PAM_USER_UNKNOWN

패스워드 서비스에서 알지 못하는 사용자.

3.1.11. PAM 세션 관리 시작하기

#include <security/pam_appl.h>
int pam_open_session(pamh,  
 flags); 
pam_handle_t *pamh;
int flags;
 

3.1.11.1. 설명

pam_open_session 함수는 앞서 인증에 성공한 사용자를 위한 사용자 세션을 준비한다. 이후 pam_close_session(3)으로 그 세션을 종결해야 한다.

응용의 실효 uid, 즉 geteuid(2) 값이 예를 들어 사용자 홈 디렉터리 생성이나 마운트 같은 작업을 수행하기에 충분한 권한이 있어야 한다는 점에 유의하자.

flags 인자는 다음 값을 0개 이상 조합한 것이다.

PAM_SILENT

어떤 메시지도 찍지 않기.

3.1.11.2. 반환 값

PAM_ABORT

일반 오류.

PAM_BUF_ERR

메모리 버퍼 오류.

PAM_SESSION_ERR

세션 오류.

PAM_SUCCESS

세션이 성공적으로 생성되었음.

3.1.12. PAM 세션 관리 종결하기

#include <security/pam_appl.h>
int pam_close_session(pamh,  
 flags); 
pam_handle_t *pamh;
int flags;
 

3.1.12.1. 설명

pam_close_session 함수를 이용해 인증 세션이 끝났음을 알린다. pam_open_session(3) 호출로 생성한 세션이어야 한다.

응용의 실효 uid, 즉 geteuid(2) 값이 예를 들어 사용자 홈 디렉터리 언마운트 같은 작업을 수행하기에 충분한 권한이 있어야 한다는 점에 유의하자.

flags 인자는 다음 값을 0개 이상 조합한 것이다.

PAM_SILENT

어떤 메시지도 찍지 않기.

3.1.12.2. 반환 값

PAM_ABORT

일반 오류.

PAM_BUF_ERR

메모리 버퍼 오류.

PAM_SESSION_ERR

세션 오류.

PAM_SUCCESS

세션이 성공적으로 종결되었음.

3.1.13. PAM 환경 변수 설정 및 변경하기

#include <security/pam_appl.h>
int pam_putenv(pamh,  
 name_value); 
pam_handle_t *pamh;
const char *name_value;
 

3.1.13.1. 설명

pam_putenv 함수를 이용해 pamh 핸들에 연계된 PAM 환경 변수의 값을 추가하거나 바꾼다.

pamh 인자는 앞선 pam_start() 호출로 얻은 인증 핸들이다. name_value 인자는 단일 NUL 종료 문자열이며, 다음 중 한 형태다.

NAME=변수 값

이 경우 이름이 NAME인 환경 변수를 변수 값으로 설정한다. 이미 있는 변수면 덮어 쓴다. 아니면 PAM 환경에 추가한다.

NAME=

변수를 빈 값으로 설정한다. 그렇게 설정하려면 이 방식으로 해야 한다는 걸 보이기 위해 따로 나열한다.

NAME

'='가 없으면 pam_putenv() 함수에서 해당 변수를 PAM 환경에서 삭제하게 된다.

pam_putenv()는 name_value의 사본을 가지고 동작한다. 따라서 putenv(3)와 달리 응용에서 데이터의 메모리를 해제할 책임이 있다.

3.1.13.2. 반환 값

PAM_PERM_DENIED

name_value 인자를 NULL로 줬음.

PAM_BAD_ITEM

(삭제를) 요청한 변수가 현재 설정돼 있지 않음.

PAM_ABORT

pamh 핸들이 깨졌음.

PAM_BUF_ERR

메모리 버퍼 오류.

PAM_SUCCESS

환경 변수가 성공적으로 갱신되었음.

3.1.14. PAM 환경 변수 얻기

#include <security/pam_appl.h>
const char *pam_getenv(pamh,  
 name); 
pam_handle_t *pamh;
const char *name;
 

3.1.14.1. 설명

pam_getenv 함수는 pamh 핸들에 연계된 PAM 환경 목록에서 name이 가리키는 문자열과 일치하는 항목을 찾아서 그 환경 변수의 값에 대한 포인터를 반환한다. 응용에서 그 데이터의 메모리를 해제해선 안 된다.

3.1.14.2. 반환 값

pam_getenv 함수는 실패 시 NULL을 반환한다.

3.1.15. PAM 환경 얻기

#include <security/pam_appl.h>
char **pam_getenvlist(pamh); 
pam_handle_t *pamh;
 

3.1.15.1. 설명

pam_getenvlist 함수는 pamh 핸들에 연계된 PAM 환경의 전체 사본을 반환한다. 그 PAM 환경 변수들이 사용자가 인증돼서 서비스가 인가됐을 때의 일반 환경 변수들을 내용을 나타낸다.

메모리 형식은 char 포인터들의 malloc() 한 배열이다. 마지막 항목은 NULL로 설정돼 있다. 그 배열의 NULL 아닌 항목 각각이 "name=value" 형식으로 된 NUL 종료이고 malloc() 된 문자열을 가리킨다.

이 메모리를 libpam에서 절대 free() 하지 않는다는 점에 유의해야 한다. pam_getenvlist 호출로 얻은 후에는 호출한 응용에서 그 메모리를 free() 할 책임이 있다.

반환되는 배열의 형식과 내용이 execle(3) 함수 호출 세 번째 인자의 요건과 일치하는 건 우연이 아니라 의도된 것이다.

3.1.15.2. 반환 값

pam_getenvlist 함수는 실패 시 NULL을 반환한다.