예제 #1
0
파일: netshare.c 프로젝트: twistround/pbis
static
DWORD
DeconstructSecurityDescriptor(
    DWORD dwLength,
    PSECURITY_DESCRIPTOR_RELATIVE pRelative,
    PDWORD pdwAllowUserCount,
    PWSTR** pppwszAllowUsers,
    PDWORD pdwDenyUserCount,
    PWSTR** pppwszDenyUsers,
    PBOOLEAN pbReadOnly
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    DWORD dwError = 0;
    ULONG ulSize = 0;
    ULONG ulDaclSize = 0;
    ULONG ulSaclSize = 0;
    ULONG ulOwnerSize = 0;
    ULONG ulGroupSize = 0;
    PSID pOwner = NULL;
    PSID pGroup = NULL;
    PACL pSacl = NULL;
    PSECURITY_DESCRIPTOR_ABSOLUTE pAbsolute = NULL;
    PACL pDacl = NULL;
    ULONG ulIndex = 0;
    PVOID pAce = NULL;
    PACCESS_ALLOWED_ACE pAllow = NULL;
    PACCESS_DENIED_ACE pDeny = NULL;
    DWORD dwAllowUserCount = 0;
    PWSTR* ppwszAllowUsers = NULL;
    DWORD dwDenyUserCount = 0;
    PWSTR* ppwszDenyUsers = NULL;
    PSID pSid = NULL;
    PWSTR pwszUser = NULL;
    HANDLE hLsa = NULL;
    ACCESS_MASK leastMask = FILE_ALL_ACCESS;

    dwError = LsaOpenServer(&hLsa);
    BAIL_ON_LTNET_ERROR(dwError);

    status = RtlSelfRelativeToAbsoluteSD(
        pRelative,
        pAbsolute,
        &ulSize,
        pDacl,
        &ulDaclSize,
        pSacl,
        &ulSaclSize,
        pOwner,
        &ulOwnerSize,
        pGroup,
        &ulGroupSize);
    if (status != STATUS_BUFFER_TOO_SMALL)
    {
        dwError = LwNtStatusToWin32Error(status);
        BAIL_ON_LTNET_ERROR(dwError);
    }

    dwError = LwNetAllocateMemory(ulSize, OUT_PPVOID(&pAbsolute));
    BAIL_ON_LTNET_ERROR(dwError);

    if (ulDaclSize)
    {
        dwError = LwNetAllocateMemory(ulDaclSize, OUT_PPVOID(&pDacl));
        BAIL_ON_LTNET_ERROR(dwError);
    }

    if (ulSaclSize)
    {
        dwError = LwNetAllocateMemory(ulSaclSize, OUT_PPVOID(&pSacl));
        BAIL_ON_LTNET_ERROR(dwError);
    }

    if (ulOwnerSize)
    {
        dwError = LwNetAllocateMemory(ulOwnerSize, OUT_PPVOID(&pOwner));
        BAIL_ON_LTNET_ERROR(dwError);
    }

    if (ulGroupSize)
    {
        dwError = LwNetAllocateMemory(ulGroupSize, OUT_PPVOID(&pGroup));
        BAIL_ON_LTNET_ERROR(dwError);
    }

    dwError = LwNtStatusToWin32Error(
        RtlSelfRelativeToAbsoluteSD(
            pRelative,
            pAbsolute,
            &ulSize,
            pDacl,
            &ulDaclSize,
            pSacl,
            &ulSaclSize,
            pOwner,
            &ulOwnerSize,
            pGroup,
            &ulGroupSize));
    BAIL_ON_LTNET_ERROR(dwError);

    if (pDacl)
    {
        for (ulIndex = 0; ulIndex < RtlGetAclAceCount(pDacl); ulIndex++)
        {
            RtlGetAce(pDacl, ulIndex, &pAce);

            switch(((PACE_HEADER) pAce)->AceType)
            {
            case ACCESS_ALLOWED_ACE_TYPE:
                pAllow = pAce;
                pSid = (PSID) &pAllow->SidStart;

                if ((pAllow->Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ)
                {
                    dwError = MapSidToName(hLsa, pSid, &pwszUser);
                    if (dwError != LW_ERROR_SUCCESS)
                    {
                        dwError = MapBuiltinSidToName(&pwszUser, pSid);
                    }
                    BAIL_ON_LTNET_ERROR(dwError);

                    dwError = LwNetAppendStringArray(
                        &dwAllowUserCount,
                        &ppwszAllowUsers,
                        pwszUser);
                    BAIL_ON_LTNET_ERROR(dwError);

                    pwszUser = NULL;

                    leastMask &= pAllow->Mask;
                }
                break;
            case ACCESS_DENIED_ACE_TYPE:
                pDeny = pAce;
                pSid = (PSID) &pDeny->SidStart;

                if ((pDeny->Mask & FILE_GENERIC_READ) == FILE_GENERIC_READ)
                {
                    dwError = MapSidToName(hLsa, pSid, &pwszUser);
                    if (dwError != LW_ERROR_SUCCESS)
                    {
                        dwError = MapBuiltinSidToName(&pwszUser, pSid);
                    }
                    BAIL_ON_LTNET_ERROR(dwError);

                    dwError = LwNetAppendStringArray(
                        &dwDenyUserCount,
                        &ppwszDenyUsers,
                        pwszUser);
                    BAIL_ON_LTNET_ERROR(dwError);

                    pwszUser = NULL;
                }
                break;
            default:
                break;
            }
        }
    }

    *pppwszAllowUsers = ppwszAllowUsers;
    *pdwAllowUserCount = dwAllowUserCount;
    *pppwszDenyUsers = ppwszDenyUsers;
    *pdwDenyUserCount = dwDenyUserCount;
    *pbReadOnly = !((leastMask & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE);

cleanup:

    if (hLsa)
    {
        LsaCloseServer(hLsa);
    }

    LTNET_SAFE_FREE_MEMORY(pSacl);
    LTNET_SAFE_FREE_MEMORY(pOwner);
    LTNET_SAFE_FREE_MEMORY(pGroup);
    LTNET_SAFE_FREE_MEMORY(pwszUser);
    LTNET_SAFE_FREE_MEMORY(pDacl);
    LTNET_SAFE_FREE_MEMORY(pAbsolute);

    return dwError;

error:

    *pppwszAllowUsers = NULL;
    *pdwAllowUserCount = 0;
    *pppwszDenyUsers = NULL;
    *pdwDenyUserCount = 0;

    goto cleanup;
}
예제 #2
0
static
DWORD
ParseShareAddOrSetinfoOptionArgs(
    IN int argc,
    IN int indexStart,
    IN char** argv,
    IN NET_SHARE_CTRL_CODE dwCtrlCode,
    IN OUT PNET_SHARE_ADD_OR_SET_INFO_PARAMS pShareAddOrSetParams
    )
{
    DWORD dwError = 0;
    DWORD dwIndex = 0;
    PWSTR pwszArg = NULL;

    for (dwIndex = indexStart; dwIndex < argc; dwIndex++)
    {
        if (!strcmp(argv[dwIndex], "--allow"))
        {
            dwError = LwMbsToWc16s(argv[++dwIndex], &pwszArg);
            BAIL_ON_LTNET_ERROR(dwError);

            dwError = LwNetAppendStringArray(
                &pShareAddOrSetParams->dwAllowUserCount,
                &pShareAddOrSetParams->ppwszAllowUsers,
                pwszArg);
            BAIL_ON_LTNET_ERROR(dwError);

            pwszArg = NULL;
        }
        else if (!strcmp(argv[dwIndex], "--deny"))
        {
            dwError = LwMbsToWc16s(argv[++dwIndex], &pwszArg);
            BAIL_ON_LTNET_ERROR(dwError);

            dwError = LwNetAppendStringArray(
                &pShareAddOrSetParams->dwDenyUserCount,
                &pShareAddOrSetParams->ppwszDenyUsers,
                pwszArg);
            BAIL_ON_LTNET_ERROR(dwError);

            pwszArg = NULL;
        }
        else if (!strcmp(argv[dwIndex], "--comment"))
        {
            dwError = LwMbsToWc16s(argv[++dwIndex], &pShareAddOrSetParams->pwszComment);
            BAIL_ON_LTNET_ERROR(dwError);
        }
        else if (!strcmp(argv[dwIndex], "--read-only"))
        {
            pShareAddOrSetParams->bReadOnly = TRUE;
        }
        else if (!strcmp(argv[dwIndex], "--read-write"))
        {
            pShareAddOrSetParams->bReadWrite = TRUE;
        }
        else if (!strcmp(argv[dwIndex], "--clear-allow")
                && NET_SHARE_SETINFO == dwCtrlCode)
        {
            pShareAddOrSetParams->bClearAllow = TRUE;
        }
        else if (!strcmp(argv[dwIndex], "--clear-deny")
                && NET_SHARE_SETINFO == dwCtrlCode)
        {
            pShareAddOrSetParams->bClearDeny = TRUE;
        }
        else
        {
            dwError = LwMbsToWc16s(argv[dwIndex], &pShareAddOrSetParams->pwszTarget);
            BAIL_ON_LTNET_ERROR(dwError);
            break;
        }
    }

error:

    LTNET_SAFE_FREE_MEMORY(pwszArg);

    return dwError;
}