2014-01-22 12 views
1

POSIX에는 프로세스의 실제 유효 UID를 가져 오기위한 잘 알려진 함수 getuid()geteuid()이 있습니다. 그러나 저장된 UID를 검사하는 것이 유용합니다 (POSIX 저장된 UID를 지원하는 플랫폼, 모든 현재 OS).프로세스의 저장된 uid를 검색하려면 어떻게해야합니까?

예를 들어, 클래식 가이드 "Setuid Demystified" (Chen, Dean, Wagner 2002)에서 저자는 setuid() 함수를 호출 한 직후 실제, 유효 및 저장된 uid가 모두 예상대로되었는지 확인하는 것이 좋습니다. 그러나 구현 가이드 라인에서는 모든 플랫폼에서 저장된 uid를 확인하는 방법을 설명하지 않습니다.

내 프로세스의 저장된 uid를 검색하려면 어떻게해야합니까?

답변

1

다음 스 니펫은 getsuid() 기능을 구현합니다. Linux 2.6 이상, FreeBSD 8 이상, Solaris 8 이상, AIX 5.3 이상, HP-UX 11.00 이상, MacOS 10.6 이상에서 작동하도록 테스트되었습니다. 아마 이전 버전에서도 작동 할 것입니다.

#include <unistd.h> 
#include <stdio.h> 
#ifdef _AIX 
#include <sys/id.h> 
#elif defined(__sun) 
#include <fcntl.h> 
#include <procfs.h> 
#elif defined(__hpux) 
#include <dlfcn.h> 
#include <sys/pstat.h> 
#elif defined(__APPLE__) 
#include <sys/sysctl.h> 
#endif 

#if defined(__linux) || defined(__FreeBSD__) 
static int getsuid(uid_t* suid) { 
    uid_t ruid, euid; 
    return getresuid(&ruid, &euid, suid); 
} 

#elif defined(_AIX) 
static int getsuid(uid_t* suid) { 
    *suid = getuidx(ID_SAVED); 
    return *suid == (uid_t)-1 ? -1 : 0; 
} 

#elif defined(__sun) 
static int getsuid(uid_t* suid) { 
    int fd = open("/proc/self/cred", O_RDONLY); 
    if (fd < 0) return -1; 
    prcred_t prcred; 
    int n = read(fd, &prcred, sizeof(prcred)); 
    close(fd); 
    if (n != sizeof(prcred)) return -1; 
    *suid = prcred.pr_suid; 
    return 0; 
} 

#elif defined(__hpux) 
static int getsuid(uid_t* suid) 
{ 
    // HP-UX does have getresuid, but only on 11.11 onwards. 
    void* handle; 
    int (*getresuid_)(uid_t*,uid_t*,uid_t*); 
    struct pst_status pst; 
    int i; 

    if ((handle = dlopen("libc.sl", RTLD_LAZY | RTLD_GLOBAL)) && 
     (getresuid_ = dlsym(handle, "getresuid"))) 
    { 
    uid_t dummy1, dummy2, result; 
    if ((*getresuid_)(&dummy1, &dummy2, &result)) 
     return -1; 
    *suid = result; 
    dlclose(handle); 
    return 0; 
    } 
    if (handle) dlclose(handle); 

    for (i = 0; pstat_getproc(&pst, sizeof(pst), 1, i); ++i) { 
    if (pst.pst_pid != getpid()) 
     continue; 
    *suid = pst.pst_suid; 
    return 0; 
    } 
    return -1; 
} 

#elif defined(__APPLE__) 
static int getsuid(uid_t* suid) 
{ 
    int ctl[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; 
    struct kinfo_proc kip; 
    size_t len = sizeof(kip); 
    if (sysctl(ctl, 4, &kip, &len, 0, 0) < 0) 
    return -1; 
    *suid = kip.kp_eproc.e_pcred.p_svuid; 
    return 0; 
} 

#else 
#error getsuid() not implemented for this platform 
#endif 

#ifdef TEST_CODE 
int main() { 
    uid_t ruid, euid, suid; 
    ruid = getuid(); 
    euid = geteuid(); 
    if (getsuid(&suid) < 0) { 
    perror("getsuid failure"); 
    return -1; 
    } 
    printf("uid: %ld, euid: %ld, suid: %ld\n", 
     (long)ruid, (long)euid, (long)suid); 
} 
#endif