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.
927 lines
31 KiB
927 lines
31 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 2000
|
|
//
|
|
// File: querybld.cpp
|
|
//
|
|
// Contents: Contains implementatin of functions to build query.
|
|
//
|
|
// History: 24-Sep-2000 Hiteshr Created
|
|
//
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
|
|
#include "pch.h"
|
|
#include "cstrings.h"
|
|
#include "querytable.h"
|
|
#include "usage.h"
|
|
#include "querybld.h"
|
|
#include "resource.h" // For IDS_MSG_INVALID_ACCT_ERROR
|
|
#include <lmaccess.h> // UF_ACCOUNTDISABLE and UF_DONT_EXPIRE_PASSWD
|
|
#include <ntldap.h> // LDAP_MATCHING_RULE_BIT_AND_W
|
|
#include <Sddl.h> // For ConvertSidToStringSid
|
|
|
|
static const LPWSTR g_szUserAccountCtrlQuery = L"(userAccountControl:" LDAP_MATCHING_RULE_BIT_AND_W L":=%u)";
|
|
static const LPWSTR g_szServerIsGCQuery = L"(&(objectCategory=NTDS-DSA)(options:" LDAP_MATCHING_RULE_BIT_AND_W L":=1))";
|
|
|
|
|
|
static const LPWSTR g_szCommonQueryFormat= L"(%s=%s)";
|
|
|
|
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: LdapEscape
|
|
//
|
|
// Synopsis: Escape the characters in *[pszInput] as required by
|
|
// RFC 2254.
|
|
//
|
|
// Arguments: [pszInput] - string to escape
|
|
//
|
|
// History: 06-23-2000 DavidMun Created
|
|
//
|
|
// Notes: RFC 2254
|
|
//
|
|
// If a value should contain any of the following characters
|
|
//
|
|
// Character ASCII value
|
|
// ---------------------------
|
|
// * 0x2a
|
|
// ( 0x28
|
|
// ) 0x29
|
|
// \ 0x5c
|
|
// NUL 0x00
|
|
//
|
|
// the character must be encoded as the backslash '\'
|
|
// character (ASCII 0x5c) followed by the two hexadecimal
|
|
// digits representing the ASCII value of the encoded
|
|
// character. The case of the two hexadecimal digits is not
|
|
// significant.
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool
|
|
LdapEscape(IN LPCWSTR pszInput, OUT CComBSTR& strFilter)
|
|
{
|
|
if(!pszInput)
|
|
return FALSE;
|
|
|
|
|
|
//Security Review:pszInput is null terminated.
|
|
int iLen = (int)wcslen(pszInput);
|
|
|
|
for( int i = 0; i < iLen; ++i)
|
|
{
|
|
switch (*(pszInput+i))
|
|
{
|
|
case L'(':
|
|
strFilter += L"\\28";
|
|
break;
|
|
|
|
case L')':
|
|
strFilter += L"\\29";
|
|
break;
|
|
|
|
case L'\\':
|
|
if( i + 1 < iLen )
|
|
{
|
|
// \\ is treated as '\'
|
|
switch (*(pszInput+i + 1))
|
|
{
|
|
case L'\\':
|
|
strFilter += L"\\5c";
|
|
i++;
|
|
break;
|
|
// \* is treated as '*'
|
|
case L'*':
|
|
strFilter += L"\\2a";
|
|
i++;
|
|
break;
|
|
default:
|
|
// \X is treated \X only
|
|
strFilter += L"\\5c";
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
strFilter += L"\\5c";
|
|
|
|
break;
|
|
|
|
default:
|
|
strFilter.Append(pszInput+i,1);
|
|
break;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
HRESULT MakeQuery(IN LPCWSTR pszAttrName,
|
|
IN LPCWSTR pszCommandLineFilter,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, MakeQuery, hr);
|
|
|
|
if(!pszAttrName || !pszCommandLineFilter)
|
|
{
|
|
ASSERT(FALSE);
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
CComBSTR strEscapedCLFilter;
|
|
LdapEscape(pszCommandLineFilter,strEscapedCLFilter);
|
|
|
|
strFilter = L"(";
|
|
strFilter += pszAttrName;
|
|
strFilter += L"=";
|
|
strFilter += strEscapedCLFilter;
|
|
strFilter += L")";
|
|
return hr;
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: CommonFilterFunc
|
|
//
|
|
// Synopsis: This function takes the input filter from the commandline
|
|
// and converts it into ldapfilter.
|
|
// For ex -user (ab* | bc*) is converted to |(cn=ab*)(cn=bc*)
|
|
// The pEntry->pszName given the attribute name to use in
|
|
// filter( cn in above example).
|
|
//
|
|
// Arguments: [pRecord - IN] : the command line argument structure used
|
|
// to retrieve the filter entered by user
|
|
// [pObjectEntry - IN] : pointer to the DSQUERY_ATTR_TABLE_ENTRY
|
|
// which has info on attribute corresponding
|
|
// switch in pRecord
|
|
// [pVoid - IN] :Not used.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
// E_INVALIDARG if the object entry wasn't found
|
|
// Anything else is a failure code from an ADSI call
|
|
//
|
|
// History: 25-Sep-2000 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT CommonFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *pEntry,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& /*refBasePathsInfo*/,
|
|
IN CDSCmdCredentialObject& /*refCredentialObject*/,
|
|
IN PVOID ,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, CommonFilterFunc, hr);
|
|
|
|
//validate input
|
|
if( !pEntry || !pRecord
|
|
//validate DSQUERY_ATTR_TABLE_ENTRY entry
|
|
|| !pEntry->pszName || !pEntry->nAttributeID
|
|
//validate pRecord
|
|
|| !pRecord->bDefined || !pRecord->strValue)
|
|
{
|
|
ASSERT(FALSE);
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
//Make Query
|
|
hr = MakeQuery(pEntry->pszName,
|
|
pRecord->strValue,
|
|
strFilter);
|
|
|
|
DEBUG_OUTPUT(LEVEL3_LOGGING, L"filter = %s", strFilter);
|
|
return hr;
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: StarFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for dsquery *. It returns the value of
|
|
// -filter flag.
|
|
//
|
|
// Arguments: [pRecord - IN] : the command line argument structure used
|
|
// to retrieve the filter entered by user
|
|
// [pObjectEntry - IN] : pointer to the DSQUERY_ATTR_TABLE_ENTRY
|
|
// which has info on attribute corresponding
|
|
// switch in pRecord
|
|
// [pVoid - IN] :Not used.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
// E_INVALIDARG if the object entry wasn't found
|
|
// Anything else is a failure code from an ADSI call
|
|
//
|
|
// History: 25-Sep-2000 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT StarFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *pEntry,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& /*refBasePathsInfo*/,
|
|
IN CDSCmdCredentialObject& /*refCredentialObject*/,
|
|
IN PVOID ,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, StarFilterFunc, hr);
|
|
|
|
//validate input
|
|
if(!pEntry || !pRecord
|
|
//validate DSQUERY_ATTR_TABLE_ENTRY entry
|
|
|| !pEntry->nAttributeID
|
|
//validate pRecord
|
|
|| !pRecord->bDefined || !pRecord->strValue)
|
|
{
|
|
ASSERT(FALSE);
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
strFilter = pRecord->strValue;
|
|
DEBUG_OUTPUT(LEVEL3_LOGGING, L"filter = %s", strFilter);
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: InactiveComputerFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for computer inactive query.
|
|
//
|
|
// Arguments: [pRecord - IN] : Not Used
|
|
// [pObjectEntry - IN] : Not Used
|
|
// [pVoid - IN] :Not used.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
// E_INVALIDARG if the object entry wasn't found
|
|
// Anything else is a failure code from an ADSI call
|
|
//
|
|
// History: 06-05-2002 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT InactiveComputerFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *pEntry,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& refBasePathsInfo,
|
|
IN CDSCmdCredentialObject& refCredentialObject,
|
|
IN PVOID pData,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
return InactiveFilterFunc(pEntry,
|
|
pRecord,
|
|
refBasePathsInfo,
|
|
refCredentialObject,
|
|
pData,
|
|
strFilter,
|
|
true);
|
|
}
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: InactiveUserFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for user inactive query.
|
|
//
|
|
// Arguments: [pRecord - IN] : Not Used
|
|
// [pObjectEntry - IN] : Not Used
|
|
// [pVoid - IN] :Not used.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
// E_INVALIDARG if the object entry wasn't found
|
|
// Anything else is a failure code from an ADSI call
|
|
//
|
|
// History: 25-Sep-2000 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT InactiveUserFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *pEntry,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& refBasePathsInfo,
|
|
IN CDSCmdCredentialObject& refCredentialObject,
|
|
IN PVOID pData,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
return InactiveFilterFunc(pEntry,
|
|
pRecord,
|
|
refBasePathsInfo,
|
|
refCredentialObject,
|
|
pData,
|
|
strFilter,
|
|
false);
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: InactiveFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for account inactive query.
|
|
//
|
|
// Arguments: [pRecord - IN] : Not Used
|
|
// [pObjectEntry - IN] : Not Used
|
|
// [pVoid - IN] :Not used.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// [bComputer]: if true query is for inactive computer accounts
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
// E_INVALIDARG if the object entry wasn't found
|
|
// Anything else is a failure code from an ADSI call
|
|
//
|
|
// History: 25-Sep-2000 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT InactiveFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *pEntry,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& /*refBasePathsInfo*/,
|
|
IN CDSCmdCredentialObject& /*refCredentialObject*/,
|
|
IN PVOID ,
|
|
OUT CComBSTR& strFilter,
|
|
IN bool bComputer)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, InactiveFilterFunc, hr);
|
|
|
|
if( !pEntry || !pRecord || !pRecord->bDefined )
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
if(pRecord->nValue < 0 )
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
//Unit at commandline is Week
|
|
//
|
|
int nDays = pRecord->nValue * 7;
|
|
|
|
FILETIME ftCurrent;
|
|
::GetSystemTimeAsFileTime(&ftCurrent);
|
|
|
|
LARGE_INTEGER li;
|
|
li.LowPart = ftCurrent.dwLowDateTime;
|
|
li.HighPart = ftCurrent.dwHighDateTime;
|
|
|
|
//
|
|
//Get the number of days since the reference time
|
|
//
|
|
int nDaysSince1600 = (int)(li.QuadPart/(((LONGLONG) (24 * 60) * 60) * 10000000));
|
|
|
|
if(nDaysSince1600 < nDays)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
li.QuadPart -= ((((LONGLONG)nDays * 24) * 60) * 60) * 10000000;
|
|
|
|
CComBSTR strTime;
|
|
litow(li, strTime);
|
|
WCHAR buffer[256];
|
|
//Security Review:Replace with strsafe api
|
|
//NTRAID#NTBUG9-573989-2002/03/12-hiteshr
|
|
if(bComputer)
|
|
{
|
|
//NTRAID#NTBUG9-616892-2002/06/05-hiteshr
|
|
//Cluster creates some virtual computers which never update password or login and
|
|
//these accounts should not be displayed by dsquery computer -[inactive|stalepwd]
|
|
hr = StringCchPrintf(buffer,256,L"(!(serviceprincipalname=msclustervirtualserver/*))(lastLogonTimestamp<=%s)",(LPCWSTR)strTime);
|
|
}
|
|
else
|
|
{
|
|
hr = StringCchPrintf(buffer,256,L"(lastLogonTimestamp<=%s)",(LPCWSTR)strTime);
|
|
}
|
|
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
strFilter = buffer;
|
|
DEBUG_OUTPUT(LEVEL3_LOGGING, L"filter = %s", strFilter);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: StalepwdComputerFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for Stale Computer Password query.
|
|
//
|
|
// Arguments: [pRecord - IN] : Not Used
|
|
// [pObjectEntry - IN] : Not Used
|
|
// [pVoid - IN] :Not used.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
// E_INVALIDARG if the object entry wasn't found
|
|
// Anything else is a failure code from an ADSI call
|
|
//
|
|
// History: 25-Sep-2000 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT StalepwdComputerFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *pEntry,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& refBasePathsInfo,
|
|
IN CDSCmdCredentialObject& refCredentialObject,
|
|
IN PVOID pData,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
return StalepwdFilterFunc(pEntry,
|
|
pRecord,
|
|
refBasePathsInfo,
|
|
refCredentialObject,
|
|
pData,
|
|
strFilter,
|
|
true);
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: StalepwdUserFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for Stale User Password query.
|
|
//
|
|
// Arguments: [pRecord - IN] : Not Used
|
|
// [pObjectEntry - IN] : Not Used
|
|
// [pVoid - IN] :Not used.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
// E_INVALIDARG if the object entry wasn't found
|
|
// Anything else is a failure code from an ADSI call
|
|
//
|
|
// History: 25-Sep-2000 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT StalepwdUserFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *pEntry,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& refBasePathsInfo,
|
|
IN CDSCmdCredentialObject& refCredentialObject,
|
|
IN PVOID pData,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
return StalepwdFilterFunc(pEntry,
|
|
pRecord,
|
|
refBasePathsInfo,
|
|
refCredentialObject,
|
|
pData,
|
|
strFilter,
|
|
false);
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: StalepwdFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for Stale Password query.
|
|
//
|
|
// Arguments: [pRecord - IN] : Not Used
|
|
// [pObjectEntry - IN] : Not Used
|
|
// [pVoid - IN] :Not used.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// [bComputer]: if true query is for inactive computer accounts
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
// E_INVALIDARG if the object entry wasn't found
|
|
// Anything else is a failure code from an ADSI call
|
|
//
|
|
// History: 25-Sep-2000 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT StalepwdFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *pEntry,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& /*refBasePathsInfo*/,
|
|
IN CDSCmdCredentialObject& /*refCredentialObject*/,
|
|
IN PVOID ,
|
|
OUT CComBSTR& strFilter,
|
|
bool bComputer)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, StalepwdFilterFunc, hr);
|
|
|
|
if( !pEntry || !pRecord || !pRecord->bDefined )
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
int nDays = pRecord->nValue;
|
|
|
|
if(nDays < 0)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
FILETIME ftCurrent;
|
|
::GetSystemTimeAsFileTime(&ftCurrent);
|
|
|
|
LARGE_INTEGER li;
|
|
li.LowPart = ftCurrent.dwLowDateTime;
|
|
li.HighPart = ftCurrent.dwHighDateTime;
|
|
//
|
|
//Get the number of days since the reference time
|
|
//
|
|
int nDaysSince1600 = (int)(li.QuadPart/(((LONGLONG) (24 * 60) * 60) * 10000000));
|
|
|
|
if(nDaysSince1600 < nDays)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
|
|
li.QuadPart -= ((((ULONGLONG)nDays * 24) * 60) * 60) * 10000000;
|
|
|
|
CComBSTR strTime;
|
|
litow(li, strTime);
|
|
WCHAR buffer[256];
|
|
//Security Review:Replace with strsafe api
|
|
//NTRAID#NTBUG9-573989-2002/03/12-hiteshr
|
|
if(bComputer)
|
|
{
|
|
//NTRAID#NTBUG9-616892-2002/06/05-hiteshr
|
|
//Cluster creates some virtual computers which never update password or login and
|
|
//these accounts should not be displayed by dsquery computer -[inactive|stalepwd]
|
|
hr = StringCchPrintf(buffer,256,L"(!(serviceprincipalname=msclustervirtualserver/*))(pwdLastSet<=%s)",(LPCWSTR)strTime);
|
|
}
|
|
else
|
|
{
|
|
hr = StringCchPrintf(buffer,256,L"(pwdLastSet<=%s)",(LPCWSTR)strTime);
|
|
}
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
strFilter = buffer;
|
|
DEBUG_OUTPUT(LEVEL3_LOGGING, L"filter = %s", strFilter);
|
|
}
|
|
return hr;
|
|
}
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: DisabledFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for account disabled query.
|
|
//
|
|
// Arguments: [pRecord - IN] : Not Used
|
|
// [pObjectEntry - IN] : Not Used
|
|
// [pVoid - IN] :Not used.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
// E_INVALIDARG if the object entry wasn't found
|
|
// Anything else is a failure code from an ADSI call
|
|
//
|
|
// History: 25-Sep-2000 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
HRESULT DisabledFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *,
|
|
IN ARG_RECORD* ,
|
|
IN CDSCmdBasePathsInfo& /*refBasePathsInfo*/,
|
|
IN CDSCmdCredentialObject& /*refCredentialObject*/,
|
|
IN PVOID ,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, DisabledFilterFunc, hr);
|
|
|
|
WCHAR buffer[256]; //This is long enough
|
|
|
|
//Security Review:Replace with strsafe api
|
|
//NTRAID#NTBUG9-573989-2002/03/12-hiteshr
|
|
hr = StringCchPrintf(buffer,256,g_szUserAccountCtrlQuery,UF_ACCOUNTDISABLE);
|
|
if(SUCCEEDED(hr))
|
|
{
|
|
strFilter = buffer;
|
|
|
|
DEBUG_OUTPUT(LEVEL3_LOGGING, L"filter = %s", strFilter);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: SubnetSiteFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for -site switch in dsquery subnet.
|
|
//
|
|
// Arguments: [pEntry - IN] : Not Used
|
|
// [pRecord - IN] : Command Line value supplied by user
|
|
// [pVoid - IN] : suffix for the siteobject attribute.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
//
|
|
// History: 24-April-2001 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT SubnetSiteFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& /*refBasePathsInfo*/,
|
|
IN CDSCmdCredentialObject& /*refCredentialObject*/,
|
|
IN PVOID pParam,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, InactiveFilterFunc, hr);
|
|
|
|
if( !pRecord || !pRecord->bDefined || !pParam)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
CComBSTR strEscapedCLFilter;
|
|
LdapEscape(pRecord->strValue,strEscapedCLFilter);
|
|
|
|
|
|
strFilter = L"(siteobject=cn=";
|
|
strFilter += strEscapedCLFilter;
|
|
strFilter += L",";
|
|
strFilter += *(static_cast<BSTR*>(pParam));
|
|
strFilter += L")";
|
|
return hr;
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: BuildQueryFilter
|
|
//
|
|
// Synopsis: This function builds the LDAP query filter for given object type.
|
|
//
|
|
// Arguments: [pCommandArgs - IN] :the command line argument structure used
|
|
// to retrieve the values of switches
|
|
// [pObjectEntry - IN] :Contains info about the object type
|
|
// [pParam -IN] :This value is passed to filter function.
|
|
// [strLDAPFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
// E_INVALIDARG if the object entry wasn't found
|
|
// Anything else is a failure code from an ADSI call
|
|
//
|
|
// History: 25-Sep-2000 hiteshr Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
HRESULT BuildQueryFilter(PARG_RECORD pCommandArgs,
|
|
PDSQueryObjectTableEntry pObjectEntry,
|
|
CDSCmdBasePathsInfo& refBasePathsInfo,
|
|
CDSCmdCredentialObject& refCredentialObject,
|
|
PVOID pParam,
|
|
CComBSTR& strLDAPFilter)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, BuildQueryFilter, hr);
|
|
|
|
if( !pCommandArgs || !pObjectEntry )
|
|
{
|
|
ASSERT(FALSE);
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
DSQUERY_ATTR_TABLE_ENTRY** pAttributeTable;
|
|
DWORD dwAttributeCount;
|
|
|
|
|
|
pAttributeTable = pObjectEntry->pAttributeTable;
|
|
dwAttributeCount = pObjectEntry->dwAttributeCount;
|
|
|
|
if( !pAttributeTable || !dwAttributeCount )
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
BOOL bUseDefaultFilter = TRUE;
|
|
CComBSTR strFilter;
|
|
for( UINT i = 0; i < dwAttributeCount; ++i )
|
|
{
|
|
if(pCommandArgs[pAttributeTable[i]->nAttributeID].bDefined)
|
|
{
|
|
bUseDefaultFilter = FALSE;
|
|
CComBSTR strLocalFilter;
|
|
hr = pAttributeTable[i]->pMakeFilterFunc(pAttributeTable[i],
|
|
pCommandArgs + pAttributeTable[i]->nAttributeID,
|
|
refBasePathsInfo,
|
|
refCredentialObject,
|
|
pParam,
|
|
strLocalFilter);
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
strFilter += strLocalFilter;
|
|
DEBUG_OUTPUT(FULL_LOGGING, L"Current filter = %s", strFilter);
|
|
}
|
|
}
|
|
//
|
|
//If none of the commandline filter switches are specified, use
|
|
//default filter
|
|
//
|
|
strLDAPFilter = L"(";
|
|
if(bUseDefaultFilter)
|
|
{
|
|
strLDAPFilter += pObjectEntry->pszDefaultFilter;
|
|
}
|
|
else
|
|
{
|
|
if(pObjectEntry->pszPrefixFilter)
|
|
{
|
|
strLDAPFilter += pObjectEntry->pszPrefixFilter;
|
|
strLDAPFilter += strFilter;
|
|
}
|
|
else
|
|
strLDAPFilter += strFilter;
|
|
}
|
|
strLDAPFilter += L")";
|
|
|
|
DEBUG_OUTPUT(LEVEL3_LOGGING, L"ldapfilter = %s", strLDAPFilter);
|
|
return hr;
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: QLimitFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for -qlimit switch in dsquery quota.
|
|
//
|
|
// Arguments: [pEntry - IN] : Not Used
|
|
// [pRecord - IN] : Command Line value supplied by user
|
|
// [pVoid - IN] : unused.
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
//
|
|
// History: 13-Aug-2002 ronmart Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT QLimitFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& /*refBasePathsInfo*/,
|
|
IN CDSCmdCredentialObject& /*refCredentialObject*/,
|
|
IN PVOID,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, QLimitFilterFunc, hr);
|
|
|
|
if( !pRecord || !pRecord->bDefined)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
// Build the quotaAmount string
|
|
strFilter = L"(msDS-QuotaAmount";
|
|
strFilter += pRecord->strValue;
|
|
strFilter += L")";
|
|
return hr;
|
|
}
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: AccountFilterFunc
|
|
//
|
|
// Synopsis: Filter Function for -acct switch in dsquery quota.
|
|
//
|
|
// Arguments: [pEntry - IN] : Not Used
|
|
// [pRecord - IN] : Command Line value supplied by user
|
|
// [pVoid - IN] : Not Used
|
|
// [strFilter - OUT] :Contains the output filter.
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
//
|
|
// History: 14-Aug-2002 ronmart Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT AccountFilterFunc(IN DSQUERY_ATTR_TABLE_ENTRY *,
|
|
IN ARG_RECORD* pRecord,
|
|
IN CDSCmdBasePathsInfo& refBasePathsInfo,
|
|
IN CDSCmdCredentialObject& refCredentialObject,
|
|
IN PVOID ,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, AccountFilterFunc, hr);
|
|
|
|
if( !pRecord || !pRecord->bDefined || !refBasePathsInfo.IsInitialized())
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
PWSTR* ppszArray = NULL; // Array of accts from param or STDIN
|
|
|
|
do // false loop
|
|
{
|
|
// Get the accts (trustees)
|
|
UINT nStrings = 0;
|
|
ParseNullSeparatedString(pRecord->strValue,
|
|
&ppszArray,
|
|
&nStrings);
|
|
if (nStrings < 1 ||
|
|
!ppszArray)
|
|
{
|
|
ASSERT(false); // This should never happen
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
// Or the return values together
|
|
strFilter = L"(|";
|
|
// Get a trustee query for each acct
|
|
for(UINT i = 0; i < nStrings; i++)
|
|
{
|
|
// Append (msDS-QuotaTrustee=<sid>) for this acct
|
|
// to the filter
|
|
hr = AddSingleAccountFilter(ppszArray[i], refBasePathsInfo,
|
|
refCredentialObject, strFilter);
|
|
if(FAILED(hr))
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
}
|
|
}
|
|
// Close the query string
|
|
strFilter += L")";
|
|
} while (false);
|
|
|
|
// Free the Acct array
|
|
if(ppszArray)
|
|
LocalFree(ppszArray);
|
|
|
|
// If we failed in the loop then clear out the filter string
|
|
if(FAILED(hr))
|
|
strFilter = L"";
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+--------------------------------------------------------------------------
|
|
//
|
|
// Function: AddSingleAccountFilter
|
|
//
|
|
// Synopsis: Appends an account string to strFilter for the specified user
|
|
//
|
|
// Arguments: [lpszUser - IN] : User whose sid string is requested
|
|
// [strFilter - OUT] : Contains the output filter to append to
|
|
// Returns: HRESULT : S_OK if everything succeeded
|
|
//
|
|
// History: 14-Aug-2002 ronmart Created
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
HRESULT AddSingleAccountFilter(IN LPCWSTR lpszUser,
|
|
IN CDSCmdBasePathsInfo& refBasePathsInfo,
|
|
IN CDSCmdCredentialObject& refCredentialObject,
|
|
OUT CComBSTR& strFilter)
|
|
{
|
|
ENTER_FUNCTION_HR(LEVEL3_LOGGING, AddSingleAccountFilter, hr);
|
|
|
|
if(!lpszUser)
|
|
{
|
|
hr = E_INVALIDARG;
|
|
return hr;
|
|
}
|
|
|
|
PSID pSid = NULL;
|
|
LPWSTR pszSid = NULL;
|
|
LPWSTR lpszDN = NULL;
|
|
|
|
do // false loop
|
|
{
|
|
// TODO: Need to provide the first param
|
|
hr = ConvertTrusteeToDN(NULL, lpszUser, &lpszDN);
|
|
if(FAILED(hr))
|
|
{
|
|
// 700068 - If the user doesn't exist or has been deleted then
|
|
// give the user a clue as to what went wrong. 686693 addresses
|
|
// the known issue of multiple error messages being displayed
|
|
// and may not be addressed until a future release - ronmart
|
|
hr = E_INVALIDARG;
|
|
DisplayErrorMessage(g_pszDSCommandName, 0, hr, IDS_MSG_INVALID_ACCT_ERROR);
|
|
break;
|
|
}
|
|
|
|
// Get the SID
|
|
hr = GetDNSid(lpszDN,
|
|
refBasePathsInfo,
|
|
refCredentialObject,
|
|
&pSid);
|
|
if(FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
// Convert the sid to a string
|
|
if(ConvertSidToStringSid(pSid, &pszSid))
|
|
{
|
|
DEBUG_OUTPUT(LEVEL3_LOGGING, L"ConvertSidToStringSid = %s", pszSid);
|
|
// APPEND the trustee query with the sid
|
|
strFilter += L"(msDS-QuotaTrustee=";
|
|
strFilter += pszSid;
|
|
strFilter += L")";
|
|
}
|
|
else
|
|
{
|
|
DEBUG_OUTPUT(LEVEL3_LOGGING, L"ConvertSidToStringSid failed!");
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
} while (false);
|
|
|
|
if(pSid)
|
|
LocalFree(pSid);
|
|
|
|
if(pszSid)
|
|
LocalFree(pszSid);
|
|
|
|
if(lpszDN)
|
|
LocalFree(lpszDN);
|
|
|
|
return hr;
|
|
}
|