meg18019
meg18019

Reputation: 159

How to determine if the process owner is an administrator on Mac OS X in C++

How do I programmatically check if the user that ran my executable is an administrator?

This is C++ on Mac OS X 10.6 (Snow Leopard) or higher. My many searches have not turned up anything.

Upvotes: 5

Views: 2303

Answers (4)

Kyokook Hwang
Kyokook Hwang

Reputation: 2762

How about checking a user id by calling getuid()? OS X is based on BSD. Thus, I think you might be able to check what ID runs the process by this function.

Upvotes: 1

Mecki
Mecki

Reputation: 132919

#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;
}

Upvotes: 2

Jeffery Thomas
Jeffery Thomas

Reputation: 42588

It looks like Open Directory is the proper way to do this. You might be able to cheap it out by using getegid() and/or setegid()

I haven't tested it but this might work:

// 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.
}

Just a couple of quick ideas to follow up on. I hope they lead you in the right direction.

Upvotes: 0

Arafangion
Arafangion

Reputation: 11910

Check the groups that the user is in, and confirm that the user is in the required group. I think you want to check that the user belongs to 'admin', but you may instead want to check for other, more specific access. Why do you want to check for admin anyway? It's usually a better idea to directly attempt the task, than to check for a broad level of access and failing if the user doesn't have that access, but does infact have the specific access you want.

Upvotes: 2

Related Questions