Exemplo n.º 1
0
struct security_descriptor *get_xattr_sd( int fd )
{
    struct security_descriptor *sd;
    char buffer[XATTR_SIZE_MAX];
    int n;

    n = xattr_fget( fd, WINE_XATTR_SD, buffer, sizeof(buffer) );
    if (n == -1 || n < 2 + sizeof(struct security_descriptor)) return NULL;

    /* validate that we can handle the descriptor */
    if (buffer[0] != SECURITY_DESCRIPTOR_REVISION || buffer[1] != 0 ||
            !sd_is_valid( (struct security_descriptor *)&buffer[2], n - 2 ))
        return NULL;

    sd = mem_alloc( n - 2 );
    if (sd) memcpy( sd, &buffer[2], n - 2 );
    return sd;
}
Exemplo n.º 2
0
/* return object attributes from the current request */
const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd,
                                                           struct unicode_str *name,
                                                           struct object **root )
{
    static const struct object_attributes empty_attributes;
    const struct object_attributes *attr = get_req_data();
    data_size_t size = get_req_data_size();

    if (root) *root = NULL;

    if (!size)
    {
        *sd = NULL;
        name->len = 0;
        return &empty_attributes;
    }

    if ((size < sizeof(*attr)) || (size - sizeof(*attr) < attr->sd_len) ||
        (size - sizeof(*attr) - attr->sd_len < attr->name_len))
    {
        set_error( STATUS_ACCESS_VIOLATION );
        return NULL;
    }
    if (attr->sd_len && !sd_is_valid( (const struct security_descriptor *)(attr + 1), attr->sd_len ))
    {
        set_error( STATUS_INVALID_SECURITY_DESCR );
        return NULL;
    }
    if ((attr->name_len & (sizeof(WCHAR) - 1)) || attr->name_len >= 65534)
    {
        set_error( STATUS_OBJECT_NAME_INVALID );
        return NULL;
    }
    if (root && attr->rootdir && attr->name_len)
    {
        if (!(*root = get_directory_obj( current->process, attr->rootdir ))) return NULL;
    }
    *sd = attr->sd_len ? (const struct security_descriptor *)(attr + 1) : NULL;
    name->len = attr->name_len;
    name->str = (const WCHAR *)(attr + 1) + attr->sd_len / sizeof(WCHAR);
    return attr;
}
Exemplo n.º 3
0
struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group )
{
    int dacl_size = sizeof(ACL), n;
    int offset, type, flags, mask, rev, ia, sa;
    char buffer[XATTR_SIZE_MAX + 1], *p, *ptr;
    struct security_descriptor *sd;
    ACL *dacl;

    n = xattr_fget( fd, XATTR_USER_PREFIX "wine.acl", buffer, sizeof(buffer) - 1 );
    if (n == -1) return NULL;
    buffer[n] = 0; /* ensure NULL terminated buffer for string functions */

    p = buffer;
    do
    {
        int sub_authority_count = 0;

        if (sscanf(p, "%x,%x,%x,S-%u-%d%n", &type, &flags, &mask, &rev, &ia, &offset) != 5)
            return NULL;
        p += offset;

        while (sscanf(p, "-%u%n", &sa, &offset) == 1)
        {
            p += offset;
            sub_authority_count++;
        }

        if (*p == ';') p++;
        else if (*p) return NULL;

        /* verify that the SubAuthorityCount does not exceed the maximum permitted value */
        if (sub_authority_count > SID_MAX_SUB_AUTHORITIES)
            continue;

        switch (type)
        {
            case ACCESS_DENIED_ACE_TYPE:
                dacl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
                             FIELD_OFFSET(SID, SubAuthority[sub_authority_count]);
                break;
            case ACCESS_ALLOWED_ACE_TYPE:
                dacl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
                             FIELD_OFFSET(SID, SubAuthority[sub_authority_count]);
                break;
            default:
                continue;
        }
    }
    while (*p);

    n = sizeof(struct security_descriptor) +
        FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]) +
        FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]) +
        dacl_size;

    sd = mem_alloc( n );
    if (!sd) return NULL;

    sd->control = SE_DACL_PRESENT;
    sd->owner_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]);
    sd->group_len = FIELD_OFFSET(SID, SubAuthority[group->SubAuthorityCount]);
    sd->sacl_len = 0;
    sd->dacl_len = dacl_size;

    ptr = (char *)(sd + 1);
    memcpy( ptr, user, sd->owner_len );
    ptr += sd->owner_len;
    memcpy( ptr, group, sd->group_len );
    ptr += sd->group_len;

    dacl = (ACL *)ptr;
    dacl->AclRevision = ACL_REVISION;
    dacl->Sbz1 = 0;
    dacl->AclSize = dacl_size;
    dacl->AceCount = 0;
    dacl->Sbz2 = 0;

    ptr = (char *)(dacl + 1);
    p = buffer;
    do
    {
        char sid_buffer[sizeof(SID) + sizeof(ULONG) * SID_MAX_SUB_AUTHORITIES];
        SID *sid = (SID *)sid_buffer;
        int sub_authority_count = 0;

        if (sscanf(p, "%x,%x,%x,S-%u-%d%n", &type, &flags, &mask, &rev, &ia, &offset) != 5)
            goto err;
        p += offset;

        while (sscanf(p, "-%u%n", &sa, &offset) == 1)
        {
            p += offset;
            if (sub_authority_count < SID_MAX_SUB_AUTHORITIES)
                sid->SubAuthority[sub_authority_count] = sa;
            sub_authority_count++;
        }

        if (*p == ';') p++;
        else if (*p) goto err;

        if (sub_authority_count > SID_MAX_SUB_AUTHORITIES)
            continue;

        sid->Revision = rev;
        sid->IdentifierAuthority.Value[0] = 0;
        sid->IdentifierAuthority.Value[1] = 0;
        sid->IdentifierAuthority.Value[2] = HIBYTE(HIWORD(ia));
        sid->IdentifierAuthority.Value[3] = LOBYTE(HIWORD(ia));
        sid->IdentifierAuthority.Value[4] = HIBYTE(LOWORD(ia));
        sid->IdentifierAuthority.Value[5] = LOBYTE(LOWORD(ia));
        sid->SubAuthorityCount = sub_authority_count;

        /* Handle the specific ACE */
        switch (type)
        {
            case ACCESS_DENIED_ACE_TYPE:
                {
                    ACCESS_DENIED_ACE *ada = (ACCESS_DENIED_ACE *)ptr;
                    ada->Header.AceType  = type;
                    ada->Header.AceFlags = flags;
                    ada->Header.AceSize  = FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) +
                                           FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
                    ada->Mask            = mask;
                    memcpy( &ada->SidStart, sid, FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) );
                }
                break;
            case ACCESS_ALLOWED_ACE_TYPE:
                {
                    ACCESS_ALLOWED_ACE *aaa = (ACCESS_ALLOWED_ACE *)ptr;
                    aaa->Header.AceType  = type;
                    aaa->Header.AceFlags = flags;
                    aaa->Header.AceSize  = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) +
                                           FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]);
                    aaa->Mask            = mask;
                    memcpy( &aaa->SidStart, sid, FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]) );
                }
                break;
            default:
                continue;
        }

        ptr = (char *)ace_next( (ACE_HEADER *)ptr );
        dacl->AceCount++;
    }
    while (*p);

    if (sd_is_valid( sd, n ))
        return sd;

err:
    free( sd );
    return NULL;
}