Click here to Skip to main content
15,880,651 members
Articles / Desktop Programming / ATL
Article

Check User’s Permissions On A File or Folder

Rate me:
Please Sign up or sign in to vote.
3.80/5 (9 votes)
24 Feb 20024 min read 209.1K   3.2K   49   15
A component to check if given user has a particular access rights on a file/folder or not.

Introduction

Every now and then we are faced with a question concerning our web applications which is, "What kind of permissions the a user has on a certain file or folder?". The answer to this question assists 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 be able to read the contents of a file but don’t allow them to make any modifications to it. So if you know beforehand 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 along that path. There is nothing worse than a frustrated user who sees the error message "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 a component that can 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 the 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 users or groups have 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, the component implements the 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.

  1. Given a user’s logon ID, get the corresponding SID. Make use of LookupAccountName API to accomplish this step.
  2. bRetVal = ::LookupAccountName((strDCServer.length() == 0) ? NULL : strDCServer.c_str(),
    				strUser.c_str(),
    				pUserSID,
    				&cbUserSID,
    				pszDomain,
    				&cbDomain,
    				&snuType);

    In this project, this step has been implemented in the GetUserSID function. Take a look at the source code for more implementation details.

  3. Next you need to get the SD and DACL associated with the object. The Platform SDK provides the following APIs to get SD.

    GetSecurityInfo
    GetNamedSecurityInfo

    We have used the earlier version of the API. It returns SD and DACL associated with the SD. Take a look at the SDK documentation to get more information on their usage and their limitations. In the project this step has been implemented in the GetFileSD function.
  4. dwErr = ::GetSecurityInfo(hFile,
    			  SE_FILE_OBJECT,
    			  secInfo,
    			  NULL,
    			  NULL,
    			  pACL,
    			  NULL,
    			  pFileSD);
  5. The next step is to check if the specified access rights exist in the DACL that was obtained in step 2. We have made use of the high-level GetEffectiveRightsFromAcl security API to get the mask describing the actual rights the user has on the given object.
  6. ACCESS_MASK mask;
    dwRetVal = ::GetEffectiveRightsFromAcl( pACL,
    					pTrustee,
    					&mask);

    The second parameter to this API is a pointer to TRUSTEE structure. This structure specifies user, group or logon session information. There are four different flavors of the API to build this structure.

    BuildTruteeWithSid
    BuildTrusteeWithName
    BuildTrusteeWithObjectsAndName
    BuildTrusteeWithObjectsAndSid
    We have used the first flavor to construct a TRUSTEE structure with a SID.

    BuildTrusteeWithSid(pTrustee, pUserSID);

    The GetEffectiveRightsFromAcl function returns a DWORD value indicating the access mask. This mask can be used to check if a specified right exists or not. This step has been implemented in the GetUserRights function of the class.

  7. The last step is to check the mask obtained in step 3.
  8. lRetMask = this->GetUserRights(pUserSID, pFileDACL);
    if (lRetMask & lAccessToCheck)
    {
        *pbOK = TRUE;
    }
    else
    {
        *pbOK = FALSE;
    }

Using The Component

As stated earlier, the component has been implemented as an ASP COM component. It contains the ITrusteeUtil interface which implements a couple of interfaces. For checking the access rights, you need to call the CheckPermissionsOnFile method. The third parameter is the complete file or folder path for which you want to check the rights. The fourth parameter is the access mask you want to check for. This mask can be constructed using the same values as specified in the 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 the method.

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

VBScript
<%										
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 implemention and improvise as per your requirements. For suggestions and questions, please feel free to contact us at softomatix@pardesiservices.com or visit us at Softomatix

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
To learn more about us, Please visit us at http://www.netomatix.com

Comments and Discussions

 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey7-Feb-12 19:45
professionalManoj Kumar Choubey7-Feb-12 19:45 
Questionlan permissions Pin
lelik9325-Jan-07 5:37
lelik9325-Jan-07 5:37 
GeneralRights on LAN shares Pin
tourschj17-May-06 21:42
tourschj17-May-06 21:42 
GeneralFailed to get user SID Pin
namtt27-Feb-06 16:51
namtt27-Feb-06 16:51 
GeneralInherited from Pin
Sam Hobbs19-Feb-06 6:50
Sam Hobbs19-Feb-06 6:50 
QuestionWith Windows Forms and VB.NET also ? Pin
AlfredoDS17-Jun-03 21:21
AlfredoDS17-Jun-03 21:21 
AnswerRe: With Windows Forms and VB.NET also ? Pin
Softomatix3-Jul-03 10:58
Softomatix3-Jul-03 10:58 
GeneralGet permisions on a folder Pin
momomomommo13-Jun-03 11:48
momomomommo13-Jun-03 11:48 
GeneralRe: Get permisions on a folder Pin
Softomatix13-Jun-03 12:21
Softomatix13-Jun-03 12:21 
SuggestionRe: Get permisions on a folder Pin
stormbit20-May-12 7:44
stormbit20-May-12 7:44 
GeneralRe: Get permisions on a folder: - easy way to do this Pin
JustmeNick21-Mar-07 14:20
JustmeNick21-Mar-07 14:20 
GeneralRe: Get permisions on a folder Pin
staffan_v19-Feb-10 4:23
professionalstaffan_v19-Feb-10 4:23 
GeneralGetEffectiveRightsFromAcl fails Pin
xy_yao29-May-02 10:35
xy_yao29-May-02 10:35 
GeneralGreat!!! Pin
26-Feb-02 7:58
suss26-Feb-02 7:58 
GeneralRe: Great!!! Pin
Softomatix27-Feb-02 15:14
Softomatix27-Feb-02 15:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.