본문 바로가기
IT/C++

[MFC] 특정 사용자 권한으로 공유폴더 만들기

by Spring Up!! 2017. 2. 10.
반응형
출처 : http://forums.codeguru.com/showthread.php?231589-How-to-set-share-permissions-for-shared-folder-programmatically

 

// CreateRTXShare.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <Windows.h>
#include <lm.h>
#include <AccCtrl.h>
#include <AclAPI.h>
#include <sddl.h>


#pragma comment(lib, "Netapi32.lib")
#define MAX_ERROR_BUFFER_SZ 0xFFFF

int CreateShare(LPTSTR name, LPTSTR path);
TCHAR* GetErrorText(DWORD error);
PSID GetSIDForNamedUserOrGroup(LPTSTR pUserName);

int _tmain(int argc, _TCHAR* argv[])
{
if (argc != 3)
{
_tprintf(_T("Usage:\nShare name path\n"));
return 0;
}
DWORD err = CreateShare(argv[1], argv[2]);
if (err)
_tprintf(_T("ERROR:\n%s"), GetErrorText(err));

return err;
}

// Create theShare
int CreateShare(LPTSTR name, LPTSTR path)
{
DWORD err = 0;
NET_API_STATUS res = 0;
SHARE_INFO_502 p = { 0 };
DWORD dwUserNameSz = UNLEN + 1;
TCHAR chCurrentUser[UNLEN + 1] = { 0 };
PSID pAdminSID = NULL;
PSID pAuthenticatedUsersSID = NULL;
PSID pCurrentUserSID = NULL;
PSID pSystemSID = NULL;
PSID pEveryOneSID = NULL;
PACL pACL = NULL;
PEXPLICIT_ACCESS ea = NULL;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
DWORD sidSize = SECURITY_MAX_SID_SIZE;
PSECURITY_DESCRIPTOR pSD = NULL;

// Get the current logged in User Name
GetUserName(chCurrentUser, &dwUserNameSz);

// Get SID of Current User
pCurrentUserSID = GetSIDForNamedUserOrGroup(chCurrentUser);

// Get SID of System
sidSize = SECURITY_MAX_SID_SIZE;
pSystemSID = LocalAlloc(LPTR, sidSize);
CreateWellKnownSid(WinLocalSystemSid, NULL, pSystemSID, &sidSize);;

// get Sid for EveryOne
sidSize = SECURITY_MAX_SID_SIZE;
pEveryOneSID = LocalAlloc(LPTR, sidSize);
CreateWellKnownSid(WinWorldSid, NULL, pEveryOneSID, &sidSize);

do
{
if (!AllocateAndInitializeSid(&SIDAuthNT, 1,
SECURITY_AUTHENTICATED_USER_RID,
0, 0, 0, 0, 0, 0, 0,
&pAuthenticatedUsersSID))
{
err = GetLastError();
break;
}

// Create a SID for the BUILTIN\Administrators group.
if (!AllocateAndInitializeSid(&SIDAuthNT, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pAdminSID))
{
err = GetLastError();
break;
}
// SID array
PSID pSIDs[] =
{
pCurrentUserSID,
pAuthenticatedUsersSID,
pAdminSID,
pSystemSID,
pEveryOneSID,
};
int numSids = sizeof(pSIDs) / sizeof(PSID);

// Initialize an EXPLICIT_ACCESS structure for an ACE.
ea = (PEXPLICIT_ACCESS)LocalAlloc(LPTR, sizeof(EXPLICIT_ACCESS) * numSids);
if (!ea)
{
err = GetLastError();
break;
}

int sidIndex = 0;
for (int i = 0; i < numSids; i++)
{
// Check current user SID
if (!IsValidSid(pSIDs[i]))
continue;

ea[sidIndex].grfAccessPermissions = TRUSTEE_ACCESS_ALL;
ea[sidIndex].grfAccessMode = GRANT_ACCESS;
ea[sidIndex].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea[sidIndex].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[sidIndex].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[sidIndex].Trustee.ptstrName = (LPTSTR)pSIDs[sidIndex];
sidIndex++;
}
numSids = sidIndex;

// Create a new ACL that contains the new ACEs.
if (SetEntriesInAcl(numSids, ea, NULL, &pACL))
{
err = GetLastError();
break;
}

// Initialize a security descriptor.
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);

// init the descriptor
if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
{
err = GetLastError();
LocalFree(pSD);
pSD = NULL;
break;
}

// Add the ACL to the security descriptor.
if (!SetSecurityDescriptorDacl(pSD,
TRUE,     // bDaclPresent flag
pACL,
FALSE))   // not a default DACL
{
err = GetLastError();
LocalFree(pSD);
pSD = NULL;
break;
}

// Set the Owner
if (!SetSecurityDescriptorOwner(pSD, pCurrentUserSID, TRUE))
{
err = GetLastError();
LocalFree(pSD);
pSD = NULL;
break;
}

} while (false);

if (!err)
{
p.shi502_netname = name;
p.shi502_type = STYPE_DISKTREE;
p.shi502_remark = name;
p.shi502_permissions = 0;
p.shi502_max_uses = -1;
p.shi502_current_uses = 0;
p.shi502_path = path;
p.shi502_passwd = NULL; // no password
p.shi502_security_descriptor = pSD;

res = NetShareAdd(NULL, 502, (LPBYTE)&p, &err);
if (res)
return err;

if (!SetFileSecurity(path, DACL_SECURITY_INFORMATION, pSD))
err = GetLastError();
}

// free SIDs
if (pAuthenticatedUsersSID)
FreeSid(pAuthenticatedUsersSID);
if (pAdminSID)
FreeSid(pAdminSID);
// free buffers
if (pEveryOneSID)
LocalFree(pEveryOneSID);
if (pCurrentUserSID)
LocalFree(pCurrentUserSID);
if (pSystemSID)
LocalFree(pSystemSID);
if (pACL)
LocalFree(pACL);
if (ea)
LocalFree(ea);
if (pSD)
LocalFree(pSD);
return err;
}

//************************************
// Method:    GetSIDForNamedUserOrGroup
// FullName:  GetSIDForNamedUserOrGroup
// Access:    public
// Returns:   PSID
// Qualifier:
// Parameter: LPTSTR pUserName
//************************************
PSID GetSIDForNamedUserOrGroup(LPTSTR pUserName)
{
SID_NAME_USE eSidType = SidTypeUnknown;
DWORD dwDomainSz = 0;
DWORD dwUserSIDsz = SECURITY_MAX_SID_SIZE;
LPTSTR pDomainName = NULL;
PSID pUserSID = NULL;

// get size of buffers needed
LookupAccountName(
NULL,           // Computer name. NULL for the local computer
pUserName,
pUserSID, // Pointer to the SID buffer. Use NULL to get the size needed,
&dwUserSIDsz, // Size of the SID buffer needed.
pDomainName, // wszDomainName NULL to get the size needed,
&dwDomainSz, //
&eSidType
);

pUserSID = (PSID)LocalAlloc(LPTR, (dwUserSIDsz + 1) * sizeof(TCHAR)); // allocate space for user SID
pDomainName = (LPTSTR)LocalAlloc(LPTR, (dwDomainSz + 1) * sizeof(TCHAR)); // allocate space for Domain
LookupAccountName(
NULL,           // Computer name. NULL for the local computer
pUserName,
pUserSID, // Pointer to the SID buffer. Use NULL to get the size needed,
&dwUserSIDsz, // Size of the SID buffer needed.
pDomainName, // wszDomainName,
&dwDomainSz,
&eSidType
);

// Free Domain
if (pDomainName)
LocalFree(pDomainName);

return pUserSID;
}

TCHAR* GetErrorText(DWORD error)
{
static TCHAR tempBuffer[MAX_ERROR_BUFFER_SZ] = { 0 };

DWORD size = FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error,
LOCALE_USER_DEFAULT,
(LPTSTR)&tempBuffer,
MAX_ERROR_BUFFER_SZ,
NULL);

while (size > 0 && (tempBuffer[size - 1] == '\r' || tempBuffer[size - 1] == '\n'))
tempBuffer[--size] = 0;

return tempBuffer;
}
반응형

'IT > C++' 카테고리의 다른 글

linux 파일에 lastmodified date 쓰기  (0) 2023.09.06
Install Google Test and Google Mock on Ubuntu  (0) 2023.08.11
객체에서 std::shared_ptr 얻기  (0) 2023.08.07
ASPICE 에 대해서.  (0) 2023.03.30
lambda expression  (0) 2020.09.26
[MFC] 사용자 계정 생성  (0) 2017.02.08
[MFC] Shared Folder 찾아서 제거하기  (0) 2017.01.16
[MFC] Radio Button 투명 배경  (0) 2016.11.01
[MFC] 시작프로그램에 등록하기  (0) 2016.10.27
[MFC] 심플한 로그 함수  (0) 2016.10.18

댓글