|
|
#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 ); }
|