/*++ 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 #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 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 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 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 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; // // 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]; // // 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; // // 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) \ ExAcquireResourceExclusive( &((pLogon)->CredentialListResource), TRUE ) #define NwAcquireSharedCredList( pLogon ) \ ExAcquireResourceShared( &((pLogon)->CredentialListResource), TRUE ) #define NwReleaseCredList( pLogon ) \ ExReleaseResource( &((pLogon)->CredentialListResource) ) #include typedef struct { DWORD verb; UINT count; char *bufEnd; PVOID nextItem; } NDS_TAG, *PNDS_TAG; #include 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 PUNICODE_STRING puTreeName, IN PLOGON pLogon, OUT PNDS_SECURITY_CONTEXT *ppCredentials, DWORD dwDesiredAccess, BOOLEAN fCreate ); 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 ); 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 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, 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 ); NTSTATUS NdsSetContext( PIRP_CONTEXT pIrpContext, PNWR_NDS_REQUEST_PACKET pNdsRequest ); NTSTATUS NdsGetContext( PIRP_CONTEXT pIrpContext, PNWR_NDS_REQUEST_PACKET pNdsRequest ); NTSTATUS NdsVerifyTreeHandle( PIRP_CONTEXT pIrpContext, PNWR_NDS_REQUEST_PACKET pNdsRequest ); NTSTATUS NdsGetPrintQueueInfo( PIRP_CONTEXT pIrpContext, PNWR_NDS_REQUEST_PACKET pNdsRequest ); NTSTATUS NdsGetVolumeInformation( PIRP_CONTEXT pIrpContext, PNWR_NDS_REQUEST_PACKET pNdsRequest ); // // 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 );