Querying from AD - NO_OBJECT - active-directory

My AD entry has the property msExchAddressBookPolicyLink with the value CN=ABL_Sub,CN=AddressBook Mailbox Policies,CN=MyExchange,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=intra,DC=contoso,DC=com.
This value I put into variable abpLink (I checked in VisualStudio Debugger), then using
if(abp!=null) {
DirectoryEntry abpEntry = new DirectoryEntry("LDAP://"+abpLink);
At that point, abpEntry has raised a COMException, and when looking into the returned Properties, I find the error "problem 2001: NO_OBJECT".
(The ABL_Sub Address Book Policy does still exist, I did not delete it in Exchange.)
How so?

Related

cloud firestore role based access example: can user create a comment?

While reading the cloud firestore role based access example https://firebase.google.com/docs/firestore/solutions/role-based-access#rules, step 4, I find it not clear whether the user can create a comment or not.
According to the above link, the comment is owned by a user, here is the data model:
/stories/{storyid}/comments/{commentid}
{
user: "alice",
content: "I think this is a great story!"
}
And the rules:
match /comments/{comment} {
allow read: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
['owner', 'writer', 'commenter', 'reader']);
// Owners, writers, and commenters can create comments. The
// user id in the comment document must match the requesting
// user's id.
//
// Note: we have to use get() here to retrieve the story
// document so that we can check the user's role.
allow create: if isOneOfRoles(get(/databases/$(database)/documents/stories/$(story)),
['owner', 'writer', 'commenter'])
&& request.resource.data.user == request.auth.uid;
}
Note the last line of the rules, to create the comment, the authenticated user (request.auth.uid) has to be the user who is the owner of the comment. However, before even create this comment, how can this user property exist? Maybe, when create the comment, do not require the last segment of the rule "&& request.resource.data.user == request.auth.uid". But when update the comment, can add this rule.
Did I miss anything? Btw, do they actually test examples before using them for online reference? It is also a pity that there is no timestamp when these online documents are created. I was told nowadays things two years old can be obsolete.
The request.resource variable contains the document as it will exist after this operation is completed (assuming it is allowed). So request.resource.data.user is the value of the user field that the operation is trying to write, not the value as it currently exists (that'd be resource.data.user, without request.).

Using FindPagesWithCriteria in Episerver returns no results

i wonder if someone else has come accross this issue. I am trying to use FindPagesWithCriteria and i am creating my property criteria as like this:
PropertyCriteria dateCriteria = new PropertyCriteria();
dateCriteria.Condition = CompareCondition.GreaterThan;
dateCriteria.Name = "PageStopPublish";
dateCriteria.Type = PropertyDataType.Date;
dateCriteria.Value = DateTime.Now.ToString();
dateCriteria.Required = true;
so i am trying to find all the pages that are not expired. However, some pages may not have StopPublish property set in which case Datetime.MaxValue should be used. But in this particular case (no StopPublish value set) FindPagesWithCriteria will not return any results. Is there a reason for this or is it a bug? As a workaround, i am returning using PageTypeName criteria and then applying some additional filterin for returned PageDataCollection
FindPagesWithCriteria will only give you published pages (and pages that the current user have access to) so having StopPublish as a criteria is not necessary.
FindAllPagesWithCriteria will return all pages, including unpublished pages and pages the current user does not have access to.
EPiServer properties with an empty value are never stored in the database. If you access it from code, it will always be null.
To search for a null property using PropertyCriteria, set the IsNull property to true

AD returns Objectsid as String and SecurityIdentifier is failing interprete this

Usually AD returns 'Objectsid' as a byte[]. So I type cast the value returned by AD in to byte[]. This procedure worked against several AD but not in one case. In this AD environment, I get following exception.
Exception: Unable to cast object of type 'System.String' to type 'System.Byte[]'. (System.InvalidCastException)
To debug this I started checking data-type of the value returned by AD, and it was system.string not byte[]. I printed this string and it was garbage. Then I passed this string to SecurityIdentifier() and I got exception again.
Exception: Value was invalid. Parameter name: sddlForm (System.ArgumentException)
Code:
//Using System.DirectoryServices.Protocols objects
object s = objSrEc[k1].Attributes[(string)obj3.Current][0];
string x = s.GetType().FullName;
if (x.ToLower() == "system.byte[]")
{
byte[] bSID = ((byte[])s);
if (bSID != null)
{
SecurityIdentifier SID = new SecurityIdentifier(bSID, 0);
String ObjectSID = SID.Value;
}
}
else if (x.ToLower() == "system.string")
{
SecurityIdentifier SID = new SecurityIdentifier((String)s); //ssdl excception
String ObjectSID = SID.Value;
}
This is the first time I am seeing AD return string data for ObjectSID. I have run my code against many AD servers. I am planning to check the data-type of ObjectSID in AD schema.
Do any one come across this behavior? Should I call the Win32 api ConvertByteToStringSid()?
Thanks
Ramesh
Sorry for reviving a graveyard post, but I had the same issue a year or so ago, managed to find out why and I figured I'd at least share the reason behind this behavior.
When using the System.DirectoryServices.Protocols namespace, all attribute values should be either a) a byte array, or b) a UTF-8 string. Thing is, the developers at Microsoft figured that they should help people by returning a string when the byte array returned from the underlying LDAP API can be formatted as one, and the byte array itself when the UTF-8 conversion fails. However, this is only true for the indexer of the DirectoryAttribute class, and not for the iterator (which always returns the byte array) or the GetValues method.
The safest way to always get a byte array when you want the SID is, as previously mentioned by others, the GetValues method.
I came through the same. Found this behavior normal when deal with ForeignSecurityPrincipals, however recently found this when translate attributes of built-in groups from some old Win 2K3 domains.
I don't like this as can't just ask the result attribute to tell me via GetType() what type are you and what should I do with you ( GetValues(Attribute.GetType()) ). One of the solutions was reading all attributes definition from AD schema, but this part might be a bit heavy (depends what you're looking for) although it was only a small part of overall AD processing the solution was performing.
Cheers,
Greg

How to get LDAP unboundid AttributeSyntax?

I'm trying to find out the unboundid AttributeSyntax type for a specific attribute name and it's simply not working.
Here's the example test code that I'm using to achieve this:
#Test
public void testLDAPSchema() {
try {
LDAPConnection connection = new LDAPConnection();
connection.connect("hessmain", 389);
connection.bind("CN=Administrator,CN=Users,DC=FISHBOWL,DC=NET", "password");
Schema s = connection.getSchema();
System.out.println(s.toString());
AttributeTypeDefinition atd = s.getAttributeType("directReports");
Set<AttributeTypeDefinition> oat = s.getOperationalAttributeTypes();
Set<AttributeSyntaxDefinition> l = s.getAttributeSyntaxes();
AttributeSyntaxDefinition asd1 = s.getAttributeSyntax(atd.getOID());
AttributeSyntaxDefinition asd2 = s.getAttributeSyntax(atd.getSyntaxOID());
AttributeSyntaxDefinition asd3 = s.getAttributeSyntax(atd.getBaseSyntaxOID());
connection.close();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
}
From the above code, all the sets are empty. This also means that no matter which OID I pass to the schema getAttributeSyntax method that I will simply get a null return.
Is there any reason why I can't get the attribute syntaxes from an Active Directory server schema?
Thanks
I don't think that this is specific to the UnboundID LDAP SDK for Java. I'm not sure that Active Directory exposes this information over LDAP. When I perform a general LDAP search to retrieve schema information, I can see the attributeTypes and objectClasses attributes, but ldapSyntaxes isn't returned (and in fact ldapSyntaxes doesn't appear in the list of attribute types).
Similarly, none of the attribute type definitions includes a USAGE element, which is what is used to indicate that the attribute type is operational (e.g., "USAGE directoryOperation").
It may well be that Active Directory simply doesn't report this information at all. It could be that it provides some other non-standard way to get this information (e.g., a control or extended operation, or some other entry that can be retrieved), but if there is then I don't know about it.

programming the active directory

I've got an asp application running but i want to search the Active Directory.
i am using vb (visual web developer 2008)
how do i search the active directory for a given user?
ie: user enters login name in text box, clicks submit. active directory is searched on-click for this user. when found user information is displayed .
Thanks
What version of the .NET framework can you use? Searching and looking up stuff in AD has become extremely easy in .NET 3.5 - see this great MSDN article by Ethan Wilanski and Joe Kaplan on using the security principals API for that.
If you're not on .NET 3.5 yet, you'll have to use the DirectorySearcher class and set up the search filters as you need. Getting the LDAP filter right is probably the biggest obstacle.
Robbie Allen also has two great intro article on System.DirectoryServices programming:
- Part 1
- Part 2
There are some really good resources at http://www.directoryprogramming.net (Joe Kaplan's site - he's a Microsoft Active Directory MVP), and Richard Mueller has some great reference excel sheets on what properties are available for each of the ADSI providers, and what they mean, and how their LDAP name is - see http://www.rlmueller.net.
Marc
EDIT: Ok- here's the .NET 2.0 / 3.0 approach:
// set the search root - the AD container to search from
DirectoryEntry searchRoot = new DirectoryEntry("LDAP://dc=yourdomain,dc=com");
// create directory searcher
DirectorySearcher ds = new DirectorySearcher(searchRoot);
ds.SearchScope = SearchScope.Subtree;
// set the properties to load in the search results
// the fewer you load, the better your performance
ds.PropertiesToLoad.Add("cn");
ds.PropertiesToLoad.Add("sn");
ds.PropertiesToLoad.Add("givenName");
ds.PropertiesToLoad.Add("mail");
// set the filter - here I'm using objectCategory since this attribute is
// single-valued and indexed --> much better than objectClass in performance
// the "anr" is the "ambiguous name resolution" property which basically
// searches for all normally interesting name properties
ds.Filter = "(&(objectCategory=person)(anr=user-name-here))";
// get the result collection
SearchResultCollection src = ds.FindAll();
// iterate over the results
foreach (SearchResult sr in src)
{
// do whatever you need to do with the search result
// I'm extracting the properties I specified in the PropertiesToLoad
// mind you - a property might not be set in AD and thus would
// be NULL here (e.g. not included in the Properties collection)
// also, all result properties are really multi-valued, so you need
// to do this trickery to get the first of the values returned
string surname = string.Empty;
if (sr.Properties.Contains("sn"))
{
surname = sr.Properties["sn"][0].ToString();
}
string givenName = string.Empty;
if (sr.Properties.Contains("givenName"))
{
givenName = sr.Properties["givenName"][0].ToString();
}
string email = string.Empty;
if (sr.Properties.Contains("mail"))
{
email = sr.Properties["mail"][0].ToString();
}
Console.WriteLine("Name: {0} {1} / Mail: {2}", givenName, surname, email);
}
Hope this helps!
Marc

Resources