Leaked source code of windows server 2003
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.
 
 
 
 
 
 

194 lines
5.0 KiB

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation
//
// SYNOPSIS
//
// Defines the class RasUser.
//
///////////////////////////////////////////////////////////////////////////////
#include <ias.h>
#include <iastlutl.h>
#define IASSAMAPI
#include <iaslsa.h>
#include <iasntds.h>
#include <iasparms.h>
#include <sdoias.h>
#include <rasuser.h>
#include <userschema.h>
//////////
// Attributes that should be retrieved for each user.
//////////
const PCWSTR USER_PARMS[] =
{
L"userParameters",
NULL
};
HRESULT RasUser::initialize() throw ()
{
//////////
// Let's get everything that could fail out of the way first.
//////////
PIASATTRIBUTE attrs[3];
DWORD error = IASAttributeAlloc(3, attrs);
if (error) { return HRESULT_FROM_WIN32(error); }
//////////
// Initialize the dial-in bit attributes.
//////////
attrs[0]->dwId = IAS_ATTRIBUTE_ALLOW_DIALIN;
attrs[0]->Value.itType = IASTYPE_BOOLEAN;
attrs[0]->Value.Boolean = TRUE;
attrs[1]->dwFlags = 0;
allowAccess.attach(attrs[0], false);
attrs[1]->dwId = IAS_ATTRIBUTE_ALLOW_DIALIN;
attrs[1]->Value.itType = IASTYPE_BOOLEAN;
attrs[1]->Value.Boolean = FALSE;
attrs[1]->dwFlags = 0;
denyAccess.attach(attrs[1], false);
attrs[2]->dwId = RADIUS_ATTRIBUTE_SERVICE_TYPE;
attrs[2]->Value.itType = IASTYPE_ENUM;
attrs[2]->Value.Enumerator = 4;
attrs[2]->dwFlags = IAS_INCLUDE_IN_ACCEPT;
callbackFramed.attach(attrs[2], false);
return S_OK;
}
void RasUser::finalize() throw ()
{
allowAccess.release();
denyAccess.release();
callbackFramed.release();
}
IASREQUESTSTATUS RasUser::processUser(
IASRequest& request,
PCWSTR domainName,
PCWSTR username
)
{
IASTraceString("Using downlevel dial-in parameters.");
DWORD error;
RAS_USER_0 ru0;
// Try using LDAP first since it's fastest.
IASNtdsResult result;
error = IASNtdsQueryUserAttributes(
domainName,
username,
LDAP_SCOPE_SUBTREE,
const_cast<PWCHAR*>(USER_PARMS),
&result
);
if (error == NO_ERROR)
{
// Retrieve the connection for this message.
LDAP* ld = ldap_conn_from_msg(NULL, result.msg);
LDAPMessage* entry = ldap_first_entry(ld, result.msg);
if (entry)
{
// Store the user's DN.
PWCHAR dn = ldap_get_dnW(ld, entry);
IASStoreFQUserName(request, DS_FQDN_1779_NAME, dn);
ldap_memfree(dn);
// There is at most one attribute.
PWCHAR *str = ldap_get_valuesW(
ld,
entry,
const_cast<PWCHAR>(USER_PARMS[0])
);
// It's okay if we didn't get anything, the API can handle NULL
// UserParameters.
error = IASParmsQueryRasUser0((str ? *str : NULL), &ru0);
ldap_value_freeW(str);
}
else
{
error = ERROR_NO_SUCH_USER;
}
}
else if (error == ERROR_DS_NOT_INSTALLED)
{
// No DS, so fall back to SAM APIs.
error = IASGetRASUserInfo(username, domainName, &ru0);
}
if (error)
{
IASTraceFailure("Per-user attribute retrieval", error);
HRESULT hr = IASMapWin32Error(error, IAS_SERVER_UNAVAILABLE);
return IASProcessFailure(request, hr);
}
// Used for injecting single attributes.
ATTRIBUTEPOSITION pos, *first, *last;
first = &pos;
last = first + 1;
//////////
// Insert the always present Allow-Dialin attribute.
//////////
if ((ru0.bfPrivilege & RASPRIV_DialinPrivilege) == 0)
{
first->pAttribute = denyAccess;
}
else
{
first->pAttribute = allowAccess;
}
IASTraceString("Inserting attribute msNPAllowDialin.");
OverwriteAttribute(request, first, last);
//////////
// Insert the "Callback Framed" service type if callback is allowed.
//////////
if ((ru0.bfPrivilege & RASPRIV_CallbackType) != RASPRIV_NoCallback)
{
first->pAttribute = callbackFramed;
IASTraceString("Inserting attribute msRADIUSServiceType.");
OverwriteAttribute(request, first, last);
}
//////////
// Insert the Callback-Number if present.
//////////
if (ru0.bfPrivilege & RASPRIV_AdminSetCallback)
{
IASAttribute callback(true);
callback->dwId = RADIUS_ATTRIBUTE_CALLBACK_NUMBER;
callback.setOctetString(ru0.wszPhoneNumber);
callback.setFlag(IAS_INCLUDE_IN_ACCEPT);
first->pAttribute = callback;
IASTraceString("Inserting attribute msRADIUSCallbackNumber.");
OverwriteAttribute(request, first, last);
}
IASTraceString("Successfully retrieved per-user attributes.");
return IAS_REQUEST_STATUS_HANDLED;
}