Windows2003-3790/inetsrv/pop3/shared/pop3auth/authlocalaccount.cpp
2020-09-30 16:53:55 +02:00

422 lines
10 KiB
C++

#include "stdafx.h"
#include "Pop3Auth.h"
#include "AuthLocalAccount.h"
CAuthLocalAccount::CAuthLocalAccount()
{
m_bstrServerName=NULL;
}
CAuthLocalAccount::~CAuthLocalAccount()
{
if(m_bstrServerName!=NULL)
{
SysFreeString(m_bstrServerName);
m_bstrServerName=NULL;
}
}
STDMETHODIMP CAuthLocalAccount::Authenticate(/*[in]*/BSTR bstrUserName,/*[in]*/VARIANT vPassword)
{
WCHAR *pAt=NULL;
if(vPassword.vt != VT_BSTR)
{
return E_INVALIDARG;
}
if(NULL==bstrUserName)
{
return E_POINTER;
}
HANDLE hToken;
pAt=wcschr(bstrUserName, L'@');
if(NULL!=pAt)
{
*pAt=0;
}
if( LogonUser(bstrUserName,
LOCAL_DOMAIN,
vPassword.bstrVal,
LOGON32_LOGON_NETWORK,
LOGON32_PROVIDER_DEFAULT,
&hToken))
{
CloseHandle(hToken);
return S_OK;
}
return E_FAIL;
}
STDMETHODIMP CAuthLocalAccount::get_Name(/*[out]*/BSTR *pVal)
{
WCHAR wszBuffer[MAX_PATH+1];
if(NULL==pVal)
{
return E_POINTER;
}
if(LoadString(_Module.GetResourceInstance(), IDS_AUTH_LOCAL_ACCOUNT, wszBuffer, MAX_PATH))
{
*pVal=SysAllocString(wszBuffer);
if(NULL==*pVal)
{
return E_OUTOFMEMORY;
}
else
{
return S_OK;
}
}
else
{
return E_FAIL;
}
}
STDMETHODIMP CAuthLocalAccount::get_ID(/*[out]*/BSTR *pVal)
{
if(NULL==pVal)
{
return E_POINTER;
}
*pVal=SysAllocString(SZ_AUTH_ID_LOCAL_SAM);
if(NULL==*pVal)
{
return E_OUTOFMEMORY;
}
else
{
return S_OK;
}
}
STDMETHODIMP CAuthLocalAccount::Get(/*[in]*/BSTR bstrName, /*[out]*/VARIANT *pVal)
{
return E_NOTIMPL;
}
STDMETHODIMP CAuthLocalAccount::Put(/*[in]*/BSTR bstrName, /*[in]*/VARIANT vVal)
{
if(NULL == bstrName)
{
return E_INVALIDARG;
}
if(0==wcscmp(bstrName,SZ_SERVER_NAME ))
{
if( (vVal.vt!=VT_BSTR) ||
(vVal.bstrVal==NULL ) )
{
return E_INVALIDARG;
}
else
{
if(m_bstrServerName!=NULL)
{
SysFreeString(m_bstrServerName);
m_bstrServerName=NULL;
}
m_bstrServerName = SysAllocString(vVal.bstrVal);
if(NULL == m_bstrServerName)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
}
return S_FALSE;
}
STDMETHODIMP CAuthLocalAccount::CreateUser(/*[in]*/BSTR bstrUserName,/*[in]*/VARIANT vPassword)
{
DWORD dwRt;
WCHAR *pAt=NULL;
HRESULT hr=S_OK;
if( NULL == bstrUserName )
{
return E_POINTER;
}
if( vPassword.vt!= VT_BSTR )
{
return E_INVALIDARG;
}
dwRt=CheckPop3UserGroup();
if( NERR_Success != dwRt )
{
return HRESULT_FROM_WIN32(dwRt);
}
pAt=wcschr(bstrUserName, L'@');
if(pAt)
{
*pAt=NULL;
}
if(wcslen(bstrUserName) > MAX_USER_NAME_LENGTH)
{
hr=HRESULT_FROM_WIN32(WSAENAMETOOLONG);
}
else
{
USER_INFO_1 UserInfoBuf;
UserInfoBuf.usri1_name=bstrUserName;
UserInfoBuf.usri1_password=vPassword.bstrVal;
UserInfoBuf.usri1_priv=USER_PRIV_USER;
UserInfoBuf.usri1_home_dir=NULL;
UserInfoBuf.usri1_comment=NULL;
UserInfoBuf.usri1_flags=UF_NORMAL_ACCOUNT;
UserInfoBuf.usri1_script_path=NULL;
dwRt=NetUserAdd(m_bstrServerName,
1,
(LPBYTE)(&UserInfoBuf),
NULL);
if(NERR_Success==dwRt)
{
LOCALGROUP_MEMBERS_INFO_3 lgmInfo;
lgmInfo.lgrmi3_domainandname=bstrUserName;
dwRt=NetLocalGroupAddMembers(m_bstrServerName, WSZ_POP3_USERS_GROUP, 3, (LPBYTE)(&lgmInfo), 1);
if(NERR_Success!=dwRt)
{ //Delete the account just created if can not add to the group
NetUserDel(m_bstrServerName, bstrUserName);
}
}
else
{
hr=HRESULT_FROM_WIN32(dwRt);
}
}
if(pAt)
{
*pAt=L'@';
}
return hr;
}
STDMETHODIMP CAuthLocalAccount::DeleteUser(/*[in]*/BSTR bstrUserName)
{
DWORD dwRt;
WCHAR *pAt=NULL;
if( NULL == bstrUserName)
{
return E_POINTER;
}
pAt=wcschr(bstrUserName, L'@');
if(pAt)
{
*pAt=NULL;
}
dwRt=NetUserDel(m_bstrServerName, bstrUserName);
if(NERR_Success==dwRt)
{
return S_OK;
}
if(pAt)
{
*pAt=L'@';
}
return HRESULT_FROM_WIN32(dwRt);
}
STDMETHODIMP CAuthLocalAccount::ChangePassword(/*[in]*/BSTR bstrUserName,/*[in]*/VARIANT vNewPassword,/*[in]*/VARIANT vOldPassword)
{
DWORD dwRt;
WCHAR *pAt=NULL;
BOOL bServerName=FALSE;
if( NULL == bstrUserName)
{
return E_POINTER;
}
if( vNewPassword.vt!= VT_BSTR )
{
return E_INVALIDARG;
}
USER_INFO_1 * pUserInfo=NULL;
pAt=wcschr(bstrUserName, L'@');
if(pAt)
{
*pAt=0;
}
dwRt=NetUserGetInfo(m_bstrServerName,
bstrUserName,
1,
( LPBYTE *)&pUserInfo);
if(NERR_Success==dwRt)
{
pUserInfo->usri1_password=vNewPassword.bstrVal;
dwRt=NetUserSetInfo(m_bstrServerName,
bstrUserName,
1,
(LPBYTE)pUserInfo,
NULL);
pUserInfo->usri1_password=NULL;
NetApiBufferFree(pUserInfo);
}
if(pAt)
{
*pAt=L'@';
}
if(NERR_Success==dwRt)
{
return S_OK;
}
return HRESULT_FROM_WIN32(dwRt);
}
//To check if the POP3 Users group exists
//if not, create the group.
//Return 0 if the group exists or is created
//Return error code if failed to create the group
DWORD CAuthLocalAccount::CheckPop3UserGroup()
{
LPBYTE pBuffer=NULL;
DWORD dwRt;
WCHAR wszBuffer[MAXCOMMENTSZ];
dwRt=NetLocalGroupGetInfo(m_bstrServerName,
WSZ_POP3_USERS_GROUP,
1,
&pBuffer);
if(NERR_Success == dwRt )
{
NetApiBufferFree(pBuffer);
return NO_ERROR;
}
if(NERR_GroupNotFound == dwRt)
{
//Create the group
//Load the comments to the group
if(LoadString(_Module.GetResourceInstance(), IDS_AUTH_POP3_GROUP, wszBuffer, MAXCOMMENTSZ))
{
GROUP_INFO_1 GroupInfo={WSZ_POP3_USERS_GROUP, wszBuffer};
dwRt=NetLocalGroupAdd(m_bstrServerName,
1,
(LPBYTE)(&GroupInfo),
NULL);
if(NERR_Success != dwRt )
{
return dwRt;
}
//Now the group is created, set the local logon policy
//So that members of the group can not log on interactively
dwRt=SetLogonPolicy();
if(0!=dwRt)
{
NetLocalGroupDel(m_bstrServerName, WSZ_POP3_USERS_GROUP );
return dwRt;
}
}
else
{
dwRt=GetLastError();
}
}
return dwRt;
}
DWORD CAuthLocalAccount::SetLogonPolicy()
{
//First get the sid of the POP3 Users group
char pSid[LSA_WIN_STANDARD_BUFFER_SIZE];
DWORD dwSizeSid=LSA_WIN_STANDARD_BUFFER_SIZE;
WCHAR wszDomainName[MAX_PATH];
DWORD cbDomainName=sizeof(wszDomainName);
SID_NAME_USE sidType=SidTypeGroup;
if(!LookupAccountName(NULL,
WSZ_POP3_USERS_GROUP,
(PSID)pSid,
&dwSizeSid,
wszDomainName,
&cbDomainName,
&sidType))
{
return GetLastError();
}
//Then set the logon policy
NTSTATUS Status;
LSA_HANDLE PolicyHandle = NULL;
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
ZeroMemory( &ObjectAttributes, sizeof( ObjectAttributes ) );
Status = LsaOpenPolicy(NULL, &ObjectAttributes ,POLICY_WRITE|POLICY_LOOKUP_NAMES,&PolicyHandle);
if ( ERROR_SUCCESS !=Status )
{
return Status;
}
LSA_UNICODE_STRING PrivilegeString;
PrivilegeString.Length=wcslen(SE_DENY_INTERACTIVE_LOGON_NAME)*sizeof(WCHAR);//Count in bytes
PrivilegeString.MaximumLength=PrivilegeString.Length+sizeof(WCHAR);//Plus the last \0
PrivilegeString.Buffer=SE_DENY_INTERACTIVE_LOGON_NAME;
Status=LsaAddAccountRights( PolicyHandle, // open policy handle
(PSID)pSid, // target SID
&PrivilegeString, // privileges
1); // privilege count
LsaClose(PolicyHandle);
return Status;
}
STDMETHODIMP CAuthLocalAccount::AssociateEmailWithUser(/*[in]*/BSTR bstrEmailAddr)
{
//Make sure the user account exist
DWORD dwRt;
WCHAR *pAt=NULL;
if( NULL == bstrEmailAddr)
{
return E_POINTER;
}
USER_INFO_1 * pUserInfo=NULL;
pAt=wcschr(bstrEmailAddr, L'@');
if(pAt)
{
*pAt=0;
}
dwRt=NetUserGetInfo(m_bstrServerName,
bstrEmailAddr,
1,
( LPBYTE *)&pUserInfo);
if(pAt)
{
*pAt=L'@';
}
if(NERR_Success==dwRt)
{
NetApiBufferFree(pUserInfo);
return S_OK;
}
return HRESULT_FROM_WIN32(dwRt);
}
STDMETHODIMP CAuthLocalAccount::UnassociateEmailWithUser(/*[in]*/BSTR bstrEmailAddr)
{
// Do the same as Associate: Make sure the account exists
return AssociateEmailWithUser( bstrEmailAddr );
}