Solved

CreateDirectory using specific rights !

Posted on 2004-04-16
4
814 Views
Last Modified: 2008-02-20
I have to create a directory on a NTFS disk.

This directory must have the Everyone Group and all permissions checked but not Full Control.

Therefore, I have create this function (see below) but have problems with the security descriptor.

The directory is correctly created and the Everyone group is the only one present (is correct)
but nothing is checked in Permissions !

Did someone has an idea ?


BOOL CCleanEditMediaServerDirSharesDlg::MyCreateDirectory(LPCTSTR lpszPathName)
 {
  // ----- CREATE SECURITY DESCRIPTOR -----

  PSID                 pstSIDEveryone = NULL;
  PACL                 pstACL         = NULL;
  PSECURITY_DESCRIPTOR pstSecDesc     = NULL;

  if (1)
   {
    BOOL bRet;

    // Create a well-known SID for the everyone group

    SID_IDENTIFIER_AUTHORITY stSIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;

    bRet = AllocateAndInitializeSid(&stSIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pstSIDEveryone);

    if (!bRet) return FALSE;

    // Initialize an EXPLICIT_ACCESS structure for an ACE

    EXPLICIT_ACCESS stEA[1];

    memset(stEA, 0, sizeof(stEA));

    // The ACE will allow everyone full access to the shared directory

    stEA[0].grfAccessPermissions             = SPECIFIC_RIGHTS_ALL | DELETE | READ_CONTROL | SYNCHRONIZE;
    stEA[0].grfAccessMode                    = SET_ACCESS;
    stEA[0].grfInheritance                   = NO_INHERITANCE;
    //stEA[0].Trustee.pMultipleTrustee         = NULL;
    //stEA[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
    stEA[0].Trustee.TrusteeForm              = TRUSTEE_IS_SID;
    stEA[0].Trustee.TrusteeType              = TRUSTEE_IS_WELL_KNOWN_GROUP;
    stEA[0].Trustee.ptstrName                = (LPTSTR)pstSIDEveryone;

    // Create a new ACL that contains the new ACEs

    DWORD nRet = SetEntriesInAcl(1, stEA, NULL, &pstACL);

    if (nRet != ERROR_SUCCESS)
     {
      FreeSid(pstSIDEveryone);
      return FALSE;
     }

    // Allocate a security descriptor

    pstSecDesc = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);

    if (!pstSecDesc)
     {
      FreeSid(pstSIDEveryone);
      LocalFree(pstACL);
      return FALSE;
     }

    // Initialize security descriptor

    bRet = InitializeSecurityDescriptor(pstSecDesc, SECURITY_DESCRIPTOR_REVISION);

    if (!bRet)
     {
      FreeSid(pstSIDEveryone);
      LocalFree(pstACL);
      LocalFree(pstSecDesc);
      return FALSE;
     }

    // Add the ACL to the security descriptor

    bRet = SetSecurityDescriptorDacl(pstSecDesc, TRUE, pstACL, FALSE);

    if (!bRet)
     {
      FreeSid(pstSIDEveryone);
      LocalFree(pstACL);
      LocalFree(pstSecDesc);
      return FALSE;
     }
   }

  // ----- CREATE SECURITY ATTRIBUTES -----

  SECURITY_ATTRIBUTES stSA;

  stSA.nLength              = sizeof(stSA);
  stSA.bInheritHandle       = FALSE;
  stSA.lpSecurityDescriptor = pstSecDesc;

  // ----- CREATE DIRECTORY -----

  BOOL bRet = CreateDirectory(lpszPathName, &stSA);

  if (pstSecDesc)
   {
    FreeSid(pstSIDEveryone);
    LocalFree(pstACL);
    LocalFree(pstSecDesc);
   }

  return bRet;
 }
0
Comment
Question by:mike_marquet
  • 2
  • 2
4 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Have you tried

stEA[0].grfAccessPermissions             = SPECIFIC_RIGHTS_ALL | STANDARD_RIGHTS_REQUIRED;

?
0
 

Author Comment

by:mike_marquet
Comment Utility
I have tried it but it is the same.

The only difference, is that after directory creation, I can no more delete it.
To delete it, I must delete it from an other computer running NT4
0
 
LVL 86

Accepted Solution

by:
jkr earned 250 total points
Comment Utility
OK, this one might be more what you want:

  LPTSTR FileName = "C:\\MyNewDirectory";
  LPTSTR TrusteeName = "Everyone";

  DWORD InheritFlag = NO_INHERITANCE;
  ACCESS_MODE option = GRANT_ACCESS;
  EXPLICIT_ACCESS explicitaccess;

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

  DWORD dwError;

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

  BuildExplicitAccessWithName(
        &explicitaccess,
        TrusteeName,
        GENERIC_READ | GENERIC_WRITE | STANDARD_RIGHTS_ALL,
        SET_ACCESS,
        InheritFlag
        );

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

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

  //
  // apply new security to file
  //

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

Author Comment

by:mike_marquet
Comment Utility
Thanks, it's working
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now