WindowsXP-SP1/termsrv/setup/dll/users.cpp
2020-09-30 16:53:49 +02:00

276 lines
7.5 KiB
C++

#include "stdafx.h"
// #include <windows.h>
#include <lm.h>
#include <dsrole.h>
NET_API_STATUS GetDomainUsersSid(OUT PSID *ppSid);
DWORD GetWellKnownName(IN DWORD dwRID, OUT WCHAR **pszName);
/*****************************************************************************
*
* RemoveAllFromRDUsersGroup
*
* Removes all entries from "Remote Desktop Users" group
*
* ENTRY:
* none
*
*
* NOTES:
*
*
* EXIT:
* Returns: 0 if success, error code if failure
*
*
*
****************************************************************************/
DWORD
RemoveAllFromRDUsersGroup()
{
NET_API_STATUS Result,Result1;
//Get "Remote Desktop Users" group name.
//It may be different in different languages
WCHAR *szRemoteGroupName = NULL;
Result = GetWellKnownName(DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS, &szRemoteGroupName);
if(Result == NERR_Success)
{
//Copy members of "Users" group to "Remote Desktop Users" group
PLOCALGROUP_MEMBERS_INFO_0 plmi0 = NULL;
DWORD entriesread = 0;
DWORD totalentries = 0;
DWORD_PTR resumehandle = 0;
do
{
Result = NetLocalGroupGetMembers(NULL,szRemoteGroupName,0,(LPBYTE *)&plmi0,
1000,&entriesread,
&totalentries,&resumehandle);
if((Result == NERR_Success || Result == ERROR_MORE_DATA) &&
entriesread)
{
for(DWORD i=0;i<entriesread;i++)
{
//We have to add users one by one because of the stupid behaviour
//of this function, not allowing to add users if some of them are already
//members of the group.
Result1 = NetLocalGroupDelMembers(NULL,szRemoteGroupName,0,(LPBYTE)&plmi0[i],1);
if(Result1 != ERROR_SUCCESS && Result1 != ERROR_MEMBER_IN_ALIAS)
{
LOGMESSAGE1(_T("NetLocalGroupDelMembers failed %d\n"),Result1);
break;
}
}
NetApiBufferFree(plmi0);
if(Result1 != ERROR_SUCCESS && Result1 != ERROR_MEMBER_IN_ALIAS)
{
Result = Result1;
break;
}
}
}while (Result == ERROR_MORE_DATA);
delete szRemoteGroupName;
}
else
{
LOGMESSAGE1(_T("GetWellKnownName(DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS) failed %d\n"),Result);
}
return Result;
}
/*****************************************************************************
*
* CopyUsersGroupToRDUsersGroup
*
* Copies all members of "Users" group to "Remote Desktop Users" group
*
* ENTRY:
* none
*
*
* NOTES:
*
*
* EXIT:
* Returns: 0 if success, error code if failure
*
*
*
****************************************************************************/
DWORD
CopyUsersGroupToRDUsersGroup()
{
NET_API_STATUS Result,Result1;
//Get real name of "Users" group
//It may be different in different languages
WCHAR *szUsersName = NULL;
Result = GetWellKnownName(DOMAIN_ALIAS_RID_USERS, &szUsersName);
if(Result != NERR_Success)
{
LOGMESSAGE1(_T("GetWellKnownName(DOMAIN_ALIAS_RID_USERS) failed %d\n"),Result);
return Result;
}
//Get "Remote Desktop Users" group name.
//It may be different in different languages
WCHAR *szRemoteGroupName = NULL;
Result = GetWellKnownName(DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS, &szRemoteGroupName);
if(Result == NERR_Success)
{
//Copy members of "Users" group to "Remote Desktop Users" group
PLOCALGROUP_MEMBERS_INFO_0 plmi0 = NULL;
DWORD entriesread = 0;
DWORD totalentries = 0;
DWORD_PTR resumehandle = 0;
do
{
Result = NetLocalGroupGetMembers(NULL,szUsersName,0,(LPBYTE *)&plmi0,
1000,&entriesread,
&totalentries,&resumehandle);
if((Result == NERR_Success || Result == ERROR_MORE_DATA) &&
entriesread)
{
for(DWORD i=0;i<entriesread;i++)
{
//We have to add users one by one because of the stupid behaviour
//of this function, not allowing to add users if some of them are already
//members of the group.
Result1 = NetLocalGroupAddMembers(NULL,szRemoteGroupName,0,(LPBYTE)&plmi0[i],1);
if(Result1 != ERROR_SUCCESS && Result1 != ERROR_MEMBER_IN_ALIAS)
{
LOGMESSAGE1(_T("NetLocalGroupAddMembers failed %d\n"),Result1);
break;
}
}
NetApiBufferFree(plmi0);
if(Result1 != ERROR_SUCCESS && Result1 != ERROR_MEMBER_IN_ALIAS)
{
Result = Result1;
break;
}
}
}while (Result == ERROR_MORE_DATA);
delete szRemoteGroupName;
}
else
{
LOGMESSAGE1(_T("GetWellKnownName(DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS) failed %d\n"),Result);
}
delete szUsersName;
return Result;
}
/*****************************************************************************
*
* GetWellKnownName
*
* Returns a real name of any well-known account
*
* ENTRY:
* IN DWORD dwRID
* OUT WCHAR **pszName
*
*
* NOTES:
* To free returned buffer use "delete" operator.
*
* EXIT:
* Returns: NERR_Success if success, error code if failure
*
*
*
****************************************************************************/
DWORD
GetWellKnownName(
IN DWORD dwRID,
OUT WCHAR **pszName)
{
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
PSID pSid=NULL;
if( !AllocateAndInitializeSid( &sia, 2,
SECURITY_BUILTIN_DOMAIN_RID,
dwRID,
0, 0, 0, 0, 0, 0,&pSid ) )
{
return GetLastError();
}
//Lookup name
WCHAR *szDomainName = NULL;
DWORD cName = MAX_PATH;
DWORD cDomainName = MAX_PATH;
SID_NAME_USE eUse;
DWORD Result = NERR_Success;
for(int i=0; i<2; i++)
{
Result = NERR_Success;
*pszName = new WCHAR[cName];
if(!(*pszName))
{
Result = ERROR_NOT_ENOUGH_MEMORY;
break;
}
szDomainName = new WCHAR[cDomainName];
if(!szDomainName)
{
delete *pszName;
*pszName = NULL;
Result = ERROR_NOT_ENOUGH_MEMORY;
break;
}
if(!LookupAccountSidW(NULL,pSid,
*pszName,&cName,
szDomainName,&cDomainName,
&eUse))
{
delete *pszName;
delete szDomainName;
*pszName = NULL;
szDomainName = NULL;
Result = GetLastError();
if(Result == ERROR_INSUFFICIENT_BUFFER)
{
continue;
}
else
{
break;
}
}
break;
}
if(szDomainName)
{
delete szDomainName;
}
FreeSid(pSid);
return Result;
}