Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

326 lines
12 KiB

Remote Access Support in User Manager
-------------------------------------
Purpose:
LAN Manager has been flamed in the press for having separate
Admin tools for each of the component services, such as Remote
Access. Since granting/revoking user permissions is the primary
RAS administration activity, this deficiency can be addressed by
allowing Remote Access Permissions to be set from within the NT
User Manager tool.
Note: Integration of the other RASADMIN features into Computer
Manager was considered, but rejected. There were several
reasons why it would confuse the user (we're domain
oriented, our "connections" are async side instead of LAN
side, etc). A stand-alone RASADMIN will be provided with
this functionality. The RASADMIN icon should appear in the
NT Admin UI program group to help the user find this
functionality.
Development Effort:
The majority of the code implementing the Remote Access support
will be supplied in a DLL (RASUSER.DLL) which will be owned by
the Remote Access group.
A small amount of code to detect the RASUSER.DLL, conditionally
display a "Remote" button on the User Properties dialog, and call
the DLL when the button is pressed must live in the main User
Manager program. This code will be owned by the NT UI group with
the Remote Access group providing as much help as is productive.
An outline of this code is provided below.
Design Notes:
It is important to decouple the RAS/UserMgr interface to a fair
degree for the following reasons:
* RAS releases will not necessarily correspond to core NT
releases. A clean interface will prevent mix+match headaches
down the road. This is why a DLL is chosen rather than static
linking into UserMgr.
* RAS's use of the UAS user_parms field is questionable since
others may attempt to use the field for their own purpose
(though NETADMIN no longer lets the user edit it). The
significant effort to manually replicate the information has
delayed a cleaner solution. This could well change in the
future.
The initial design will use DLL->UserMgr callouts to retrieve
and set the caller's user_parms data as per JonN's mail.
However, the concept of "instance" cannot be scrapped because
doing so would prevent RAS from abandoning user_parms in a
future version. This is not a lot of work for UserMgr who
simply calls the RAS Open/Close calls at dialog
initialization/termination. (Note that the user names are no
longer passed in the Open. It is simply a call to exchange
handles)
Calling Sequence:
1. User: Invokes UserMgr.
2. UserMgr: Checks for RASUSER DLL and loads entry points if found.
(hereafter, it is assumed that RAS was found)
...
3. User: Invokes "User Properties" dialog (or variant).
4. UserMgr: Calls RasuserOpen with handle of "User Properties" dialog.
RasuserOpen returns a "DLL-client" handle.
Enables "Remote" button on toolbar
5. User: Presses "Remote" button
6. UserMgr: Calls RasuserPermissionsDlg passing the number of
users selected and GetUserName, GetUserParms, and
SetUserParms entry points.
7. RasUser: For each user
Calls back to GetUserName and GetUserParms in UserMgr
8. User: Presses OK or Cancel.
9. RasUser: If OK pressed and permissions changed
For each user
Calls SetUserParms with new settings
Terminate dialog
10. User: Presses OK or Cancel on "User Properties" dialog
11. UserMgr: Calls RasuserClose with commit flag TRUE if OK, FALSE if Cancel.
12. RasUser: Does nothing.
13. UserMgr: If OK pressed
Write user_parms (and other) changes.
Terminate dialog.
A future RAS release could skip the calls to GetUserParms and
SetUserParms and call a different "Get" routine at step 7 and a
different "Set" routine at step 12. The Open/Close calls
indicate the duration of a given UserProperty dialog to RAS so
the commit occurs at UserProperty->OK as desired.
User Manager Code Description:
Assumptions:
All system calls listed in the outline below are Win32.
It is assumed that the User Manager will guarantee that the
user is either an admin or has ACCOUNT operator privilege.
Initialization:
/* Globals...
*/
BOOL fRasInstalled;
FARPROC pfuncRasuserOpen;
FARPROC pfuncRasuserClose;
FARPROC pfuncRasuserPermissionsDlg;
/* Determine if RAS is installed and load the RAS extensions
** library if it is. Obtain entry addresses for the various
** RASUSER routines. (GetProcAddress is used rather than an
** import library so that the User Manager program can load
** and run when the RASUSER.DLL is not present)
*/
hRasuser = LoadLibrary( "RASUSER.DLL" );
fRasInstalled = (hRasuser != NULL);
if (fRasInstalled)
{
pfuncRasuserOpen = GetProcAddress( hRasuser, "RASUSEROPEN" );
if (pfuncRasuserOpen == NULL)
/* Report error */;
pfuncRasuserClose = GetProcAddress( hRasuser, "RASUSERCLOSE" );
if (pfuncRasuserClose == NULL)
/* Report error */;
pfuncRasuserPermissionsDlg =
GetProcAddress( hRasuser, "RASUSERPERMISSIONSDLG" );
if (pfuncRasuserPermissionsDlg == NULL)
/* Report error */;
}
User Properties dialog:
/* At User Properties dialog initialization...
*/
HANDLE hRasuserInstance;
if (fRasInstalled)
{
/* Enable and make visible the "Remote" button on the end
** of the toolbar.
*/
<code by NT UI group>
/* Tell DLL to create an instance of RAS user data for
** the specified user. The handle of the User Manager
** dialog window is passed for use as a BLT powin by the
** DLL.
*/
hRasuserInstance =
(*pfuncRasuserOpen)( hwndUserPropertiesDlg );
if (hRasuserInstance == NULL)
/* Report error */;
}
/* When "Remote" button is pressed...
**
** Run the RAS Permissions dialog:
**
** ---------------------------------------------------------------
** | - | Remote Access Permissions |
** |-------------------------------------------------------------|
** | |
** | {Multiple-user-box-like-UserMgr-uses} [ OK ] |
** | |
** | [ Cancel ] |
** | [X] Remote Access Permission |
** | [ Help ] |
** | -- Callback Number -------------------------- |
** | | | |
** | | (*) No Callback | |
** | | ( ) Set By Caller | |
** | | ( ) Preset To: [.....................] | |
** | | | |
** | --------------------------------------------- |
** | |
** ---------------------------------------------------------------
**
** The dialog call returns an error (non-0) only if the
** dialog cannot be constructed or some other fundamental
** error occurs. Net API errors and user errors are handled
** by the RAS dialog.
*/
apierr = (*pfuncRasuserPermissionsDlg)(
hRasuserInstance,
cUsers,
pfuncGetUserName,
pfuncGetUserParms,
pfuncSetUserParms );
if (apierr != NO_ERROR)
/* Report error */;
/* At User Properties dialog termination...
**
** Tell DLL to release the data associated with this User
** Manager instance. If the 'commit' flag is true (i.e. the
** user presses OK on the User Properties dialog, rather than
** Cancel) then the changes are written to the UAS (with
** NetUserXxx calls).
*/
if (fRasInstalled)
(*pfRasuserClose)( hRasuserInstance, fCommitChanges );
Callback functions in UserMgr:
APIERR GetUserName( IN USHORT iName, OUT CHAR* pchNameBuf );
'iName' is an index 0 to 'cUsers'-1 indicating the user
name to return in 'pchNameBuf'.
'pchNameBuf' is the address of a buffer to receive the
user name. (The buffer will be oversized in case the
user name increases in size the future.)
Returns: 0 if successful, non-0 otherwise.
APIERR GetUserParms( IN USHORT iName, OUT CHAR* pchParmsBuf );
'iName' is an index 0 to 'cUsers'-1 indicating the user
name whose user_parms are returned in 'pchParmsBuf'.
'pchParmsBuf' is the address of a buffer to receive the
user_parms data. (The buffer will be oversized in
case the user_parms increases in size the future.)
Returns: 0 if successful, non-0 otherwise.
APIERR SetUserParms( IN USHORT iName, IN CHAR* pchParmsBuf );
'iName' is an index 0 to 'cUsers'-1 indicating the user
name whose user_parms are in 'pchParmsBuf'.
'pchParmsBuf' is the address of a buffer containing the
user_parms data.
Returns: 0 if successful, non-0 otherwise.
RASUSER Code Description:
The RASUSER DLL will borrow the appropriate code from the
RASADMIN Permissions dialog to display and operate the new
dialog.
As in LM21, the RAS permission data is stored in coded form in
the user_parms field of the UAS. RASUSER will use NetUserGetInfo
and NetUserSetInfo calls from the NT LMAPI conversion library to
retrieve and store the user data. This will require an
additional DialinXxx admin API call (internal RASADMIN API).
New code to store client instance data between Open/Close calls
will be needed.
Issues:
* Must make sure that User Manager does not overwrite RASUSER
changes when it saves user information set in the User
Properties dialog.
A: (See above)
* Can access to BLT LM error message resources be shared between
the User Manager and RASUSER?
A: (mail to BenG outstanding)
* It's my understanding that the NetGet/SetUserInfo calls will
work (thru the NT LMAPI) in the same way as they did on LM21.
That is, the user_parms field is supported and the user's UAS
account data is automatically replicated to all servers in the
domain. Please comment if you can confirm/refute this.
A: Yes, they will work, and UserMgr also uses the converted
NetXxx calls.
* Does it make sense to allocate a bit to represent RAS privilege
in a standard NT place (like where?) rather than use the
user_parms field? (A catch is that the callback number must
also be stored on a per-user basis anyway)
A: Appears not.
* Where should the help for the RAS dialog live?
A: Hopefully BLT will support us here. (mail to BenG outstanding)
* Need information about how UserMgr displays multiple user
names. We want to be consistent here.
A: We will borrow the code to display the multiple users in
listbox form from UserMgr.