【问题标题】:Programmatically getting UID and GID from username in Unix?以编程方式从 Unix 中的用户名获取 UID 和 GID?
【发布时间】:2010-11-03 19:13:23
【问题描述】:

我正在尝试使用 setuid() 和 setgid() 来设置程序的相应 id 以从 root 中删除权限,但是要使用它们,我需要知道我想要更改的用户的 uid 和 gid到。

是否有系统调用来执行此操作?我不想硬编码它或从 /etc/passwd 解析。

我也想以编程方式而不是使用:

id -u 用户名

任何帮助将不胜感激

【问题讨论】:

  • 解析/etc/passwd有什么问题?
  • 我应该说,“我宁愿不解析 /etc/passwd”,因为我怀疑有一个更简单的方法,感谢答案,我找到了。
  • 解析 /etc/passwd 的一个问题是用户名可能没有存储在那里 - 它们可能在某个目录服务器(LDAP 等)上。另一个错误是 getpwnam() 等人已经为你完成了。

标签: c++ c unix privileges system-calls


【解决方案1】:

可以使用以下代码sn-ps:

#include <pwd.h>
#include <grp.h>

gid_t Sandbox::getGroupIdByName(const char *name)
{
    struct group *grp = getgrnam(name); /* don't free, see getgrnam() for details */
    if(grp == NULL) {
        throw runtime_error(string("Failed to get groupId from groupname : ") + name);
    } 
    return grp->gr_gid;
}

uid_t Sandbox::getUserIdByName(const char *name)
{
    struct passwd *pwd = getpwnam(name); /* don't free, see getpwnam() for details */
    if(pwd == NULL) {
        throw runtime_error(string("Failed to get userId from username : ") + name);
    } 
    return pwd->pw_uid;
}

参考:getpwnam()getgrnam()

【讨论】:

  • 详情:你应该使用nullptr而不是NULL吗?一个好的编码实践/风格是设置变量的文字左侧:nullptr == grp,以避免在分配而不是错误比较时出现问题。
【解决方案2】:
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    char *username = ...

    struct passwd *pwd = calloc(1, sizeof(struct passwd));
    if(pwd == NULL)
    {
        fprintf(stderr, "Failed to allocate struct passwd for getpwnam_r.\n");
        exit(1);
    }
    size_t buffer_len = sysconf(_SC_GETPW_R_SIZE_MAX) * sizeof(char);
    char *buffer = malloc(buffer_len);
    if(buffer == NULL)
    {
        fprintf(stderr, "Failed to allocate buffer for getpwnam_r.\n");
        exit(2);
    }
    getpwnam_r(username, pwd, buffer, buffer_len, &pwd);
    if(pwd == NULL)
    {
        fprintf(stderr, "getpwnam_r failed to find requested entry.\n");
        exit(3);
    }
    printf("uid: %d\n", pwd->pw_uid);
    printf("gid: %d\n", pwd->pw_gid);

    free(pwd);
    free(buffer);

    return 0;
}

【讨论】:

  • 你永远不会释放 pwdbuffer - 但你为什么还要费心在堆上分配 pwdbuffer
  • @Siler,我添加了免费。我同意它可以在堆栈上完成(唯一需要注意的是确保 sysconf(_SC_GETPW_R_SIZE_MAX) 不太大(它不太可能在任何实际系统上)。但是,我不会为此重写它。
  • 这很好当您知道用户名时,但不能替代getuid()
【解决方案3】:

查看 getpwnam 和 struct passwd。

【讨论】:

    【解决方案4】:

    您想使用 getpw* 系列系统调用,通常在 pwd.h 中。它本质上是 /etc/passwd 中信息的 C 级接口。

    【讨论】:

      【解决方案5】:

      查看getpwnam()getgrnam() 函数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-12
        • 1970-01-01
        • 1970-01-01
        • 2019-05-28
        相关资源
        最近更新 更多