/*++ Copyright (c) 1996 Microsoft Corporation Module Name: rdns.hxx Abstract: Reverse DNS service Author: Philippe Choquier (phillich) 5-june-1996 --*/ #if !defined(_RDNS_INCLUDE) #define _RDNS_INCLUDE typedef LPVOID DNSARG; typedef void (*DNSFUNC)( DNSARG, BOOL, LPSTR ); #define RDNS_REQUEST_TYPE_IP2DNS 0 #define RDNS_REQUEST_TYPE_DNS2IP 1 #define SIZEOF_IP_ADDRESS (4) typedef struct _DNSFUNCDESC { DWORD dwRequestType; DNSFUNC pFunc; } DNSFUNCDESC, *PDNSFUNCDESC; extern BOOL InitRDns(); extern void TerminateRDns(); BOOL AsyncHostByAddr( PDNSFUNCDESC pFunc, // will store DNS name, post dummy completion status // if NULL ( or g_cMaxThreadLimit==0 ) then sync request DNSARG pArg, // ptr to be passed to FUNC struct sockaddr *pHostAddr, BOOL *pfSync, // updated with TRUE if sync call LPSTR pName, DWORD dwMaxNameLen ); BOOL AsyncAddrByHost( PDNSFUNCDESC pFunc, // will store DNS name, post dummy completion status // if NULL ( or g_cMaxThreadLimit==0 ) then sync request DNSARG pArg, // ptr to be passed to FUNC struct sockaddr *pHostAddr, BOOL *pfSync, // updated with TRUE if sync call LPSTR pName ); BOOL FireUpNewThread( PDNSFUNCDESC pFunc, DNSARG pArg, LPVOID pOvr ); #define XAR_GRAIN 256 // // extensible array class // class XAR { public: XAR() { m_fDidAlloc = FALSE; m_pAlloc = NULL; m_cAlloc = m_cUsed = 0; } ~XAR() { if ( m_fDidAlloc ) LocalFree( m_pAlloc ); } BOOL Init( LPBYTE p=NULL, DWORD c=0) { m_fDidAlloc = FALSE; m_pAlloc = p; m_cAlloc = m_cUsed = c; return TRUE; } VOID Terminate() { if ( m_fDidAlloc ) { LocalFree( m_pAlloc ); } m_fDidAlloc = FALSE; m_pAlloc = NULL; m_cAlloc = m_cUsed = 0; } BOOL Resize( DWORD dwDelta ); DWORD GetUsed() { return m_cUsed; } VOID SetUsed( DWORD c ) { m_cUsed = c; } VOID AdjustUsed( int c ) { m_cUsed += (DWORD)c; } LPBYTE GetAlloc() { return m_pAlloc; } private: LPBYTE m_pAlloc; DWORD m_cAlloc; DWORD m_cUsed; BOOL m_fDidAlloc; } ; // // This type defines a relocatable index inside a dynamic array. // to allow easy fixups when part of the array is to be extended/shrinked // index are identified by setting bit 31 to 1. Other DWORD in the reference // part of the array are assumed to have bit 31 set to 0. // The size of the reference part of the array is defined by cRefSize // typedef DWORD SELFREFINDEX; // combine array base address with SELFREFINDEX #define MAKEPTR(a,b) ((LPBYTE)(a)+((b)&0x7fffffff)) // build a SELFREFINDEX from an offset in array #define MAKEREF(a) ((a)|0x80000000) // build an offset from a SELFREFINDEX #define MAKEOFFSET(a) ((a)&0x7fffffff) // // ADDRESS_CHECK_LIST Flags. bit31 must not be used. // #define RDNS_FLAG_DODNS2IPCHECK 0x00000001 // uses non-standard extension : zero-sized array in struct #pragma warning(disable:4200) // array header typedef struct _ADDRESS_CHECK_LIST { SELFREFINDEX iDenyAddr; // address deny list // points to ADDRESS_HEADER SELFREFINDEX iGrantAddr; // address grant list // points to ADDRESS_HEADER SELFREFINDEX iDenyName; // DNS name deny list // points to NAME_HEADER SELFREFINDEX iGrantName; // DNS name grant list // points to NAME_HEADER DWORD dwFlags; DWORD cRefSize; // size of reference area ( in bytes ) } ADDRESS_CHECK_LIST, *PADDRESS_CHECK_LIST; typedef struct _ADDRESS_LIST_ENTRY { DWORD iFamily; DWORD cAddresses; DWORD cFullBytes; DWORD LastByte; SELFREFINDEX iFirstAddress; // points to array of addresses // which size are derived from iFamily } ADDRESS_LIST_ENTRY, *PADDRESS_LIST_ENTRY; typedef struct _ADDRESS_HEADER { DWORD cEntries; // # of Entries[] DWORD cAddresses; // total # of addresses in all // ADDRESS_LIST_ENTRY ADDRESS_LIST_ENTRY Entries[]; } ADDRESS_HEADER, *PADDRESS_HEADER ; typedef struct _NAME_LIST_ENTRY { DWORD cComponents; // # of DNS components DWORD cNames; SELFREFINDEX iName[]; // array of references to DNS names } NAME_LIST_ENTRY, *PNAME_LIST_ENTRY; typedef struct _NAME_HEADER { DWORD cEntries; DWORD cNames; // total # of names for all Entries[] //NAME_LIST_ENTRY Entries[0]; // array of name classes } NAME_HEADER, *PNAME_HEADER ; typedef struct ADDRCMPDESC { LPBYTE pMask; UINT cFullBytes; UINT LastByte; UINT cSizeAddress; } ADDRCMPDESC, *PADDRCMPDESC; typedef struct NAMECMPDESC { LPVOID pName; LPBYTE pBase; } NAMECMPDESC, *PNAMECMPDESC; typedef LPVOID ADDRCHECKARG; typedef void (*ADDRCHECKFUNC)(ADDRCHECKARG, BOOL ); typedef void (*ADDRCHECKFUNCEX)(ADDRCHECKARG, BOOL, LPSTR ); typedef int (__cdecl *CMPFUNC)(const void*, const void*, LPVOID); #define SIZE_FAST_REVERSE_DNS 128 enum AC_RESULT { AC_NOT_CHECKED, AC_IN_DENY_LIST, AC_NOT_IN_DENY_LIST, // deny list present but not in deny list AC_IN_GRANT_LIST, AC_NOT_IN_GRANT_LIST, // grant list present but not in grant list AC_NO_LIST } ; #define DNSLIST_FLAG_NOSUBDOMAIN 0x80000000 #define DNSLIST_FLAGS 0x80000000 // bitmask of all flags class ADDRESS_CHECK { public: ADDRESS_CHECK() { m_pszDnsName = NULL; m_fDnsResolved = FALSE; } ~ADDRESS_CHECK() { if ( m_pszDnsName != NULL ) { LocalFree( m_pszDnsName ); m_pszDnsName = NULL; } } // BOOL BindCheckList( LPBYTE p = NULL, DWORD c = 0 ); VOID UnbindCheckList() { m_Storage.Terminate(); } BOOL BindAddr( struct sockaddr* pAddr ) { m_pAddr = pAddr; m_fDnsResolved = FALSE; m_fIpResolved = FALSE; m_dwErrorResolving = 0; return TRUE; } VOID UnbindAddr() { m_pAddr = NULL; m_fDnsResolved = FALSE; } XAR* GetStorage() { return &m_Storage; } AC_RESULT CheckAccess( LPBOOL pfSync, ADDRCHECKFUNC pFunc, ADDRCHECKARG pArg ); // void AdjustRefs( LPBYTE, DWORD dwCut, DWORD dwAdj ); // UINT GetAddrSize( DWORD ); VOID MakeAcd( PADDRCMPDESC pacd, LPBYTE pMask, UINT cLen ); // for UI, addr BOOL AddAddr( BOOL fGrant, DWORD dwFamily, LPBYTE pMask, LPBYTE pAddr ); BOOL DeleteAddr( BOOL fGrant, DWORD iIndex ); BOOL GetAddr( BOOL fGrant, DWORD iIndex, LPDWORD pdwFamily, LPBYTE* pMask, LPBYTE* pAddr ); DWORD GetNbAddr( BOOL fGrant ); BOOL LocateAddr( BOOL fGrant, DWORD iIndex, PADDRESS_HEADER* ppHd, PADDRESS_LIST_ENTRY* pHeader, LPDWORD iIndexInHeader ); BOOL DeleteAllAddr( BOOL fGrant ); BOOL SetFlag( DWORD dwFlag, BOOL fEnable ); DWORD GetFlags(); // test all mask for this family, do bsearch on each BOOL IsMatchAddr( BOOL fGrant, DWORD dwFamily, LPBYTE pAddr ); AC_RESULT CheckAddress( struct sockaddr* pAddr ); BOOL QueryDnsName( LPBOOL pfSync, ADDRCHECKFUNCEX pFunc, ADDRCHECKARG pArg, LPSTR * ppName ); AC_RESULT CheckIpAccess( LPBOOL pfNeedDns); AC_RESULT CheckDnsAccess() { return CheckName( m_pszDnsName ); } BOOL IsDnsResolved() { return m_fDnsResolved; } LPSTR QueryResolvedDnsName() { return m_pszDnsName; } DWORD QueryErrorResolving() { return m_dwErrorResolving; } // for UI, name BOOL AddName( BOOL fGrant, LPSTR pName, DWORD dwFlags = 0 ); BOOL AddReversedName( BOOL fGrant, LPSTR pName ); BOOL DeleteName( BOOL fGrant, DWORD iIndex ); BOOL GetName( BOOL fGrant, DWORD iIndex, LPSTR* ppName, LPDWORD pdwFlags = NULL ); BOOL GetReversedName( BOOL fGrant, DWORD iIndex, LPSTR pName, LPDWORD pdwSize ); DWORD GetNbName( BOOL fGrant ); BOOL LocateName( BOOL fGrant, DWORD iIndex, PNAME_HEADER* ppHd, PNAME_LIST_ENTRY* pHeader, LPDWORD iIndexInHeader ); BOOL DeleteAllName( BOOL fGrant ); DWORD QueryCheckListSize() { return m_Storage.GetUsed(); } LPBYTE QueryCheckListPtr() { return m_Storage.GetAlloc(); } UINT GetNbComponent( LPSTR pName ); // test all classes, do bsearch on each BOOL IsMatchName( BOOL fGrant, LPSTR pName ); BOOL CheckReversedName( LPSTR pName ); // synchronous version AC_RESULT CheckName( LPSTR pName ); // synchronous version LPSTR InitReverse( LPSTR pR, LPSTR pTarget, LPBOOL pfAlloc ); VOID TerminateReverse( LPSTR, BOOL ); VOID AddrCheckDnsCallBack( BOOL fSt, LPSTR pDns ); VOID AddrCheckDnsCallBack2( BOOL fSt, struct sockaddr* pAddr ); VOID AddrCheckDnsCallBack3( BOOL fSt, struct sockaddr* pAddr ); VOID ResolveDnsCallBack( BOOL fSt, LPSTR pDns ); #if DBG VOID DumpAddrAndName( VOID ); VOID DumpAddr( BOOL ); VOID DumpName( BOOL ); #endif private: XAR m_Storage; struct sockaddr * m_pAddr; struct sockaddr m_ResolvedAddr; LPSTR m_pszDnsName; BOOL m_fDnsResolved; BOOL m_fIpResolved; DWORD m_dwErrorResolving; ADDRCHECKFUNC m_HttpReqCallback; ADDRCHECKFUNCEX m_HttpReqCallbackEx; ADDRCHECKARG m_HttpReqParam; } ; typedef struct _SID_CACHE_ENTRY { DWORD tExpire; // now + TTL DWORD dwSidLen; BYTE Sid[0]; } SID_CACHE_ENTRY, *PSID_CACHE_ENTRY; class CSidCache { public: CSidCache() {} ~CSidCache() {} // BOOL Init(); VOID Terminate(); // BOOL AddToCache( PSID, DWORD dwTTL ); // TTL in seconds BOOL IsInCache( PSID ); BOOL CheckPresentAndResetTtl( PSID, DWORD ); // BOOL Scavenger(); private: XAR xaStore; // buffer of SID_CACHE_ENTRY CRITICAL_SECTION csLock; } ; // // PEN : Password Expiration Notification API // extern CSidCache g_scPen; BOOL PenAddToCache( PSID, DWORD ); BOOL PenIsInCache( PSID ); BOOL PenCheckPresentAndResetTtl( PSID, DWORD ); #define PEN_TTL (10*60) // in seconds #if DBG extern VOID TestAPI(); #endif #if defined(_RDNS_STANDALONE) typedef VOID (* PFN_SCHED_CALLBACK)( VOID * pContext ); DWORD ScheduleWorkItem( PFN_SCHED_CALLBACK pfnCallback, PVOID pContext, DWORD msecTimeInterval, BOOL fPeriodic = FALSE ) { return 0; } BOOL RemoveWorkItem( DWORD pdwCookie ) { return FALSE; } #endif #endif