Directory Services

How to Specify Comparison Values

Each attribute type has a syntax that determines the type of comparison values that you can specify in a search filter for that attribute.

The following sections describe requirements for each attribute syntax. For more information about attribute syntaxes, see Syntaxes for Active Directory Attributes.

Boolean
The value specified in a filter must be one of the following string values:

TRUE

FALSE

Examples of Boolean

Filter specifying showInAdvancedViewOnly set to TRUE:

(showInAdvancedViewOnly=TRUE)

Filter specifying showInAdvancedViewOnly set to FALSE:

(showInAdvancedViewOnly=FALSE)
Integer and Enumeration
The value specified in a filter must be a decimal Integer. Hexadecimal values must be converted to decimal.

Be aware that the LDAP matching rule controls can be used to perform bit-wise comparisons.

Matching rules have the following syntax:

attributename:ruleOID:=value

where attributename is the lDAPDisplayName of the attribute, ruleOID is the OID for the matching rule control, and value is the value to use for comparison.

Active Directory supports the following matching rules.

Examples of Integer and Enumeration

Filter specifying groupType of Universal group (ADS_GROUP_TYPE_UNIVERSAL_GROUP is 0x00000008).

(groupType=8)

Filter specifying groupType of security-enabled Universal group (ADS_GROUP_TYPE_SECURITY_ENABLED is 0x80000000). So, ADS_GROUP_TYPE_SECURITY_ENABLED | ADS_GROUP_TYPE_UNIVERSAL_GROUP is 0x80000008 and converted to decimal value is 2147483650.

(groupType=2147483650)

Bit-wise comparisons

Filter specifying groupType with the ADS_GROUP_TYPE_SECURITY_ENABLED bit set:

(groupType:1.2.840.113556.1.4.804:=2147483648) )

The following query string searches for Universal distribution groups; that is, Universal groups without ADS_GROUP_TYPE_SECURITY_ENABLED flag:

(&(objectCategory=group)((&(groupType:1.2.840.113556.1.4.804:=8)(!(groupType:1.2.840.113556.1.4.803:=2147483650)))))
OctetString
The value specified in a filter is the data to be found. The data must be represented as an encoded byte string where each byte is preceded by a backslash (\).

Use the ADsEncodeBinaryData function to create an encoded string representation of binary data.

Wildcards are accepted.

Example of OctetString

Filter containing encoded string for schemaIDGUID with GUID value (in StringFromGUID2 format) of {BF967ABA-0DE6-11D0-A285-00AA003049E2}:

(schemaidguid=\BA\7A\96\BF\E6\0D\D0\11\A2\85\00\AA\00\30\49\E2)

Filter containing encoded string for objectGUID with GUID value (in StringFromGUID2 format) of {FB4B7B35-E0AF-11D2-868C-00C04F8607E2}:

(objectguid=\35\7B\4B\FB\AF\E0\D2\11\86\8C\00\C0\4F\86\07\E2)

The following code example prints the encoded string for the GUID guidmyTestAttributeDNString:

static const GUID guidmyTestAttributeDNString = 
  { 
  /* 9cb304e4-d60d-11d2-81a7-00c04fb98c1a */
	0x9cb304e4,
	0xd60d,
	0x11d2,
	{0x81, 0xa7, 0x00, 0xc0, 0x4f, 0xb9, 0x8c, 0x1a}
  };
 
LPOLESTR szTestBuffer = NULL;
HRESULT hrTemp = E_FAIL;
 
hrTemp = ADsEncodeBinaryData((LPBYTE)&guidmyTestAttributeDNString,
							sizeof(GUID), &szTestBuffer);
if (SUCCEEDED(hrTemp))
	wprintf(L"%s\n",szTestBuffer);
 
if(szTestBuffer)
	FreeADsMem(szTestBuffer);
Sid
The value specified in a filter is the encoded byte string representation of the SID. For more information about encoded byte strings, see the previous section in this topic which discusses OctetString syntax.

Example of SID

Filter containing encoded string for objectSid with SID string value of S-1-5-21-1935655697-308236825-1417001333:

(ObjectSid=\01\04\00\00\00\00\00\05\15\00\00\00\11\C3\5Fs\19R\5F\12u\B9uT)
DN
The entire distinguished name, to be matched, must be supplied.

Wildcards are not accepted.

Be aware that the objectCategory property also enables you to specify the lDAPDisplayName of the class set on the property.

Examples of DN

Filter that specifies a member containing CN=TestUser,DC=Fabrikam,DC=COM:

(member=CN=TestUser,DC=Fabrikam,DC=COM)

Two equivalent filters specifying an objectCategory set to CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=Fabrikam,DC=COM:

(objectCategory=CN=Attribute-Schema,CN=Schema,CN=Configuration,DC=Fabrikam,DC=COM)
 
(objectCategory=attributeSchema)
INTEGER8
The value specified in a filter must be a decimal integer. Convert hexadecimal values to decimal.

Examples of Integers

Filter specifying a creationTime set to a FILETIME of 3/10/99 3:31:32 PM:

(creationTime=125655822921406250)

The following functions create an exact match (=) filter for a large integer attribute and verify the attribute in the schema and its syntax:

//***************************************************************************
//
//  CheckAttribute()
//
//***************************************************************************

HRESULT CheckAttribute(LPOLESTR szAttribute, LPOLESTR szSyntax)
{
	HRESULT hr = E_FAIL;
	BSTR bstr;
	IADsProperty *pObject = NULL;
	LPWSTR szPrefix = L"LDAP://schema/";
	LPWSTR szPath;
	 
	if((!szAttribute) || (!szSyntax))
	{
		return E_POINTER;
}

	// Allocate a buffer large enough to hold the ADsPath of the attribute.
	szPath = new WCHAR[lstrlenW(szPrefix) + lstrlenW(szAttribute) + 1];
	if(NULL == szPath)
	{
		return E_OUTOFMEMORY;
}
	 
	// Create the ADsPath of the attribute.
	lstrcpyW(szPath, szPrefix);
	lstrcatW(szPath, szAttribute);

	hr = ADsOpenObject( szPath,
						NULL,
						NULL,
						ADS_SECURE_AUTHENTICATION, // Use Secure Authentication.
						IID_IADsProperty,
						(void**)&pObject);
	if(SUCCEEDED(hr)) 
	{
		hr = pObject->get_Syntax(&bstr);
		if (SUCCEEDED(hr)) 
		{
			if (0==lstrcmpiW(bstr, szSyntax)) 
			{
				hr = S_OK;
		}
			else
			{
				hr = S_FALSE;
		}
	}

		SysFreeString(bstr);
}

	if(pObject)
	{
		pObject->Release();
}

	delete szPath;

	return hr;
}

//***************************************************************************
//
//  CreateExactMatchFilterLargeInteger()
//
//***************************************************************************

HRESULT CreateExactMatchFilterLargeInteger( LPOLESTR szAttribute, 
											INT64 liValue, 
											LPOLESTR *pszFilter)
{
	HRESULT hr = E_FAIL;
	 
	if ((!szAttribute) || (!pszFilter))
	{
		return E_POINTER;
}
	 
	// Verify that the attribute exists and has 
	// Integer8 (Large Integer) syntax.
	 
	hr = CheckAttribute(szAttribute, L"Integer8");
	if (S_OK == hr) 
	{
		LPWSTR szFormat = L"%s=%I64d";
		LPWSTR szTempFilter = new WCHAR[lstrlenW(szFormat) + lstrlenW(szAttribute) + 20 + 1];

		if(NULL == szTempFilter)
		{
			return E_OUTOFMEMORY;
	}
	
		swprintf(szTempFilter, L"%s=%I64d", szAttribute, liValue);
	 
		// Allocate buffer for the filter string.
		// Caller must free the buffer using CoTaskMemFree.
		*pszFilter = (OLECHAR *)CoTaskMemAlloc(sizeof(OLECHAR) * (lstrlenW(szTempFilter) + 1));
		if (*pszFilter) 
		{
			wcscpy(*pszFilter, szTempFilter);
			hr = S_OK;
	}
		else
		{
			hr = E_OUTOFMEMORY;
	}

		delete szTempFilter;
}

	return hr;
}
PrintableString
Attributes with these syntaxes should adhere to specific character sets. For more information, see Syntaxes for Active Directory Attributes. Currently, Active Directory does not enforce those character sets.

The value specified in a filter is a string. The comparison is case-sensitive.

(myAttribute=TheValue)
GeneralizedTime
The value specified in a filter is a string that represents the date in the following form:
YYYYMMDDHHMMSS.0Z

Z indicates no time differential. Be aware that Active Directory stores date/time as Greenwich Mean Time (GMT) time. If a time differential is not specified, the default is GMT.

If the local time zone is not GMT, use a differential value to specify your local time zone and apply the differential to GMT. The differential is based on: GMT=Local+differential.

To specify a differential, use:

YYYYMMDDHHMMSS.0[+/-]HHMM

Examples of GeneralizedTime

Filter specifying a whenCreated time set to 3/23/99 8:52:58 PM:

(whenCreated=19990323205258.0Z)

Filter specifying a whenCreated time set to 3/23/99 8:52:58 PM New Zealand Standard Time (differential is 12 hours):

(whenCreated=19990323205258.0+1200)

Calculating Time Zone Differential

The following function returns the differential between the current local time zone and GMT. The value returned is a string in the following format:

[+/-]HHMM

For example, Pacific Standard Time is -0800.

//***************************************************************************
//
//  GetLocalTimeZoneDifferential()
//
//***************************************************************************

HRESULT GetLocalTimeZoneDifferential(LPOLESTR *pszDifferential)
{
	if(NULL == pszDifferential)
	{
		return E_INVALIDARG;
}

	HRESULT hr = E_FAIL;
	DWORD dwReturn;
	TIME_ZONE_INFORMATION timezoneinfo;
	LONG lTimeDifferential;
	LONG lHours;
	LONG lMinutes;

	dwReturn  = GetTimeZoneInformation(&timezoneinfo);

	switch (dwReturn)
	{
	case TIME_ZONE_ID_STANDARD:
		lTimeDifferential = timezoneinfo.Bias + timezoneinfo.StandardBias;
	
		// Bias is in minutes. Calculate the hours for HHMM format.
		lHours = -(lTimeDifferential/60);
	
		// Bias is in minutes. Calculate the minutes for HHMM format.
		lMinutes = lTimeDifferential%60L;

		hr = S_OK;
		break;

	case TIME_ZONE_ID_DAYLIGHT:
		lTimeDifferential = timezoneinfo.Bias + timezoneinfo.DaylightBias;
	
		// Bias is in minutes. Calculate the hours for HHMM format.
		// Apply the additive inverse.
		// Bias is based on GMT=Local+Bias.
		// A differential, based on GMT=Local-Bias, is required.
		lHours = -(lTimeDifferential/60);
	
		// Bias is in minutes. Calculate the minutes for HHMM format.
		lMinutes = lTimeDifferential%60L;
	
		hr = S_OK;
		break;

	case TIME_ZONE_ID_INVALID:
	default:
		hr = E_FAIL;
		break;
}
	 
	if (SUCCEEDED(hr))
	{
		// The caller must free the memory using CoTaskMemFree.
		*pszDifferential = (OLECHAR *)CoTaskMemAlloc(sizeof(OLECHAR) * (3 + 2 + 1));
		if (*pszDifferential)
		{
			swprintf(*pszDifferential, L"%+03d%02d", lHours, lMinutes);
		
			hr = S_OK;
	}
		else
		{
			hr = E_OUTOFMEMORY;
	}
}
	 
	return hr;
}
UTCTime
The value specified in a filter is a string that represents the date in the following form:
YYMMDDHHMMSSZ

Z indicates no time differential. Be aware that Active Directory stores date and time as GMT time. If a time differential is not specified, GMT is the default.

The seconds value (SS) is optional.

If GMT is not the local time zone, apply a local differential value to specify your local time zone. The differential is: GMT=Local+differential.

To specify a differential, use:

YYMMDDHHMMSS[+/-]HHMM

Examples of UTCTime

Filter specifying a myTimeAttrib time set to 3/23/99 8:52:58 PM:

(myTimeAttrib=990323205258Z)

Filter specifying a myTimeAttrib time set to 3/23/99 8:52:58 PM without seconds specified:

(myTimeAttrib=9903232052Z)

Filter specifying a myTimeAttrib time set to 3/23/99 8:52:58 PM New Zealand Standard Time (differential is 12 hours). This is equivalent to 3/23/99 8:52:58 AM GMT.

(myTimeAttrib=990323205258+1200)
DirectoryString
The value specified in a filter is a string. DirectoryString can contain Unicode characters. The comparison is case-insensitive.
(myAttribute2=THEVALUE)
OID
The entire OID to be matched must be supplied.

Wildcards are not accepted.

The objectCategory property enables you to specify the lDAPDisplayName of the class set for the property.

Examples of OID

Filter specifying governsID for volume class:

(governsID=1.2.840.113556.1.5.36)

Two equivalent filters specifying systemMustContain property containing uNCName, which has an OID of 1.2.840.113556.1.4.137:

(SystemMustContain=uNCName)
 
(SystemMustContain=1.2.840.113556.1.4.137)
Other Syntaxes
The following syntaxes are evaluated in a filter similar to an octet string: