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.
1215 lines
28 KiB
1215 lines
28 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
infostub.c
|
|
|
|
Abstract:
|
|
|
|
Client stubs of the Internet Info Server Admin APIs.
|
|
|
|
Author:
|
|
|
|
Madan Appiah (madana) 10-Oct-1993
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
--*/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
|
|
#include "info_cli.h"
|
|
|
|
#include <ntsam.h>
|
|
#include <ntlsa.h>
|
|
|
|
#include <ftpd.h>
|
|
#include <w3svc.h>
|
|
#include <rpcutil.h>
|
|
#include <winsock2.h>
|
|
#include <rpcasync.h>
|
|
|
|
//
|
|
// Quick macro to initialize a unicode string
|
|
//
|
|
|
|
WCHAR g_wchUnicodeNull[] = L"";
|
|
|
|
#define _InitUnicodeString( pUnicode, pwch ) \
|
|
{ \
|
|
(pUnicode)->Buffer = pwch; \
|
|
(pUnicode)->Length = wcslen( pwch ) * sizeof(WCHAR); \
|
|
(pUnicode)->MaximumLength = (pUnicode)->Length + sizeof(WCHAR); \
|
|
}
|
|
|
|
# define InitUnicodeString( pUnicode, pwch) \
|
|
if (pwch == NULL) { _InitUnicodeString( pUnicode, g_wchUnicodeNull); } \
|
|
else { _InitUnicodeString( pUnicode, pwch); } \
|
|
|
|
|
|
//
|
|
// Returns a unicode empty string if the string is NULL
|
|
//
|
|
|
|
#define EMPTY_IF_NULL(str) (str ? str : L"")
|
|
|
|
struct SRV_SECRET_NAMES
|
|
{
|
|
DWORD dwID;
|
|
LPWSTR SecretName;
|
|
LPWSTR RootSecretName;
|
|
}
|
|
aSrvSecrets[] =
|
|
{
|
|
INET_FTP, FTPD_ANONYMOUS_SECRET_W, FTPD_ROOT_SECRET_W,
|
|
INET_HTTP, W3_ANONYMOUS_SECRET_W, W3_ROOT_SECRET_W,
|
|
INET_GOPHER, GOPHERD_ANONYMOUS_SECRET_W , GOPHERD_ROOT_SECRET_W,
|
|
//INET_CHAT, CHAT_ANONYMOUS_SECRET_W, CHAT_ROOT_SECRET_W,
|
|
//INET_NNTP, NNTP_ANONYMOUS_SECRET_W, NNTP_ROOT_SECRET_W,
|
|
//INET_SMTP, SMTP_ANONYMOUS_SECRET_W, SMTP_ROOT_SECRET_W,
|
|
//INET_POP3, POP3_ANONYMOUS_SECRET_W, POP3_ROOT_SECRET_W,
|
|
//INET_LDAP, LDAP_ANONYMOUS_SECRET_W, LDAP_ROOT_SECRET_W,
|
|
//INET_IMAP, IMAP_ANONYMOUS_SECRET_W, IMAP_ROOT_SECRET_W,
|
|
0, NULL, NULL
|
|
};
|
|
|
|
DWORD
|
|
GetSecret(
|
|
IN LPWSTR Server,
|
|
IN LPWSTR SecretName,
|
|
OUT LPWSTR * ppSecret
|
|
);
|
|
|
|
DWORD
|
|
SetSecret(
|
|
IN LPWSTR Server,
|
|
IN LPWSTR SecretName,
|
|
IN LPWSTR pSecret,
|
|
IN DWORD cbSecret
|
|
);
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InetInfoGetVersion(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwReserved,
|
|
OUT DWORD * pdwVersion
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
//
|
|
// Try RPC (local or remote) version of API.
|
|
//
|
|
status = R_InetInfoGetVersion(
|
|
Server,
|
|
dwReserved,
|
|
pdwVersion
|
|
);
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return (status);
|
|
|
|
} // InetInfoGetVersion()
|
|
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InetInfoGetServerCapabilities(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwReserved,
|
|
OUT LPINET_INFO_CAPABILITIES * ppCap
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
*ppCap = NULL;
|
|
RpcTryExcept
|
|
{
|
|
//
|
|
// Try RPC (local or remote) version of API.
|
|
//
|
|
status = R_InetInfoGetServerCapabilities(
|
|
Server,
|
|
dwReserved,
|
|
(LPINET_INFO_CAPABILITIES_STRUCT *)ppCap
|
|
);
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return (status);
|
|
|
|
} // InetInfoServerCapabilities()
|
|
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InetInfoQueryStatistics(
|
|
IN LPWSTR pszServer OPTIONAL,
|
|
IN DWORD Level,
|
|
IN DWORD dwServerMask,
|
|
OUT LPBYTE * Buffer
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
*Buffer = NULL;
|
|
RpcTryExcept
|
|
{
|
|
//
|
|
// Try RPC (local or remote) version of API.
|
|
//
|
|
status = R_InetInfoQueryStatistics(
|
|
pszServer,
|
|
Level,
|
|
dwServerMask,
|
|
(LPINET_INFO_STATISTICS_INFO) Buffer
|
|
);
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return (status);
|
|
} // InetInfoQueryStatistics()
|
|
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InetInfoClearStatistics(
|
|
IN LPWSTR pszServer OPTIONAL,
|
|
IN DWORD dwServerMask
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
|
|
//
|
|
// Try RPC (local or remote) version of API.
|
|
//
|
|
status = R_InetInfoClearStatistics(
|
|
pszServer,
|
|
dwServerMask
|
|
);
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return (status);
|
|
} // InetInfoClearStatistics()
|
|
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InetInfoFlushMemoryCache(
|
|
IN LPWSTR pszServer OPTIONAL,
|
|
IN DWORD dwServerMask
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
|
|
//
|
|
// Try RPC (local or remote) version of API.
|
|
//
|
|
status = R_InetInfoFlushMemoryCache(
|
|
pszServer,
|
|
dwServerMask
|
|
);
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return (status);
|
|
} // InetInfoFlushMemoryCache()
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InetInfoGetGlobalAdminInformation(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwReserved,
|
|
OUT LPINET_INFO_GLOBAL_CONFIG_INFO * ppConfig
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_InetInfoGetGlobalAdminInformation(
|
|
Server,
|
|
dwReserved,
|
|
ppConfig
|
|
);
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
} // InetInfoGetGlobalAdminInformation()
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InetInfoGetSites(
|
|
IN LPWSTR pszServer OPTIONAL,
|
|
IN DWORD dwServerMask,
|
|
OUT LPINET_INFO_SITE_LIST * ppSites
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_InetInfoGetSites(
|
|
pszServer,
|
|
dwServerMask,
|
|
ppSites
|
|
);
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
} // InetInfoGetSites()
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InetInfoSetGlobalAdminInformation(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwReserved,
|
|
IN INET_INFO_GLOBAL_CONFIG_INFO * pConfig
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_InetInfoSetGlobalAdminInformation(
|
|
Server,
|
|
dwReserved,
|
|
pConfig
|
|
);
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
} // InetInfoSetGlobalAdminInformation()
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InetInfoGetAdminInformation(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwServerMask,
|
|
OUT LPINET_INFO_CONFIG_INFO * ppConfig
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
BOOL fGetPassword = TRUE;
|
|
LPWSTR pSecret;
|
|
DWORD i = 0;
|
|
DWORD j;
|
|
LPWSTR pszCurrent;
|
|
INET_INFO_VIRTUAL_ROOT_ENTRY * pVirtRoot;
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_InetInfoGetAdminInformation(
|
|
Server,
|
|
dwServerMask,
|
|
ppConfig
|
|
);
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
if ( status )
|
|
return status;
|
|
|
|
#ifndef CHICAGO
|
|
|
|
//
|
|
// Get the anonymous account password
|
|
//
|
|
|
|
while ( aSrvSecrets[i].dwID &&
|
|
!(aSrvSecrets[i].dwID & dwServerMask ) )
|
|
{
|
|
i++;
|
|
}
|
|
|
|
// Note: Only the service corresponding to first mask is chosen.
|
|
|
|
if ( !aSrvSecrets[i].dwID )
|
|
return ERROR_INVALID_PARAMETER;
|
|
|
|
status = GetSecret( Server,
|
|
aSrvSecrets[i].SecretName,
|
|
&pSecret );
|
|
|
|
if ( status )
|
|
return status;
|
|
|
|
memcpy( (*ppConfig)->szAnonPassword,
|
|
pSecret,
|
|
sizeof(WCHAR) * min( wcslen( pSecret ), PWLEN ));
|
|
|
|
(*ppConfig)->szAnonPassword[PWLEN] = L'\0';
|
|
|
|
LocalFree( pSecret );
|
|
|
|
//
|
|
// Zero terminate all of the passwords in case there is no associated
|
|
// secret
|
|
//
|
|
|
|
for ( j = 0; j < (*ppConfig)->VirtualRoots->cEntries; j++ )
|
|
{
|
|
*(*ppConfig)->VirtualRoots->aVirtRootEntry[j].AccountPassword = L'\0';
|
|
}
|
|
|
|
status = GetSecret( Server,
|
|
aSrvSecrets[i].RootSecretName,
|
|
&pSecret );
|
|
|
|
if ( status )
|
|
return status;
|
|
|
|
pszCurrent = pSecret;
|
|
|
|
while ( *pszCurrent )
|
|
{
|
|
LPWSTR pszRoot;
|
|
LPWSTR pszPassword;
|
|
LPWSTR pszAddress;
|
|
LPWSTR pszNextLine = pszCurrent + wcslen(pszCurrent) + 1;
|
|
|
|
|
|
//
|
|
// The list is in the form:
|
|
//
|
|
// <Root>,<Addresss>=<Password>\0
|
|
// <Root>,<Addresss>=<Password>\0
|
|
// \0
|
|
//
|
|
|
|
pszRoot = pszCurrent;
|
|
|
|
pszPassword = wcschr( pszCurrent, L'=' );
|
|
|
|
if ( !pszPassword )
|
|
{
|
|
//
|
|
// Bad list format, skip this one
|
|
//
|
|
|
|
goto NextLine;
|
|
}
|
|
|
|
*pszPassword = L'\0';
|
|
pszPassword++;
|
|
|
|
pszAddress = wcschr( pszRoot, L',');
|
|
|
|
if ( !pszAddress )
|
|
{
|
|
goto NextLine;
|
|
|
|
}
|
|
|
|
*pszAddress = L'\0';
|
|
pszAddress++;
|
|
|
|
//
|
|
// Now look for this root and address in the virtual root list
|
|
// so we can set the password
|
|
//
|
|
|
|
for ( i = 0; i < (*ppConfig)->VirtualRoots->cEntries; i++ )
|
|
{
|
|
pVirtRoot = &(*ppConfig)->VirtualRoots->aVirtRootEntry[i];
|
|
|
|
if ( !_wcsicmp( pszRoot, pVirtRoot->pszRoot ) &&
|
|
(!pszAddress || !_wcsicmp( pszAddress, pVirtRoot->pszAddress)))
|
|
{
|
|
//
|
|
// If the password length is invalid, we just ignore it.
|
|
// This shouldn't happen because we check before setting the
|
|
// password
|
|
//
|
|
|
|
if ( wcslen( pszPassword ) <= PWLEN )
|
|
{
|
|
wcscpy( pVirtRoot->AccountPassword,
|
|
pszPassword );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
NextLine:
|
|
|
|
pszCurrent = pszNextLine;
|
|
}
|
|
|
|
LocalFree( pSecret );
|
|
#else // CHICAGO
|
|
//
|
|
// Zero terminate all of the passwords in case there is no associated
|
|
// secret
|
|
//
|
|
|
|
for ( j = 0; j < (*ppConfig)->VirtualRoots->cEntries; j++ )
|
|
{
|
|
*(*ppConfig)->VirtualRoots->aVirtRootEntry[j].AccountPassword = L'\0';
|
|
}
|
|
#endif // CHICAGO
|
|
return status;
|
|
} // InetInfoGetAdminInformation()
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InetInfoSetAdminInformation(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwServerMask,
|
|
IN INET_INFO_CONFIG_INFO * pConfig
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
WCHAR szAnonPassword[PWLEN+1];
|
|
LPWSTR pszRootPasswords = NULL;
|
|
LPWSTR pszPassword;
|
|
DWORD i, j;
|
|
|
|
#ifndef CHICAGO
|
|
|
|
//
|
|
// Enumerate the LSA secret names for the specified servers. We set the
|
|
// secrets first so the anonymous user name password can be refreshed
|
|
// in the server side InetInfoSetAdminInformation
|
|
//
|
|
|
|
i = 0;
|
|
while ( aSrvSecrets[i].dwID )
|
|
{
|
|
if ( !(aSrvSecrets[i].dwID & dwServerMask ))
|
|
{
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_ANON_PASSWORD ))
|
|
{
|
|
status = SetSecret( Server,
|
|
aSrvSecrets[i].SecretName,
|
|
pConfig->szAnonPassword,
|
|
(wcslen( pConfig->szAnonPassword ) + 1)
|
|
* sizeof(WCHAR));
|
|
|
|
if ( status )
|
|
return status;
|
|
}
|
|
|
|
if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_VIRTUAL_ROOTS ))
|
|
{
|
|
DWORD cbNeeded = sizeof(WCHAR);
|
|
INET_INFO_VIRTUAL_ROOT_ENTRY * pVirtRoot;
|
|
LPWSTR psz;
|
|
LPWSTR pszSecret;
|
|
|
|
//
|
|
// Build a string that looks like:
|
|
//
|
|
// <Root>,<Addresss>=<Password>\0
|
|
// <Root>,<Addresss>=<Password>\0
|
|
// \0
|
|
//
|
|
|
|
//
|
|
// Do a first pass to figure the buffer size we need to build
|
|
//
|
|
|
|
for ( j = 0; j < pConfig->VirtualRoots->cEntries; j++ )
|
|
{
|
|
pVirtRoot = &pConfig->VirtualRoots->aVirtRootEntry[j];
|
|
|
|
cbNeeded += (wcslen( pVirtRoot->pszRoot ) +
|
|
wcslen( EMPTY_IF_NULL(pVirtRoot->pszAddress)) +
|
|
wcslen( pVirtRoot->AccountPassword ) +
|
|
(PWLEN + 3)) * sizeof(WCHAR);
|
|
}
|
|
|
|
//
|
|
// We always allocate at least enough room for a '\0'
|
|
//
|
|
|
|
pszSecret = LocalAlloc( LPTR, cbNeeded + sizeof(WCHAR) );
|
|
|
|
if ( !pszSecret )
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
psz = pszSecret;
|
|
|
|
//
|
|
// Now build the string
|
|
//
|
|
|
|
for ( j = 0; j < pConfig->VirtualRoots->cEntries; j++ )
|
|
{
|
|
pVirtRoot = &pConfig->VirtualRoots->aVirtRootEntry[j];
|
|
|
|
psz += wsprintfW( psz,
|
|
L"%ls,%ls=%ls",
|
|
pVirtRoot->pszRoot,
|
|
EMPTY_IF_NULL(pVirtRoot->pszAddress),
|
|
pVirtRoot->AccountPassword );
|
|
psz++;
|
|
}
|
|
|
|
//
|
|
// Add the list terminating NULL
|
|
//
|
|
|
|
*psz = L'\0';
|
|
|
|
status = SetSecret( Server,
|
|
aSrvSecrets[i].RootSecretName,
|
|
pszSecret,
|
|
cbNeeded );
|
|
|
|
LocalFree( pszSecret );
|
|
|
|
if ( status )
|
|
return status;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
#endif // CHICAGO
|
|
|
|
//
|
|
// Set the passwords to NULL so it doesn't go out on the
|
|
// wire. We set them as a secrets above
|
|
//
|
|
|
|
if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_VIRTUAL_ROOTS ))
|
|
{
|
|
pszRootPasswords = LocalAlloc( LPTR,
|
|
pConfig->VirtualRoots->cEntries *
|
|
(PWLEN + 1) * sizeof(WCHAR) );
|
|
|
|
if ( !pszRootPasswords )
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
for ( i = 0; i < pConfig->VirtualRoots->cEntries; i++ )
|
|
{
|
|
pszPassword = pConfig->VirtualRoots->aVirtRootEntry[i].AccountPassword;
|
|
|
|
if ( wcslen( pszPassword ) > PWLEN )
|
|
{
|
|
LocalFree( pszRootPasswords );
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
wcscpy( pszRootPasswords + i * (PWLEN + 1),
|
|
pszPassword );
|
|
|
|
SecureZeroMemory( pszPassword,
|
|
sizeof( pConfig->VirtualRoots->aVirtRootEntry[i].AccountPassword ));
|
|
}
|
|
}
|
|
|
|
if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_ANON_PASSWORD ))
|
|
{
|
|
memcpy( szAnonPassword,
|
|
pConfig->szAnonPassword,
|
|
sizeof(pConfig->szAnonPassword) );
|
|
|
|
SecureZeroMemory( pConfig->szAnonPassword,
|
|
sizeof(pConfig->szAnonPassword) );
|
|
}
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_InetInfoSetAdminInformation(
|
|
Server,
|
|
dwServerMask,
|
|
pConfig
|
|
);
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
//
|
|
// Restore the structure we just mucked with
|
|
//
|
|
|
|
if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_ANON_PASSWORD ))
|
|
{
|
|
memcpy( pConfig->szAnonPassword,
|
|
szAnonPassword,
|
|
sizeof(pConfig->szAnonPassword) );
|
|
|
|
SecureZeroMemory( szAnonPassword, sizeof( szAnonPassword ));
|
|
}
|
|
|
|
if ( IsFieldSet( pConfig->FieldControl, FC_INET_INFO_VIRTUAL_ROOTS ))
|
|
{
|
|
for ( i = 0; i < pConfig->VirtualRoots->cEntries; i++ )
|
|
{
|
|
pszPassword = pConfig->VirtualRoots->aVirtRootEntry[i].AccountPassword;
|
|
|
|
wcscpy( pszPassword,
|
|
pszRootPasswords + i * (PWLEN + 1) );
|
|
}
|
|
|
|
SecureZeroMemory( pszRootPasswords,
|
|
pConfig->VirtualRoots->cEntries * (PWLEN + 1) * sizeof(WCHAR));
|
|
|
|
LocalFree( pszRootPasswords );
|
|
|
|
pszRootPasswords = NULL;
|
|
}
|
|
|
|
return status;
|
|
} // InetInfoSetAdminInformation()
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
IISEnumerateUsers(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwLevel,
|
|
IN DWORD dwServiceId,
|
|
IN DWORD dwInstance,
|
|
OUT PDWORD nRead,
|
|
OUT LPBYTE *pBuffer
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
GENERIC_INFO_CONTAINER genInfo;
|
|
GENERIC_ENUM_STRUCT genStruct;
|
|
|
|
genInfo.Buffer = NULL;
|
|
genInfo.EntriesRead = 0;
|
|
|
|
genStruct.Container = &genInfo;
|
|
genStruct.Level = dwLevel;
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_IISEnumerateUsers(
|
|
Server,
|
|
dwServiceId,
|
|
dwInstance,
|
|
(LPIIS_USER_ENUM_STRUCT)&genStruct
|
|
);
|
|
|
|
if ( genInfo.Buffer != NULL ) {
|
|
*pBuffer = (LPBYTE)genInfo.Buffer;
|
|
*nRead = genInfo.EntriesRead;
|
|
|
|
} else {
|
|
*pBuffer = NULL;
|
|
*nRead = 0;
|
|
}
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
|
|
} // IISEnumerateUsers
|
|
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
IISDisconnectUser(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwServiceId,
|
|
IN DWORD dwInstance,
|
|
IN DWORD dwIdUser
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_IISDisconnectUser(
|
|
Server,
|
|
dwServiceId,
|
|
dwInstance,
|
|
dwIdUser
|
|
);
|
|
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
|
|
} // IISDisconnectUser
|
|
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
InitW3CounterStructure(
|
|
IN LPWSTR Server OPTIONAL,
|
|
OUT LPDWORD lpcbTotalRequired
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_InitW3CounterStructure(Server, lpcbTotalRequired);
|
|
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
} //InitW3CounterStructure
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
CollectW3PerfData(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN LPWSTR lpValueName,
|
|
OUT LPBYTE lppData,
|
|
IN OUT LPDWORD lpcbTotalBytes,
|
|
OUT LPDWORD lpNumObjectTypes
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_CollectW3PerfData(
|
|
Server,
|
|
lpValueName,
|
|
lppData,
|
|
lpcbTotalBytes,
|
|
lpNumObjectTypes
|
|
);
|
|
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
} //CollectW3PerfData
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
W3QueryStatistics2(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwLevel,
|
|
IN DWORD dwInstance,
|
|
IN DWORD dwReserved,
|
|
OUT LPBYTE * pBuffer
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
*pBuffer = NULL;
|
|
RpcTryExcept
|
|
{
|
|
status = R_W3QueryStatistics2(
|
|
Server,
|
|
dwLevel,
|
|
dwInstance,
|
|
dwReserved,
|
|
(LPW3_STATISTICS_STRUCT)pBuffer
|
|
);
|
|
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
} // W3QueryStatistics2
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
W3ClearStatistics2(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwInstance
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_W3ClearStatistics2(
|
|
Server,
|
|
dwInstance
|
|
);
|
|
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
|
|
} // W3ClearStatistics2
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
FtpQueryStatistics2(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwLevel,
|
|
IN DWORD dwInstance,
|
|
IN DWORD dwReserved,
|
|
OUT LPBYTE * pBuffer
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
*pBuffer = NULL;
|
|
RpcTryExcept
|
|
{
|
|
status = R_FtpQueryStatistics2(
|
|
Server,
|
|
dwLevel,
|
|
dwInstance,
|
|
dwReserved,
|
|
(LPFTP_STATISTICS_STRUCT)pBuffer
|
|
);
|
|
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
} // FtpQueryStatistics2
|
|
|
|
|
|
NET_API_STATUS
|
|
NET_API_FUNCTION
|
|
FtpClearStatistics2(
|
|
IN LPWSTR Server OPTIONAL,
|
|
IN DWORD dwInstance
|
|
)
|
|
{
|
|
NET_API_STATUS status;
|
|
|
|
RpcTryExcept
|
|
{
|
|
status = R_FtpClearStatistics2(
|
|
Server,
|
|
dwInstance
|
|
);
|
|
|
|
}
|
|
RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
|
|
{
|
|
status = RpcExceptionCode();
|
|
}
|
|
RpcEndExcept
|
|
|
|
return status;
|
|
|
|
} // FtpClearStatistics2
|
|
|
|
|
|
#ifndef CHICAGO
|
|
|
|
DWORD
|
|
GetSecret(
|
|
IN LPWSTR Server,
|
|
IN LPWSTR SecretName,
|
|
OUT LPWSTR * ppSecret
|
|
)
|
|
/*++
|
|
|
|
Description
|
|
|
|
Gets the specified LSA secret
|
|
|
|
Arguments:
|
|
|
|
Server - Server name (or NULL) secret lives on
|
|
SecretName - Name of the LSA secret
|
|
ppSecret - Receives an allocated block of memory containing the secret.
|
|
Must be freed with LocalFree.
|
|
|
|
Note:
|
|
|
|
--*/
|
|
{
|
|
LSA_HANDLE hPolicy;
|
|
UNICODE_STRING * punicodePassword;
|
|
UNICODE_STRING unicodeServer;
|
|
NTSTATUS ntStatus;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
UNICODE_STRING unicodeSecret;
|
|
|
|
|
|
InitUnicodeString( &unicodeServer,
|
|
Server );
|
|
|
|
//
|
|
// Open a policy to the remote LSA
|
|
//
|
|
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
NULL,
|
|
0L,
|
|
NULL,
|
|
NULL );
|
|
|
|
ntStatus = LsaOpenPolicy( &unicodeServer,
|
|
&ObjectAttributes,
|
|
POLICY_ALL_ACCESS,
|
|
&hPolicy );
|
|
|
|
if ( !NT_SUCCESS( ntStatus ) )
|
|
return LsaNtStatusToWinError( ntStatus );
|
|
|
|
InitUnicodeString( &unicodeSecret,
|
|
SecretName );
|
|
|
|
|
|
//
|
|
// Query the secret value
|
|
//
|
|
|
|
ntStatus = LsaRetrievePrivateData( hPolicy,
|
|
&unicodeSecret,
|
|
&punicodePassword );
|
|
|
|
LsaClose( hPolicy );
|
|
|
|
if ( !NT_SUCCESS( ntStatus ))
|
|
return LsaNtStatusToWinError( ntStatus );
|
|
|
|
*ppSecret = LocalAlloc( LPTR, punicodePassword->Length + sizeof(WCHAR) );
|
|
|
|
if ( !*ppSecret )
|
|
{
|
|
RtlZeroMemory( punicodePassword->Buffer,
|
|
punicodePassword->MaximumLength );
|
|
|
|
LsaFreeMemory( (PVOID) punicodePassword );
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
//
|
|
// Copy it into the buffer, Length is count of bytes
|
|
//
|
|
|
|
memcpy( *ppSecret,
|
|
punicodePassword->Buffer,
|
|
punicodePassword->Length );
|
|
|
|
(*ppSecret)[punicodePassword->Length/sizeof(WCHAR)] = L'\0';
|
|
|
|
RtlZeroMemory( punicodePassword->Buffer,
|
|
punicodePassword->MaximumLength );
|
|
|
|
LsaFreeMemory( (PVOID) punicodePassword );
|
|
|
|
return NO_ERROR;
|
|
} // GetSecret()
|
|
|
|
|
|
DWORD
|
|
SetSecret(
|
|
IN LPWSTR Server,
|
|
IN LPWSTR SecretName,
|
|
IN LPWSTR pSecret,
|
|
IN DWORD cbSecret
|
|
)
|
|
/*++
|
|
|
|
Description
|
|
|
|
Sets the specified LSA secret
|
|
|
|
Arguments:
|
|
|
|
Server - Server name (or NULL) secret lives on
|
|
SecretName - Name of the LSA secret
|
|
pSecret - Pointer to secret memory
|
|
cbSecret - Size of pSecret memory block
|
|
|
|
Note:
|
|
|
|
--*/
|
|
{
|
|
LSA_HANDLE hPolicy;
|
|
UNICODE_STRING unicodePassword;
|
|
UNICODE_STRING unicodeServer;
|
|
NTSTATUS ntStatus;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
UNICODE_STRING unicodeSecret;
|
|
|
|
|
|
InitUnicodeString( &unicodeServer,
|
|
Server );
|
|
|
|
//
|
|
// Initialize the unicode string by hand so we can handle '\0' in the
|
|
// string
|
|
//
|
|
|
|
unicodePassword.Buffer = pSecret;
|
|
unicodePassword.Length = (USHORT) cbSecret;
|
|
unicodePassword.MaximumLength = (USHORT) cbSecret;
|
|
|
|
//
|
|
// Open a policy to the remote LSA
|
|
//
|
|
|
|
InitializeObjectAttributes( &ObjectAttributes,
|
|
NULL,
|
|
0L,
|
|
NULL,
|
|
NULL );
|
|
|
|
ntStatus = LsaOpenPolicy( &unicodeServer,
|
|
&ObjectAttributes,
|
|
POLICY_ALL_ACCESS,
|
|
&hPolicy );
|
|
|
|
if ( !NT_SUCCESS( ntStatus ) )
|
|
return LsaNtStatusToWinError( ntStatus );
|
|
|
|
//
|
|
// Create or open the LSA secret
|
|
//
|
|
|
|
InitUnicodeString( &unicodeSecret,
|
|
SecretName );
|
|
|
|
ntStatus = LsaStorePrivateData( hPolicy,
|
|
&unicodeSecret,
|
|
&unicodePassword );
|
|
|
|
LsaClose( hPolicy );
|
|
|
|
if ( !NT_SUCCESS( ntStatus ))
|
|
{
|
|
return LsaNtStatusToWinError( ntStatus );
|
|
}
|
|
|
|
return NO_ERROR;
|
|
} // SetSecret()
|
|
|
|
|
|
#else // CHICAGO
|
|
|
|
|
|
|
|
DWORD
|
|
GetSecret(
|
|
IN LPWSTR Server,
|
|
IN LPWSTR SecretName,
|
|
OUT LPWSTR * ppSecret
|
|
)
|
|
{
|
|
return(NO_ERROR);
|
|
}
|
|
|
|
DWORD
|
|
SetSecret(
|
|
IN LPWSTR Server,
|
|
IN LPWSTR SecretName,
|
|
IN LPWSTR pSecret,
|
|
IN DWORD cbSecret
|
|
)
|
|
{
|
|
return(NO_ERROR);
|
|
}
|
|
#endif // CHICAGO
|
|
|
|
|