2330 lines
60 KiB
C++
2330 lines
60 KiB
C++
/*++
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
admin.cxx
|
|
|
|
Abstract:
|
|
|
|
This module contains code for doing admin rpcs
|
|
|
|
Author:
|
|
|
|
Todd Christensen (ToddCh) 28-Apr-1996
|
|
|
|
Revision History:
|
|
|
|
Rohan Phillips (Rohanp) - enabled virtual server support 4-Feb-1997
|
|
|
|
--*/
|
|
|
|
#define INCL_INETSRV_INCS
|
|
#include "smtpinc.h"
|
|
#include "smtpsvc.h"
|
|
#include "smtpcli.hxx"
|
|
#include "admin.hxx"
|
|
|
|
// Address validation lib (KeithLau 7/28/96)
|
|
#include "address.hxx"
|
|
#include "findiis.hxx"
|
|
#include <stdio.h>
|
|
#include <malloc.h>
|
|
|
|
//
|
|
// Quick and dirty string validation
|
|
//
|
|
static inline BOOL pValidateStringPtr(LPWSTR lpwszString, DWORD dwMaxLength)
|
|
{
|
|
if (IsBadStringPtr((LPCTSTR)lpwszString, dwMaxLength))
|
|
return(FALSE);
|
|
while (dwMaxLength--)
|
|
if (*lpwszString++ == 0)
|
|
return(TRUE);
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Quick and dirty range check using inlines
|
|
//
|
|
static inline BOOL pValidateRange(DWORD dwValue, DWORD dwLower, DWORD dwUpper)
|
|
{
|
|
// Inclusive
|
|
if ((dwValue >= dwLower) && (dwValue <= dwUpper))
|
|
return(TRUE);
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprGetAdminInformation(
|
|
IN LPWSTR pszServer OPTIONAL,
|
|
OUT LPSMTP_CONFIG_INFO * ppConfig,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
/*++
|
|
|
|
Description
|
|
|
|
Retrieves the admin information
|
|
|
|
Arguments:
|
|
|
|
pszServer - unused
|
|
ppConfig - Receives pointer to admin information
|
|
|
|
Note:
|
|
|
|
--*/
|
|
{
|
|
SMTP_CONFIG_INFO * pConfig;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
DWORD err = NO_ERROR;
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (IsBadWritePtr((LPVOID)ppConfig, sizeof(LPSMTP_CONFIG_INFO)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
// In case we exit on an error...
|
|
*ppConfig = NULL;
|
|
|
|
if ( err = TsApiAccessCheck( TCP_QUERY_ADMIN_INFORMATION ))
|
|
return err;
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
if (!ConvertSmtpConfigToRpc(&pConfig, pInstance))
|
|
{
|
|
err = GetLastError();
|
|
goto exit;
|
|
}
|
|
|
|
if (!ConvertSmtpRoutingListToRpc(&(pConfig->RoutingList), pInstance))
|
|
{
|
|
FreeRpcSmtpConfig(pConfig);
|
|
err = GetLastError();
|
|
goto exit;
|
|
}
|
|
|
|
*ppConfig = pConfig;
|
|
|
|
exit:
|
|
|
|
pInstance->Dereference();
|
|
return err;
|
|
}
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprSetAdminInformation(
|
|
IN LPWSTR pszServer OPTIONAL,
|
|
IN SMTP_CONFIG_INFO * pConfig,
|
|
IN DWORD dwInstance
|
|
)
|
|
/*++
|
|
|
|
Description
|
|
|
|
Sets the common service admin information for the servers specified
|
|
in dwServerMask.
|
|
|
|
Arguments:
|
|
|
|
pszServer - unused
|
|
pConfig - Admin information to set
|
|
|
|
Note:
|
|
|
|
--*/
|
|
{
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
if (IsBadReadPtr((LPVOID)pConfig, sizeof(SMTP_CONFIG_INFO)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
DWORD err;
|
|
|
|
if ( err = TsApiAccessCheck( TCP_SET_ADMIN_INFORMATION ))
|
|
return err;
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance != NULL)
|
|
{
|
|
// raid 129712 - we treat this case the same as before.
|
|
if ( !(pInstance->WriteRegParams(pConfig)) ||
|
|
!(pInstance->ReadRegParams(pConfig->FieldControl, TRUE)))
|
|
{
|
|
pInstance->Dereference();
|
|
return GetLastError();
|
|
}
|
|
|
|
pInstance->Dereference();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
return ERROR_INVALID_DATA;
|
|
}
|
|
|
|
|
|
|
|
//+---------------------------------------------------------------
|
|
//
|
|
// Function: ConvertSmtpConfigToRpc
|
|
//
|
|
// Synopsis: Moves config values into the RPC structure
|
|
//
|
|
// Arguments: LPSMTP_CONFIG_INFO *: structure to be filled with
|
|
// configuration data.
|
|
//
|
|
// Returns: BOOL - TRUE on SUCCESS, FALSE on FAIL
|
|
//
|
|
//----------------------------------------------------------------
|
|
BOOL ConvertSmtpConfigToRpc(LPSMTP_CONFIG_INFO *ppConfig, PSMTP_SERVER_INSTANCE pInstance)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void FreeRpcSmtpConfig(LPSMTP_CONFIG_INFO pConfig)
|
|
{
|
|
if (pConfig)
|
|
{
|
|
if (pConfig->lpszSmartHostName)
|
|
FreeRpcString(pConfig->lpszSmartHostName);
|
|
if (pConfig->lpszConnectResp)
|
|
FreeRpcString(pConfig->lpszConnectResp);
|
|
if (pConfig->lpszBadMailDir)
|
|
FreeRpcString(pConfig->lpszBadMailDir);
|
|
|
|
if (pConfig->RoutingList)
|
|
FreeRpcSmtpRoutingList(pConfig->RoutingList);
|
|
|
|
MIDL_user_free(pConfig);
|
|
}
|
|
}
|
|
|
|
|
|
BOOL ConvertSmtpRoutingListToRpc(LPSMTP_CONFIG_ROUTING_LIST *ppRoutingList, PSMTP_SERVER_INSTANCE pInstance)
|
|
{
|
|
#if 0
|
|
LPSMTP_CONFIG_ROUTING_LIST pRoutingList;
|
|
DWORD dwErr;
|
|
DWORD iSource;
|
|
DWORD cSources = 0;
|
|
DWORD cbAlloc;
|
|
PLIST_ENTRY pEntry;
|
|
PLIST_ENTRY pHead;
|
|
|
|
cSources = pInstance->GetRoutingSourceCount();
|
|
|
|
cbAlloc = sizeof(SMTP_CONFIG_ROUTING_LIST) + cSources * sizeof(SMTP_CONFIG_ROUTING_ENTRY);
|
|
pRoutingList = (LPSMTP_CONFIG_ROUTING_LIST) MIDL_user_allocate(cbAlloc);
|
|
if (!pRoutingList)
|
|
{
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
return FALSE;
|
|
}
|
|
|
|
ZeroMemory(pRoutingList, cbAlloc);
|
|
|
|
pRoutingList->cEntries = cSources;
|
|
pHead = pInstance->GetRoutingSourceList();
|
|
|
|
for (pEntry = pHead->Flink, iSource = 0 ; pEntry != pHead ; pEntry = pEntry->Flink, iSource++)
|
|
{
|
|
if (!ConvertStringToRpc(&(pRoutingList->aRoutingEntry[iSource].lpszSource),
|
|
CONTAINING_RECORD(pEntry, ABSOURCE, list)->szConfig))
|
|
{
|
|
dwErr = GetLastError();
|
|
for (iSource = 0 ; iSource < cSources ; iSource++)
|
|
{
|
|
if (pRoutingList->aRoutingEntry[iSource].lpszSource)
|
|
FreeRpcString(pRoutingList->aRoutingEntry[iSource].lpszSource);
|
|
}
|
|
|
|
MIDL_user_free(pRoutingList);
|
|
SetLastError(dwErr);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
*ppRoutingList = pRoutingList;
|
|
#endif
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
|
|
void FreeRpcSmtpRoutingList(LPSMTP_CONFIG_ROUTING_LIST pRoutingList)
|
|
{
|
|
DWORD iSource;
|
|
|
|
if (pRoutingList)
|
|
{
|
|
for (iSource = 0 ; iSource < pRoutingList->cEntries ; iSource++)
|
|
{
|
|
if (pRoutingList->aRoutingEntry[iSource].lpszSource)
|
|
FreeRpcString(pRoutingList->aRoutingEntry[iSource].lpszSource);
|
|
}
|
|
|
|
MIDL_user_free(pRoutingList);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprGetConnectedUserList(
|
|
IN LPWSTR pszServer OPTIONAL,
|
|
OUT LPSMTP_CONN_USER_LIST *ppConnUserList,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
/*++
|
|
|
|
Description
|
|
|
|
Retrieves the connected user list
|
|
|
|
Arguments:
|
|
|
|
pszServer - unused
|
|
ppConnUserList - Receives pointer to admin information
|
|
|
|
Note:
|
|
|
|
--*/
|
|
{
|
|
SMTP_CONN_USER_LIST *pConnUserList;
|
|
SMTP_CONN_USER_ENTRY *pConnEntry;
|
|
DWORD dwErr;
|
|
PLIST_ENTRY pleHead;
|
|
PLIST_ENTRY pleT;
|
|
SMTP_CONNECTION *pConn;
|
|
DWORD iEntry;
|
|
DWORD NumUsers = 0;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
// In case we exit on an error...
|
|
*ppConnUserList = NULL;
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (IsBadWritePtr((LPVOID)ppConnUserList, sizeof(LPSMTP_CONN_USER_LIST)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
if (dwErr = TsApiAccessCheck( TCP_QUERY_ADMIN_INFORMATION))
|
|
return dwErr;
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
pInstance->LockConfig();
|
|
|
|
//loop through the list to get the count of all connected users.
|
|
//These are users whose sockets are not equal to INVALID_SOCKET
|
|
pleHead = pInstance->GetConnectionList();
|
|
for (pleT = pleHead->Flink ; pleT != pleHead ; pleT = pleT->Flink)
|
|
{
|
|
pConn = CONTAINING_RECORD(pleT, SMTP_CONNECTION, m_listEntry);
|
|
if(pConn->QueryClientSocket() != INVALID_SOCKET)
|
|
{
|
|
NumUsers++;
|
|
}
|
|
}
|
|
|
|
pConnUserList = (SMTP_CONN_USER_LIST *)MIDL_user_allocate(sizeof(SMTP_CONN_USER_LIST) +
|
|
sizeof(SMTP_CONN_USER_ENTRY) * NumUsers);
|
|
if (!pConnUserList)
|
|
{
|
|
pInstance->UnLockConfig();
|
|
pInstance->Dereference();
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
pConnUserList->cEntries = NumUsers;
|
|
pConnEntry = pConnUserList->aConnUserEntry;
|
|
ZeroMemory(pConnEntry, sizeof(SMTP_CONN_USER_ENTRY) * pConnUserList->cEntries);
|
|
|
|
pleHead = pInstance->GetConnectionList();
|
|
for (pleT = pleHead->Flink ; pleT != pleHead ; pleT = pleT->Flink)
|
|
{
|
|
pConn = CONTAINING_RECORD(pleT, SMTP_CONNECTION, m_listEntry);
|
|
|
|
//disregard anyone whose socket is invalid
|
|
if(pConn->QueryClientSocket() == INVALID_SOCKET)
|
|
continue;
|
|
|
|
pConnEntry->dwUserId = pConn->QueryClientId();
|
|
pConnEntry->dwConnectTime = pConn->QuerySessionTime();
|
|
if (pConn->QueryClientUserName())
|
|
{
|
|
if (!ConvertStringToRpc(&(pConnEntry->lpszName), pConn->QueryClientUserName()))
|
|
{
|
|
pInstance->UnLockConfig();
|
|
|
|
pConnEntry = pConnUserList->aConnUserEntry;
|
|
for (iEntry = 0 ; iEntry < pConnUserList->cEntries ; iEntry++, pConnEntry++)
|
|
{
|
|
if (pConnEntry->lpszName)
|
|
FreeRpcString(pConnEntry->lpszName);
|
|
if (pConnEntry->lpszHost)
|
|
FreeRpcString(pConnEntry->lpszHost);
|
|
}
|
|
MIDL_user_free(pConnUserList);
|
|
|
|
pInstance->Dereference();
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
|
|
if (pConn->QueryClientHostName())
|
|
{
|
|
if (!ConvertStringToRpc(&(pConnEntry->lpszHost), pConn->QueryClientHostName()))
|
|
{
|
|
pInstance->UnLockConfig();
|
|
|
|
pConnEntry = pConnUserList->aConnUserEntry;
|
|
for (iEntry = 0 ; iEntry < pConnUserList->cEntries ; iEntry++, pConnEntry++)
|
|
{
|
|
if (pConnEntry->lpszName)
|
|
FreeRpcString(pConnEntry->lpszName);
|
|
if (pConnEntry->lpszHost)
|
|
FreeRpcString(pConnEntry->lpszHost);
|
|
}
|
|
MIDL_user_free(pConnUserList);
|
|
pInstance->Dereference();
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
|
|
pConnEntry++;
|
|
}
|
|
|
|
pInstance->UnLockConfig();
|
|
*ppConnUserList = pConnUserList;
|
|
|
|
pInstance->Dereference();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprDisconnectUser(
|
|
IN LPWSTR pszServer OPTIONAL,
|
|
IN DWORD dwUserId,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
/*++
|
|
|
|
Description
|
|
|
|
Disconnects the specified user
|
|
|
|
Arguments:
|
|
|
|
pszServer - unused
|
|
dwUserId - user to disconnect
|
|
|
|
Note:
|
|
|
|
--*/
|
|
{
|
|
DWORD dwErr;
|
|
PLIST_ENTRY pleHead;
|
|
PLIST_ENTRY pleT;
|
|
SMTP_CONNECTION *pConn;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (dwErr = TsApiAccessCheck( TCP_QUERY_ADMIN_INFORMATION))
|
|
return dwErr;
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
pInstance->LockConfig();
|
|
|
|
pleHead = pInstance->GetConnectionList();
|
|
for (pleT = pleHead->Flink ; pleT != pleHead ; pleT = pleT->Flink)
|
|
{
|
|
pConn = CONTAINING_RECORD(pleT, SMTP_CONNECTION, m_listEntry);
|
|
if (pConn->QueryClientId() == dwUserId)
|
|
{
|
|
pConn->DisconnectClient();
|
|
pInstance->UnLockConfig();
|
|
pInstance->Dereference();
|
|
|
|
return NO_ERROR;
|
|
}
|
|
}
|
|
|
|
pInstance->UnLockConfig();
|
|
pInstance->Dereference();
|
|
return ERROR_NO_SUCH_USER;
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Description:
|
|
Adds a user
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprCreateUser(
|
|
IN LPWSTR wszServer,
|
|
IN LPWSTR wszEmail,
|
|
IN LPWSTR wszForwardEmail,
|
|
IN DWORD dwLocal,
|
|
IN DWORD dwMailboxSize,
|
|
IN DWORD dwMailboxMessageSize,
|
|
IN LPWSTR wszVRoot,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
{
|
|
DWORD dwErr;
|
|
LPSTR szEmail;
|
|
LPSTR szForward = NULL;
|
|
LPSTR szVRoot = NULL;
|
|
HANDLE hToken;
|
|
DWORD cbRoot;
|
|
char szRoot[MAX_PATH + 1];
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
TraceFunctEnter("SmtprCreateUser");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
TraceFunctLeave();
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
if (wszForwardEmail &&
|
|
!pValidateStringPtr(wszForwardEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
if (wszVRoot &&
|
|
!pValidateStringPtr(wszVRoot, AB_MAX_VROOT))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
DebugTrace(NULL, "Email name: %ls", wszEmail);
|
|
szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
|
|
if (!szEmail)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %u", wszEmail, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
DebugTrace(NULL, "Forward: %ls", wszForwardEmail ? wszForwardEmail : L"<NULL>");
|
|
if (wszForwardEmail)
|
|
{
|
|
szForward = ConvertUnicodeToAnsi(wszForwardEmail, NULL, 0);
|
|
if (!szForward)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %u", wszForwardEmail, dwErr);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
}
|
|
|
|
// Parameter checking
|
|
if (!CAddr::ValidateEmailName(szEmail)) // Note: ANSI version
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
|
|
(wszEmail)?wszEmail:L"NULL");
|
|
if (szForward)
|
|
TCP_FREE(szForward);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (wszForwardEmail)
|
|
if (!CAddr::ValidateEmailName(szForward)) // Note: ANSI version
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszForwardEmail (%ls)\n",
|
|
(wszForwardEmail)?wszForwardEmail:L"NULL");
|
|
if (szForward)
|
|
TCP_FREE(szForward);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (!pValidateRange(dwLocal, 0, 1))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: dwLocal (%u)\n",
|
|
dwLocal);
|
|
if (szForward)
|
|
TCP_FREE(szForward);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
// VRoot is checked downstream
|
|
|
|
DebugTrace(NULL, "Create mailbox: %s", dwLocal ? "TRUE" : "FALSE");
|
|
if (dwLocal)
|
|
{
|
|
DebugTrace(NULL, "VRoot: %ls", wszVRoot ? wszVRoot : L"<NULL>");
|
|
if (wszVRoot)
|
|
{
|
|
szVRoot = ConvertUnicodeToAnsi(wszVRoot, NULL, 0);
|
|
if (!szVRoot)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %u", wszVRoot, dwErr);
|
|
if (szForward)
|
|
TCP_FREE(szForward);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
DWORD dwAccessMask = 0;
|
|
|
|
// Parameter checking for valid vroot
|
|
cbRoot = sizeof(szRoot);
|
|
if(!pInstance->QueryVrootTable()->LookupVirtualRoot(
|
|
szVRoot, szRoot, &cbRoot, &dwAccessMask, NULL, NULL,
|
|
&hToken, NULL))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to resolve virtual root(%ls): %u", wszVRoot, dwErr);
|
|
if (szForward)
|
|
TCP_FREE(szForward);
|
|
TCP_FREE(szEmail);
|
|
TCP_FREE(szVRoot);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
szVRoot = (LPSTR)TCP_ALLOC(MAX_PATH);
|
|
if (!szVRoot)
|
|
{
|
|
ErrorTrace(NULL, "Allocation failed");
|
|
if (szForward)
|
|
TCP_FREE(szForward);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
if (!pInstance->FindBestVRoot(szVRoot))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to FindBestVRoot: %u", dwErr);
|
|
if (szForward)
|
|
TCP_FREE(szForward);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/*
|
|
if (!pInstance->PRtx()->CreateUser(szEmail, szForward, dwLocal, szVRoot, dwMailboxSize, dwMailboxMessageSize))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to create user %s: %u", szEmail, dwErr);
|
|
if (szVRoot)
|
|
TCP_FREE(szVRoot);
|
|
if (szForward)
|
|
TCP_FREE(szForward);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
*/
|
|
if (szVRoot)
|
|
TCP_FREE(szVRoot);
|
|
if (szForward)
|
|
TCP_FREE(szForward);
|
|
TCP_FREE(szEmail);
|
|
|
|
pInstance->Dereference();
|
|
|
|
TraceFunctLeave();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Description:
|
|
Deletes a user
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprDeleteUser(
|
|
IN LPWSTR wszServer,
|
|
IN LPWSTR wszEmail,
|
|
IN DWORD dwInstance
|
|
)
|
|
{
|
|
DWORD dwErr;
|
|
LPSTR szEmail;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
TraceFunctEnter("SmtprDeleteUser");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
TraceFunctLeave();
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
{
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
DebugTrace(NULL, "Email name: %ls", wszEmail);
|
|
szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
|
|
if (!szEmail)
|
|
{
|
|
dwErr = GetLastError();
|
|
TCP_FREE(szEmail);
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
// Parameter checking
|
|
if (!CAddr::ValidateEmailName(szEmail))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
|
|
(wszEmail)?wszEmail:L"NULL");
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
/*
|
|
if (!pInstance->PRtx()->DeleteUser(szEmail))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to delete user %s: %d", szEmail, dwErr);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
*/
|
|
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
|
|
TraceFunctLeave();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Description:
|
|
Gets user properties
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprGetUserProps(
|
|
IN LPWSTR wszServer,
|
|
IN LPWSTR wszEmail,
|
|
OUT LPSMTP_USER_PROPS *ppUserProps,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
{
|
|
#if 0
|
|
LPSTR szEmail;
|
|
DWORD dwErr;
|
|
LPSMTP_USER_PROPS pUserProps;
|
|
RTX_USER_PROPS rtxuserprops;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
TraceFunctEnter("SmtprGetUserProps");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
if (IsBadWritePtr((LPVOID)ppUserProps, sizeof(LPSMTP_USER_PROPS)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
|
|
if (!szEmail)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
// Parameter checking
|
|
if (!CAddr::ValidateEmailName(szEmail))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
|
|
(wszEmail)?wszEmail:L"NULL");
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
if (!pInstance->PRtx()->GetUserProps(szEmail, &rtxuserprops))
|
|
{
|
|
ErrorTrace(NULL, "GetUserProps call failed: %u", GetLastError());
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
return GetLastError();
|
|
}
|
|
TCP_FREE(szEmail);
|
|
|
|
pUserProps = (LPSMTP_USER_PROPS) MIDL_user_allocate(sizeof(SMTP_USER_PROPS));
|
|
|
|
if (!ConvertStringToRpc(&(pUserProps->wszForward), rtxuserprops.szForward))
|
|
{
|
|
ErrorTrace(NULL, "Unable to convert forward to rpc string: %u", GetLastError());
|
|
MIDL_user_free(pUserProps);
|
|
pInstance->Dereference();
|
|
|
|
return GetLastError();
|
|
}
|
|
|
|
if (!ConvertStringToRpc(&(pUserProps->wszVRoot), rtxuserprops.szVRoot))
|
|
{
|
|
ErrorTrace(NULL, "Unable to convert vroot to rpc string: %u", GetLastError());
|
|
FreeRpcString(pUserProps->wszForward);
|
|
MIDL_user_free(pUserProps);
|
|
pInstance->Dereference();
|
|
|
|
return GetLastError();
|
|
}
|
|
|
|
pUserProps->dwMailboxMax = rtxuserprops.cbMailBoxSize;
|
|
pUserProps->dwMailboxMessageMax = rtxuserprops.cbMailboxMessageSize;
|
|
pUserProps->dwLocal = rtxuserprops.fLocal;
|
|
pUserProps->fc = FC_SMTP_USER_PROPS_ALL;
|
|
|
|
*ppUserProps = pUserProps;
|
|
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return NO_ERROR;
|
|
#endif
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Description:
|
|
Sets a users properties
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprSetUserProps(
|
|
IN LPWSTR wszServer,
|
|
IN LPWSTR wszEmail,
|
|
IN LPSMTP_USER_PROPS pUserProps,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
{
|
|
#if 0
|
|
|
|
DWORD dwErr;
|
|
DWORD dwErrKeep = NO_ERROR;
|
|
LPSTR szEmail = NULL;
|
|
LPSTR szForward = NULL;
|
|
LPSTR szVRoot = NULL;
|
|
HANDLE hToken;
|
|
DWORD cbRoot;
|
|
char szRoot[MAX_PATH + 1];
|
|
BOOL fSet;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
TraceFunctEnter("SmtprSetUserProps");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
if (IsBadReadPtr((LPVOID)pUserProps, sizeof(SMTP_USER_PROPS)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
if (!pUserProps->fc)
|
|
{
|
|
// Nothing to do...
|
|
pInstance->Dereference();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DebugTrace(NULL, "Email name: %ls", wszEmail);
|
|
szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
|
|
if (!szEmail)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
// Parameter checking
|
|
if (!CAddr::ValidateEmailName(szEmail))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
|
|
(wszEmail)?wszEmail:L"NULL");
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (!pUserProps)
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: pUserProps (NULL)\n");
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
// More checking downstream ...
|
|
|
|
if (IsFieldSet(pUserProps->fc, FC_SMTP_USER_PROPS_FORWARD))
|
|
{
|
|
fSet = TRUE;
|
|
|
|
if (pUserProps->wszForward)
|
|
{
|
|
szForward = ConvertUnicodeToAnsi(pUserProps->wszForward, NULL, 0);
|
|
if (!szForward)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", pUserProps->wszForward, dwErr);
|
|
if (dwErrKeep == NO_ERROR)
|
|
dwErrKeep = dwErr;
|
|
fSet = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
szForward = NULL;
|
|
}
|
|
|
|
// Parameter check for forward
|
|
if (szForward &&
|
|
!CAddr::ValidateEmailName(szForward))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: pconfig->pUserProps->wszForward (%s)\n",
|
|
(pUserProps->wszForward)?pUserProps->wszForward:L"NULL");
|
|
if (dwErrKeep == NO_ERROR)
|
|
dwErrKeep = ERROR_INVALID_PARAMETER;
|
|
fSet = FALSE;
|
|
}
|
|
|
|
if (fSet)
|
|
{
|
|
if (!pInstance->PRtx()->SetForward(szEmail, szForward))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to set forward for %s: %d", szEmail, dwErr);
|
|
if (dwErrKeep == NO_ERROR)
|
|
dwErrKeep = dwErr;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (IsFieldSet(pUserProps->fc, FC_SMTP_USER_PROPS_MAILBOX_SIZE))
|
|
{
|
|
if (!pInstance->PRtx()->SetMailboxSize(szEmail, pUserProps->dwMailboxMax))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to set mailbox size for %s: %d", szEmail, dwErr);
|
|
if (dwErrKeep == NO_ERROR)
|
|
dwErrKeep = dwErr;
|
|
}
|
|
}
|
|
|
|
if (IsFieldSet(pUserProps->fc, FC_SMTP_USER_PROPS_MAILBOX_MESSAGE_SIZE))
|
|
{
|
|
if (!pInstance->PRtx()->SetMailboxMessageSize(szEmail, pUserProps->dwMailboxMessageMax))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to set mailbox size for %s: %d", szEmail, dwErr);
|
|
if (dwErrKeep == NO_ERROR)
|
|
dwErrKeep = dwErr;
|
|
}
|
|
}
|
|
|
|
if (IsFieldSet(pUserProps->fc, FC_SMTP_USER_PROPS_VROOT))
|
|
{
|
|
fSet = TRUE;
|
|
szVRoot = ConvertUnicodeToAnsi(pUserProps->wszVRoot, NULL, 0);
|
|
if (!szVRoot)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", pUserProps->wszVRoot, dwErr);
|
|
if (dwErrKeep == NO_ERROR)
|
|
dwErrKeep = dwErr;
|
|
fSet = FALSE;
|
|
}
|
|
|
|
DWORD dwAccessMask = 0;
|
|
|
|
// Parameter checking for VRoot
|
|
cbRoot = sizeof(szRoot);
|
|
if(!pInstance->QueryVrootTable()->LookupVirtualRoot(
|
|
szVRoot, szRoot, &cbRoot, &dwAccessMask, NULL, NULL,
|
|
&hToken, NULL))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to resolve virtual root(%ls): %u", pUserProps->wszVRoot, dwErr);
|
|
if (dwErrKeep == NO_ERROR)
|
|
dwErrKeep = dwErr;
|
|
fSet = FALSE;
|
|
}
|
|
|
|
if (fSet)
|
|
{
|
|
if (!pInstance->PRtx()->SetVRoot(szEmail, szVRoot))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to set vroot for %s: %d", szEmail, dwErr);
|
|
if (dwErrKeep == NO_ERROR)
|
|
dwErrKeep = dwErr;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (szVRoot)
|
|
TCP_FREE(szVRoot);
|
|
if (szForward)
|
|
TCP_FREE(szForward);
|
|
TCP_FREE(szEmail);
|
|
|
|
pInstance->Dereference();
|
|
|
|
TraceFunctLeave();
|
|
return dwErrKeep;
|
|
|
|
#endif
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Description:
|
|
Creates a DL
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprCreateDistList(
|
|
IN LPWSTR wszServer,
|
|
IN LPWSTR wszEmail,
|
|
IN DWORD dwType,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
{
|
|
#if 0
|
|
DWORD dwErr;
|
|
LPSTR szEmail;
|
|
DWORD dwRtxType;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
TraceFunctEnter("SmtprCreateDistList");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
TraceFunctLeave();
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
{
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
if (dwType == NAME_TYPE_LIST_NORMAL)
|
|
dwRtxType = rtxnameDistListNormal;
|
|
else if (dwType == NAME_TYPE_LIST_SITE)
|
|
dwRtxType = rtxnameDistListSite;
|
|
else if (dwType == NAME_TYPE_LIST_DOMAIN)
|
|
dwRtxType = rtxnameDistListDomain;
|
|
else
|
|
{
|
|
ErrorTrace(NULL, "TYPE is not NAME_TYPE_LIST_NORMAL or NAME_TYPE_LIST_SITE");
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
DebugTrace(NULL, "Email name: %ls", wszEmail);
|
|
szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
|
|
if (!szEmail)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
// Parameter check
|
|
if (!CAddr::ValidateEmailName(szEmail))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
|
|
(wszEmail)?wszEmail:L"NULL");
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
if (!pInstance->PRtx()->CreateDistList(szEmail, dwRtxType))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to create list %s: %d", szEmail, dwErr);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
|
|
TraceFunctLeave();
|
|
return NO_ERROR;
|
|
#endif
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Description:
|
|
Deletes a DL
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprDeleteDistList(
|
|
IN LPWSTR wszServer,
|
|
IN LPWSTR wszEmail,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
{
|
|
DWORD dwErr;
|
|
LPSTR szEmail;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
TraceFunctEnter("SmtprDeleteDistList");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
DebugTrace(NULL, "Email name: %ls", wszEmail);
|
|
szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
|
|
if (!szEmail)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
// Parameter check
|
|
if (!CAddr::ValidateEmailName(szEmail))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
|
|
(wszEmail)?wszEmail:L"NULL");
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
#if 0
|
|
if (!pInstance->PRtx()->DeleteDistList(szEmail))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to delete list %s: %d", szEmail, dwErr);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
#endif
|
|
|
|
TCP_FREE(szEmail);
|
|
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Description:
|
|
Adds a member to the DL
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprCreateDistListMember(
|
|
IN LPWSTR wszServer,
|
|
IN LPWSTR wszEmail,
|
|
IN LPWSTR wszEmailMember,
|
|
IN DWORD dwInstance
|
|
)
|
|
{
|
|
DWORD dwErr;
|
|
LPSTR szEmail;
|
|
LPSTR szMember;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
TraceFunctEnter("SmtprCreateDistListMember");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
if (!pValidateStringPtr(wszEmailMember, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
DebugTrace(NULL, "Email name: %ls", wszEmail);
|
|
szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
|
|
if (!szEmail)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
|
|
pInstance->Dereference();
|
|
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
szMember = ConvertUnicodeToAnsi(wszEmailMember, NULL, 0);
|
|
if (!szMember)
|
|
{
|
|
dwErr = GetLastError();
|
|
TCP_FREE(szEmail);
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmailMember, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
// Parameter check
|
|
if (!CAddr::ValidateEmailName(szEmail))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
|
|
(wszEmail)?wszEmail:L"NULL");
|
|
TCP_FREE(szMember);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (!CAddr::ValidateEmailName(szMember))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmailMember (%ls)\n",
|
|
(wszEmailMember)?wszEmailMember:L"NULL");
|
|
TCP_FREE(szMember);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
#if 0
|
|
if (!pInstance->PRtx()->CreateDistListMember(szEmail, szMember))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to add member %s to %s: %d", szMember, szEmail, dwErr);
|
|
TCP_FREE(szMember);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
#endif
|
|
|
|
TCP_FREE(szMember);
|
|
TCP_FREE(szEmail);
|
|
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Description:
|
|
Deletes a member from the DL
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprDeleteDistListMember(
|
|
IN LPWSTR wszServer,
|
|
IN LPWSTR wszEmail,
|
|
IN LPWSTR wszEmailMember,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
{
|
|
DWORD dwErr;
|
|
LPSTR szEmail;
|
|
LPSTR szMember;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
TraceFunctEnter("SmtprDeleteDistListMember");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
if (!pValidateStringPtr(wszEmailMember, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
DebugTrace(NULL, "Email name: %ls", wszEmail);
|
|
szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
|
|
if (!szEmail)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
szMember = ConvertUnicodeToAnsi(wszEmailMember, NULL, 0);
|
|
if (!szMember)
|
|
{
|
|
dwErr = GetLastError();
|
|
TCP_FREE(szEmail);
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmailMember, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
// Parameter check
|
|
if (!CAddr::ValidateEmailName(szEmail))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
|
|
(wszEmail)?wszEmail:L"NULL");
|
|
TCP_FREE(szMember);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (!CAddr::ValidateEmailName(szMember))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmailMember (%ls)\n",
|
|
(wszEmailMember)?wszEmailMember:L"NULL");
|
|
TCP_FREE(szMember);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
#if 0
|
|
if (!pInstance->PRtx()->DeleteDistListMember(szEmail, szMember))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to delete member %s from %s: %d", szMember, szEmail, dwErr);
|
|
TCP_FREE(szMember);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
#endif
|
|
|
|
TCP_FREE(szMember);
|
|
TCP_FREE(szEmail);
|
|
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
|
|
/*++
|
|
|
|
Description:
|
|
Sets DL properties
|
|
|
|
Note:
|
|
|
|
--*/
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprGetNameList(
|
|
IN LPWSTR wszServer,
|
|
IN LPWSTR wszEmail,
|
|
IN DWORD dwType,
|
|
IN DWORD dwRowsReq,
|
|
IN BOOL fForward,
|
|
OUT LPSMTP_NAME_LIST *ppNameList,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
{
|
|
#if 0
|
|
|
|
DWORD dwErr;
|
|
HRTXENUM hrtxenum;
|
|
LPSTR szEmail;
|
|
DWORD crowsReturned;
|
|
DWORD cbAlloc;
|
|
DWORD irows;
|
|
LPSMTP_NAME_LIST pNameList;
|
|
DWORD dwFlags;
|
|
DWORD cbNameEntry;
|
|
char szName[cbEmailNameMax];
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
TraceFunctEnter("SmtprGetNameList");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
if (IsBadWritePtr((LPVOID)ppNameList, sizeof(LPSMTP_NAME_LIST)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
*ppNameList = NULL;
|
|
|
|
// Up front parameter check
|
|
if (!pValidateRange(dwType, 1,15))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: dwType (%u)\n",
|
|
dwType);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (!pValidateRange(dwRowsReq, 1, 100))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: dwRowsReq (%u)\n",
|
|
dwRowsReq);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (!pValidateRange(fForward, 0, 1))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: fForward (%u)\n",
|
|
fForward);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (!ppNameList)
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: ppNameList (NULL)\n");
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
|
|
// More checks downstream
|
|
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
DebugTrace(NULL, "Email name: %ls", wszEmail);
|
|
szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
|
|
if (!szEmail)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d", wszEmail, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
// Parameter change
|
|
if (szEmail[0] != 0 &&
|
|
szEmail[0] != '@' &&
|
|
!CAddr::ValidateEmailName(szEmail, TRUE))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
|
|
(wszEmail)?wszEmail:L"NULL");
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwFlags = 0;
|
|
if (dwType & NAME_TYPE_USER)
|
|
dwFlags |= rtxnameUser;
|
|
if (dwType & NAME_TYPE_LIST_NORMAL)
|
|
dwFlags |= rtxnameDistListNormal;
|
|
if (dwType & NAME_TYPE_LIST_SITE)
|
|
dwFlags |= rtxnameDistListSite;
|
|
if (dwType & NAME_TYPE_LIST_DOMAIN)
|
|
dwFlags |= rtxnameDistListDomain;
|
|
|
|
if (!pInstance->PRtx()->EnumNameList(szEmail, fForward, dwRowsReq, dwFlags, &hrtxenum))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to enum name list: %d", dwErr);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
TCP_FREE(szEmail);
|
|
|
|
crowsReturned = pInstance->PRtx()->EnumRowsReturned(hrtxenum);
|
|
cbAlloc = sizeof(SMTP_NAME_LIST) + crowsReturned * sizeof(SMTP_NAME_ENTRY);
|
|
|
|
pNameList = (LPSMTP_NAME_LIST)MIDL_user_allocate(cbAlloc);
|
|
ZeroMemory(pNameList, cbAlloc);
|
|
pNameList->cEntries = crowsReturned;
|
|
|
|
for (irows = 0 ; irows < crowsReturned ; irows++)
|
|
{
|
|
cbNameEntry = cbEmailNameMax;
|
|
if (!pInstance->PRtx()->GetNextEmail(hrtxenum, &(dwFlags),
|
|
szName))
|
|
{
|
|
dwErr = GetLastError();
|
|
_VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
|
|
_VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
|
|
for (irows = 0 ; irows < crowsReturned ; irows++)
|
|
{
|
|
if (pNameList->aNameEntry[irows].lpszName)
|
|
FreeRpcString(pNameList->aNameEntry[irows].lpszName);
|
|
}
|
|
|
|
MIDL_user_free(pNameList);
|
|
ErrorTrace(NULL, "GetNext failed on row %u: %u", irows, dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
if (dwFlags & rtxnameUser)
|
|
pNameList->aNameEntry[irows].dwType = NAME_TYPE_USER;
|
|
if (dwFlags & rtxnameDistListNormal)
|
|
pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_NORMAL;
|
|
if (dwFlags & rtxnameDistListSite)
|
|
pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_SITE;
|
|
if (dwFlags & rtxnameDistListDomain)
|
|
pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_DOMAIN;
|
|
|
|
if (!ConvertStringToRpc(&(pNameList->aNameEntry[irows].lpszName), szName))
|
|
{
|
|
dwErr = GetLastError();
|
|
_VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
|
|
_VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
|
|
for (irows = 0 ; irows < crowsReturned ; irows++)
|
|
{
|
|
if (pNameList->aNameEntry[irows].lpszName)
|
|
FreeRpcString(pNameList->aNameEntry[irows].lpszName);
|
|
}
|
|
|
|
MIDL_user_free(pNameList);
|
|
ErrorTrace(NULL, "Unable to convert %s to RPC string: %u", szName, dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
}
|
|
|
|
_VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
|
|
_VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
|
|
|
|
*ppNameList = pNameList;
|
|
pInstance->Dereference();
|
|
|
|
TraceFunctLeave();
|
|
return NO_ERROR;
|
|
|
|
#endif
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprGetNameListFromList(
|
|
IN SMTP_HANDLE wszServerName,
|
|
IN LPWSTR wszEmailList,
|
|
IN LPWSTR wszEmail,
|
|
IN DWORD dwType,
|
|
IN DWORD dwRowsRequested,
|
|
IN BOOL fForward,
|
|
OUT LPSMTP_NAME_LIST *ppNameList,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
/*++
|
|
|
|
Description
|
|
|
|
Performs a search within a list
|
|
|
|
Arguments:
|
|
|
|
wszServer - unused
|
|
wszEmailList - Email list to search from
|
|
wszEmail - Email name to search for
|
|
dwType - Type of the Email name supplied
|
|
dwRowsRequested - Number of rows requested
|
|
fForward -
|
|
ppNameList - pointer to pointer to name list to return
|
|
|
|
Note:
|
|
|
|
This RPC is added by Keith Lau (keithlau) on 7/5/96
|
|
|
|
--*/
|
|
{
|
|
|
|
#if 0
|
|
DWORD dwErr;
|
|
HRTXENUM hrtxenum;
|
|
LPSTR szEmail;
|
|
LPSTR szEmailList;
|
|
DWORD crowsReturned;
|
|
DWORD cbAlloc;
|
|
DWORD irows;
|
|
LPSMTP_NAME_LIST pNameList;
|
|
DWORD dwFlags;
|
|
DWORD cbNameEntry;
|
|
char szName[cbEmailNameMax];
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
TraceFunctEnter("SmtprGetNameListFromList");
|
|
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszEmailList, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
if (!pValidateStringPtr(wszEmail, (AB_MAX_LOGIN + AB_MAX_FULL_EMAIL_WO_NULL + 2)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
if (IsBadWritePtr((LPVOID)ppNameList, sizeof(LPSMTP_NAME_LIST)))
|
|
return(ERROR_INVALID_PARAMETER);
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
*ppNameList = NULL;
|
|
|
|
if (!pValidateRange(dwType, 1, 15))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: dwType (%u)\n",
|
|
dwType);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (!pValidateRange(dwRowsRequested, 1, 100))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: dwRowsRequested (%u)\n",
|
|
dwRowsRequested);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (!pValidateRange(fForward, 0, 1))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: fForward (%u)\n",
|
|
fForward);
|
|
pInstance->Dereference();
|
|
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (!ppNameList)
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: ppNameList (NULL)\n");
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
DebugTrace(NULL, "Email list name: %ls", wszEmailList);
|
|
szEmailList = ConvertUnicodeToAnsi(wszEmailList, NULL, 0);
|
|
if (!szEmailList)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d",
|
|
wszEmailList, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
if (!CAddr::ValidateEmailName(szEmailList))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmailList (%ls)\n",
|
|
(wszEmailList)?wszEmailList:L"NULL");
|
|
TCP_FREE(szEmailList);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
DebugTrace(NULL, "Email name: %ls", wszEmail);
|
|
szEmail = ConvertUnicodeToAnsi(wszEmail, NULL, 0);
|
|
if (!szEmail)
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d",
|
|
wszEmail, dwErr);
|
|
|
|
TCP_FREE(szEmailList);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
if (szEmail[0] != 0 &&
|
|
szEmail[0] != '@' &&
|
|
!CAddr::ValidateEmailName(szEmail, TRUE))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszEmail (%ls)\n",
|
|
(wszEmail)?wszEmail:L"NULL");
|
|
TCP_FREE(szEmail);
|
|
TCP_FREE(szEmailList);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwFlags = 0;
|
|
if (dwType & NAME_TYPE_USER)
|
|
dwFlags |= rtxnameUser;
|
|
if (dwType & NAME_TYPE_LIST_NORMAL)
|
|
dwFlags |= rtxnameDistListNormal;
|
|
if (dwType & NAME_TYPE_LIST_SITE)
|
|
dwFlags |= rtxnameDistListSite;
|
|
if (dwType & NAME_TYPE_LIST_DOMAIN)
|
|
dwFlags |= rtxnameDistListDomain;
|
|
|
|
if (!pInstance->PRtx()->EnumNameListFromDL(szEmailList,
|
|
szEmail,
|
|
fForward,
|
|
dwRowsRequested,
|
|
dwFlags,
|
|
&hrtxenum))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to enum name list: %d", dwErr);
|
|
TCP_FREE(szEmailList);
|
|
TCP_FREE(szEmail);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
TCP_FREE(szEmailList);
|
|
TCP_FREE(szEmail);
|
|
|
|
crowsReturned = pInstance->PRtx()->EnumRowsReturned(hrtxenum);
|
|
cbAlloc = sizeof(SMTP_NAME_LIST) + crowsReturned * sizeof(SMTP_NAME_ENTRY);
|
|
|
|
pNameList = (LPSMTP_NAME_LIST)MIDL_user_allocate(cbAlloc);
|
|
ZeroMemory(pNameList, cbAlloc);
|
|
pNameList->cEntries = crowsReturned;
|
|
|
|
for (irows = 0 ; irows < crowsReturned ; irows++)
|
|
{
|
|
cbNameEntry = cbEmailNameMax;
|
|
if (!pInstance->PRtx()->GetNextEmail(hrtxenum, &(dwFlags), szName))
|
|
{
|
|
dwErr = GetLastError();
|
|
_VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
|
|
_VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
|
|
for (irows = 0 ; irows < crowsReturned ; irows++)
|
|
{
|
|
if (pNameList->aNameEntry[irows].lpszName)
|
|
FreeRpcString(pNameList->aNameEntry[irows].lpszName);
|
|
}
|
|
|
|
MIDL_user_free(pNameList);
|
|
ErrorTrace(NULL, "GetNext failed on row %u: %u", irows, dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
if (dwFlags & rtxnameUser)
|
|
pNameList->aNameEntry[irows].dwType = NAME_TYPE_USER;
|
|
if (dwFlags & rtxnameDistListNormal)
|
|
pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_NORMAL;
|
|
if (dwFlags & rtxnameDistListSite)
|
|
pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_SITE;
|
|
if (dwFlags & rtxnameDistListDomain)
|
|
pNameList->aNameEntry[irows].dwType = NAME_TYPE_LIST_DOMAIN;
|
|
|
|
if (!ConvertStringToRpc(&(pNameList->aNameEntry[irows].lpszName), szName))
|
|
{
|
|
dwErr = GetLastError();
|
|
_VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
|
|
_VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
|
|
for (irows = 0 ; irows < crowsReturned ; irows++)
|
|
{
|
|
if (pNameList->aNameEntry[irows].lpszName)
|
|
FreeRpcString(pNameList->aNameEntry[irows].lpszName);
|
|
}
|
|
|
|
MIDL_user_free(pNameList);
|
|
ErrorTrace(NULL, "Unable to convert %s to RPC string: %u", szName, dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
}
|
|
|
|
_VERIFY(pInstance->PRtx()->EndEnumResult(hrtxenum));
|
|
_VERIFY(pInstance->PRtx()->FreeHrtxenum(hrtxenum));
|
|
|
|
*ppNameList = pNameList;
|
|
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return NO_ERROR;
|
|
|
|
#endif
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprGetVRootSize(
|
|
IN SMTP_HANDLE wszServerName,
|
|
IN LPWSTR wszVRoot,
|
|
OUT LPDWORD pdwBytes,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
/*++
|
|
|
|
Description
|
|
|
|
Obtains the size of the specified VRoot
|
|
|
|
Arguments:
|
|
|
|
wszServer - unused
|
|
wszVRoot - VRoot whose size to return
|
|
pdwBytes - Pointer to a DWORD to contain the VRoot size on return
|
|
|
|
Return Value:
|
|
|
|
This call returns NO_ERROR on success. ERROR_INVALID_NAME is returned
|
|
if ResolveVirtualRoot returns an invalid directory name. A Win32
|
|
error code is returned for other error conditions.
|
|
|
|
Note:
|
|
|
|
This RPC is added by Keith Lau (keithlau) on 7/5/96
|
|
|
|
--*/
|
|
{
|
|
HANDLE hToken;
|
|
DWORD cbRoot;
|
|
LPSTR szVRoot;
|
|
char szRoot[MAX_PATH + 1];
|
|
DWORD dwErr;
|
|
ULARGE_INTEGER uliBytesAvail;
|
|
ULARGE_INTEGER uliBytesTotal;
|
|
ULARGE_INTEGER uliBytesFree;
|
|
DWORD dwAccessMask = 0;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
TraceFunctEnter("SmtprGetVRootSize");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszVRoot, AB_MAX_VROOT))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszVRoot\n");
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
if (IsBadWritePtr((LPVOID)pdwBytes, sizeof(DWORD)))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: pdwBytes\n");
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
// Default the size to 0 bytes free
|
|
*pdwBytes = 0;
|
|
dwErr = NO_ERROR;
|
|
|
|
// Access check
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
// Resolve the Virtual Root, need Unicode - ANSI conversion
|
|
cbRoot = sizeof(szRoot);
|
|
DebugTrace(NULL, "VRoot name: %ls", wszVRoot);
|
|
if (!(szVRoot = ConvertUnicodeToAnsi(wszVRoot, NULL, 0)))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d",
|
|
wszVRoot, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
if(!pInstance->QueryVrootTable()->LookupVirtualRoot(
|
|
szVRoot, szRoot, &cbRoot, &dwAccessMask, NULL, NULL,
|
|
&hToken, NULL))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "ResolveVirtualRoot failed for %s, %u", wszVRoot, dwErr);
|
|
TCP_FREE(szVRoot);
|
|
}
|
|
else
|
|
{
|
|
// Free it right away lest we forget
|
|
TCP_FREE(szVRoot);
|
|
|
|
DebugTrace(NULL, "Getting free disk ratio on %s", szRoot);
|
|
if (hToken == 0 || ImpersonateLoggedOnUser(hToken))
|
|
{
|
|
if (GetDiskFreeSpaceEx(szRoot,
|
|
&uliBytesAvail,
|
|
&uliBytesTotal,
|
|
&uliBytesFree))
|
|
{
|
|
// Make sure we are not overflowing 4Gig, which is easy
|
|
_ASSERT(uliBytesAvail.HighPart == 0);
|
|
*pdwBytes = uliBytesAvail.LowPart;
|
|
}
|
|
else
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "GetDiskFreeSpaceEx failed on %s: %u", szRoot, dwErr);
|
|
}
|
|
|
|
if (hToken != 0)
|
|
_VERIFY(RevertToSelf());
|
|
}
|
|
else
|
|
{
|
|
ErrorTrace(NULL, "Impersonation failed");
|
|
dwErr = GetLastError();
|
|
}
|
|
}
|
|
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
SmtprBackupRoutingTable(
|
|
IN SMTP_HANDLE wszServerName,
|
|
IN LPWSTR wszPath,
|
|
IN DWORD dwInstance
|
|
|
|
)
|
|
/*++
|
|
|
|
Description
|
|
|
|
Tells routing table to backup itself to the given path
|
|
|
|
Arguments:
|
|
|
|
wszServer - unused
|
|
wszVRoot - Path to put backup file
|
|
|
|
Return Value:
|
|
|
|
This call returns NO_ERROR on success. Routing table error
|
|
if routing table cannot create the backup
|
|
|
|
--*/
|
|
{
|
|
|
|
#if 0
|
|
DWORD dwErr;
|
|
LPSTR szBackupDir = NULL;
|
|
PSMTP_SERVER_INSTANCE pInstance;
|
|
|
|
|
|
TraceFunctEnter("SmtprBackupRoutingTable");
|
|
|
|
if(g_IsShuttingDown)
|
|
{
|
|
return ERROR_SHUTDOWN_IN_PROGRESS;
|
|
}
|
|
|
|
if (!pValidateStringPtr(wszPath, MAX_PATH))
|
|
{
|
|
ErrorTrace(NULL, "Invalid parameter: wszPath\n");
|
|
TraceFunctLeave();
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
pInstance = FindIISInstance((PSMTP_IIS_SERVICE) g_pInetSvc, dwInstance);
|
|
if(pInstance == NULL)
|
|
{
|
|
return(ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
dwErr = NO_ERROR;
|
|
|
|
// Access check
|
|
dwErr = TsApiAccessCheck(TCP_QUERY_ADMIN_INFORMATION);
|
|
if (dwErr != NO_ERROR)
|
|
{
|
|
ErrorTrace(NULL, "Access check failed: %u", dwErr);
|
|
pInstance->Dereference();
|
|
return dwErr;
|
|
}
|
|
|
|
if (pInstance->PRtx()->GetRtType() != rttypeFF)
|
|
{
|
|
ErrorTrace(NULL, "Backup for non-FF routing table isn't allowed!");
|
|
pInstance->Dereference();
|
|
return ERROR_NOT_SUPPORTED;
|
|
}
|
|
|
|
if (!(szBackupDir = ConvertUnicodeToAnsi(wszPath, NULL, 0)))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to ConvertUnicodeToAnsi(%ls): %d",
|
|
wszPath, dwErr);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
if (!pInstance->PRtx()->MakeBackup(szBackupDir))
|
|
{
|
|
dwErr = GetLastError();
|
|
ErrorTrace(NULL, "Unable to complete backup to %s: %d", szBackupDir, dwErr);
|
|
TCP_FREE(szBackupDir);
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
}
|
|
|
|
TCP_FREE(szBackupDir);
|
|
|
|
pInstance->Dereference();
|
|
TraceFunctLeave();
|
|
return dwErr;
|
|
#endif
|
|
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
}
|
|
|