|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996
//
// File: cuser.cxx
//
// Contents: Host user object code
//
// History: Feb-14-96 t-ptam Created.
//
//----------------------------------------------------------------------------
#include "NWCOMPAT.hxx"
#pragma hdrstop
//
// Macro-ized implementation.
//
DEFINE_IDispatch_ExtMgr_Implementation(CNWCOMPATUser)
DEFINE_IADs_TempImplementation(CNWCOMPATUser)
DEFINE_IADs_PutGetImplementation(CNWCOMPATUser, UserClass, gdwUserTableSize)
DEFINE_IADsPropertyList_Implementation(CNWCOMPATUser, UserClass, gdwUserTableSize)
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::CNWCOMPATUser()
//
// Synopsis:
//
//----------------------------------------------------------------------------
CNWCOMPATUser::CNWCOMPATUser(): _pDispMgr(NULL), _pExtMgr(NULL), _pPropertyCache(NULL), _ParentType(0), _ServerName(NULL), _szHostServerName(NULL) { ENLIST_TRACKING(CNWCOMPATUser); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::CreateUser
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::CreateUser( BSTR Parent, ULONG ParentType, BSTR ServerName, BSTR UserName, DWORD dwObjectState, REFIID riid, void **ppvObj ) { CNWCOMPATUser FAR * pUser = NULL; HRESULT hr = S_OK;
hr = AllocateUserObject(&pUser); BAIL_ON_FAILURE(hr);
hr = pUser->InitializeCoreObject( Parent, UserName, USER_CLASS_NAME, USER_SCHEMA_NAME, CLSID_NWCOMPATUser, dwObjectState ); BAIL_ON_FAILURE(hr);
hr = ADsAllocString( ServerName , &pUser->_ServerName); BAIL_ON_FAILURE(hr);
hr = ADsAllocString( ServerName, &pUser->_szHostServerName); BAIL_ON_FAILURE(hr);
hr = pUser->QueryInterface(riid, ppvObj); BAIL_ON_FAILURE(hr);
pUser->Release();
hr = pUser->_pExtMgr->FinalInitializeExtensions(); BAIL_ON_FAILURE(hr);
RRETURN(hr);
error: delete pUser;
RRETURN_EXP_IF_ERR(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::~CNWCOMPATUser
//
// Synopsis:
//
//----------------------------------------------------------------------------
CNWCOMPATUser::~CNWCOMPATUser( ) { ADsFreeString(_ServerName); ADsFreeString(_szHostServerName);
delete _pExtMgr; // created last, destroyed first
delete _pDispMgr;
delete _pPropertyCache; }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::QueryInterface
//
// Synopsis:
//
//----------------------------------------------------------------------------
STDMETHODIMP CNWCOMPATUser::QueryInterface( REFIID iid, LPVOID FAR* ppv ) { if (ppv == NULL) { RRETURN(E_POINTER); }
if (IsEqualIID(iid, IID_IUnknown)) { *ppv = (IADsUser FAR *) this; } else if (IsEqualIID(iid, IID_IADsUser)) { *ppv = (IADsUser FAR *) this; } else if (IsEqualIID(iid, IID_IADs)) { *ppv = (IADsUser FAR *) this; } else if (IsEqualIID(iid, IID_IDispatch)) { *ppv = (IADsUser FAR *) this; } else if (IsEqualIID(iid, IID_ISupportErrorInfo)) { *ppv = (ISupportErrorInfo FAR *) this; } else if (IsEqualIID(iid, IID_IADsPropertyList)) { *ppv = (IADsPropertyList FAR *) this; } else if (_pExtMgr) { RRETURN(_pExtMgr->QueryInterface(iid,ppv)); } else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return NOERROR; }
/* ISupportErrorInfo method */ //----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::InterfaceSupportsErrorInfo
//
// Synopsis:
//
//----------------------------------------------------------------------------
STDMETHODIMP CNWCOMPATUser::InterfaceSupportsErrorInfo( THIS_ REFIID riid ) { if (IsEqualIID(riid, IID_IADs) || IsEqualIID(riid, IID_IADsUser) || IsEqualIID(riid, IID_IADsPropertyList)) { RRETURN(S_OK); } else { RRETURN(S_FALSE); } }
/* IADs methods */
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::SetInfo
//
// Synopsis:
//
//----------------------------------------------------------------------------
STDMETHODIMP CNWCOMPATUser::SetInfo(THIS) { HRESULT hr = S_OK; POBJECTINFO pObjectInfo = NULL; NW_USER_INFO NwUserInfo = {NULL, NULL, NULL, NULL};
//
// Bind an object to a real tangible resource if it is not bounded already.
//
if (GetObjectState() == ADS_OBJECT_UNBOUND) {
hr = BuildObjectInfo( _Parent, _Name, &pObjectInfo ); BAIL_ON_FAILURE(hr);
hr = NWApiMakeUserInfo( pObjectInfo->ComponentArray[0], pObjectInfo->ComponentArray[1], L"", // empty password initially
&NwUserInfo ); BAIL_ON_FAILURE(hr);
hr = NWApiCreateUser( &NwUserInfo ); BAIL_ON_FAILURE(hr);
SetObjectState(ADS_OBJECT_BOUND); }
//
// Persist changes.
//
hr = SetInfo(USER_WILD_CARD_ID); BAIL_ON_FAILURE(hr);
error:
if (pObjectInfo) { FreeObjectInfo(pObjectInfo); }
(void) NWApiFreeUserInfo(&NwUserInfo) ;
RRETURN_EXP_IF_ERR(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetInfo
//
// Synopsis:
//
//----------------------------------------------------------------------------
STDMETHODIMP CNWCOMPATUser::GetInfo(THIS) {
_pPropertyCache->flushpropcache();
RRETURN(GetInfo( TRUE, USER_WILD_CARD_ID )); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::AllocateUserObject
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::AllocateUserObject( CNWCOMPATUser ** ppUser ) { CNWCOMPATUser FAR * pUser = NULL; CAggregatorDispMgr FAR * pDispMgr = NULL; CPropertyCache FAR * pPropertyCache = NULL; CADsExtMgr FAR * pExtensionMgr = NULL; HRESULT hr = S_OK;
//
// Allocate memory for a User object.
//
pUser = new CNWCOMPATUser(); if (pUser == NULL) { hr = E_OUTOFMEMORY; } BAIL_ON_FAILURE(hr);
//
// Create dispatch manager.
//
pDispMgr = new CAggregatorDispMgr; if (pDispMgr == NULL) { hr = E_OUTOFMEMORY; } BAIL_ON_FAILURE(hr);
//
// Load type info.
//
hr = LoadTypeInfoEntry( pDispMgr, LIBID_ADs, IID_IADsUser, (IADsUser *)pUser, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
hr = LoadTypeInfoEntry( pDispMgr, LIBID_ADs, IID_IADsPropertyList, (IADsPropertyList *)pUser, DISPID_VALUE ); BAIL_ON_FAILURE(hr);
hr = CPropertyCache::createpropertycache( UserClass, gdwUserTableSize, (CCoreADsObject *)pUser, &pPropertyCache ); BAIL_ON_FAILURE(hr);
pDispMgr->RegisterPropertyCache( pPropertyCache );
hr = ADSILoadExtensionManager( USER_CLASS_NAME, (IADs *) pUser, pDispMgr, &pExtensionMgr ); BAIL_ON_FAILURE(hr);
//
// Return.
//
pUser->_pPropertyCache = pPropertyCache; pUser->_pDispMgr = pDispMgr; pUser->_pExtMgr = pExtensionMgr;
*ppUser = pUser;
RRETURN(hr);
error: delete pDispMgr; delete pPropertyCache; delete pUser; delete pExtensionMgr;
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::SetInfo
//
// Synopsis:
//
//----------------------------------------------------------------------------
STDMETHODIMP CNWCOMPATUser::SetInfo(THIS_ DWORD dwPropertyID) { HRESULT hr = S_OK; HRESULT hrTemp = S_OK; NWCONN_HANDLE hConn = NULL;
//
// Get a handle to the bindery this object resides on.
//
hr = NWApiGetBinderyHandle( &hConn, _ServerName ); BAIL_ON_FAILURE(hr);
//
// Persist changes in cache.
//
hr = SetBusinessInfo(hConn); BAIL_ON_FAILURE(hr);
hr = SetAccountRestrictions(hConn); BAIL_ON_FAILURE(hr);
error: //
// Release handle.
//
if (hConn) { hrTemp = NWApiReleaseBinderyHandle(hConn); }
RRETURN_EXP_IF_ERR(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::SetBusinessInfo
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::SetBusinessInfo( NWCONN_HANDLE hConn ) { LPWSTR lpszRightSize = NULL; LPWSTR pszFullName = NULL; CHAR szData[(MAX_FULLNAME_LEN + 1)*2]; HRESULT hr = S_OK;
//
// Set FullName.
//
hr = GetLPTSTRPropertyFromCache( _pPropertyCache, TEXT("FullName"), &pszFullName );
if (SUCCEEDED(hr)) {
//
// Cut the FullName down to no more than MAX_FULLNAME_LEN of characters.
//
lpszRightSize = (LPWSTR) AllocADsMem( sizeof(WCHAR) * (MAX_FULLNAME_LEN + 1) ); if (!lpszRightSize) { RRETURN_EXP_IF_ERR(E_OUTOFMEMORY); }
lpszRightSize[MAX_FULLNAME_LEN] = 0;
wcsncpy( lpszRightSize, pszFullName, MAX_FULLNAME_LEN );
//
// Convert bstr in ANSI string.
//
UnicodeToAnsiString( lpszRightSize, szData, 0 );
//
// Commit change.
//
hr = NWApiWriteProperty( hConn, _Name, OT_USER, NW_PROP_IDENTIFICATION, (LPBYTE) szData ); BAIL_ON_FAILURE(hr);
FreeADsMem(lpszRightSize); }
error:
if (pszFullName) { FreeADsStr(pszFullName); }
RRETURN(S_OK); } //----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::SetAccountRestrictions
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::SetAccountRestrictions( NWCONN_HANDLE hConn ) { BOOL fModified = FALSE; DATE daDate = 0; DWORD dwNumSegment; HRESULT hr = S_OK; LC_STRUCTURE LoginCtrl; LONG lData = 0; LP_RPLY_SGMT_LST lpReplySegment = NULL; LP_RPLY_SGMT_LST lpTemp = NULL; SYSTEMTIME SysTime; USER_DEFAULT UserDefault; BOOL fBool; WORD wDay = 0; WORD wMonth = 0; WORD wYear = 0; WCHAR szTemp[MAX_PATH]; BYTE byDateTime[6]; BOOL fAccntLckModified;
hr = NWApiGetLOGIN_CONTROL( hConn, _Name, &LoginCtrl ); BAIL_ON_FAILURE(hr);
//
// SET AccountDisabled.
//
hr = GetBOOLPropertyFromCache( _pPropertyCache, TEXT("AccountDisabled"), &fBool );
if (SUCCEEDED(hr)) {
LoginCtrl.byAccountDisabled = (BYTE) fBool;
fModified = TRUE; }
//
// SET AccountExpirationDate.
//
memset(byDateTime, 0, 6); hr = GetNw312DATEPropertyFromCache( _pPropertyCache, TEXT("AccountExpirationDate"), byDateTime );
if (SUCCEEDED(hr)) {
LoginCtrl.byAccountExpires[0] = (BYTE) byDateTime[0]; LoginCtrl.byAccountExpires[1] = (BYTE) byDateTime[1]; LoginCtrl.byAccountExpires[2] = (BYTE) byDateTime[2];
fModified = TRUE; }
//
// SET AccountCanExpire.
//
hr = GetBOOLPropertyFromCache( _pPropertyCache, TEXT("AccountCanExpire"), &fBool );
if (SUCCEEDED(hr)) {
if (fBool == FALSE) {
LoginCtrl.byAccountExpires[0] = 0; LoginCtrl.byAccountExpires[1] = 0; LoginCtrl.byAccountExpires[2] = 0;
fModified = TRUE;
} }
//
// SET GraceLoginsAllowed.
//
hr = GetDWORDPropertyFromCache( _pPropertyCache, TEXT("GraceLoginsAllowed"), (PDWORD)&lData );
if (SUCCEEDED(hr)) {
LoginCtrl.byGraceLoginReset = (BYTE) lData;
fModified = TRUE; }
//
// SET GraceLoginsRemaining.
//
hr = GetDWORDPropertyFromCache( _pPropertyCache, TEXT("GraceLoginsRemaining"), (PDWORD)&lData );
if (SUCCEEDED(hr)) {
LoginCtrl.byGraceLogins = (BYTE) lData;
fModified = TRUE; }
//
// SET IsAccountLocked.
//
//
// if this property not modified in cache, no need to set on svr
//
hr = _pPropertyCache->propertyismodified( TEXT("IsAccountLocked"), &fAccntLckModified );
if ( SUCCEEDED(hr) && fAccntLckModified==TRUE ) {
hr = GetBOOLPropertyFromCache( _pPropertyCache, TEXT("IsAccountLocked"), &fBool );
if (SUCCEEDED(hr)) {
//
// If fBool is changed from TRUE to FALSE, set wBadLogins
// back to 0 -> this will unlock account on nw svr
//
if (fBool == FALSE) {
LoginCtrl.wBadLogins = 0; fModified = TRUE;
}else {
//
// Reset it to FALSE if it is changed to TRUE.
// -> cannot lock an account on nwsvr thru' adsi
//
fBool = FALSE;
hr = SetBOOLPropertyInCache( _pPropertyCache, TEXT("IsAccountLocked"), fBool, TRUE ); BAIL_ON_FAILURE(hr); } } }
//
// SET IsAdmin.
//
hr = GetBOOLPropertyFromCache( _pPropertyCache, TEXT("IsAdmin"), &fBool );
if (SUCCEEDED(hr)) {
hr = NWApiUserAsSupervisor( hConn, _Name, fBool );
//
// For beta, disabling the bail. It does not work in the user not
// supervisor mode.
//
// BAIL_ON_FAILURE(hr);
}
//
// SET MaxLogins.
//
hr = GetDWORDPropertyFromCache( _pPropertyCache, TEXT("MaxLogins"), (PDWORD)&lData );
if (SUCCEEDED(hr)) {
LoginCtrl.wMaxConnections = NWApiReverseWORD( (WORD) lData );
fModified = TRUE; }
//
// SET PasswordExpirationDate.
//
memset(byDateTime, 0, 6); hr = GetNw312DATEPropertyFromCache( _pPropertyCache, TEXT("PasswordExpirationDate"), byDateTime );
if (SUCCEEDED(hr)) {
LoginCtrl.byPasswordExpires[0] = (BYTE) byDateTime[0]; LoginCtrl.byPasswordExpires[1] = (BYTE) byDateTime[1]; LoginCtrl.byPasswordExpires[2] = (BYTE) byDateTime[2];
fModified = TRUE; }
//
// SET PasswordCanExpire.
//
hr = GetBOOLPropertyFromCache( _pPropertyCache, TEXT("PasswordCanExpire"), &fBool );
if (SUCCEEDED(hr)) {
if (fBool == FALSE) {
//
// If passowrd cannot expire, set password expiration date to zero.
// This is what SysCon does.
//
LoginCtrl.byPasswordExpires[0] = 0; LoginCtrl.byPasswordExpires[1] = 0; LoginCtrl.byPasswordExpires[2] = 0;
fModified = TRUE;
} }
//
// SET PasswordMinimumLength.
//
hr = GetDWORDPropertyFromCache( _pPropertyCache, TEXT("PasswordMinimumLength"), (PDWORD)&lData );
if (SUCCEEDED(hr)) {
LoginCtrl.byMinPasswordLength = (BYTE) lData;
fModified = TRUE; }
//
// SET PasswordRequired. The section below must goes before "Set
// PasswordMinimumLength" for it to make sense.
//
hr = GetBOOLPropertyFromCache( _pPropertyCache, TEXT("PasswordRequired"), &fBool );
if (SUCCEEDED(hr)) {
//
// If Password is required, set PasswordMinimumLength to default value.
//
//
// If Password is not required, set PasswordMinimumLength to 0. Again,
// this is what SysCon does.
//
if (fBool) { if (!LoginCtrl.byMinPasswordLength) { LoginCtrl.byMinPasswordLength = DEFAULT_MIN_PSWD_LEN; } }else{ LoginCtrl.byMinPasswordLength = 0; }
fModified = TRUE; }
//
// Set LoginHours
//
OctetString octString;
hr = GetOctetPropertyFromCache( _pPropertyCache, TEXT("LoginHours"), &octString );
if (SUCCEEDED(hr)) { memcpy(LoginCtrl.byLoginTimes, octString.pByte, octString.dwSize); FreeADsMem(octString.pByte); fModified = TRUE; }
//
// Set RequireUniquePassword.
//
hr = GetBOOLPropertyFromCache( _pPropertyCache, TEXT("RequireUniquePassword"), &fBool );
if (SUCCEEDED(hr)) {
LoginCtrl.byRestrictions = fBool ? REQUIRE_UNIQUE_PSWD : 0;
fModified = TRUE;
}
//
// Commit changes of the properties associated with LOGIN_CONTROL.
//
if (fModified == TRUE) {
hr = NWApiWriteProperty( hConn, _Name, OT_USER, NW_PROP_LOGIN_CONTROL, (LPBYTE) &LoginCtrl ); } else {
hr = S_OK; }
error:
if (lpReplySegment) { DELETE_LIST(lpReplySegment); }
RRETURN_EXP_IF_ERR(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetInfo
//
// Synopsis:
//
//----------------------------------------------------------------------------
STDMETHODIMP CNWCOMPATUser::GetInfo( BOOL fExplicit, DWORD dwPropertyID ) { HRESULT hr = S_OK; HRESULT hrTemp = S_OK; NWCONN_HANDLE hConn = NULL;
if (GetObjectState() == ADS_OBJECT_UNBOUND) { RRETURN_EXP_IF_ERR(E_ADS_OBJECT_UNBOUND); }
//
// Get a handle to the bindery this object resides on.
//
hr = NWApiGetBinderyHandle( &hConn, _ServerName ); BAIL_ON_FAILURE(hr);
//
// Fill in all property caches with values - explicit, or return the
// indicated property - implicit.
//
if (fExplicit) { hr = ExplicitGetInfo(hConn, fExplicit); BAIL_ON_FAILURE(hr); } else { hr = ImplicitGetInfo(hConn, dwPropertyID, fExplicit); BAIL_ON_FAILURE(hr); }
error: //
// Release handle.
//
if (hConn) { hrTemp = NWApiReleaseBinderyHandle(hConn); }
RRETURN_EXP_IF_ERR(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::ExplicitGetInfo
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::ExplicitGetInfo( NWCONN_HANDLE hConn, BOOL fExplicit ) { HRESULT hr = S_OK; LC_STRUCTURE LoginCtrlStruct;
//
// Get BusinessInfo functional set.
//
hr = GetProperty_FullName( hConn, fExplicit ); BAIL_ON_FAILURE(hr);
//
// Get LOGIN_CONTROL, which is used in AccountRestriction functional set &
// AccountStatistics functional set.
//
hr = NWApiGetLOGIN_CONTROL( hConn, _Name, &LoginCtrlStruct );
if (SUCCEEDED(hr)) { //
// Get AccountRestriction functional set.
//
hr = GetProperty_LoginHours( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_AccountDisabled(
hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_AccountExpirationDate( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_CanAccountExpire( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_GraceLoginsAllowed( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_GraceLoginsRemaining( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_IsAccountLocked( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_IsAdmin( hConn, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_MaxLogins( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_CanPasswordExpire( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_PasswordExpirationDate( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_PasswordMinimumLength( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_PasswordRequired( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_RequireUniquePassword( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
//
// Get AccountStatistics functional set.
//
hr = GetProperty_BadLoginAddress( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr);
hr = GetProperty_LastLogin( hConn, LoginCtrlStruct, fExplicit ); BAIL_ON_FAILURE(hr); }
//
// if NWApiGetLOGIN_CONTROL failed, it's okay, we just ignore
// it and don't load those properties into the cache
//
hr = S_OK;
error: RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::ImplicitGetInfo
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::ImplicitGetInfo( NWCONN_HANDLE hConn, DWORD dwPropertyID, BOOL fExplicit ) { HRESULT hr = S_OK;
if (dwPropertyID < 100) { hr = GetBusinessInfo( hConn, dwPropertyID, fExplicit ); } else if (dwPropertyID < 200) { hr = GetAccountRestrictions( hConn, dwPropertyID, fExplicit ); } else if (dwPropertyID < 300) { hr = GetAccountStatistics( hConn, dwPropertyID, fExplicit ); }
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetBusinessInfo
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetBusinessInfo( NWCONN_HANDLE hConn, DWORD dwPropertyID, BOOL fExplicit ) { HRESULT hr = S_OK;
switch (dwPropertyID) {
case USER_FULLNAME_ID: hr = GetProperty_FullName( hConn, fExplicit ); break; }
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetAccountRestrictions
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetAccountRestrictions( NWCONN_HANDLE hConn, DWORD dwPropertyID, BOOL fExplicit ) { HRESULT hr = S_OK; LC_STRUCTURE LoginCtrlStruct;
//
// Get LOGIN_CONTROL.
//
hr = NWApiGetLOGIN_CONTROL( hConn, _Name, &LoginCtrlStruct ); if (SUCCEEDED(hr)) {
//
// Get property.
//
switch (dwPropertyID) {
case USER_ACCOUNTDISABLED_ID: hr = GetProperty_AccountDisabled( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_ACCOUNTEXPIRATIONDATE_ID: hr = GetProperty_AccountExpirationDate( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_CANACCOUNTEXPIRE_ID: hr = GetProperty_CanAccountExpire( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_GRACELOGINSALLOWED_ID: hr = GetProperty_GraceLoginsAllowed( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_GRACELOGINSREMAINING_ID: hr = GetProperty_GraceLoginsRemaining( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_ISACCOUNTLOCKED_ID: hr = GetProperty_IsAccountLocked( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_ISADMIN_ID: hr = GetProperty_IsAdmin( hConn, fExplicit ); break;
case USER_MAXLOGINS_ID: hr = GetProperty_MaxLogins( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_CANPASSWORDEXPIRE_ID: hr = GetProperty_CanPasswordExpire( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_PASSWORDEXPIRATIONDATE_ID: hr = GetProperty_PasswordExpirationDate( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_PASSWORDMINIMUMLENGTH_ID: hr = GetProperty_PasswordMinimumLength( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_PASSWORDREQUIRED_ID: hr = GetProperty_PasswordRequired( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_REQUIREUNIQUEPASSWORD_ID: hr = GetProperty_RequireUniquePassword( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_LOGINHOURS_ID: hr = GetProperty_LoginHours( hConn, LoginCtrlStruct, fExplicit ); break;
}
BAIL_ON_FAILURE(hr); }
//
// if NWApiGetLOGIN_CONTROL failed, it's okay, we just ignore
// it and don't load those properties into the cache
//
hr = S_OK;
error:
RRETURN_EXP_IF_ERR(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetAccountStatistics
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetAccountStatistics( NWCONN_HANDLE hConn, DWORD dwPropertyID, BOOL fExplicit ) { HRESULT hr = S_OK; LC_STRUCTURE LoginCtrlStruct;
//
// Get LOGIN_CONTROL.
//
hr = NWApiGetLOGIN_CONTROL( hConn, _Name, &LoginCtrlStruct );
if (SUCCEEDED(hr)) {
//
// Get property.
//
switch (dwPropertyID) {
case USER_BADLOGINADDRESS_ID: hr = GetProperty_BadLoginAddress( hConn, LoginCtrlStruct, fExplicit ); break;
case USER_LASTLOGIN_ID: hr = GetProperty_LastLogin( hConn, LoginCtrlStruct, fExplicit ); break; }
BAIL_ON_FAILURE(hr); }
//
// if NWApiGetLOGIN_CONTROL failed, it's okay, we just ignore
// it and don't load those properties into the cache
//
hr = S_OK;
error:
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_FullName
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_FullName( NWCONN_HANDLE hConn, BOOL fExplicit ) { LPWSTR lpszFullName = NULL; CHAR szFullName[MAX_FULLNAME_LEN + 1]; DWORD dwNumSegment = 0; HRESULT hr = S_OK; LP_RPLY_SGMT_LST lpReplySegment = NULL; LP_RPLY_SGMT_LST lpTemp = NULL; // Used by DELETE_LIST macro below
//
// Get IDENTIFICATIOIN. This property contains the full name of an object.
//
hr = NWApiGetProperty( _Name, NW_PROP_IDENTIFICATION, OT_USER, hConn, &lpReplySegment, &dwNumSegment );
//
// This call will fail for those users who has never set
// their Fullname, ie. "IDENTIFICATION" is not created. Per Raid #34833
// (resolved By Design), there is no way to distinguish a failure for
// the property not existing from a general failure --- they both return the
// same error code. In general, it is expected that a Bindery user will have
// the IDENTIFICATION property, so if this call fails we assume it was because
// the property didn't exist. In this case, we return success, since it was
// successful, there just didn't happen to be an IDENTIFICATION.
//
if (FAILED(hr)) { hr = S_OK; goto error; }
//
// Convert result into a UNICODE string.
//
strcpy(szFullName, lpReplySegment->Segment);
lpszFullName = (LPWSTR) AllocADsMem( (strlen(szFullName)+1) * sizeof(WCHAR) ); if (!lpszFullName) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY);
AnsiToUnicodeString( szFullName, lpszFullName, 0 );
//
// Unmarshall.
//
hr = SetLPTSTRPropertyInCache( _pPropertyCache, TEXT("FullName"), (LPWSTR)lpszFullName, fExplicit ); BAIL_ON_FAILURE(hr);
error:
if (lpszFullName) {
FreeADsMem(lpszFullName); } if (lpReplySegment) { DELETE_LIST(lpReplySegment); }
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_AccountDisabled
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_AccountDisabled( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { BOOL dwBool = TRUE; HRESULT hr = S_OK;
//
// Put value into a variant.
//
dwBool = (BOOL) LoginCtrlStruct.byAccountDisabled;
//
// Unmarshall.
//
hr = SetBOOLPropertyInCache( _pPropertyCache, TEXT("AccountDisabled"), dwBool, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_AccountExpirationDate
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_AccountExpirationDate( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { HRESULT hr = S_OK; BYTE byDateTime[6]; BYTE byNoDateTime[6];
memset(byNoDateTime, 0, 6); memset(byDateTime, 0, 6); memcpy(byDateTime, LoginCtrlStruct.byAccountExpires, 3);
//
// LoginCtrlSturct.byAccountExpires == 000 indicates no expired date
//
if (memcmp(byDateTime, byNoDateTime, 3)!=0) {
hr = SetNw312DATEPropertyInCache( _pPropertyCache, TEXT("AccountExpirationDate"), byDateTime, fExplicit );
BAIL_ON_FAILURE(hr); }
error:
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_CanAccountExpire
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_CanAccountExpire( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { BOOL dwBool = TRUE; HRESULT hr = S_OK;
//
// Account cannot expire if there is no expiration date.
//
if ((LoginCtrlStruct.byAccountExpires[0] == 0) && (LoginCtrlStruct.byAccountExpires[1] == 0) && (LoginCtrlStruct.byAccountExpires[2] == 0)) {
dwBool = FALSE; }
//
// Unmarshall.
//
hr = SetBOOLPropertyInCache( _pPropertyCache, TEXT("AccountCanExpire"), dwBool, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_GraceLoginsAllowed
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_GraceLoginsAllowed( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { HRESULT hr = S_OK; LONG lGraceLoginsAllowed = 0;
//
// Get "byGraceLoginReset". The property is not meaningful when it equals
// to 0xff.
//
if (LoginCtrlStruct.byGraceLoginReset != 0xff) {
lGraceLoginsAllowed = (LONG) LoginCtrlStruct.byGraceLoginReset; }
//
// Unmarshall.
//
hr = SetDWORDPropertyInCache( _pPropertyCache, TEXT("GraceLoginsAllowed"), (DWORD)lGraceLoginsAllowed, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_GraceLoginsRemaining
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_GraceLoginsRemaining( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { HRESULT hr = S_OK; LONG lGraceLoginsRemaining = 0;
//
// Get "byGraceLogins". The property is not meaningful when it equals to
// 0xff.
//
if (LoginCtrlStruct.byGraceLogins != 0xff) {
lGraceLoginsRemaining = (LONG) LoginCtrlStruct.byGraceLogins; }
//
// Unmarshall.
//
hr = SetDWORDPropertyInCache( _pPropertyCache, TEXT("GraceLoginsRemaining"), (DWORD)lGraceLoginsRemaining, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_IsAccountLocked
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_IsAccountLocked( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { BOOL dwBool = FALSE; HRESULT hr = S_OK;
//
// Account is locked when wBadLogins = 0xffff.
//
if (LoginCtrlStruct.wBadLogins == 0xffff) {
dwBool = TRUE; }
//
// Unmarshall.
//
hr = SetBOOLPropertyInCache( _pPropertyCache, TEXT("IsAccountLocked"), dwBool, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_IsAdmin
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_IsAdmin( NWCONN_HANDLE hConn, BOOL fExplicit ) { BOOL dwBool = TRUE; HRESULT hr = S_OK;
//
// Check if this user has the same security as the supervisor. If it does,
// then it is an admin.
//
hr = NWApiIsObjectInSet( hConn, _Name, OT_USER, NW_PROP_SECURITY_EQUALS, NW_PROP_SUPERVISOR, OT_USER );
// Per bug #33322 (resolved By Design), there is no way to distinguish
// "no such object" from a general failure. So we assume that any failure
// is "no such object".
if (FAILED(hr)) { dwBool = FALSE; hr = S_OK; }
//
// Unmarshall.
//
hr = SetBOOLPropertyInCache( _pPropertyCache, TEXT("IsAdmin"), dwBool, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_MaxLogins
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_MaxLogins( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { HRESULT hr = S_OK; LONG lMaxLogins = 0;
//
// Get "wMaxConnections".
//
lMaxLogins = (LONG) NWApiReverseWORD( LoginCtrlStruct.wMaxConnections );
//
// Unmarshall.
//
hr = SetDWORDPropertyInCache( _pPropertyCache, TEXT("MaxLogins"), (DWORD)lMaxLogins, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_CanPasswordExpire
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_CanPasswordExpire( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { BOOL dwBool = TRUE; HRESULT hr = S_OK;
//
// Password cannot expire if there is no expiration date.
//
if ((LoginCtrlStruct.byPasswordExpires[0] == 0) && (LoginCtrlStruct.byPasswordExpires[1] == 0) && (LoginCtrlStruct.byPasswordExpires[2] == 0)) {
dwBool = FALSE; }
//
// Unmarshall.
//
hr = SetBOOLPropertyInCache( _pPropertyCache, TEXT("PasswordCanExpire"), dwBool, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_PasswordExpirationDate
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_PasswordExpirationDate( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { HRESULT hr = S_OK; BYTE byDateTime[6];
memset(byDateTime, 0, 6); memcpy(byDateTime, LoginCtrlStruct.byPasswordExpires, 3);
hr = SetNw312DATEPropertyInCache( _pPropertyCache, TEXT("PasswordExpirationDate"), byDateTime, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_PasswordMinimumLength
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_PasswordMinimumLength( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { HRESULT hr = S_OK; LONG lMinimumLength = 0;
//
// Get "byMinPasswordLength".
//
lMinimumLength = (LONG) LoginCtrlStruct.byMinPasswordLength;
//
// Unmarshall.
//
hr = SetDWORDPropertyInCache( _pPropertyCache, TEXT("PasswordMinimumLength"), (DWORD)lMinimumLength, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_PasswordRequired
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_PasswordRequired( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { BOOL dwBool = TRUE; HRESULT hr = S_OK;
//
// Password is not required if "byMinPasswordLength" is 0.
//
if (LoginCtrlStruct.byMinPasswordLength == 0) {
dwBool = FALSE; }
//
// Unmarshall.
//
hr = SetBOOLPropertyInCache( _pPropertyCache, TEXT("PasswordRequired"), dwBool, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_RequireUniquePassword
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_RequireUniquePassword( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { BOOL dwBool = TRUE; HRESULT hr = S_OK;
//
// If byRestrictions = 0, "RequireUniquePassword" = FALSE.
//
if (LoginCtrlStruct.byRestrictions == 0) {
dwBool = FALSE; }
//
// Unmarshall.
//
hr = SetBOOLPropertyInCache( _pPropertyCache, TEXT("RequireUniquePassword"), dwBool, fExplicit );
RRETURN(hr); }
HRESULT CNWCOMPATUser::GetProperty_LoginHours( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { BOOL dwBool = TRUE; HRESULT hr = S_OK;
//
// Unmarshall.
//
hr = SetOctetPropertyInCache( _pPropertyCache, TEXT("LoginHours"), (BYTE*)LoginCtrlStruct.byLoginTimes, 24, fExplicit );
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_BadLoginAddress
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_BadLoginAddress( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) { HRESULT hr = S_OK; LPWSTR lpszTemp = NULL;
//
// Put address together in the format described in spec.
//
lpszTemp = (LPWSTR) AllocADsMem((NET_ADDRESS_NUM_CHAR+1)*sizeof(WCHAR)); if (!lpszTemp) { RRETURN(E_OUTOFMEMORY); }
wsprintf( lpszTemp, L"%s:%02X%02X%02X%02X.%02X%02X%02X%02X%02X%02X.%02X%02X", bstrAddressTypeString, LoginCtrlStruct.byBadLoginAddr[10], LoginCtrlStruct.byBadLoginAddr[11], LoginCtrlStruct.byBadLoginAddr[0], LoginCtrlStruct.byBadLoginAddr[1], LoginCtrlStruct.byBadLoginAddr[2], LoginCtrlStruct.byBadLoginAddr[3], LoginCtrlStruct.byBadLoginAddr[4], LoginCtrlStruct.byBadLoginAddr[5], LoginCtrlStruct.byBadLoginAddr[6], LoginCtrlStruct.byBadLoginAddr[7], LoginCtrlStruct.byBadLoginAddr[8], LoginCtrlStruct.byBadLoginAddr[9] );
//
// Unmarshall.
//
hr = SetLPTSTRPropertyInCache( _pPropertyCache, TEXT("BadLoginAddress"), (LPWSTR)lpszTemp, fExplicit ); BAIL_ON_FAILURE(hr);
error:
if (lpszTemp) {
FreeADsMem(lpszTemp); }
RRETURN(hr); }
//----------------------------------------------------------------------------
//
// Function: CNWCOMPATUser::GetProperty_LastLogin
//
// Synopsis:
//
//----------------------------------------------------------------------------
HRESULT CNWCOMPATUser::GetProperty_LastLogin( NWCONN_HANDLE hConn, LC_STRUCTURE LoginCtrlStruct, BOOL fExplicit ) {
HRESULT hr = S_OK; BYTE byNoDateTime[6];
memset(byNoDateTime, 0, 6);
//
// LastLogin==000000 indicates no or unknown LastLogin
//
if (memcmp(LoginCtrlStruct.byLastLogin, byNoDateTime, 6) != 0) {
hr = SetNw312DATEPropertyInCache( _pPropertyCache, TEXT("LastLogin"), LoginCtrlStruct.byLastLogin, fExplicit ); }
RRETURN(hr); }
HRESULT ConvertNW312DateToVariant( BYTE byDateTime[], PDATE pDate ) { HRESULT hr = S_OK; WORD wYear;
//
// Subtract 80 from wYear for NWApiMakeVariantTime.
//
wYear = (WORD)byDateTime[0];
if (wYear != 0) { wYear -= 80; }
//
// Convert into Variant Time.
//
hr = NWApiMakeVariantTime( pDate, (WORD)byDateTime[2], (WORD)byDateTime[1], wYear, 0,0,0 ); RRETURN(hr); }
HRESULT ConvertVariantToNW312Date( DATE daDate, BYTE byDateTime[] ) { WORD wDay; WORD wYear; WORD wMonth; HRESULT hr = S_OK;
hr = NWApiBreakVariantTime( daDate, &wDay, &wMonth, &wYear ); BAIL_ON_FAILURE(hr);
byDateTime[0] = (BYTE)wYear; byDateTime[1] = (BYTE)wMonth; byDateTime[2] = (BYTE)wDay;
byDateTime[3] = 0; byDateTime[4] = 0; byDateTime[5] = 0;
error:
RRETURN(hr); }
|