windows-nt/Source/XPSP1/NT/net/rras/netsh/ras/user.c

730 lines
16 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
#include "precomp.h"
BOOL
UserServerInfoIsInit(
IN RASMON_SERVERINFO * pServerInfo)
{
return ((pServerInfo->hServer) ||
(pServerInfo->dwBuild == RASMONTR_OS_BUILD_NT40));
}
DWORD
UserServerInfoInit(
IN RASMON_SERVERINFO * pServerInfo)
{
DWORD dwErr = NO_ERROR;
BOOL bInit = UserServerInfoIsInit(pServerInfo);
// If we're already initailized, return
//
if (bInit)
{
return NO_ERROR;
}
if ((pServerInfo->dwBuild != RASMONTR_OS_BUILD_NT40) &&
(pServerInfo->hServer == NULL))
{
//
// first time connecting to user server
//
MprAdminUserServerConnect (
pServerInfo->pszServer,
TRUE,
&(pServerInfo->hServer));
}
return dwErr;
}
DWORD
UserServerInfoUninit(
IN RASMON_SERVERINFO * pServerInfo)
{
// Release the reference to the user server
if (g_pServerInfo->hServer)
{
MprAdminUserServerDisconnect(g_pServerInfo->hServer);
g_pServerInfo->hServer = NULL;
}
return NO_ERROR;
}
DWORD
UserGetRasProperties (
IN RASMON_SERVERINFO * pServerInfo,
IN LPCWSTR pwszUser,
IN RAS_USER_0* pUser0)
{
HANDLE hUser = NULL;
DWORD dwErr;
BOOL bInit = UserServerInfoIsInit(pServerInfo);
do
{
UserServerInfoInit(pServerInfo);
// Get the information using nt40 apis
//
if (pServerInfo->dwBuild == RASMONTR_OS_BUILD_NT40)
{
dwErr = MprAdminUserGetInfo(
pServerInfo->pszServer,
pwszUser,
0,
(LPBYTE)pUser0);
if (dwErr != NO_ERROR)
{
break;
}
}
// Or get it using nt50 apis
else
{
// Get a reference to the given user
//
dwErr = MprAdminUserOpen(
pServerInfo->hServer,
(LPWSTR)pwszUser,
&hUser);
if (dwErr isnot NO_ERROR)
{
break;
}
// Set the information
//
dwErr = MprAdminUserRead(
hUser,
1, // Gives us RASPRIV_DialinPolicy
(LPBYTE)pUser0);
if (dwErr isnot NO_ERROR)
{
break;
}
}
} while (FALSE);
// Cleanup
//
{
if(hUser)
{
MprAdminUserClose(hUser);
}
if (!bInit)
{
UserServerInfoUninit(pServerInfo);
}
}
return dwErr;
}
DWORD
UserSetRasProperties (
IN RASMON_SERVERINFO * pServerInfo,
IN LPCWSTR pwszUser,
IN RAS_USER_0* pUser0)
{
HANDLE hUser = NULL;
DWORD dwErr;
BOOL bInit = UserServerInfoIsInit(pServerInfo);
do
{
UserServerInfoInit(pServerInfo);
// Set the information using nt40 apis
//
if (pServerInfo->dwBuild == RASMONTR_OS_BUILD_NT40)
{
dwErr = MprAdminUserSetInfo(
pServerInfo->pszServer,
pwszUser,
0,
(LPBYTE)pUser0);
if (dwErr != NO_ERROR)
{
break;
}
}
// Or get it using nt50 apis
else
{
// Get a reference to the given user
//
dwErr = MprAdminUserOpen(
pServerInfo->hServer,
(LPWSTR)pwszUser,
&hUser);
if (dwErr isnot NO_ERROR)
{
break;
}
// Set the information
//
dwErr = MprAdminUserWrite(
hUser,
1, // Gives us RASPRIV_DialinPolicy
(LPBYTE)pUser0);
if (dwErr isnot NO_ERROR)
{
break;
}
}
} while (FALSE);
// Cleanup
//
{
if(hUser)
{
MprAdminUserClose(hUser);
}
if (!bInit)
{
UserServerInfoUninit(pServerInfo);
}
}
return dwErr;
}
DWORD
UserAdd(
IN LPCWSTR pwszServer,
IN PRASUSER_DATA pUser)
/*++
Routine Description:
Adds the given user to the system
--*/
{
NET_API_STATUS nStatus;
USER_INFO_2 * pUser2;
LPCWSTR pwszFmtServer = pwszServer;
// Initialize the base user information
USER_INFO_1 UserInfo1 =
{
pUser->pszUsername,
pUser->pszPassword,
0,
USER_PRIV_USER,
L"",
L"",
UF_SCRIPT | UF_DONT_EXPIRE_PASSWD | UF_NORMAL_ACCOUNT,
L""
};
// Add the user
nStatus = NetUserAdd(
pwszFmtServer,
1,
(LPBYTE)&UserInfo1,
NULL);
// If the user wasn't added, find out why
if (nStatus != NERR_Success)
{
switch (nStatus)
{
case ERROR_ACCESS_DENIED:
return ERROR_ACCESS_DENIED;
case NERR_UserExists:
return ERROR_USER_EXISTS;
case NERR_PasswordTooShort:
return ERROR_INVALID_PASSWORDNAME;
}
return ERROR_CAN_NOT_COMPLETE;
}
// Add the user's full name if provided
if (pUser->pszFullname)
{
// add the user's full name
nStatus = NetUserGetInfo(
pwszFmtServer,
pUser->pszUsername,
2,
(LPBYTE*)&pUser2);
if (nStatus is NERR_Success)
{
// Modify the full name in the structure
pUser2->usri2_full_name = pUser->pszFullname;
NetUserSetInfo(
pwszFmtServer,
pUser->pszUsername,
2,
(LPBYTE)pUser2,
NULL);
NetApiBufferFree((LPBYTE)pUser2);
return NO_ERROR;
}
return ERROR_CAN_NOT_COMPLETE;
}
return NO_ERROR;
}
DWORD
UserDelete(
IN LPCWSTR pwszServer,
IN PRASUSER_DATA pUser)
/*++
Routine Description:
Deletes the given user from the system
--*/
{
NET_API_STATUS nStatus;
// Delete the user and return the status code. If the
// specified user is not in the user database, consider
// it a success
nStatus = NetUserDel(
pwszServer,
pUser->pszUsername);
if (nStatus is NERR_UserNotFound)
{
return NO_ERROR;
}
return (nStatus is NERR_Success) ? NO_ERROR : ERROR_CAN_NOT_COMPLETE;
}
DWORD
UserDumpConfig(
IN HANDLE hFile
)
/*++
Routine Description:
Dumps a script to set the ras USER information to
the given text file.
Arguments:
Return Value:
NO_ERROR
--*/
{
DWORD dwErr;
// Enumerate the users dumping them as we go
dwErr = UserEnumUsers(
g_pServerInfo,
UserShowSet,
(HANDLE)hFile);
if (dwErr isnot NO_ERROR)
{
DisplayMessage(
g_hModule,
EMSG_UNABLE_TO_ENUM_USERS);
}
return dwErr;
}
BOOL
UserShowReport(
IN PRASUSER_DATA pUser,
IN HANDLE hFile
)
/*++
Routine Description:
Prints ras user information to the display or a file if specified.
This function can be used as a callback function (see UserEnumUsers).
Arguments:
pUser - The user
hFile - The file
Return Value:
TRUE - continue enumeration
FALSE - stop enumeration
--*/
{
DWORD dwErr, dwSize;
WCHAR rgwcIfDesc[MAX_INTERFACE_NAME_LEN + 1];
PWCHAR pwszDialin = NULL,
pwszCbPolicy = NULL,
pwszCbNumber = NULL,
pwszSetCmd = NULL;
// Initialize the set command
//
pwszSetCmd = DMP_RASUSER_SET;
// Initialize the dialin string
//
if (pUser->User0.bfPrivilege & RASPRIV_DialinPolicy)
{
pwszDialin = TOKEN_POLICY;
}
else if (pUser->User0.bfPrivilege & RASPRIV_DialinPrivilege)
{
pwszDialin = TOKEN_PERMIT;
}
else
{
pwszDialin = TOKEN_DENY;
}
// Initialize the callback policy string
//
if (pUser->User0.bfPrivilege & RASPRIV_NoCallback)
{
pwszCbPolicy = TOKEN_NONE;
}
else if (pUser->User0.bfPrivilege & RASPRIV_CallerSetCallback)
{
pwszCbPolicy = TOKEN_CALLER;
}
else
{
pwszCbPolicy = TOKEN_ADMIN;
}
// Initialize the callback number string
//
pwszCbNumber = pUser->User0.wszPhoneNumber;
do
{
if(!pwszSetCmd or
!pUser->pszUsername or
!pwszDialin or
!pwszCbNumber
)
{
DisplayError(NULL,
ERROR_NOT_ENOUGH_MEMORY);
break;
}
DisplayMessage(g_hModule,
MSG_RASUSER_RASINFO,
pUser->pszUsername,
pwszDialin,
pwszCbPolicy,
pwszCbNumber);
} while(FALSE);
return TRUE;
}
BOOL
UserShowSet(
IN PRASUSER_DATA pUser,
IN HANDLE hFile
)
/*++
Routine Description:
Prints ras user information to the display or a file if specified.
This function can be used as a callback function (see UserEnumUsers).
Arguments:
pUser - The user
hFile - The file
Return Value:
TRUE - continue enumeration
FALSE - stop enumeration
--*/
{
DWORD dwErr, dwSize;
WCHAR rgwcIfDesc[MAX_INTERFACE_NAME_LEN + 1];
PWCHAR pwszName = NULL,
pwszDialin = NULL,
pwszCbPolicy = NULL,
pwszCbNumber = NULL,
pwszSetCmd = NULL;
// Initialize the set command
//
pwszSetCmd = DMP_RASUSER_SET;
// Initialize the dialin string
//
if (pUser->User0.bfPrivilege & RASPRIV_DialinPolicy)
{
pwszDialin = RutlAssignmentFromTokens(
g_hModule,
TOKEN_DIALIN,
TOKEN_POLICY);
}
else if (pUser->User0.bfPrivilege & RASPRIV_DialinPrivilege)
{
pwszDialin = RutlAssignmentFromTokens(
g_hModule,
TOKEN_DIALIN,
TOKEN_PERMIT);
}
else
{
pwszDialin = RutlAssignmentFromTokens(
g_hModule,
TOKEN_DIALIN,
TOKEN_DENY);
}
// Initialize the callback policy string
//
if (pUser->User0.bfPrivilege & RASPRIV_NoCallback)
{
pwszCbPolicy = RutlAssignmentFromTokens(
g_hModule,
TOKEN_CBPOLICY,
TOKEN_NONE);
}
else if (pUser->User0.bfPrivilege & RASPRIV_CallerSetCallback)
{
pwszCbPolicy = RutlAssignmentFromTokens(
g_hModule,
TOKEN_CBPOLICY,
TOKEN_CALLER);
}
else
{
pwszCbPolicy = RutlAssignmentFromTokens(
g_hModule,
TOKEN_CBPOLICY,
TOKEN_CALLER);
}
// Initialize the callback number string
//
if (*(pUser->User0.wszPhoneNumber))
{
pwszCbNumber = RutlAssignmentFromTokens(
g_hModule,
TOKEN_CBNUMBER,
pUser->User0.wszPhoneNumber);
}
else
{
pwszCbNumber = NULL;
}
pwszName = RutlAssignmentFromTokens(
g_hModule,
TOKEN_NAME,
pUser->pszUsername);
do
{
if(!pwszSetCmd or
!pwszName or
!pwszDialin or
!pwszCbPolicy
)
{
DisplayError(NULL,
ERROR_NOT_ENOUGH_MEMORY);
break;
}
DisplayMessage(g_hModule,
MSG_RASUSER_SET_CMD,
pwszSetCmd,
pwszName,
pwszDialin,
pwszCbPolicy,
(pwszCbNumber) ? pwszCbNumber : L"");
} while(FALSE);
// Callback
{
if (pwszDialin)
{
RutlFree(pwszDialin);
}
if (pwszCbPolicy)
{
RutlFree(pwszCbPolicy);
}
if (pwszCbNumber)
{
RutlFree(pwszCbNumber);
}
if (pwszName)
{
RutlFree(pwszName);
}
}
return TRUE;
}
BOOL
UserShowPermit(
IN PRASUSER_DATA pUser,
IN HANDLE hFile
)
{
if (pUser->User0.bfPrivilege & RASPRIV_DialinPrivilege)
{
return UserShowReport(pUser, hFile);
}
return TRUE;
}
DWORD
UserEnumUsers(
IN RASMON_SERVERINFO* pServerInfo,
IN PFN_RASUSER_ENUM_CB pEnumFn,
IN HANDLE hData
)
/*++
Routine Description:
Enumerates all users by calling the given callback function and
passing it the user information and some user defined data.
Enumeration stops when all the users have been enumerated or when
the enumeration function returns FALSE.
Arguments:
pwszServer - The server on which the users should be enumerated
pEnumFn - Enumeration function
hData - Caller defined opaque data blob
Return Value:
NO_ERROR
--*/
{
DWORD dwErr, dwIndex = 0, dwCount = 100, dwEntriesRead, i;
NET_DISPLAY_USER * pUsers;
NET_API_STATUS nStatus;
RAS_USER_0 RasUser0;
HANDLE hUser = NULL;
RASUSER_DATA UserData, *pUserData = &UserData;
BOOL bInit = UserServerInfoIsInit(pServerInfo);
UserServerInfoInit(pServerInfo);
// Enumerate the users
//
while (TRUE)
{
// Read in the next block of user names
nStatus = NetQueryDisplayInformation(
pServerInfo->pszServer,
1,
dwIndex,
dwCount,
dwCount * sizeof(NET_DISPLAY_USER),
&dwEntriesRead,
&pUsers);
// Get out if there's an error getting user names
if ((nStatus isnot NERR_Success) and
(nStatus isnot ERROR_MORE_DATA))
{
break;
}
for (i = 0; i < dwEntriesRead; i++)
{
// Initialize the user data
ZeroMemory(pUserData, sizeof(RASUSER_DATA));
// Read in the old information
dwErr = UserGetRasProperties (
pServerInfo,
pUsers[i].usri1_name,
&(pUserData->User0));
if (dwErr isnot NO_ERROR)
{
continue;
}
// Initialize the rest of the data structure
pUserData->pszUsername = pUsers[i].usri1_name;
pUserData->pszFullname = pUsers[i].usri1_full_name;
// Call the enumeration callback
if (! ((*(pEnumFn))(pUserData, hData)))
{
nStatus = NO_ERROR;
break;
}
}
// Set the index to read in the next set of users
dwIndex = pUsers[dwEntriesRead - 1].usri1_next_index;
// Free the users buffer
NetApiBufferFree (pUsers);
// If we've read in everybody, go ahead and break
if (nStatus isnot ERROR_MORE_DATA)
{
break;
}
}
if (!bInit)
{
UserServerInfoUninit(pServerInfo);
}
return NO_ERROR;
}