首页 文章

如何检查用户是否具有windows api文件的访问权限

提问于
浏览
1

我正在尝试为Windows编写一个简单的函数来回答以下问题 .

用户(U)是否在文件(F)上拥有权利(R)?
哪里,
R是(GENERIC_READ,GENERIC_WRITE,GENERIC_EXECUTE)的某种组合
U不必登录或模拟

我写的代码如下所示 . 应用程序调用显示的第一个UserHasPermission .

GetEffectiveRightsFromAcl返回的访问权限对于我测试的所有用户/文件组合是相同的($ 001200A9) . 我仔细检查过,$ 001200A9不只是指向实际存储访问权限的位置的指针 .

我的问题是双重的:
1.有更好的方法吗?
谁能告诉我哪里出错了?

function UserHasPermission(APermission: Longword; out HasPermission: Boolean; AFileName: WideString; AUserName: String; ADomainName: String): Boolean;
    var
      SID: PSID;
      ACL: PACL;
    begin
      SID := nil;
      ACL := nil;
      try
        Result := GetUserSID(SID, AUserNAme, ADomainName);
        Result := Result and GetFileDACL(AFileName, ACL);
        Result := Result and UserHasPermission(APermission, HasPermission, ACL, SID);
      finally
        Dispose(SID);
      end;
    end;

    function UserHasPermission(APermission: Longword; out HasPermission: Boolean; AACL: PACL; AUserSID: PSID): Boolean;
    var
      T: TRUSTEE;
      Rights: ACCESS_MASK;
    begin
      BuildTrusteeWithSid(@T, AUserSID);
      Result := GetEffectiveRightsFromAcl(AACL, @T, @Rights) = ERROR_SUCCESS;
      HasPermission := (Rights and APermission) = APermission;
    end;

    function GetUserSID(out ASID: PSID; AUserName: WideString; const ADomainName: WideString): Boolean;
    var
      NSID, NDomain: Longword;
      Use: SID_NAME_USE;
      DomainName: WideString;
    begin
      Result := False;
      if Length(AUserName) > 0 then
        begin
          if Length(ADomainName) > 0 then
            AUserName := ADomainName + '\' + AUserName;

          // determine memory requirements
          NSID := 0;
          NDomain := 0;
          LookupAccountNameW(nil, PWideChar(AUserName), nil, NSID, nil, NDomain, Use);

          // allocate memory
          GetMem(ASID, NSID);
          SetLength(DomainName, NDomain);

          Result := LookupAccountNameW(nil, PWideChar(AUserName), ASID, NSID, PWideChar(DomainName), NDomain, Use);
        end;
    end;

    function GetFileDACL(AFileName: WideString; out AACL: PACL): Boolean;
    var
      SD: PSecurityDescriptor;
      NSD, NNeeded: Longword;
      Present, Defualted: Longbool;
    begin
      GetFileSecurityW(PWideChar(AFileName), DACL_SECURITY_INFORMATION, nil, 0, NNeeded);
      GetMem(SD, NNeeded);
      try
        NSD := NNeeded;
        Result := GetFileSecurityW(PWideChar(AFileName), DACL_SECURITY_INFORMATION, SD, NSD, NNeeded);
        Result := Result and GetSecurityDescriptorDacl(SD, Present, AACL, Defualted);
        Result := Result and Present;
      finally
        Dispose(SD);
      end;
    end;

1 回答

  • 2

    GetEffectiveRightsFromAcl与我测试的所有用户/文件组合相同($ 001200A9) .

    这一切都取决于ACL,例如如果每个人都被授予完全控制权,那么任何使用都将完全控制 .

    代码看起来很合理,并且您正在使用其中一个Win32安全API(GetEffectiveRightsFromAcl)来完成繁重的工作 .

    建议:创建非常具体的ACL来测试你的代码(SDDL使这更容易),从没有授权的那个开始,然后只包括一个不同的用户 .

相关问题