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.
 
 
 
 
 
 

332 lines
11 KiB

// P3Users.cpp : Implementation of CP3Users
#include "stdafx.h"
#include "P3Admin.h"
#include "P3Users.h"
#include "P3UserEnum.h"
#include "P3User.h"
#include <mailbox.h>
#include <AuthID.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CP3Users::CP3Users() :
m_pIUnk(NULL), m_pAdminX(NULL), m_hfSearch(INVALID_HANDLE_VALUE)
{
ZeroMemory( m_sDomainName, sizeof(m_sDomainName));
}
CP3Users::~CP3Users()
{
if(INVALID_HANDLE_VALUE!=m_hfSearch)
{
FindClose(m_hfSearch);
}
if ( NULL != m_pIUnk )
m_pIUnk->Release();
}
//////////////////////////////////////////////////////////////////////
// IP3Users
//////////////////////////////////////////////////////////////////////
STDMETHODIMP CP3Users::get__NewEnum(IEnumVARIANT* *ppIEnumVARIANT)
{
if ( NULL == ppIEnumVARIANT ) return E_INVALIDARG;
if ( NULL == m_pAdminX ) return E_POINTER;
HRESULT hr = S_OK;
LPUNKNOWN pIUnk;
CComObject<CP3UserEnum>* p;
*ppIEnumVARIANT = NULL;
if SUCCEEDED( hr )
{
hr = CComObject<CP3UserEnum>::CreateInstance(&p); // Reference count still 0
if SUCCEEDED( hr )
{
// Increment the reference count on the source object and pass it to the new enumerator
hr = m_pIUnk->QueryInterface(IID_IUnknown, reinterpret_cast<LPVOID*>( &pIUnk ));
if SUCCEEDED( hr )
{
hr = p->Init( pIUnk, m_pAdminX, m_sDomainName );
if SUCCEEDED( hr )
hr = p->QueryInterface( IID_IEnumVARIANT, reinterpret_cast<LPVOID*>( ppIEnumVARIANT ));
}
if FAILED( hr )
delete p;
}
}
return hr;
}
STDMETHODIMP CP3Users::get_Count(long *pVal)
{
if ( NULL == m_pAdminX ) return E_POINTER;
return m_pAdminX->GetUserCount( m_sDomainName, pVal );
}
#define E_USERNOTFOUND 0x800708ad
STDMETHODIMP CP3Users::get_Item(VARIANT vIndex, IP3User **ppIUser)
{
VARIANT *pv = &vIndex;
if ( NULL == ppIUser ) return E_INVALIDARG;
if ( (VT_VARIANT|VT_BYREF) == V_VT( pv ))
pv = V_VARIANTREF( pv );
if ( VT_BSTR != V_VT( pv ) && VT_I4 != V_VT( pv ))
return E_INVALIDARG;
if ( VT_BSTR == V_VT( pv ) && NULL == V_BSTR( pv ))
return E_INVALIDARG;
if ( NULL == m_pAdminX ) return E_POINTER;
HRESULT hr;
WCHAR sMailbox[POP3_MAX_ADDRESS_LENGTH];
WCHAR sBuffer[POP3_MAX_PATH];
CMailBox mailboxX;
hr = m_pAdminX->MailboxSetRemote();
// Find the requested item
if ( VT_BSTR == V_VT( pv ))
{ // Find by Name
if ( sizeof( sMailbox )/sizeof(WCHAR) > wcslen( V_BSTR( pv )) + wcslen( m_sDomainName ) + 1 )
{
wcscpy( sMailbox, V_BSTR( pv ));
wcscat( sMailbox, L"@" );
wcscat( sMailbox, m_sDomainName );
if ( mailboxX.OpenMailBox( sMailbox ))
mailboxX.CloseMailBox();
else
hr = E_USERNOTFOUND;
if ( sizeof( sBuffer )/sizeof(WCHAR) > wcslen( V_BSTR( pv ) ))
wcscpy( sBuffer, V_BSTR( pv ));
else
hr = E_UNEXPECTED;
}
}
if ( VT_I4 == V_VT( pv ))
{ // Find by Index
int iIndex = V_I4( pv );
if ( iIndex < m_iCur )
{
hr = m_pAdminX->InitFindFirstUser( m_hfSearch, m_sDomainName, sBuffer, sizeof( sBuffer )/sizeof(WCHAR) );
m_iCur = 1;
}
while ( (S_OK == hr) && (iIndex > m_iCur) )
{
hr = m_pAdminX->GetNextUser( m_hfSearch, m_sDomainName, sBuffer, sizeof( sBuffer )/sizeof(WCHAR) );
m_iCur++;
}
if ( S_OK == hr )
{
if ( sizeof( sMailbox )/sizeof(WCHAR) > wcslen( sBuffer ) + wcslen( m_sDomainName ) + 1 )
{
wcscpy( sMailbox, sBuffer );
wcscat( sMailbox, L"@" );
wcscat( sMailbox, m_sDomainName );
if ( mailboxX.OpenMailBox( sMailbox ))
mailboxX.CloseMailBox();
else
hr = E_USERNOTFOUND;
}
}
}
m_pAdminX->MailboxResetRemote();
// Wrap it with COM
if SUCCEEDED( hr )
{
LPUNKNOWN pIUnk;
CComObject<CP3User> *p;
hr = CComObject<CP3User>::CreateInstance( &p ); // Reference count still 0
if SUCCEEDED( hr )
{
hr = m_pIUnk->QueryInterface(IID_IUnknown, reinterpret_cast<LPVOID*>( &pIUnk ));
if SUCCEEDED( hr )
{
hr = p->Init( pIUnk, m_pAdminX, m_sDomainName, sBuffer );
if SUCCEEDED( hr )
hr = p->QueryInterface(IID_IP3User, reinterpret_cast<void**>( ppIUser ));
}
if FAILED( hr )
delete p; // Release
}
}
return hr;
}
STDMETHODIMP CP3Users::Add(BSTR bstrUserName)
{
if ( NULL == m_pAdminX ) return E_POINTER;
// Associate email address with user, if this fails the user does not exist
// This will always fail in the MD5 case because we need a password! Thus the user must use the /createuser flag
HRESULT hr;
CComPtr<IAuthMethod> spIAuthMethod;
WCHAR sEmailAddr[POP3_MAX_ADDRESS_LENGTH];
_bstr_t _bstrEmailAddr;
hr = m_pAdminX->GetCurrentAuthentication( &spIAuthMethod );
if ( S_OK == hr )
hr = m_pAdminX->BuildEmailAddr( m_sDomainName, bstrUserName, sEmailAddr, sizeof( sEmailAddr )/sizeof(WCHAR) );
if ( S_OK == hr )
{
_bstrEmailAddr = sEmailAddr;
hr = spIAuthMethod->AssociateEmailWithUser( _bstrEmailAddr );
}
if ( S_OK == hr )
{
hr = m_pAdminX->AddUser( m_sDomainName, bstrUserName );
if ( S_OK != hr )
{ // Unassociate the user with the mailbox
spIAuthMethod->UnassociateEmailWithUser( _bstrEmailAddr ); // Don't want to overwrite the error code
}
}
if ( S_OK == hr ) // Create Quota SID File - won't revert from this operation
{
BSTR bstrAuthType = NULL;
hr = spIAuthMethod->get_ID( &bstrAuthType );
if ( S_OK == hr )
{
if ( 0 == _wcsicmp( bstrAuthType, SZ_AUTH_ID_DOMAIN_AD )) // In AD case use the UPN name instead of the SAM name
hr = m_pAdminX->CreateQuotaSIDFile( m_sDomainName, bstrUserName, bstrAuthType, NULL, sEmailAddr );
else if ( 0 == _wcsicmp( bstrAuthType, SZ_AUTH_ID_LOCAL_SAM ))
hr = m_pAdminX->CreateQuotaSIDFile( m_sDomainName, bstrUserName, bstrAuthType, NULL, bstrUserName );
SysFreeString( bstrAuthType );
}
}
return hr;
}
STDMETHODIMP CP3Users::AddEx(BSTR bstrUserName, BSTR bstrPassword)
{
if ( NULL == bstrUserName ) return E_INVALIDARG;
if ( NULL == bstrPassword ) return E_INVALIDARG;
if ( NULL == m_pAdminX ) return E_POINTER;
HRESULT hr;
CComPtr<IAuthMethod> spIAuthMethod;
WCHAR sEmailAddr[POP3_MAX_ADDRESS_LENGTH];
_bstr_t _bstrAccount;
_variant_t _vPassword;
BSTR bstrAuthType = NULL;
// Add to our store
hr = m_pAdminX->AddUser( m_sDomainName, bstrUserName );
if ( S_OK == hr ) // Add to the Authentication source
{
hr = m_pAdminX->GetCurrentAuthentication( &spIAuthMethod );
if ( S_OK == hr )
hr = spIAuthMethod->get_ID( &bstrAuthType );
if ( S_OK == hr )
hr = m_pAdminX->BuildEmailAddr( m_sDomainName, bstrUserName, sEmailAddr, sizeof( sEmailAddr )/sizeof(WCHAR) );
if ( S_OK == hr )
{
_bstrAccount = sEmailAddr;
_vPassword = bstrPassword;
hr = spIAuthMethod->CreateUser( _bstrAccount, _vPassword );
}
if ( S_OK != hr ) // Failed let's revert the Add to our store
m_pAdminX->RemoveUser( m_sDomainName, bstrUserName );
}
if ( S_OK == hr ) // Create Quota SID File
{
if ( 0 == _wcsicmp( bstrAuthType, SZ_AUTH_ID_DOMAIN_AD )) // In AD case use the UPN name instead of the SAM name
hr = m_pAdminX->CreateQuotaSIDFile( m_sDomainName, bstrUserName, bstrAuthType, NULL, sEmailAddr );
else if ( 0 == _wcsicmp( bstrAuthType, SZ_AUTH_ID_LOCAL_SAM ))
hr = m_pAdminX->CreateQuotaSIDFile( m_sDomainName, bstrUserName, bstrAuthType, NULL, bstrUserName );
}
if ( NULL != bstrAuthType )
SysFreeString( bstrAuthType );
return hr;
}
STDMETHODIMP CP3Users::Remove(BSTR bstrUserName)
{
if ( NULL == m_pAdminX ) return E_POINTER;
// Associate email address with user, if this fails the user does not exist
// This will always fail in the MD5 case because we need a password! Thus the user must use the /createuser flag
CComPtr<IAuthMethod> spIAuthMethod;
WCHAR sEmailAddr[POP3_MAX_ADDRESS_LENGTH];
_bstr_t _bstrEmailAddr;
HRESULT hr = m_pAdminX->GetCurrentAuthentication( &spIAuthMethod );
if ( S_OK == hr )
hr = m_pAdminX->BuildEmailAddr( m_sDomainName, bstrUserName, sEmailAddr, sizeof( sEmailAddr )/sizeof(WCHAR) );
if ( S_OK == hr )
{
_bstrEmailAddr = sEmailAddr;
hr = spIAuthMethod->UnassociateEmailWithUser( _bstrEmailAddr );
}
if ( S_OK == hr )
{
hr = m_pAdminX->RemoveUser( m_sDomainName, bstrUserName );
if ( S_OK != hr )
{ // Unassociate the user with the mailbox
spIAuthMethod->AssociateEmailWithUser( _bstrEmailAddr ); // Don't want to overwrite the error code
}
}
return hr;
}
STDMETHODIMP CP3Users::RemoveEx(BSTR bstrUserName)
{
if ( NULL == bstrUserName ) return E_INVALIDARG;
if ( NULL == m_pAdminX ) return E_POINTER;
HRESULT hr = m_pAdminX->RemoveUser( m_sDomainName, bstrUserName );
if ( S_OK == hr )
{
CComPtr<IAuthMethod> spIAuthMethod;
WCHAR sEmailAddr[POP3_MAX_ADDRESS_LENGTH];
_bstr_t _bstrAccount;
hr = m_pAdminX->GetCurrentAuthentication( &spIAuthMethod );
if ( S_OK == hr )
hr = m_pAdminX->BuildEmailAddr( m_sDomainName, bstrUserName, sEmailAddr, sizeof( sEmailAddr )/sizeof(WCHAR) );
if ( S_OK == hr )
{
_bstrAccount = sEmailAddr;
hr = spIAuthMethod->DeleteUser( _bstrAccount );
if ( S_FALSE == hr )
hr = S_OK;
}
}
return hr;
}
//////////////////////////////////////////////////////////////////////
// Implementation: public
//////////////////////////////////////////////////////////////////////
HRESULT CP3Users::Init(IUnknown *pIUnk, CP3AdminWorker *p, LPWSTR psDomainName )
{
if ( NULL == pIUnk ) return E_INVALIDARG;
if ( NULL == p ) return E_INVALIDARG;
if ( NULL == psDomainName ) return E_INVALIDARG;
m_pIUnk = pIUnk;
m_pAdminX = p;
wcsncpy( m_sDomainName, psDomainName, sizeof(m_sDomainName)/sizeof(WCHAR)-1);
return S_OK;
}
//////////////////////////////////////////////////////////////////////
// Implementation: protected
//////////////////////////////////////////////////////////////////////