Pardesi Services Logo Pardesi Services Logo


Check Userís Permissions On A File or Folder

Platforms Tested On
Windows 2000 Pro   Windows XP Pro   Windows 2000 Adv Server    Windows .NET Ent Server (Build 3604)

Every now and then we face with a question on our web applications, ďWhat kind of permissions the a user has on a certain file or folder?Ē And answer to this question helps in determining what kind of actions a user can or canít perform on that object. For example in your web site you want certain users to only read contents of a file but donít allow them to make any modifications to it. So if you know before hand that the logged in user does not have write permissions on the file, you can hide or not present them with the buttons or controls that will lead them into that path. There is nothing worst than a frustrated user who sees the error message that ďYou are not allowed to perform this operationĒ. It is always the best practice not to present a feature that a user canít perform.

This article is an attempt to implement one such component that check if a particular domain user has certain privileges on a file or folder or not. There are some operations that can be performed through ADSI interfaces. It is fine to use ADSI on a Domain Controller or network of servers. But when you are dealing with only one server machine, then all calls get routed through Net API calls. We have tried to implement this component using the low level Net API calls. No ADSI interface has been made use of.

Security Background

Whenever an object (folder, file, handle, mutex, etc.) is created in Windows environment, it is associated with a Discretionary Access Control List (DACL). The DACL contains a list of Access Control Entries (ACE). Each ACE specifies who is allowed to access this object and what kind of access certain user or group has on the object.

Therefore the idea behind this implementation is to get hold of the DACL of an object and then check if particular userís access rights exists in the DACL or not.

Implementation

This component is developed as an ATL/COM ASP component. Since we said ATL, the implementation is done using C++. Since it is implemented as an ASP component, which means that the component implements IDispatch interface so that late binding clients like javascript, vbscript, VB, etc. can use it.

The following steps describe the algorithm used to accomplish our tasking of checking a userís rights on an object.

  • Given a userís logon ID, get the corresponding SID. Make use of LookupAccountName API to accomplish this step.
    bRetVal = ::LookupAccountName((strDCServer.length() == 0) ? NULL : strDCServer.c_str(),
    				strUser.c_str(),
    				pUserSID,
    				&cbUserSID,
    				pszDomain,
    				&cbDomain,
    				&snuType);
    												
    In the project, this step has been implemented in GetUserSID function. Take a look at the source code for more implementation details.
  • Next you need to get the SD and DACL associated with the object. Platform SDK provides the following APIs to get SD.

    GetSecurityInfo
    GetNamedSecurityInfo

    We have used the earlier version of API. It returns SD and DACL associated with the SD. Take a look at the SDK documentation to get more information their usage and their limitations. In the project this step has been implemented in GetFileSD function.
    dwErr = ::GetSecurityInfo(hFile,
    			  SE_FILE_OBJECT,
    			  secInfo,
    			  NULL,
    			  NULL,
    			  pACL,
    			  NULL,
    			  pFileSD);												
    												
  • The next step is to check if the specified access rights in the DACL that was obtained in step 2. We have made use high-level GetEffectiveRightsFromAcl security API to get the mask describing the actual rights the user has on the given object.
    ACCESS_MASK mask;
    dwRetVal = ::GetEffectiveRightsFromAcl( pACL,
    					pTrustee,
    					&mask);												
    												
    The second parameter to this API is a pointer to TRUSTEE structure. This structure specifies a user, group or logon session information. There are four different flavors of API to build this structure.

    BuildTruteeWithSid
    BuildTrusteeWithName
    BuildTrusteeWithObjectsAndName
    BuildTrusteeWithObjectsAndSid
    We have used the first flavor of constructing TRUSTEE structure with SID.
    BuildTrusteeWithSid(pTrustee, pUserSID);												
    												
    The GetEffectiveRightsFromAcl returns a DWORD value indicating access mask. This mask can be used to check if a specified right exists or not. This step has been implemented in GetUserRights function of the class.
  • The last step is to check the mask obtained in step 3.
    lRetMask = this->GetUserRights(pUserSID, pFileDACL);
    if (lRetMask & lAccessToCheck)
    {
    	*pbOK = TRUE;
    }
    else
    {
    	*pbOK = FALSE;
    }												
    												

Using Component

As stated earlier, the component has been implemented as an ASP COM component. It contains ITrusteeUtil interface implementing couple of interfaces. For checking the access rights, you need to call CheckPermissionsOnFile method. The third parameter is the complete file pr folder path for which you want to check the rights. And the fourth parameter is the access mask you want to check for. This mask can be constructed using the same values as specified in WinNT.h file. Some of the values are as follows.

#define GENERIC_READ	(0x80000000L)
#define GENERIC_WRITE	(0x40000000L)
#define GENERIC_EXECUTE	(0x20000000L)
#define GENERIC_ALL	(0x10000000L)
										

We have included a file named Masks.txt in the project that contains some of the values. You can take a look at it to specify the access mask to method.

For example to check if a user has write permissions on a folder, you can use it as follows.

<%										
var hasWriteAccess;
obNet = Server.CreateObject('Pardesi.TrusteeUtil');
hasWriteAccess = obNet.CheckPermissionsOnFile("foo", "bar", "C:\\DataFiles", 0x0002)
Response.Write(hasWriteAccess);
Response.End();										
%>
										

Road Map

This component is still under development and being tested under various environments. Feel free to use and take a look at the implement and improvise as per your requirement. For suggestions and questions, please feel free to contact us at softomatix@pardesiservices.com

Graphics Tools


Paralogix®
Home     About us   Contact us  Copyright

Copyright (c) 1999-2002 Pardesi Services LLC


Hit Counter