Solved

Setting Criteria on an Active Directory search from SQL Server

Posted on 2004-10-06
10
767 Views
Last Modified: 2008-01-09
I've linked my Active Directory to SQL Server as a linked server and I've managed to run queries on the directory.

I can run a query to return all users in the directory, e.g. :

SELECT     *
FROM         OPENQUERY(ADSI,
                         '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person));name, mail, sAMAccountName, userPrincipalName, title, department')

And I wanted to place this into a view or a stored procedure which our ASP web developers can call from their web pages.  However, whenever I try to limit the recordset to only one user by setting a WHERE clause in the statement I get no results returned even though I know the user name I've used is valid, e.g. :

SELECT     *
FROM         OPENQUERY(ADSI,
                         '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person));name, mail, sAMAccountName, userPrincipalName, title, department')
WHERE sAMAccountName = 'donait'

I've tried this from both an ASP page and from within SQL Query Analyzer itself, but I get no rows returned.  If I place the criteria within the LDAP syntax itself, then I do get the user's details returned but I can't use this method because I need to place the value of a passed parameter as the sAMAccountName, e.g.:

SELECT     *
FROM         OPENQUERY(ADSI,
                         '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person)(sAMAccountName=donait));name, mail, sAMAccountName, userPrincipalName, title, department')

Does anyone know where I'm going wrong, or can you suggest a different way to achieve a solution?
0
Comment
Question by:ian_r
  • 5
  • 4
10 Comments
 
LVL 34

Expert Comment

by:arbert
ID: 12240683
If you're using ASP, build the connection string in VBS and then pass that:

Dim sSQL
Dim sAccountName
sAccountName="donait"

sSql="SELECT     *
FROM         OPENQUERY(ADSI,
                        '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person)"
sSql=sSql & "(sAMAccountName=" & sAccountName
sSql=sSql & "));name, mail, sAMAccountName, userPrincipalName, title, department')"

set rs=connection.execute(sSql)

0
 
LVL 34

Expert Comment

by:arbert
ID: 12240693
Ooops, it wrapped, but you get the idea:

sSql="SELECT     * FROM         OPENQUERY(ADSI, '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person)"
sSql=sSql & "(sAMAccountName=" & sAccountName
sSql=sSql & "));name, mail, sAMAccountName, userPrincipalName, title, department')"
0
 
LVL 6

Expert Comment

by:mcp111
ID: 12240758
probably you need to specify domainname\username
0
 

Author Comment

by:ian_r
ID: 12241253
You can run the query directly from the ASP page but I didn't want to do this because it's slower than running it from within a stored procedure and will have a higher impact on the network bandwidth.  Also, it would be easier to place this functionality within one stored procedure so I can nest it within others and allow more than one ASP application access to the same procedure without having to cut 'n paste code.

What I'm trying should be possible according to:

I don't think I need to specify the domain name with the username because the domain is part of the LDAP string, and the query works fine if I put the username in next to the "objectCategory=Person" rather than use a WHERE clause  (see original post).

I'm really keen to get this working, any suggestions?
0
 
LVL 34

Expert Comment

by:arbert
ID: 12241303
Have you tried changing the = on the outside to a like to see if there are spaces?

SELECT     *
FROM         OPENQUERY(ADSI,
                        '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person));name, mail, sAMAccountName, userPrincipalName, title, department')
WHERE sAMAccountName like 'donait%'

You could also use Dynam sql in the stored proc (as a last resort) to put the where on the inside of the linked server.  It's actually better there anyway because you KNOW the criteria is applied at AD and not at SQL Server...
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:ian_r
ID: 12241583
Thanks for the comments arbert, I'll try the 'like' when I'm back at work tomorrow.

How do I use dynamic sql within the stored proc?  I've tried inserting an input parameter within the string but I get a syntaxt error, e.g. :

SELECT     *
FROM         OPENQUERY(ADSI,
                        '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person)(sAMAccountName=' + @username + '));name, mail, sAMAccountName, userPrincipalName, title, department')

Is that what you mean, or have I got the wrong end of the stick?

The links I missed of the previous post were:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/creating_a_heterogeneous_join_between_sql_server_and_active_directory.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/creating_a_heterogeneous_join_between_sql_server_and_active_directory.asp

0
 
LVL 34

Accepted Solution

by:
arbert earned 250 total points
ID: 12241687
Close, you have to generate the string and then use EXEC(yourstring) to run.

Haven't tested, but something like this:

declare @sql varchar(2000)

select @sql='SELECT     * FROM         OPENQUERY(ADSI, ' + char(39) + '<LDAP://blah.blah.blah.uk>;(&(objectClass=user)(objectCategory=Person)(sAMAccountName=' + @username + '));name, mail, sAMAccountName, userPrincipalName, title, department' + char(39) + ')'

exec(@sql)
0
 

Author Comment

by:ian_r
ID: 12241737
Cheers arbert, that looks great.  I'll try it tomorrow and tell you how I go on.
0
 

Author Comment

by:ian_r
ID: 12246455
arbert,

Your last suggestion worked just as you suggested, without me needing to change any of your syntax - who needs testing eh?

Thanks again, I was working on this all day and I'm new to stored procedures, so I was getting pretty frustrated :-).
0
 
LVL 34

Expert Comment

by:arbert
ID: 12251331
Good deal.  I wouldn't say that dynamic SQL is ideal, but sometimes there really isn't a way around it.  With openquery, if you can pass the criteria on the "inside" you will usually get MUCH better performance than applying it on the outside.

Glad it all worked.

Brett
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Load balancing is the method of dividing the total amount of work performed by one computer between two or more computers. Its aim is to get more work done in the same amount of time, ensuring that all the users get served faster.
For both online and offline retail, the cross-channel business is the most recent pattern in the B2C trade space.
Familiarize people with the process of utilizing SQL Server functions from within Microsoft Access. Microsoft Access is a very powerful client/server development tool. One of the SQL Server objects that you can interact with from within Microsoft Ac…
Via a live example, show how to shrink a transaction log file down to a reasonable size.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now