Discussing the nuts and bolts of software development

Wednesday, May 14, 2008

 

Chmod-me Win32 - A quick look at NTFS file system permissions

Even if NTFS is the de-facto standard file system on Windows machines today, the NTFS security model uses a set of concepts that are somewhat unfamiliar to most of us or may seem familiar until we actually use them, programmatically.

A while ago, I installed a C++ application I wrote using a local administrator account on an WinXP machine. Later, I tested the application using a restricted user account and got into a situation where a "config.ini" file, copied to the Windows shared application data folder the first time the application was launched, couldn't be modified. I quickly figured that fixing the problem would just be a matter of setting the proper "config.ini" file permissions since the file, being initially copied in an Administrator security context, wouldn't have the proper permissions to be modified by a restricted user.
In the Unix world, a shell command called 'chmod' sets file access permissions for user and groups. It's simple easy, simple, effective and on a C++ program, a single system call is all you need.
Now in Windows, the NTFS security model has a much finer grain, so there's multiple things to consider:

1) In NTFS permission are chained in a list, for files permissions that list is a Discretionary Access Control List (DACLs).

2) An Access Control List contain one or more Access Control Entries (ACE) which allows to grant or deny specifics permissions. Since file permissions can inherit permissions from parent folders (provided the parent folder allows permissions to be inherited), file permission can either be granted or denied.

3) An ACE uses Security Identifiers (SIDs) to identify a user or group.

To change the permission of a single file in a Win32 C++ program, you may end-up coding something like this:

Notes:
1) For the sake of clarity, only the *Unicode* character set is used in this example.
2) The header files "AclApi.h" and "Sddl.h" are required."
3) _WIN32_WINNT 0x0500" needs to be added to your project "Preprocessor Definitions" settings.
/*******************************************************************************
*
* FUNCTION SetFilePermissions
*
* DESCRIPTION Sets file permissions for a specific file
*
* PARAMETERS string filename: full pathname of the file to change permissions
* string username: name of a user or a group
* int permissions: can be one or more of the following:
* {GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE OR GENERIC_ALL}
*
* If a permission is omitted and is currently associated
* with the specified file, it will be removed,
* unless that permission is inherited.
*
* RETURNS non-zero if succeeds, zero if it fails.
* Use GetLastError() to get extended the error information.
*
******************************************************************************/
bool SetFilePermissions(LPCWSTR filename, LPCWSTR username, int permissions)
{
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
EXPLICIT_ACCESS eAcc;

PSID pSid = NULL;
PACL dacl = NULL;
int lRes = ERROR_SUCCESS;

eAcc.grfAccessMode = GRANT_ACCESS;
eAcc.grfAccessPermissions = permissions;
eAcc.grfInheritance = OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE;
eAcc.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
eAcc.Trustee.pMultipleTrustee = NULL;
eAcc.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;

// NOTE: In some cases, you will want to use a "well-known security identifiers"
// (http://support.microsoft.com/kb/243330) instead of a username or group
// since SIDs remain the same from one operating system language to another.
if( ConvertStringSidToSid(username, &pSid) )
{
eAcc.Trustee.TrusteeForm = TRUSTEE_IS_SID;
eAcc.Trustee.ptstrName = static_cast(pSid);
}
else
{
// Reset lasterror since ConvertSidToStringSid() is also used
// to determine if a username is a SID or not.
SetLastError(0);
eAcc.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
eAcc.Trustee.ptstrName = const_cast(username);
}

// Create a DACL
lRes = SetEntriesInAcl(1, &eAcc, NULL, &dacl);
if (lRes == ERROR_SUCCESS)
{
// Set DACL
lRes = SetNamedSecurityInfo( const_cast(filename), SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION, NULL, NULL, dacl, NULL);
}

if (pSid != NULL)
LocalFree((HLOCAL)pSid);

if (dacl != NULL)
LocalFree((HLOCAL)dacl);

return lRes == ERROR_SUCCESS;
}

int wmain(int argc, WCHAR* argv[])
{
// As an example, let's allow "Read" and "Write" permissions to the group
// "Everyone" for the file "myconfig.ini". Since the actual name "Everyone"
// depends on the actual operating system language, we'll use its
// matching SID string representation (S-1-1-0) instead.
bool success = SetFilePermissions(
L"C:/Documents and Settings/All Users/Application Data/myapp/myconfig.ini",
L"S-1-1-0", GENERIC_READ | GENERIC_WRITE);

// For security purposes, It might make more sense to allow only
// authenticated users ( SID: S-1-5-11 ) instead of the group "Everyone".

return !success; // zero means the program ran successfully
}
The Windows security model isn't trivial, but fortunately some good articles have been published on the subject. The following gives a good overviews of permissions precedence and this one provides more details about ACL Inheritance. For a more in-dept API coverage, please refer to the MSDN documentation .

You if are in a hurry you can always get away by using the real Microsoft chmod command line equivalent - CACLS.EXE in a script.

Happy Chmoding - Thanks Mikhail for your input.

Labels: , , ,


Comments:
What about getting information about essay writing? On https://writemyessay4me.org/blog/how-to-write-any-type-of-essay- you can read more about it
 
IEEE Project Domain management in software engineering is distinct from traditional project deveopment in that software projects have a unique lifecycle process that requires multiple rounds of testing, updating, and faculty feedback. A IEEE Domain project Final Year Projects for CSE system development life cycle is essentially a phased project model that defines the organizational constraints of a large-scale systems project. The methods used in a IEEE DOmain Project systems development life cycle strategy Project Centers in Chennai For CSE provide clearly defined phases of work to plan, design, test, deploy, and maintain information systems.


This is enough for me. I want to write software that anyone can use, and virtually everyone who has an internet connected device with a screen can use apps written in JavaScript. JavaScript Training in Chennai JavaScript was used for little more than mouse hover animations and little calculations to make static websites feel more interactive. Let’s assume 90% of all websites using JavaScript use it in a trivial way. That still leaves 150 million substantial JavaScript Training in Chennai JavaScript applications.
 
Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?