Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Changing permissions on a directory

120 views
Skip to first unread message

Anthony Hunter

unread,
May 6, 2001, 11:16:53 AM5/6/01
to
Does anyone know how I can change the permissions on a directory? I
want to be able to set the group Everyone to Change access. It also has
to work on Win2000 in all languages.


Thanks,
Anthony

Prabagar Ramadasse

unread,
May 11, 2001, 5:20:26 PM5/11/01
to
Anthony,

Check out VB sample code in

Q240176 - HOWTO: Set Security on a NTFS Folder Programmatically
http://support.microsoft.com/support/kb/articles/Q240/1/76.asp

ADSI method

Q279682 - HOWTO: Use ADsSecurity.dll to Add an Access Control Entry to an
NTFS Folder
http://support.microsoft.com/support/kb/articles/Q279/6/82.asp

and 'C' sample code in

Q102102 - HOWTO: Add an Access-Allowed ACE to a File
http://support.microsoft.com/support/kb/articles/Q102/1/02.asp

The code in article Q102102 does only for files and adds ACCESS_ALLOWED_ACE
always at the end of the DACL.

If you are on Window 2000, you have to add this ACE "before" any
INHERITED_ACEs that you have in the Existing DACL and that is the only
change you need.

The ACE specification for Container Objects like a directory is explained in

Q188760 - HOWTO: Specify Access Control on Window NT/Windows 2000 Container
Objects
http://support.microsoft.com/support/kb/articles/Q188/7/60.asp

Thanks,
Prabagar

"Anthony Hunter" <anthony...@wonderware.com> wrote in message
news:3AF56AE5...@wonderware.com...

Anthony Hunter

unread,
May 16, 2001, 12:03:33 PM5/16/01
to
I've been able to get it to work, but it seems to only work on a file. When
I try to set the permissions on a directory it removes them. I think that I
might be passing the directory name incorrectly in the functions
GetNamedSecurityInfo() and SetNamedSecurityInfo(). I'm currently passing it
like this: "D:\\testdir".


Anthony

Prabagar Ramadasse

unread,
May 16, 2001, 10:38:38 PM5/16/01
to
Anthony,

If you want to target only on Windows 2000, you can look at ACLAPI sample in
Microsoft Platform SDK. It is located in
%MSSDK%\Samples\WinBase\Security\WinNT\AclApi folder after Installing
Microsoft Platform SDK samples from

http://www.microsoft.com/msdownload/platformsdk/setuplauncher.asp

It has examples of GRANT_ACCESS as well as SET_ACCESS mode using
EXPLICIT_ACCESS structures.

GRANT_ACCESS
An input flag that creates an ACCESS_ALLOWED_ACE. The new ACE combines the
specified rights with any existing allowed or denied rights of the trustee.
SET_ACCESS
Indicates an ACCESS_ALLOWED_ACE that allows the specified rights. On input,
this flag discards any existing access-control information for the trustee.

Thanks,
Prabagar

"Anthony Hunter" <anthony...@wonderware.com> wrote in message

news:3B02A4D5...@wonderware.com...

Anthony Hunter

unread,
May 17, 2001, 10:33:44 AM5/17/01
to
I've taken a look at the example it in the Platform SDK, and it is very
similar to what I am already doing. It some what works on a directory. It does
set the security, but only the directory access security, the file access is set
to not specified. But it also removes all security that is already on the
directory. I've tried using GetExplicitEntriesFromAcl() to keep the original
security settings, but it seems to ignore it. On a file it works properly,
just like mine does.


Thanks,

Prabagar Ramadasse

unread,
May 17, 2001, 11:24:22 AM5/17/01
to
If you are using GetExplicitEntriesFromAcl() API in your code, you might be
seeing the following symptoms.

GetExplicitEntriesFromAcl() has a known bug on Windows 2000 as explained in
the following knowledge base article.

Q260307 - INFO: The GetExplicitEntriesFromAcl() Function Returns the
Incorrect Number of ACEs
http://support.microsoft.com/support/kb/articles/Q260/3/07.asp

Do not use this API. The AclApi Microsoft Platform SDK sample does not use
this API.

The Aclapi sample should work fine on Windows 2000.

The following options

aclapi c:\test /Set Administrator 2032127 3

will add "Administrator" "Full Control" permissions to c:\test folder and
the ACE is inheritable by subfolders as well as files.

If you specify inheritance of 0, then the ACE is applicable only for the
folder.

If you specify OBJECT_INHERIT_ACE in inheritance, the ACE will be inherited
by files.

If you specify CONTAINER_INHERIT_ACE in inheritance, the ACE will be
inherited by subfolders.

2032127 in the command line above is the access mask that corresponds to
"Full Control" for file/folder securable object.

3 in the command line above is OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE
value.

Thanks,
Prabagar

"Anthony Hunter" <anthony...@wonderware.com> wrote in message

news:3B03E148...@wonderware.com...

Anthony Hunter

unread,
May 17, 2001, 12:53:59 PM5/17/01
to
This is the command that I have used:

aclapi d:\test /Set Everyone 3758161920 3

where 3758161920 is setting the group Everyone to Change access.

This works, but removes all other groups there were part of the permissions. If
I run the same command on a file it leaves everything in tack, and changes the
permissions on the group Everyone. Also, the subdirectories and files did not
inherit the new permissions. (or does that only apply to new files?)


Anthony

Prabagar Ramadasse

unread,
May 17, 2001, 5:39:49 PM5/17/01
to
Anthony,

I tested the following on Windows 2000 as well as Windows 2000 Service Pack
1.

aclapi c:\test /Set Everyone 3758161920 3

It works as expected on both the folder as well as file. i.e. it either adds
or modifies the Everyone ACE to Modify access. All other ACEs are
"unaffected". Also, if applied on a folder, existing subfolders as well as
files inherit the Everyone ACE.

It is strange that this sample is not working on your Windows 2000 system.

My setup on the c:\test folder before running AclAPI sample, contains only
one ACE for "Administrators" Group expilicity specified with Full Control.

What setup do you have before running AclAPI sample? You can run Check_SD
sample from %MSSDK%\Samples\WinBase\Security\WinNT\Check_SD folder to dump
the SD information before and after running AclAPI sample.

I am not sure whether you are experimenting with the latest version of
Microsoft Platform SDK samples.

Below is the AclApi sample I am using

/********************/
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Copyright (C) 1996 - 2000. Microsoft Corporation. All rights reserved.

Module Name:

aclapi.c

Abstract:

This module illustrates new Acl management API for Windows NT 4.0.

Developers of new software which is to run on Windows NT version 4.0
and above are encouraged to utilize these security API rather than
implementing code which uses lower level security API. The development
and test time can be drastically reduced by utilizing these new API.

This sample illustrates this point by implementing code which modifies
the security on an existing file using the new Windows NT 4.0
Acl management API.


The following new API functions are illustrated in this sample:

GetNamedSecurityInfo()
BuildExplicitAccessWithName()
SetEntriesInAcl()
SetNamedSecurityInfo()

The following lower-level security API would have been used to achieve
the same result:

LookupAccountName()
InitializeSecurityDescriptor()
InitializeAcl()
GetSecurityDescriptorDacl()
GetAclInformation()
GetAce()
SetSecurityDescriptorDacl()
AddAce()
AddAccessAllowedAce() / AddAccessDeniedAce()
GetFileSecurity()
SetFileSecurity()

Less code and less complex code is required to achieve this task using
the new Windows NT 4.0 Acl management API.

--*/

#include <windows.h>
#include <aclapi.h>
#include <lmerr.h>

#include <stdio.h>

#define RTN_OK 0
#define RTN_USAGE 1
#define RTN_ERROR 13

void
DisplayLastError(
LPSTR szAPI
);

int
__cdecl
main(
int argc,
char *argv[]
)
{
LPTSTR FileName;
LPTSTR TrusteeName;

DWORD AccessMask = GENERIC_ALL;
DWORD InheritFlag = NO_INHERITANCE;
ACCESS_MODE option;
EXPLICIT_ACCESS explicitaccess;

PACL ExistingDacl;
PACL NewAcl = NULL;
PSECURITY_DESCRIPTOR psd = NULL;

DWORD dwError;
BOOL bSuccess = FALSE; // assume failure

if(argc < 4) {
printf("Usage: %s <filename> {/Deny | /Grant | /Revoke | /Set}
[<trustee>] [<permissions>] [<InheritFlag>]\n", argv[0]);
return RTN_USAGE;
}

FileName = argv[1];
TrusteeName = argv[3];

if ( (0 == stricmp(argv[2], "/Deny") ) ||
(0 == stricmp(argv[2], "/D") ) )
{
option = DENY_ACCESS;
} else if ( ( (0 == stricmp(argv[2], "/Revoke") ) ||
(0 == stricmp(argv[2], "/R") ) ) )
{
option = REVOKE_ACCESS;
} else if ( (0 == stricmp(argv[2], "/Set") ) ||
(0 == stricmp(argv[2], "/S") ) )
{
option = SET_ACCESS;
} else if ( (0 == stricmp(argv[2], "/Grant") ) ||
(0 == stricmp(argv[2], "/G") ) )
{
option = GRANT_ACCESS;
} else {
printf("Invalid action specified\n");
return RTN_ERROR;
}

if (argc > 4)
{
AccessMask = atol( argv[4] );
}

if (argc > 5)
{
InheritFlag = atol( argv[5] );
}

//
// get current Dacl on specified file
//

dwError = GetNamedSecurityInfo(
FileName,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION,
NULL,
NULL,
&ExistingDacl,
NULL,
&psd
);

if(dwError != ERROR_SUCCESS) {
DisplayLastError("GetNamedSecurityInfo");
return RTN_ERROR;
}

BuildExplicitAccessWithName(
&explicitaccess,
TrusteeName,
AccessMask,
option,
InheritFlag
);

//
// add specified access to the object
//

dwError = SetEntriesInAcl(
1,
&explicitaccess,
ExistingDacl,
&NewAcl
);

if(dwError != ERROR_SUCCESS) {
DisplayLastError("SetEntriesInAcl");
goto cleanup;
}

//
// apply new security to file
//

dwError = SetNamedSecurityInfo(
FileName,
SE_FILE_OBJECT, // object type
DACL_SECURITY_INFORMATION,
NULL,
NULL,
NewAcl,
NULL
);

if(dwError != ERROR_SUCCESS) {
DisplayLastError("SetNamedSecurityInfo");
goto cleanup;
}

bSuccess = TRUE; // indicate success

cleanup:

if( NewAcl != NULL ) AccFree( NewAcl );
if( psd != NULL) AccFree( psd );


if(!bSuccess)
return RTN_ERROR;

return RTN_OK;
}

void
DisplayLastError(
LPSTR szAPI
)
{
HMODULE hModule = NULL; // default to system source
DWORD dwLastError = GetLastError();
LPSTR MessageBuffer;
DWORD dwBufferLength;

DWORD dwFormatFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM ;

//
// if dwLastError is in the network range, load the message source
//

if(dwLastError >= NERR_BASE && dwLastError <= MAX_NERR) {
hModule = LoadLibraryEx(
TEXT("netmsg.dll"),
NULL,
LOAD_LIBRARY_AS_DATAFILE
);

if(hModule != NULL)
dwFormatFlags |= FORMAT_MESSAGE_FROM_HMODULE;
}

printf("%s error! (rc=%lu)\n", szAPI, dwLastError);

//
// call FormatMessage() to allow for message text to be acquired
// from the system or the supplied module handle
//

if(dwBufferLength = FormatMessageA(
dwFormatFlags,
hModule, // module to get message from (NULL == system)
dwLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPSTR) &MessageBuffer,
0,
NULL
))
{
DWORD dwBytesWritten;

//
// Output message string on stderr
//
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
MessageBuffer,
dwBufferLength,
&dwBytesWritten,
NULL
);

//
// free the buffer allocated by the system
//
LocalFree(MessageBuffer);
}

//
// if we loaded a message source, unload it
//
if(hModule != NULL)
FreeLibrary(hModule);
}
/********************/

>or does that only apply to new files?)

When adding ACEs using SetNamedSecurityInfo() with inheritance value of 3,
"existing" files & subfolders will inherit that Everyone Change ACE through
Automatic inheritance only on Windows 2000.

Thanks,
Prabagar

"Anthony Hunter" <anthony...@wonderware.com> wrote in message

news:3B040226...@wonderware.com...

0 new messages