【问题标题】:How to determine if the process owner is an administrator on Mac OS X in C++如何在 C++ 中确定进程所有者是否是 Mac OS X 上的管理员
【发布时间】:2012-06-14 01:29:12
【问题描述】:

如何以编程方式检查运行我的可执行文件的用户是否是管理员?

这是 Mac OS X 10.6 (Snow Leopard) 或更高版本上的 C++。我的许多搜索都没有找到任何东西。

【问题讨论】:

  • 是的,我看到的一切都只是关于如何提升权限。您是否正在使用某种通往可可的桥梁?在我开始四处寻找之前知道这一点会很好:) 我建议将您的搜索指向 Unix 而不是 OS X,因为查找权限的 C 代码可能与任何 Unix 系统上的相同。

标签: c++ macos


【解决方案1】:

检查用户所在的groups,并确认用户在所需的组中。我认为您想检查用户是否属于“管理员”,但您可能想检查其他更具体的访问权限。你为什么要检查管理员呢?直接尝试该任务通常是一个更好的主意,而不是检查广泛的访问级别,如果用户没有该访问权限,但实际上确实具有您想要的特定访问权限,则失败。

【讨论】:

  • 我想在程序启动时检查,如果不是管理员就退出。
  • @meg18019:“管理员”是什么意思?您的意思是 root 访问权限,还是 sudo 访问权限,还是属于 admin 组?
【解决方案2】:
#include <grp.h>
#include <pwd.h>
#include <string.h>

bool currentUserIsAdmin ( ) {
    // A user cannot be member in more than NGROUPS groups,
    // not counting the default group (hence the + 1)
    gid_t groupIDs[NGROUPS + 1];
    // ID of user who started the process
    uid_t userID = getuid();
    // Get user password info for that user
    struct passwd * pw = getpwuid(userID);

    int groupCount;
    if (pw) {
        // Look up groups that user belongs to
        groupCount = NGROUPS + 1;
        // getgrouplist returns ints and not gid_t and
        // both may not necessarily have the same size
        int intGroupIDs[NGROUPS + 1];
        getgrouplist(pw->pw_name, pw->pw_gid, intGroupIDs, &groupCount);
        // Copy them to real array
        for (int i = 0; i < groupCount; i++) groupIDs[i] = intGroupIDs[i];

    } else {
        // We cannot lookup the user but we can look what groups this process
        // currently belongs to (which is usually the same group list).
        groupCount = getgroups(NGROUPS + 1, groupIDs);
    }

    for (int i = 0; i < groupCount; i++) {
        // Get the group info for each group
        struct group * group = getgrgid(groupIDs[i]);
        if (!group) continue;
        // An admin user is member of the group named "admin"
        if (strcmp(group->gr_name, "admin") == 0) return true;
    }
    return false;
}

【讨论】:

    【解决方案3】:

    通过调用 getuid() 检查用户 ID 怎么样? OS X 基于 BSD。因此,我认为您可以通过此函数检查运行进程的 ID。

    【讨论】:

    • 这可能会返回进程的真实用户ID——即执行程序的人的用户帐户。 geteuid() 将返回进程的有效用户id,用于访问控制检查的用户id。 geteuid() 是更好的答案,但可能不完整。
    【解决方案4】:

    看起来Open Directory 是执行此操作的正确方法。你也许可以通过使用getegid() 和/或setegid() 来降低成本

    我还没有测试过,但这可能有效:

    // 80 should be the admin group number, but it Apple might change it in a later release.
    if (getegid() == 80 || setegid(80) == 0) {
        // Yea! I'm an admin.
    }
    

    只需几个快速的想法即可跟进。我希望他们能引导你走向正确的方向。

    【讨论】:

    • 错误地投反对票,现在不能投赞成票 :(。Open Directory 听起来不错。
    • 您如何使用 Open Directory 并以正确的方式进行操作?
    • @Kaydell 您是否声称非管理员用户可以将进程的有效组 ID 设置为管理员?除非您在二进制文件上设置了组 ID sticky bit,否则它违反了文档 setegid(2) 和基本安全性。
    • @Jeffery Thomas,我声称 getegid() 为我返回了 20,即使我是管理员并且 setegid(80) 为我的管理员帐户返回了 -1,我认为我的标准帐户也是如此。至少,对于我的管理员帐户和标准帐户,整个表达式: (getegid() == 80 || setegid(80) == 0) 始终为真。这是一个正常工作的解决方案的链接:stackoverflow.com/questions/6614901/… 此链接中接受的答案有效,您的“便宜”解决方案不起作用。
    • @Kaydell 没关系。我不确定getegid() == 80 是假的,setegid(80) == 0 是假的,但getegid() == 80 || setegid(80) == 0 是真的。也许您正在使用另一种布尔逻辑。无论哪种方式setegid(80) 都不应返回-1,如果用户是管理员。很抱歉,它对您不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多