#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; }