Syntax to query LDAP over SSL - ssl

I was able to query LDAP over port 636 with the below. How do I modify it so I can query the below AD path:
"OU=Staff,OU=Accounts,OU=ABC PROD,DC=Abc,DC=com"
=============================================================
SELECT top 900 * FROM OpenQuery (
ADSI,
'SELECT *
FROM ''LDAP://ABC.com:636''
WHERE objectClass = ''User''
')
Thank you so much..

Doing trial an error, this seems to work. Thank you.
SELECT top 900 * FROM OpenQuery (
ADSI,
'SELECT *
FROM ''LDAP://abc.com:636/OU=Staff,OU=Accounts,OU=ABC PROD,DC=abc,DC=com''
WHERE objectClass = ''User''
'
)

Related

Iterate each row and perform update accordingly

I have PostgreSQL SQL that should look for a backslash in a column called source_username and if it finds the backslash, it should replace the current value of the source_username column with the same value without the characters before the backslash.
For example:
before source_username: domain\username
after source_username: username
with os_user as (
select source_username from itpserver.managed_incidents mi;
),
osUserWithoutDomain as (
select (
case when (select * from os_user) ilike '%\\%' and (select position('-' in (select * from os_user))>= 1) and (select length((select * from os_user)) != (select position('-' in (select * from os_user))) + 1)
then (
select substring(
(select * from os_user),(select position('\' in (select * from os_user)) + 1),(select length((select * from os_user)) - 1)
))
else ((select * from os_user))
end
)
)
UPDATE itpserver.managed_incidents SET source_username = replace(source_username, (select * from os_user), (select * from osUserWithoutDomain)),
description = replace(description , (select * from os_user), (select * from osUserWithoutDomain)),
additional_info = replace(additional_info , (select * from os_user), (select * from osUserWithoutDomain)),
typical_behavior = replace(typical_behavior , (select * from os_user), (select * from osUserWithoutDomain)),
raw_description = replace(raw_description , (select * from os_user), (select * from osUserWithoutDomain));
This SQL works fine when I have only one row in the table.
If I have multiple rows, I need to specify the row that I want to work with by adding where id = <id>
I wish to iterate all the relevant rows (all the rows that source_username contains backslash) and on each row to perform the SQL above.
I tried to do this with LOOP:
create or replace function fetcher()
returns void as $$
declare
emp record;
begin
for emp in select *
from itpserver.managed_incidents
order by id
limit 10
loop
raise notice '%', emp.id;
<my sql> where id = emp.id
end loop;
end;
$$language plpgsql;
select fetcher();
However, I get an error because I don't think it likes the 'with' statement.
Any idea how can I do it?
It's far simpler than that. You need to use the SUBSTR and STRPOS functions. Take a look at the results of this query.
https://dbfiddle.uk/9-yPKn6E
with os_user (source_username) as (
select 'domain\username'
union select 'mydomain\joe'
union select 'janet'
)
select u.source_username
, strpos(u.source_username, '\')
, substr(u.source_username, strpos(u.source_username, '\') + 1)
from os_user u
source_username
strpos
substr
domain\username
7
username
janet
0
janet
mydomain\joe
9
joe
What you need is:
UPDATE itpserver.managed_incidents
SET source_username = substr(source_username, strpos(source_username, '\') + 1)
, description = replace(description , source_username, substr(source_username, strpos(source_username, '\') + 1))
, additional_info = replace(additional_info , source_username, substr(source_username, strpos(source_username, '\') + 1))
, typical_behavior = replace(typical_behavior , source_username, substr(source_username, strpos(source_username, '\') + 1))
, raw_description = replace(raw_description , source_username, substr(source_username, strpos(source_username, '\') + 1));
This is based on lengthy experience with SQL Server and some quick document searches for Postgresql. The UPDATE statement may not work as I expect.
SQL by design/default works on complete data sets. It thus eliminates LOOPS entirely from the language - they are not needed. (Well not quite there are recursive queries). Your task is accomplished in a single update statement with a simple regular expression. See documentation String Functions:
update managed_incidents
set source_username = regexp_replace(source_username,'.*\\(.*)','\1');
Demo here.
Main Take away: Drop procedural logic terminology (for, loop, if then, ...) from your SQL vocabulary. (you choose alternatives with case.)

Create dynamic SQL query to list all users from over all databases

I want to create a dynamic query to list all unique users in a single table, from which I only need the username, from all different databases, which have the same database schema.
As the names of the tables differ on the different environments I would like to have something dynamic so it can be executed on different environments.
The basic query looks like this:
SELECT USERNAME FROM DATABASE.DBO.USERTABLE WHERE LOGIN = 'Y'
To execute this query on 3 databases, it would look like this:
SELECT *
FROM ( SELECT UT.USERNAME AS 'DB1'
FROM DB1.DBO.USERTABLE UT
WHERE UT.LOGIN = 'Y'
) a
full outer join
( SELECT UT.USERNAME AS 'DB2'
FROM DOSSIER.DBO.USERTABLE UT
WHERE UT.LOGIN = 'Y'
) b ON a.DB1 = b.DB2
full outer join
( SELECT UT.USERNAME AS 'DB3'
FROM DB3.DBO.USERTABLE UT
WHERE UT.LOGIN = 'Y'
) c ON a.DB1 = c.DB3
ORDER BY A.DB1
Is there an easy way to create a dynamic query for this, which can be applied on multiple databases?
I've already tried the code below, but I found it hard to get the JOIN ON working.
DECLARE #Sql NVARCHAR(MAX) = NULL;
SELECT #Sql = COALESCE(#Sql + ' AS '+ name + ' FULL OUTER JOIN ON' + CHAR(13) + CHAR(10), '' ) + 'SELECT USERNAME AS ' + name + ' FROM [' + name + '].[DBO].[USERTABLE] AS '+ name
FROM master.sys.databases
WHERE NOT [name] IN ( 'master', 'tempdb', 'model', 'msdb')
PRINT #Sql;
So what I would like to create is the thing below.
SELECT USERNAME
FROM [DATA].[DBO].[USERTABLE]
RESULTS
USER1
USER2
USER3
SELECT USERNAME
FROM [OTHER].[DBO].[USERTABLE]
RESULTS
USER3
USER4
USER6
SELECT USERNAME
FROM [NEW].[DBO].[USERTABLE]
RESULTS
USER1
USER6
USER7
SELECT USERNAME
FROM [SOME].[DBO].[USERTABLE]
RESULTS
USER2
USER5
USER7
So the resulting query should present the list below.
DATA____OTHER___NEW_____SOME____
USER1___________USER1___________
USER2___________________USER2___
USER3___USER3___________________
________USER4___________________
________________________USER5___
________USER6___USER6___________
________________USER7___USER7___
As mentioned, this has te be dynamic, as:
1. I don't know before how many databases are on an environment;
2. It has to be easy usable for anyone;

how to append a character in WHERE clause of SQL query?

I need a query like below,
select * from table1 where usr_id = user-id + '#' (i.e. if user-id is
1234, then value to be validated is '1234#')
Please let me know how to do this in SQL?
It seems you want to concatenate two strings. The way to do it depend on your DBMS:
-- SQL Server / Microsoft Access
SELECT * FROM table1 WHERE usr_id = user-id + '#'
-- Oracle
SELECT * FROM table1 WHERE usr_id = user-id || '#'
-- MySQL
SELECT * FROM table1 WHERE usr_id = CONCAT(user-id, '#')
Reference : SQL CONCATENATE (appending strings to one another)
Try this
SELECT * FROM table1 WHERE usr_id = CONVERT(VARCHAR(100), #ID) + '#'
OR
SELECT * FROM table1 WHERE REPLACE(usr_id , '#', '') = #ID

SQL Server Inner Query Problem

I have a very simple query in SQL Server. But it is giving errors.
select * from(
select emp_name + ' ' + emp.surname as employee from ca_contact
)
This query is not working.
But when I write like the below, it is working:
select emp_name + ' ' + emp.surname as employee from ca_contact
You'd need an alias. In this case foobar
select * from
(select emp_name + ' ' + emp.surname as employee from ca_contact) foobar
I think you need to specify table alias --
select * from(
select emp_name + ' ' + emp.surname as employee from ca_contact
) t1
In SQL Server, all derived tables must be given an alias [exception is if do not select anything from them, e.g. in an IN/EXISTS clause]. An alternative for what you are doing from SQL Server 2005 onwards is to use a Common Table Expression, which incidentally is also now available in recent versions of Oracle.
A simple meaningless alias
select * from
(select emp_name + ' ' + surname as employee from ca_contact) [ ]
A Common Table Expression, also naming the column at the sametime
;WITH [ ](employee) AS (
select emp_name + ' ' + surname
from ca_contact)
select * from [ ]
FWIW, you can omit the CTE column names and derive them from the query
WITH [ ] AS (
select emp_name + ' ' + surname as employee
from ca_contact)
select * from [ ]
Note: Not sure how you can have emp.surname since there is no table/alias emp defined in your query
Please try the below query
select employee from (select emp_name + ' ' + emp.surname as employee from ca_contact) as test

Querying Active Directory from SQL Server 2005

How can I query Active Directory from SQL Server 2005?
Pretty general question but here are some pointers.
You need a linked server creating on the SQL Server that points to ADSI (Active Directory Service Interface) something like this will do it.
EXEC sp_addlinkedserver 'ADSI', 'Active Directory Services 2.5', 'ADSDSOObject', 'adsdatasource'
Then you can use the following sort of query.
SELECT *
FROM OPENQUERY(ADSI, 'SELECT sAMAccountName
FROM ''LDAP://DC=MyDC,DC=com,DC=uk''
WHERE objectCategory = ''Person''
AND objectClass = ''user''')
You'll need to set the LDAP:// line appropriately (ask your AD admin for the details) and be aware that distributed adhoc queries using OpenQuery are disabled by default in SQL Server. Once you have the above though it should be pretty easy to google for any particular variations.
Yes.
Linked server:
EXEC master.dbo.sp_addlinkedserver
#server = N'ADSI',
#srvproduct=N'Active Directory Services',
#provider=N'ADsDSOObject',
#datasrc=N'Servername.domain.com'
Query:
select * from openquery
(
ADSI,'SELECT name
FROM ''LDAP://Servername.domain.com''
WHERE objectCategory = ''Person'' AND objectClass = ''user''
')
There are lots of examples if you search linked server and LDPA on Google.
I say this because LDAP can be quite complicated to work with.
In order to overcome the maximum limit of 1000 records returned at a time from the Active Directory queries, you can use the function which I wrote below.
CREATE FUNCTION [dbo].[tf_GetAllUsersFromActiveDirectory]
()
RETURNS
#USERS TABLE
(
sAMAccountName VARCHAR(25) PRIMARY KEY CLUSTERED
, givenName VARCHAR(200)
, SN VARCHAR(200)
, userAccountControl VARBINARY(8)
, mail VARCHAR(200)
)
AS
BEGIN
INSERT INTO #Users
SELECT sAMAccountName,givenName, sn, userAccountControl,mail FROM OpenQuery(ADSI, '<LDAP://YourDomain.com:389>;(&(objectClass=User)(|(sAMAccountName=A*)(sAMAccountName=B*)(sAMAccountName=C*)(sAMAccountName=D*)) );sAMAccountName,givenName, sn, mail,userAccountControl;subtree')
UNION ALL
SELECT sAMAccountName,givenName, sn, userAccountControl,mail FROM OpenQuery(ADSI, '<LDAP://YourDomain.com:389>;(&(objectClass=User)(|(sAMAccountName=E*)(sAMAccountName=F*)(sAMAccountName=G*)(sAMAccountName=H*)) );sAMAccountName,givenName, sn, mail,userAccountControl;subtree')
UNION ALL
SELECT sAMAccountName,givenName, sn, userAccountControl,mail FROM OpenQuery(ADSI, '<LDAP://YourDomain.com:389>;(&(objectClass=User)(|(sAMAccountName=I*)(sAMAccountName=J*)(sAMAccountName=K*)(sAMAccountName=L*)) );sAMAccountName,givenName, sn, mail,userAccountControl;subtree')
UNION ALL
SELECT sAMAccountName,givenName, sn, userAccountControl,mail FROM OpenQuery(ADSI, '<LDAP://YourDomain.com:389>;(&(objectClass=User)(|(sAMAccountName=M*)(sAMAccountName=N*)(sAMAccountName=O*)(sAMAccountName=P*)) );sAMAccountName,givenName, sn, mail,userAccountControl;subtree')
UNION ALL
SELECT sAMAccountName,givenName, sn, userAccountControl,mail FROM OpenQuery(ADSI, '<LDAP://YourDomain.com:389>;(&(objectClass=User)(|(sAMAccountName=Q*)(sAMAccountName=R*)(sAMAccountName=S*)(sAMAccountName=T*)) );sAMAccountName,givenName, sn, mail,userAccountControl;subtree')
UNION ALL
SELECT sAMAccountName,givenName, sn, userAccountControl,mail FROM OpenQuery(ADSI, '<LDAP://YourDomain.com:389>;(&(objectClass=User)(|(sAMAccountName=U*)(sAMAccountName=V*)(sAMAccountName=W*)(sAMAccountName=X*)) );sAMAccountName,givenName, sn, mail,userAccountControl;subtree')
UNION ALL
SELECT sAMAccountName,givenName, sn, userAccountControl,mail FROM OpenQuery(ADSI, '<LDAP://YourDomain.com:389>;(&(objectClass=User)(|(sAMAccountName=Y*)(sAMAccountName=Z*)) );sAMAccountName,givenName, sn, mail,userAccountControl;subtree')
RETURN
END
GO
Just a note; to remove the link use
exec sp_dropserver 'ADSI';