getpwnam(3) - username으로 상세 user정보 얻기
getpwnam(3)
#include <sys/types.h>
#include <pwd.h>
struct passwd *getpwnam(const char *name);
LINUX / UNIX의 계정인 name(문자열)으로 그 계정에 대한 상세 정보를 얻는 함수입니다. LINUX/UNIX 계정의 상세 정보는 /etc/passwd 파일에 저장이 됩니다. UNIX의 초기에는 이 passwd 파일에 비밀번호까지 관리를 해서 아마도 passwd 파일이라고 이름을 지은 것 같습니다. passwd 파일은 아무나 읽을 수 있는 파일이라 보안상 문제가 있어서, 현재는 비밀번호는 /etc/shadow 파일에 root 계정만 접근 가능하도록 변경되었습니다. 구조체 struct passwd도 그 passwd 파일의 항목으로 구성되어 있습니다. /etc/passwd 파일을 열어보면 다음과 같은 구성으로 되어 있습니다.
user1:x:3001:3000:User Comment:/home/user1:/bin/bash
user1 : OS 계정 (사용자ID)
x : 비밀번호. 비밀번호가 x이면 비밀번호는 /etc/shadow 파일에 암호화되어 저장되어 있다는 의미
3001 : user1에 대한 uid (숫자) - LINUX 내에서 실제 사용은 이 숫자인 uid를 사용함
3000 : user1이 소속된 그룹ID (gid)
User Comment : 사용자에 대한 설명
/home/user1 : user1의 home directory
/bin/bash : user1이 사용할 shell 종류
getpwnam(3)함수가 return하는 struct passwd * 는 getpwname(3) 내에서 static 변수로 선언되어 multi-thread환경에서 문제가 발생할 수 있는 함수이므로 multi-thread에서는 getpwname_r(3)함수를 이용하도록 합니다. 또한 동시에 두 계정 정보를 얻어야 하는 경우는 얻은 정보를 다른 변수에 복제를 해두어야 합니다. 함수가 호출되면 가장 마지막에 조회한 계정정보로 바뀝니다.
상세한 오류 정보를 얻기 위해서는 함수 호출 전에 errno = 0; 으로 초기화를 해야 합니다.
getpwnam(3) 함수의 return type인 struct passwd *의 구조는 아래와 같습니다.
struct passwd {
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
파리미터
name
: 상세정보를 얻으려는 LINUX / UNIX 계정명입니다.
RETURN
NULL 아님
: 정상적으로 결과를 얻었습니다.
NULL
: 오류가 발생하였거나 matching되는 계정이 없으며 오류 내용은 errno에 설정됩니다.
0 or ENOENT or ESRCH or EBADF or EPERM : 등록된 계정이 아닙니다.
EINTR : signal이 발생하였으니 다시 조회하세요.
EIO : I/O 오류가 발생하였습니다. (/etc/passwd 파일을 읽지 못함)
EMFILE : 사용자 열 수 있는 파일 갯수 제한에 걸려 /etc/passwd 파일을 열지 못하였습니다.
ENFILE : System 전체에서 열 수 있는 파일 갯수 제한에 걸려 /etc/passwd 파일을 열지 못하였습니다.
ENOMEM : 메모리가 부족하여 struct passwd에 대한 메모리 할당에 실패하였습니다.
ERANGE : 제공된 메모리 space가 부족합니다.
활용 예제
sample. user1이라는 계정의 정보를 출력하는 예제
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
#include <errno.h>
int main(int argc, char *argv[])
{
struct passwd *result;
struct passwd pwd;
errno = 0;
if((result = getpwnam("user1")) == NULL) {
printf("error: %s\n", strerror(errno));
return 1;
}
memcpy(&pwd, result, sizeof(struct passwd));
printf("user :%s\n", pwd.pw_name);
printf("uid :%d\n", pwd.pw_uid);
printf("gid :%d\n", pwd.pw_gid);
printf("home :%s\n", pwd.pw_dir);
printf("shell:%s\n", pwd.pw_shell);
return 0;
}
see also : getpwnam_r(3) getpwuid(3) getpwuid_r(3) 사용자 및 그룹 관련 Library