Microsoft KB Archive/277631

{|
 * width="100%"|

BUG: WTSSetUserConfig May Modify a User's Remote Access Permission

 * }

Q277631

-

The information in this article applies to:


 * Microsoft Win32 Application Programming Interface (API), included with:
 * the operating system: Microsoft Windows 2000

-

SYMPTOMS
If WTSSetUserConfig is used to modify a domain user's Terminal Server settings, it may also modify the user's remote access permission as a side effect. When this occurs, the remote access permission level is changed to &quot;Deny access&quot; from its original default value of &quot;Control access through Remote Access Policy.&quot; This problem occurs only if the remote access permission has never been explicitly set for the user.

CAUSE
In a Windows 2000 domain, a user's remote access permission is controlled by an Active Directory attribute called msNPAllowDialin. When the user's account is created, the structure that contains this attribute is uninitialized. In this case, the system's default behavior is to control dial-in access for the user according to the Remote Access Policy. The WTSSetUserConfig API initializes the Active Directory structure if it has never been initialized before. During this initialization, the msNPAllowDialin attribute is set to deny dial-in access for the user.

RESOLUTION
To work around this problem, a program can explicitly set the user's dial-in settings prior to calling WTSSetUserConfig. The Remote Access Service (RAS) APIs can be used for this purpose. The following sample code demonstrates how to do this.

Sample Code
The following code uses the RAS function MprAdminUserGetInfo to retrieve a user's current dial-in settings. Then a call to MprAdminUserSetInfo is made to explicitly store these settings. If this is the first time that the settings have been explicitly set, the Active Directory structure that contains dial-in settings will be initialized, thereby preventing future WTSSetUserConfig calls from altering the settings.

#define UNICODE
 * 1) define _UNICODE


 * 1) include 
 * 2) include 
 * 3) include   // must be linked with mprapi.lib

void wmain(int argc, WCHAR *argv[]) {

WCHAR szUser[UNLEN + 1]; WCHAR szDomain[DNLEN + 1]; WCHAR szUasServer[UNCLEN + 1]; DWORD dwResult;

// We must use the RAS_USER_1 structure to preserve all // Windows 2000 remote access permission attributes RAS_USER_1 ru1;

if (argc < 3) { wprintf(L&quot;usage: %s \n&quot;, argv[0]); return; }

wcscpy(szUser, argv[1]); wcscpy(szDomain, argv[2]); // Retrieve the name of the server with the User Accounts Subsystem dwResult = MprAdminGetPDCServer(szDomain, NULL, (PWSTR) szUasServer); if (dwResult != NO_ERROR) { wprintf(L&quot;MprAdminGetPDCServer failed. Error %d\n&quot;, dwResult); return; }

// Retrieve the user's current dial-in settings dwResult = MprAdminUserGetInfo(szUasServer, szUser, 1, (PBYTE) &ru1); if (dwResult != NO_ERROR) { wprintf(L&quot;MprAdminUserGetInfo failed. Error %d\n&quot;, dwResult); return; }

// Explicitly reset the user's dial-in settings dwResult = MprAdminUserSetInfo(szUasServer, szUser, 1, (PBYTE) &ru1); if (dwResult != NO_ERROR) { wprintf(L&quot;MprAdminUserSetInfo failed. Error %d\n&quot;, dwResult); return; }

// Now it is safe to call WTSSetUserConfig

return; }

STATUS
Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article.