windows-nt/Source/XPSP1/NT/ds/nw/rdr/ndsprocs.h

854 lines
16 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
NdsProcs.h
Abstract:
This defines the necessary NDS data structures and
symbolic constants.
Author:
Cory West [CoryWest] 23-Feb-1995
Revision History:
--*/
#include "data.h"
#include "nodetype.h"
#include "struct.h"
#include <stdarg.h>
#include "crypto.h"
//
// Security information.
//
#define ENC_TYPE_RSA_PUBLIC 0x90001
#define ENC_TYPE_RC2_CBC 0x60001
#define RAND_KEY_DATA_LEN 28
#define RAND_FL_DATA_LEN 1024
#define RC2_KEY_LEN 8
#define MAX_PUBLIC_KEY_LEN 1300
#define MAX_BSAFE_PUBLIC_KEY_LEN 200 // Typically 179.
#define MAX_BSAFE_PRIV_KEY_LEN 280 // Typically 273.
#define MAX_PW_CHARS 16
//
// The max size for various NDS components.
//
#define MAX_RSA_BITS 512 // Really 420.
#define NDS_TREE_NAME_LEN 32
#define NDS_BINDERY_TREE_NAME 48
#define MAX_CREDENTIAL_LEN ( sizeof( NDS_CREDENTIAL ) + MAX_NDS_NAME_SIZE )
#define MAX_SIGNATURE_LEN ( sizeof( NDS_SIGNATURE ) + MAX_RSA_BYTES )
#define MAX_ENC_PRIV_KEY_LEN ( MAX_BSAFE_PRIV_KEY_LEN + 64 )
#define BSAFE_CHECKSUM_LEN 5
#define DEFAULT_RESOLVE_FLAGS RSLV_DEREF_ALIASES | RSLV_WALK_TREE | RSLV_WRITABLE
#include <packon.h>
typedef struct {
DWORD syntaxId; // OCTET STRING (9)
struct {
DWORD nameLength;
WORD name[11]; // "Public Key"
WORD filler;
} attribName;
DWORD entries; // = 1
DWORD totalLength; // of attribute value OCTET STRING
DWORD unknown1; // = 1
DWORD unknown2; // = 4
WORD _issuerDNLength;
WORD totalDNLength;
WORD length2;
WORD length3;
WORD issuerDNLength;
WORD userDNLength;
WORD bsafeSectionLength;
DWORD length4;
} PUBLIC_KEY_ATTRIB;
#include <packoff.h>
typedef struct {
DWORD blockLength; // cipherLength + size of following hdr fields
DWORD version; // = 1
DWORD encType; // 0x060001 for RC2; 0x090001 and 0x0A0001 for RSA
WORD cipherLength; // of ciphertext
WORD dataLength; // of plaintext
} ENC_BLOCK_HDR, *PENC_BLOCK_HDR;
typedef struct {
DWORD rand1;
DWORD rand2Len;
BYTE rand2[RAND_FL_DATA_LEN];
} NDS_RAND_BYTE_BLOCK, *PNDS_RAND_BYTE_BLOCK;
typedef struct {
DWORD version;
DWORD verb;
DWORD svrRand;
DWORD credentialLength;
} NDS_AUTH_MSG, *PNDS_AUTH_MSG;
//
// VLM Uses the Tagged Data Store as a sort of registry on the fly.
// We, of course, don't use it, but still need the headers.
//
// We need these to be packed.
//
#include <packon.h>
typedef struct {
DWORD version;
WORD tag;
} TAG_DATA_HEADER;
#define TAG_PRIVATE_KEY 2
#define TAG_PUBLIC_KEY 4
#define TAG_CREDENTIAL 6
#define TAG_SIGNATURE 7
#define TAG_PROOF 8
typedef struct {
TAG_DATA_HEADER tdh;
DWORD validityBegin;
DWORD validityEnd;
DWORD random;
WORD optDataSize;
WORD userNameLength;
// BYTE optData[optDataSize];
// BYTE userName[userNameLength];
} NDS_CREDENTIAL, *PNDS_CREDENTIAL;
typedef struct {
TAG_DATA_HEADER tdh;
WORD signDataLength;
//BYTE signData[signLength];
} NDS_SIGNATURE, *PNDS_SIGNATURE;
typedef struct {
TAG_DATA_HEADER tdh;
WORD keyDataLength;
//BYTE BsafeKeyData[keyDataLength];
} NDS_PRIVATE_KEY, *PNDS_PRIVATE_KEY;
typedef struct {
DWORD dwMaxFragSize;
DWORD dwRequestSize;
DWORD dwFragmentFlags;
DWORD dwNdsVerb;
DWORD dwReplyBufferSize;
} NDS_REQUEST_HEADER, *PNDS_REQUEST_HEADER;
typedef struct {
DWORD dwFragmentSize;
DWORD dwFraggerHandle;
} NDS_REPLY_HEADER, *PNDS_REPLY_HEADER;
#include <packoff.h>
typedef struct _NDS_CONTEXT_HEAD {
//
// Node id and list entries.
//
NODE_TYPE_CODE ntc;
NODE_BYTE_SIZE nts;
//
// We can set this flag if we need to pause
// all tree activity (like, for a logout).
//
BOOLEAN CredentialLocked;
LIST_ENTRY Next;
//
// User's credentials.
//
PNDS_CREDENTIAL Credential;
//
// User's signature.
//
PNDS_SIGNATURE Signature;
//
// Password for this tree connection.
//
OEM_STRING Password;
//
// User's public key.
//
DWORD PublicKeyLen;
BYTE *PublicNdsKey;
//
// If this is a supplemental credential, we track
// the handle count and the last close time so that
// we can delete the credential when the last
// handle closes.
//
PLOGON pOwningLogon;
ULONG SupplementalHandleCount;
LARGE_INTEGER LastUsedTime;
//
// NDS tree name. Leave enough room for the munged credential name.
//
UNICODE_STRING NdsTreeName;
WCHAR NdsTreeNameBuffer[NDS_TREE_NAME_LEN + MAX_NDS_NAME_CHARS + 2];
//
// The current context for this tree.
//
UNICODE_STRING CurrentContext;
WCHAR CurrentContextString[MAX_NDS_NAME_CHARS];
} NDS_SECURITY_CONTEXT, *PNDS_SECURITY_CONTEXT;
typedef struct _NDS_CHPW_MSG {
DWORD challenge;
DWORD oldPwLength;
BYTE oldPwHash[16];
DWORD unknown;
DWORD newPwLength;
BYTE newPwHash[16];
ENC_BLOCK_HDR encPrivKeyHdr;
// BYTE encPrivKey[];
} NDS_CHPW_MSG, *PNDS_CHPW_MSG;
//
// Credential list handling routines.
//
#define NwAcquireExclusiveCredList( pLogon, pIrpContext ) \
ExAcquireResourceExclusiveLite( &((pLogon)->CredentialListResource), TRUE ); \
SetFlag( (pIrpContext)->Flags, IRP_FLAG_HAS_CREDENTIAL_LOCK )
#define NwReleaseCredList( pLogon, pIrpContext ) \
ClearFlag( (pIrpContext)->Flags, IRP_FLAG_HAS_CREDENTIAL_LOCK ); \
ExReleaseResourceLite( &((pLogon)->CredentialListResource) )
#include <packon.h>
typedef struct {
DWORD verb;
UINT count;
char *bufEnd;
PVOID nextItem;
} NDS_TAG, *PNDS_TAG;
#include <packoff.h>
typedef struct _nds_list_response {
DWORD ccode;
DWORD iterationHandle;
DWORD numEntries;
//
// Followed by an array of these.
//
// struct {
// DWORD entryId;
// DWORD flags;
// DWORD subCount;
// DWORD modTime;
// NDS_STRING BaseClass;
// NDS_STRING entryName;
// } [];
//
} NDS_LIST_RESPONSE, *PNDS_LIST_RESPONSE;
typedef struct _locked_buffer {
//
// Describes a writeable response buffer
// that we have locked down for the transport.
//
PVOID pRecvBufferVa;
DWORD dwRecvLen;
PMDL pRecvMdl;
DWORD dwBytesWritten;
} LOCKED_BUFFER, *PLOCKED_BUFFER;
//
// Some of the response packet formats from ndsapi32.h
//
typedef struct {
DWORD CompletionCode;
DWORD RemoteEntry;
DWORD EntryId;
DWORD ServerAddresses;
DWORD AddressType;
DWORD AddressLength;
//
// The address is of length
// AddressLength, of course.
//
BYTE Address[1];
} NDS_WIRE_RESPONSE_RESOLVE_NAME, *PNDS_WIRE_RESPONSE_RESOLVE_NAME;
typedef struct {
DWORD CompletionCode;
DWORD RemoteEntry;
DWORD EntryId;
DWORD Unknown;
DWORD ServerAddresses;
DWORD AddressType;
DWORD AddressLength;
//
// The address is of length
// AddressLength, of course.
//
BYTE Address[1];
} NDS_WIRE_RESPONSE_RESOLVE_NAME_REFERRAL,
*PNDS_WIRE_RESPONSE_RESOLVE_NAME_REFERRAL;
//
// Strings for searching ds attributes.
//
#define PUBLIC_KEY_ATTRIBUTE L"Public Key"
#define VOLUME_ATTRIBUTE L"Volume"
#define QUEUE_ATTRIBUTE L"Queue"
#define DIR_MAP_ATTRIBUTE L"Directory Map"
#define HOST_SERVER_ATTRIBUTE L"Host Server"
#define HOST_VOLUME_ATTRIBUTE L"Host Resource Name"
#define HOST_QUEUE_ATTRIBUTE L"CN"
#define HOST_PATH_ATTRIBUTE L"Path"
#define NT_GATEWAY_GROUP L"NTGATEWAY"
#define GROUPS_ATTRIBUTE L"Group Membership"
//
// Prototypes from ndslogin.c
//
NTSTATUS
NdsCanonUserName(
IN PNDS_SECURITY_CONTEXT pNdsContext,
IN PUNICODE_STRING puUserName,
IN OUT PUNICODE_STRING puCanonUserName
);
NTSTATUS
NdsCheckCredentials(
IN PIRP_CONTEXT pIrpContext,
IN PUNICODE_STRING puUserName,
IN PUNICODE_STRING puPassword
);
NTSTATUS
NdsCheckCredentialsEx(
IN PIRP_CONTEXT pIrpContext,
IN PLOGON pLogon,
IN PNDS_SECURITY_CONTEXT pNdsContext,
IN PUNICODE_STRING puUserName,
IN PUNICODE_STRING puPassword
);
#define CREDENTIAL_READ 0
#define CREDENTIAL_WRITE 1
NTSTATUS
NdsLookupCredentials(
IN PIRP_CONTEXT pIrpContext,
IN PUNICODE_STRING puTreeName,
IN PLOGON pLogon,
OUT PNDS_SECURITY_CONTEXT *ppCredentials,
DWORD dwDesiredAccess,
BOOLEAN fCreate
);
NTSTATUS
NdsLookupCredentials2(
IN PIRP_CONTEXT pIrpContext,
IN PUNICODE_STRING puTreeName,
IN PLOGON pLogon,
OUT PNDS_SECURITY_CONTEXT *ppCredentials,
BOOL LowerIrpHasLock
);
NTSTATUS
NdsGetCredentials(
IN PIRP_CONTEXT pIrpContext,
IN PLOGON pLogon,
IN PUNICODE_STRING puUserName,
IN PUNICODE_STRING puPassword
);
NTSTATUS
ChangeNdsPassword(
PIRP_CONTEXT pIrpContext,
DWORD dwUserOID,
DWORD dwChallenge,
PBYTE pbOldPwHash,
PBYTE pbNewPwHash,
PNDS_PRIVATE_KEY pUserPrivKey,
PBYTE pServerPublicBsafeKey,
UINT ServerPubKeyLen,
USHORT NewPassLen
);
NTSTATUS
DoNdsLogon(
IN PIRP_CONTEXT pIrpContext,
IN PUNICODE_STRING UserName,
IN PUNICODE_STRING Password
);
NTSTATUS
NdsTreeLogin(
IN PIRP_CONTEXT pIrpContext,
IN PUNICODE_STRING puUser,
IN POEM_STRING pOemPassword,
IN POEM_STRING pOemNewPassword,
IN PLOGON pUserLogon
);
NTSTATUS
BeginLogin(
IN PIRP_CONTEXT pIrpContext,
IN DWORD userId,
OUT DWORD *loginId,
OUT DWORD *challenge
);
NTSTATUS
FinishLogin(
IN PIRP_CONTEXT pIrpContext,
IN DWORD dwUserOID,
IN DWORD dwLoginFlags,
IN BYTE pbEncryptedChallenge[16],
IN BYTE *pbServerPublicBsafeKey,
IN int cbServerPublicBsafeKeyLen,
OUT BYTE *pbUserEncPrivateNdsKey,
OUT int *pcbUserEncPrivateNdsKeyLen,
OUT DWORD *pdwCredentialStartTime,
OUT DWORD *pdwCredentialEndTime
);
NTSTATUS
NdsServerAuthenticate(
IN PIRP_CONTEXT pIrpContext,
IN PNDS_SECURITY_CONTEXT pNdsContext
);
NTSTATUS BeginAuthenticate(
IN PIRP_CONTEXT pIrpContext,
IN DWORD dwUserId,
OUT DWORD *pdwSvrRandom
);
NTSTATUS
NdsLicenseConnection(
PIRP_CONTEXT pIrpContext
);
NTSTATUS
NdsUnlicenseConnection(
PIRP_CONTEXT pIrpContext
);
NTSTATUS
NdsLogoff(
IN PIRP_CONTEXT pIrpContext
);
//
// Prototypes from fragex.c
//
NTSTATUS
FragExWithWait(
IN PIRP_CONTEXT pIrpContext,
IN DWORD NdsVerb,
IN PLOCKED_BUFFER pReplyBuffer,
IN BYTE *NdsRequestStr,
...
);
int
_cdecl
FormatBuf(
char *buf,
int bufLen,
const char *format,
va_list args
);
int
_cdecl
FormatBufS(
char *buf,
int bufLen,
const char *format,
...
);
//
// Prototypes from ndsfsctl.c
//
NTSTATUS
NdsCreateTreeScb(
IN PIRP_CONTEXT pIrpContext,
IN OUT PSCB *ppScb,
IN PUNICODE_STRING puTree,
IN PUNICODE_STRING puUserName,
IN PUNICODE_STRING puPassword,
IN BOOLEAN DeferredLogon,
IN BOOLEAN DeleteOnClose
);
NTSTATUS
NdsLookupServerName(
PSCB pTreeScb,
PIRP_CONTEXT pIrpContext,
IPXaddress *pDirServerAddress,
POEM_STRING pOemServerServerName
);
NTSTATUS
DispatchNds(
IN ULONG IoctlCode,
IN PIRP_CONTEXT IrpContext
);
NTSTATUS
PrepareLockedBufferFromFsd(
PIRP_CONTEXT pIrpContext,
PLOCKED_BUFFER pLockedBuffer
);
NTSTATUS
DoBrowseFsctl( PIRP_CONTEXT pIrpContext,
ULONG IoctlCode,
BOOL LockdownBuffer
);
NTSTATUS
ConnectBinderyVolume(
PIRP_CONTEXT pIrpContext,
PUNICODE_STRING puServerName,
PUNICODE_STRING puVolumeName
);
NTSTATUS
HandleVolumeAttach(
PIRP_CONTEXT pIrpContext,
PUNICODE_STRING puServerName,
PUNICODE_STRING puVolumeName
);
NTSTATUS
NdsGetDsObjectFromPath(
IN PIRP_CONTEXT pIrpContext,
OUT PUNICODE_STRING puDsObject
);
#define NDS_OBJECTTYPE_VOLUME 1
#define NDS_OBJECTTYPE_QUEUE 2
#define NDS_OBJECTTYPE_DIRMAP 3
NTSTATUS
NdsVerifyObject(
IN PIRP_CONTEXT pIrpContext,
IN PUNICODE_STRING puVolumeObject,
IN BOOLEAN fAllowServerJump,
IN DWORD dwResolverFlags,
OUT PDWORD pdwVolumeOid,
OUT PDWORD pdwObjectType
);
NTSTATUS
NdsMapObjectToServerShare(
PIRP_CONTEXT pIrpContext,
PSCB *ppScb,
PUNICODE_STRING puServerSharePath,
BOOLEAN CreateTreeConnection,
PDWORD pdwObjectId
);
NTSTATUS
NdsVerifyContext(
PIRP_CONTEXT pIrpContext,
PUNICODE_STRING puTree,
PUNICODE_STRING puContext
);
NTSTATUS
NdsRawFragex(
PIRP_CONTEXT pIrpContext
);
NTSTATUS
NdsChangePass(
PIRP_CONTEXT pIrpContext
);
NTSTATUS
NdsListTrees(
PIRP_CONTEXT pIrpContext
);
//
// Browsing prototypes from ndsread.c
//
NTSTATUS
NdsGetServerBasicName(
IN PUNICODE_STRING pServerX500Name,
IN OUT PUNICODE_STRING pServerName
);
NTSTATUS
NdsCheckGroupMembership(
PIRP_CONTEXT pIrpContext,
DWORD dwUserOid,
PUNICODE_STRING puGroupName
);
NTSTATUS
NdsResolveName(
IN PIRP_CONTEXT pIrpContext,
IN PNWR_NDS_REQUEST_PACKET pNdsRequest,
IN ULONG RequestLength,
IN PLOCKED_BUFFER pLockedBuffer
);
NTSTATUS
NdsGetObjectInfo(
IN PIRP_CONTEXT pIrpContext,
IN PNWR_NDS_REQUEST_PACKET pNdsRequest,
IN PLOCKED_BUFFER pLockedBuffer
);
NTSTATUS
NdsListSubordinates(
IN PIRP_CONTEXT pIrpContext,
IN PNWR_NDS_REQUEST_PACKET pNdsRequest,
IN PLOCKED_BUFFER pLockedBuffer
);
NTSTATUS
NdsReadAttributes(
PIRP_CONTEXT pIrpContext,
PNWR_NDS_REQUEST_PACKET pNdsRequest,
ULONG RequestLength,
PLOCKED_BUFFER pLockedBuffer
);
NTSTATUS
NdsReadAttributesKm(
PIRP_CONTEXT pIrpContext,
DWORD dwObjectId,
PUNICODE_STRING puAttribute,
PLOCKED_BUFFER pLockedBuffer
);
NTSTATUS
NdsOpenStream(
PIRP_CONTEXT pIrpContext,
PNWR_NDS_REQUEST_PACKET pNdsRequest,
ULONG RequestLength
);
NTSTATUS
NdsSetContext(
PIRP_CONTEXT pIrpContext,
PNWR_NDS_REQUEST_PACKET pNdsRequest,
ULONG RequestLength
);
NTSTATUS
NdsGetContext(
PIRP_CONTEXT pIrpContext,
PNWR_NDS_REQUEST_PACKET pNdsRequest,
ULONG RequestLength
);
NTSTATUS
NdsVerifyTreeHandle(
PIRP_CONTEXT pIrpContext,
PNWR_NDS_REQUEST_PACKET pNdsRequest,
ULONG RequestLength
);
NTSTATUS
NdsGetPrintQueueInfo(
PIRP_CONTEXT pIrpContext,
PNWR_NDS_REQUEST_PACKET pNdsRequest,
ULONG RequestLength
);
NTSTATUS
NdsGetVolumeInformation(
PIRP_CONTEXT pIrpContext,
PNWR_NDS_REQUEST_PACKET pNdsRequest,
ULONG RequestLength
);
//
// Kernel mode browsing prototypes from ndsread.c
//
NTSTATUS
NdsResolveNameKm (
PIRP_CONTEXT pIrpContext,
IN PUNICODE_STRING puObjectName,
OUT DWORD *dwObjectId,
BOOLEAN AllowDsJump,
DWORD dwFlags
);
NTSTATUS
NdsReadStringAttribute(
PIRP_CONTEXT pIrpContext,
IN DWORD dwObjectId,
IN PUNICODE_STRING puAttributeName,
OUT PUNICODE_STRING puAttributeVal
);
NTSTATUS
NdsGetServerName(
IN PIRP_CONTEXT pIrpContext,
OUT PUNICODE_STRING pUnicodeString
);
NTSTATUS
NdsGetUserName(
IN PIRP_CONTEXT pIrpContext,
IN DWORD dwUserOid,
OUT PUNICODE_STRING puUserName
);
//
// Other helper prototypes from ndsread.c
//
VOID
FreeNdsContext(
PNDS_SECURITY_CONTEXT pNdsContext
);
VOID
NdsPing(
IN PIRP_CONTEXT pIrpContext,
IN PSCB pScb
);
NTSTATUS
NdsSelectConnection(
PIRP_CONTEXT pIrpContext,
PUNICODE_STRING puTreeName,
PUNICODE_STRING puUserName,
PUNICODE_STRING puPassword,
BOOL DeferredLogon,
BOOL UseBinderyConnections,
PNONPAGED_SCB *ppNpScb
);
NTSTATUS
NdsCompletionCodetoNtStatus(
IN PLOCKED_BUFFER pLockedBuffer
);
NTSTATUS
NdsReadPublicKey(
IN PIRP_CONTEXT pIrpContext,
IN DWORD entryId,
OUT BYTE *pPubKeyVal,
IN DWORD *pPubKeyLen
);
int
NdsGetBsafeKey(
UCHAR *pPubKey,
const int pubKeyLen,
UCHAR **ppBsafeKey
);
NTSTATUS
NdsAllocateLockedBuffer(
PLOCKED_BUFFER NdsRequest,
DWORD BufferSize
);
NTSTATUS
NdsFreeLockedBuffer(
PLOCKED_BUFFER NdsRequest
);