ConvertStringSidToSidA("S-1-22-1-1", &sid) fails with invalid sid for Unix_User+1

76 views Asked by At

I tried a simple three line hello world program, which tries to get the SID for Unix_User+1:

bash -c 'getent passwd "Unix_User+1"'
Unix_User+1:*:4278190081:4278190081:U-Unix_User\1,S-1-22-1-1:/:/sbin/nologin

But putting "S-1-22-1-1" into ConvertStringSidToSidA() fails with ERROR_INVALID_SID on Cygwin.

ConvertStringSidToSidA("S-1-22-1-1", &sid)

Why? I thought SMB had "S-1-22-1-*" reserved for its usage, and Cygwin uses Unix_User+1 in ls -l output.

How can I get ConvertStringSidToSidA() working in my program?

1

There are 1 answers

0
Roland Mainz On

I solved this in our codebase (https://github.com/kofemann/ms-nfs41-client/blob/master/daemon/acl.c) like this:

/*
 * Allocate a SID from SECURITY_SAMBA_UNIX_AUTHORITY, which encodes an
 * UNIX/POSIX uid directly into a SID.
 *
 * Examples:
 * UID 1616 gets mapped to "Unix_User+1616", encoding the UID into the
 * SID as "S-1-22-1-1616":
 * $ getent passwd Unix_User+1616
 * Unix_User+1616:*:4278191696:4278191696:U-Unix_User\1616,S-1-22-1-1616:/:/sbin/nologin
 *
 * GID 1984 gets mapped to "Unix_Group+1984", encoding the GID into the
 * SID as "S-1-22-2-1984":
 * $ getent group Unix_Group+1984
 * Unix_Group+1984:S-1-22-2-1984:4278192064:
 *
 */

#define SECURITY_SAMBA_UNIX_AUTHORITY { { 0,0,0,0,0,22 } }
SID_IDENTIFIER_AUTHORITY sid_id_auth = SECURITY_SAMBA_UNIX_AUTHORITY;

static
BOOL allocate_unixuser_sid(unsigned long uid, PSID *pSid)
{
    PSID sid = NULL;
    PSID malloced_sid = NULL;
    DWORD sid_len;

    if (AllocateAndInitializeSid(&sid_id_auth, 2, 1, (DWORD)uid,
        0, 0, 0, 0, 0, 0, &sid)) {
        sid_len = GetLengthSid(sid);

        malloced_sid = malloc(sid_len);

        if (malloced_sid) {
            /*
             * |AllocateAndInitializeSid()| has an own memory
             * allocator, but we need the sid in memory from
             * |malloc()|
             */
            if (CopySid(sid_len, malloced_sid, sid)) {
                FreeSid(sid);
                *pSid = malloced_sid;
                dprintf(ACLLVL, "allocate_unixuser_sid(): Allocated "
                    "Unix_User+%lu: success, len=%ld\n",
                    uid, (long)sid_len);
                return TRUE;
            }
        }
    }

    FreeSid(sid);
    free(malloced_sid);
    dprintf(ACLLVL, "allocate_unixuser_sid(): Failed to allocate "
        "SID for Unix_User+%lu: error code %d\n",
        uid, GetLastError());
    return FALSE;
}

static
BOOL allocate_unixgroup_sid(unsigned long gid, PSID *pSid)
{
    PSID sid = NULL;
    PSID malloced_sid = NULL;
    DWORD sid_len;

    if (AllocateAndInitializeSid(&sid_id_auth, 2, 2, (DWORD)gid,
        0, 0, 0, 0, 0, 0, &sid)) {
        sid_len = GetLengthSid(sid);

        malloced_sid = malloc(sid_len);

        if (malloced_sid) {
            /*
             * |AllocateAndInitializeSid()| has an own memory
             * allocator, but we need the sid in memory from
             * |malloc()|
             */
            if (CopySid(sid_len, malloced_sid, sid)) {
                FreeSid(sid);
                *pSid = malloced_sid;
                dprintf(ACLLVL, "allocate_unixgroup_sid(): Allocated "
                    "Unix_Group+%lu: success, len=%ld\n",
                    gid, (long)sid_len);
                return TRUE;
            }
        }
    }

    FreeSid(sid);
    free(malloced_sid);
    dprintf(ACLLVL, "allocate_unixgroup_sid(): Failed to allocate "
        "SID for Unix_Group+%lu: error code %d\n",
        gid, GetLastError());
    return FALSE;
}