joeware - never stop exploring... :)

Information about joeware mixed with wild and crazy opinions...

From the mailbag – Trouble with LDAP filters with embedded backslash literals

by @ 4:37 am on 1/29/2009. Filed under tech

I received an email this evening that I swore I had previously wrote something up on the blog for and didn’t, so I will share…

The email

From: xxx@domain.gov
Sent: Wednesday, January 28, 2009 7:28 PM
To: ‘joe@joeware.net’
Subject: Adfind piped into admod question

Good evening Joe,

First I’d like to commend you on your books, website, and apps, I use many of them almost on a daily basis. 

So here it is:

We have users who’s home folders are being moved from \\xxx-home to \\abc-xxx
now \\abc-xxx and \\xxx-home aren’t the only home servers so it’s not like i can replace them all so I’ve written this script to test it out. In the servers OU I placed a user account and have populated the home directory as \\xxx-home2\joesmith$…again this account is just for testing.

run this script

adfind -b “ou=xxx,dc=domain,dc=gov” -f “(&(objectcategory=person)(objectclass=user)(homedirectory=\\xxx-home*))” samaccountname -adcsv | admod -unsafe homedirectory::\\abc-xxx.domain.gov\%username%$

the script runs just fine and updates joesmith’s home directory to \\abc-xxx.domain.gov\joesmith$ which was anticipated.
So this works all fine and dandy, where the problem is, is if down the road we want to utilize this again it doesn’t work. so for instance:
user account joesmith who’s home directory is now \\abc-xxx.domain.gov\joesmith$ (home directory was changed with utilizing the above script)
if \\abc-xxx was being retired and we were putting \\abc-home10 in it’s place. If you adjust the script find homedirectory=\\abc-xxx* it wont find anything to alter. The only way to make it find something is to tell it to find homedirectory=*

At first I thought it was because of AD replication (that is all DC’s aren’t up to date with the correct information), but I checked all our DC and it was updated before I ran the 2nd update.  Then I thought well what if there was a space before the \\ so I opened up ADUC and ADSedit and verified there wasn’t s space in the homedirectory attribute.  
Any clue why it wouldn’t update the 2nd time around?  Also what does the -adcsv –dsq switch do? Tried to find some documentation on it but there was little.

Any information you could provide would be much appreciated.

Thanks again,

     xxx

I get questions like this pretty regularly which is why I guess I thought I blogged about it before, but I couldn’t find a blog entry for it so here was my response

Hey xxx, glad you like the tools, book, et al. 🙂

First off, I wanted to point something out… This first command

adfind -b “ou=xxx,dc=domain,dc=gov” -f “(&(objectcategory=person)(objectclass=user)(homedirectory=\\xxx-home*))” samaccountname -adcsv | admod -unsafe homedirectory::\\abc-xxx.domain.gov\%username%$

has an issue with the admod portion. Specifically the %username% won’t work. That will decode to the current environment variable for username which should be your current logon account. That little shortcut in ADUC is just that, a shortcut in ADUC, it isn’t a global AD thing. I think what you would really want would be

adfind -b “ou=xxx,dc=domain,dc=gov” -f “(&(objectcategory=person)(objectclass=user)(homedirectory=\\xxx-home*))” samaccountname -adcsv | admod -unsafe homedirectory::\\abc-xxx.domain.gov\{{samaccountname}}$

That will take the samaccountname that is returned from the query and piped across to admod and use that to populate the username piece of the share name so it would be specific to every user queried, it wouldn’t set the value to your current username environment variable for every account returned.

Second, the issue you see with the \\abc-xxx… is doing something you probably don’t expect… In an LDAP query, the backslash (\) character is an escape character. It tells LDAP that something special is coming – specifically a hex character sequence like \2a for example. This is generally not a problem and it all sorts itself out so you likely never have an issue using \\someserver… However if you follow a backslash with character that is a valid HEX character the escape and the HEX character are taken together… In that case, the proper way to search for a value that has embedded back slash literals is to use \5c for each backslash, so it would be \5c\5cabc-xxx. You can check out http://msdn.microsoft.com/en-us/library/ms675768(VS.85).aspx which discusses this and more about creating query filters.

    joe

And then I realized I didn’t answer his last two questions so I added

Sorry, didn’t answer the other questions:

-adcsv : As the adfind usage indicates, it is a special CSV mode that embeds some extra info in the CSV for AdMod or whatever tool being piped to to better understand the request, for example some things that can get embedded would be hostname, userid, password, etc used in the adfind query.

   -adcsv xxx    Special CSV mode for interacting with other joeware tools.
                 xxx is an optional string that specifies value to use for
                 use for empty attribs.

-dsq : This is simply quoted DN output like DSQuery outputs.

  -dsq          DSQuery style quoted DN output

   joe

 

So a little more discussion on the embedded backslashes, as the MSDN article above discusses the following characters all need to be escaped with “need” being a little more loosely defined for the backslash character itself than the other characters.

* \2a
( \28
) \29
\ \5c
NUL \00

 

So now I know at least one or two of you are thinking… wow… so joe, why don’t you just help the guy out and likely help me out too and just make AdFind smart enough to do that embedding work for me… Well I could try… But I really really try hard not to mess with the actual LDAP query that is entered. The minimal amount I do for -bit to do a find/replace on some specific strings is fired off by the actual -bit switch. If people have to specify a switch to encode backslashes why don’t they just instead encode the backslashes themselves since it isn’t that much more and I don’t have to try and guess which backslashes should and shouldn’t be encoded. But joe… \5c is a pain in the butt to remember… Yes, for me too… The way I remember it when I need to is to query for the object I know that has one of the troublesome homedirectories in it and then tell AdFind to return the homedirectory value in binary so I can quickly see the HEX characters I need to enter. Like so

[Thu 01/29/2009  3:32:04.61]
G:\new1\Dev\Current\CPP\AdFind\Release>adfind -default -f “&(name=someuser)(homedirectory=*)” homedirectory

AdFind V01.40.00cpp **BETA** Joe Richards (joe@joeware.net) January 2009

Using server: TEST-DC1.test.loc:389
Directory: Windows Server 2003
Base DN: DC=test,DC=loc

dn:CN=someuser,OU=Users,OU=TestOU,DC=test,DC=loc
>homeDirectory: \\abc-xxx\someuser$

1 Objects returned

[Thu 01/29/2009  3:32:06.72]
G:\new1\Dev\Current\CPP\AdFind\Release>adfind -default -f “&(name=someuser)(homedirectory=*)” homedirectory;binary

AdFind V01.40.00cpp **BETA** Joe Richards (joe@joeware.net) January 2009

Using server: TEST-DC1.test.loc:389
Directory: Windows Server 2003
Base DN: DC=test,DC=loc

dn:CN=someuser,OU=Users,OU=TestOU,DC=test,DC=loc
>homeDirectory;binary: 5C5C 6162 632D 7878 785C 736F 6D65 7573 6572 24

1 Objects returned

Note the 5C5C right there at the front…

 

    joe

Rating 3.00 out of 5

One Response to “From the mailbag – Trouble with LDAP filters with embedded backslash literals”

  1. Andrew from Vancouver says:

    And for those who like more rigor in their sources or believe that Microsoft is just screwing with them on this business of the escape sequence requirements, here’s the RFC:

    http://www.rfc-editor.org/rfc/rfc2254.txt

[joeware – never stop exploring… :) is proudly powered by WordPress.]