How To Modify or Query the RDP Connection Permissions for Terminal Services (259129)



The information in this article applies to:

  • Microsoft Win32 Application Programming Interface (API), when used with:
    • the operating system: Microsoft Windows NT 4.0
    • the operating system: Microsoft Windows 2000

This article was previously published under Q259129
IMPORTANT: This article contains information about modifying the registry. Before you modify the registry, make sure to back it up and make sure that you understand how to restore the registry if a problem occurs. For information about how to back up, restore, and edit the registry, click the following article number to view the article in the Microsoft Knowledge Base:

256986 Description of the Microsoft Windows Registry

SUMMARY

The Microsoft Terminal Services configuration application allows you to change the Remote Desktop Protocol-Transmission Control Protocol (RDP-TCP) connection permissions. These permissions determine which users can perform actions (connect, disconnect, logoff, query, and so on) against a Terminal Services session. An application can programmatically change the RDP-TCP connection permissions through the Windows registry.

MORE INFORMATION

WARNING: If you use Registry Editor incorrectly, you may cause serious problems that may require you to reinstall your operating system. Microsoft cannot guarantee that you can solve problems that result from using Registry Editor incorrectly. Use Registry Editor at your own risk.

The security descriptor is stored in self-relative format in the registry. To obtain or modify the security descriptor, you must convert it to absolute format. After you modify the security descriptor, you must convert it back to self-relative format, and then resave.

The default security settings are stored in the DefaultSecurity registry value under the following key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations

If you modify the security settings, they are stored in the Security value under the following key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp

If you modify the default security descriptor and the Security value does not exist under the RDP-Tcp key, you must create the value.

Sample Code

The following code demonstrates how to modify the current RDP-TCP connection permissions. This code checks for a modified security descriptor under the RDP-Tcp key. If none is found, it opens the default security descriptor under the WinStations key. After you modify the descriptor, it is saved under the RDP-Tcp key.

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

#define USER_ACCESS  0x1A1
#define GUEST_ACCESS 0x20
#define FULL_CONTROL 0xF03FF

void _tmain(void) {

   BYTE   buffer[4096];
   BYTE   acl[1024];
   DWORD  dwAcl = sizeof(acl);
   BYTE   sacl[1024];
   DWORD  dwSacl = sizeof(sacl);
   BYTE   sidOwner[1024];
   DWORD  dwSidOwner = sizeof(sidOwner);
   BYTE   sidGroup[1024];
   DWORD  dwSidGroup = sizeof(sidGroup);
   DWORD  dwSize = sizeof(buffer);
   HKEY   hKey = NULL;
   LONG   lResult;
   BYTE   AbsSD[4096];
   BYTE   AbsModifiedSD[4096];
   DWORD  dwAbsMod = sizeof(AbsModifiedSD);

   // Open the rdp-tcp key
   lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
         TEXT("system\\currentcontrolset\\control")
         TEXT("\\terminal server\\winstations\\rdp-tcp"),
         0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hKey);
   if (lResult != ERROR_SUCCESS) {
      _tprintf(TEXT("RegOpenKeyEx failed with error %u\n"), lResult);
      return;
   }

   // Query the Security value
   lResult = RegQueryValueEx(hKey, TEXT("Security"), NULL, NULL, buffer,
         &dwSize);

   // Close the rdp-tcp key
   RegCloseKey(hKey);

   if (lResult != ERROR_SUCCESS && lResult != ERROR_FILE_NOT_FOUND) {
      _tprintf(TEXT("RegQueryValueEx failed with error %u\n"),
            lResult);
      return;
   }

   // If the value was not present, get the default security descriptor
   if (lResult == ERROR_FILE_NOT_FOUND) {

      // Open the WinStations key
      lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
            TEXT("system\\currentcontrolset\\control")
            TEXT("\\terminal server\\winstations"), 
            0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hKey);
      if (lResult != ERROR_SUCCESS) {
         _tprintf(TEXT("RegOpenKeyEx failed with error %u\n"),
               lResult);
         return;
      }

      // Query the DefaultSecurity value
      lResult = RegQueryValueEx(hKey, TEXT("DefaultSecurity"), NULL,
            NULL, buffer, &dwSize);

      // Close the WinStations key
      RegCloseKey(hKey);

      if (lResult != ERROR_SUCCESS) {
         _tprintf(TEXT("RegQueryValueEx failed with error %u\n"),
               lResult);
         return;
      }
   }

   // Convert the self-relative security descriptor to the absolute form
   dwSize = sizeof(AbsSD);
   if (!MakeAbsoluteSD((PSECURITY_DESCRIPTOR) buffer, AbsSD, &dwSize, 
         (PACL) acl, &dwAcl, (PACL) sacl, &dwSacl, (PSID) sidOwner, 
         &dwSidOwner, (PSID) sidGroup, &dwSidGroup)) {
      _tprintf(TEXT("MakeAbsoluteSD failed with error %u\n"), 
            GetLastError());
      return;
   }

   // 
   // TODO: Your code to modify the dacl goes here
   // 
   // CAUTION: Incorrectly modifying the DACL may prevent the 
   // system from operating properly.  For added safety, be sure 
   // to back up the registry before you run your code.
   // 


   
   // Convert the security descriptor back to the self-relative form
   if (!MakeSelfRelativeSD(AbsSD, AbsModifiedSD, &dwAbsMod)){
      _tprintf(TEXT("MakeSelfRelativeSD failed with error %u\n"),
            GetLastError());
      return;
   }

   // Open the rdp-tcp key
   lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
         TEXT("system\\currentcontrolset\\control")
         TEXT("\\terminal server\\winstations\\rdp-tcp"),
         0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hKey);
   if (lResult != ERROR_SUCCESS) {
      _tprintf(TEXT("RegOpenKeyEx failed with error %u\n"), lResult);
      return;
   }

   // Save the modified security value
   lResult = RegSetValueEx(hKey, TEXT("Security"), 0, REG_BINARY, 
         AbsModifiedSD, dwAbsMod);
   if (lResult != ERROR_SUCCESS){
      _tprintf(TEXT("RegSetValueEx failed with %u\n"), lResult);
      return;
   }

   // Close the rdp-tcp key
   RegCloseKey(hKey);
}
				

Modification Type:MinorLast Reviewed:7/2/2004
Keywords:kbAPI kbhowto kbKernBase KB259129 kbAudDeveloper