Adding AD group with python-ldap - python

I am trying to create group within AD with no success, below is my code:
import ldap
import ldap.modlist as modlist
LDAPserver = 'hidden'
LDAPlogin = 'hidden'
LDAPpassword = 'hidden'
l = ldap.initialize('ldap://' + LDAPserver)
l.simple_bind_s(LDAPlogin, LDAPpassword)
dn = 'OU=someunit,OU=someunit,OU=someunit,OU=someunit,DC=my-company,DC=local'
attrs = {}
attrs['objectclass'] = ['top','Group']
attrs['cn'] = 'group name to be created'
attrs['description'] = 'Test Group'
ldif = modlist.addModlist(attrs)
l.add_s(dn,ldif)
l.unbind_s()
Following snippet gives me an error:
ldap.INSUFFICIENT_ACCESS: {'info': '00000005: SecErr: DSID-031521D0, problem 4003
(INSUFF_ACCESS_RIGHTS), data 0\n', 'desc': 'Insufficient access'}
However, using same credentials I can create group with some UI tools like LDAP Admin
so I suppose that I have proper permissions to create groups, but still no success with python-ldap.
I can also query existing groups and fetch its members via script.
I believe that the problem is in my attributes, maybe Active Directory need some different values to be inserted into attrs variable. AD is running under Win Server 2012 R2.
Any help would be appreciated :)

The dn should actually be CN=<groupname> + base_dn, so in your case something like
dn = 'CN=groupname,OU=someunit,OU=someunit,OU=someunit,OU=someunit,DC=my-company,DC=local'

Please try to replace LDAPlogin to a full bind dn value such as
"cn=hidden,dc=example,dc=com"

Related

Having issues with accessing activity tables though Oracle Eloqua's API in python

So I am working with Eloqua's API gets in python and was successfully able to connect to a varity of endpoints using this method, but am having trouble connecting to the Activity tables (see referenced documentation)
Here is the code the I am trying to run:
id = 123
startDate = 1656685075
endDate = 1659363475
type = 'emailOpen'
url_eloqua = f'http://secure.p04.eloqua.com/API/REST/1.0/data/activities/contact/{id}?type={type}&startDate={startDate}&endDate={endDate}'
print(url_eloqua)
user_eloqua = dbutils.secrets.get(scope = "abc", key = "Eloqua_User")
password_eloqua = dbutils.secrets.get(scope = "abc", key = "Eloqua_Pswd")
results = requests.get(url_eloqua, auth=HTTPBasicAuth(user_eloqua, password_eloqua), headers={'Content-Type':'application/json'}).json()
results
And here is the response that I am getting both in postman and in python:
http://secure.p04.eloqua.com/API/REST/1.0/data/activities/contact/123?type=emailOpen&startDate=1656685075&endDate=1659363475
Out[65]: {'Message': 'There was an error processing the request.',
'StackTrace': '',
'ExceptionType': ''}
Does anyone know what I am doing wrong here? I could really use some support in getting this to work. It lookes to be formated correctly and the general format matches other endpoints build that have successfully produced and output. The id is made up here but the real id is associated with a confirmed id in Eloqua.
Nevermind. My issue was that I was associated the wrong id. Was inputing the activity id instead of the contact id.

Python3 LDAP query to get name and email of a specific group

I would like to get the users' name and email of a specific group when querying an LDAP server using ldap3 Python library.
I have been trying the following command, but I am not getting also the email address.
c.search(search_base=LDAP_BASE,search_filter=("(&(objectclass=group)(cn=test-group))"),attributes=["*"])
Any idea how to get have this filter to retrieve the desired data?
This query is not retrieving also the email address.
Thank you.
If everyone needs the same query, here is the answer:
# Firstly find out the DN associated with LDAP group
c.search(base_dn, '(sAMAccountName="test-group")',
search_scope=SUBTREE, attributes=['distinguishedName', 'member'])
dn_json = json.loads(c.response_to_json())
distinguished_name = dn_json["entries"][0]["attributes"]["distinguishedName"]
# Retrieve data based on DN
c.search(base_dn, '(&(objectclass=user)(memberOf={}))'.format(distinguished_name),
attributes=["givenName", "sn", "mail"])
user_data = json.loads(c.response_to_json())
for index in range(len(user_data["entries"])):
first_name = user_data["entries"][index]["attributes"]["givenName"]
surname = user_data["entries"][index]["attributes"]["sn"]
mail = user_data["entries"][index]["attributes"]["mail"]

Error - UNWILLING_TO_PERFORM - while change user password in AD ldap using python code

I am creating a simple python function to change the user password. I have tested my AD set up, able to search the user and get correct response but when try to run l.modify_s, I get the below error. AD user has the required permissions. Not sure why am I getting this error.
Any help will be great. Please let me know if you need any more information or code as well to understand the issue better.
"errorType": "**UNWILLING_TO_PERFORM**",
"errorMessage": "{'info': u'0000001F: SvcErr: DSID-031A12D2, problem 5003 (WILL_NOT_PERFORM), data 0\\n', 'msgid': 3, 'msgtype': 103, 'result': 53, 'desc': u'Server is unwilling to perform', 'ctrls': []}"
}```
Please find my code below
``` import ldap
import os
import boto3
import random
import string
from base64 import b64decode
import ldap
def lambda_handler(event, context):
try:
cert = os.path.join('/Users/marsh79/Downloads', 'Serverssl.cer')
print "My cert is", cert
# LDAP connection initialization
l = ldap.initialize('ldap://example.corp.com')
# Set LDAP protocol version used
l.protocol_version = ldap.VERSION3
#Force cert validation
l.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
# Set path name of file containing all trusted CA certificates
l.set_option(ldap.OPT_X_TLS_CACERTFILE, cert)
# Force libldap to create a new SSL context (must be last TLS option!)
l.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
bind = l.simple_bind_s("admin#corp.example.com", "secret_pass")
base = "OU=Enterprise,OU=Users,OU=corp,DC=corp,DC=example,DC=com"
criteria = "(objectClass=user)"
attributes = ['distinguishedName']
result = l.search_s(base, ldap.SCOPE_SUBTREE, criteria, attributes)
results = [entry for dn, entry in result if isinstance(entry, dict)]
new_password='secretpass_new'
unicode_pass = unicode('\"' + new_password + '\"', 'iso-8859-1')
password_value = unicode_pass.encode('utf-16-le')
add_pass = [(ldap.MOD_REPLACE, 'unicodePwd', [password_value])]
print "My result distinguishedName1:", results[0]['distinguishedName'][0]
print "My result distinguishedName2:", results[1]['distinguishedName'][0]
l.modify_s(results[0]['distinguishedName'][0],add_pass)
print results
finally:
l.unbind()
I have checked multiple things
Password complexity is good
Enabled secured ldap on my AD server and tested this using ldp.exe and I can connect using port 636
I am able to run this code if I just need to search the user. I get the search results.
But when I try to modify the password, it breaks and my head is just throwing up to work out where it is going wrong :X
I'm not a Python programmer, but I know how AD and LDAP works. It's probably still not connected via LDAPS. From examples I've seen online, you might need to specify ldaps://:
l = ldap.initialize('ldaps://<server name>.corp.example.com')
Or possibly the port as well:
l = ldap.initialize('ldaps://<server name>.corp.example.com:636')
You don't need to supply the cert file on the client side, but the issuer of the certificate on the server must be trusted by the client computer. I guess that's what you're trying to do with cert. But you may not have to. Try without that and see what happens. If you're running this on Windows, it may use the Trusted Certificate Store from Windows itself and it should work as long as the server isn't using a self-signed cert.

How to bind (authenticate) a user with ldap3 in python3

I'm trying to update some code to python3, using ldap3 version '0.9.7.4'.
(https://pypi.python.org/pypi/ldap3)
Previously, I used python-ldap with python2 to authenticate a user like this:
import ldap
address = "ldap://HOST:389"
con = ldap.initialize(address)
base_dn = "ourDN=jjj"
con.protocol_version = ldap.VERSION3
search_filter = "(uid=USERNAME)"
result = con.search_s(base_dn, ldap.SCOPE_SUBTREE, search_filter, None)
user_dn = result[0][0] # get the user DN
con.simple_bind_s(user_dn, "PASSWORD")
This properly returns (97, [], 2, []) on correct password, and raises ldap.INVALID_CREDENTIALS on a bind attempt using an incorrect password.
Using ldap3 in python3 I'm doing the following:
from ldap3 import Server, Connection, AUTH_SIMPLE, STRATEGY_SYNC, ALL
s = Server(HOST, port=389, get_info=ALL)
c = Connection(s, authentication=AUTH_SIMPLE, user=user_dn, password=PASSWORD, check_names=True, lazy=False, client_strategy=STRATEGY_SYNC, raise_exceptions=True)
c.open()
c.bind()
It's raising the following exception:
ldap3.core.exceptions.LDAPInvalidCredentialsResult: LDAPInvalidCredentialsResult - 49 - invalidCredentials - [{'dn': '', 'message': '', 'type': 'bindResponse', 'result': 0, 'saslCreds': 'None', 'description': 'success', 'referrals': None}]
I'm using the user_dn value returned by python2's ldap search, since this appears to be working in python2.
How can I get this to bind properly using ldap3 in python3?
(One thing strange, I noticed, is that the ldap3's LDAPInvalidCredentialsResult includes 'description': 'success'. I'm guessing this just means response successfully recieved...)
I'm the author of ldap3, please set raise_exceptions=False in the Connection definition and check the connection.result after the bind. You should get the reason why your bind() is unsuccessful.
Confirm that your DN doesn't need to escape a comma using backslash \.
My organization gives users a CN of "last name, first name", so my DN needed to be "CN=Doe\, Jane, OU=xyz, ..., DC=abc, DC=com"
I realized this by using Active Directory Explorer to navigate to my user object, r-click > view properties to see the distinguished name. I ran into this invalid credential error when using the DN that AD Explorer displays in its Path breadcrumb which omits the escape character.

python-ldap creating a group

I'm trying to create a security group in AD from a python script with python-ldap.
I'm able to bind my user which has sufficient rights to perform such an operation (confirmed by creating the group from ADExplorer gui client) and search the domain, but when it comes to adding the new group it fails with:
ldap.INSUFFICIENT_ACCESS: {'info': '00000005: SecErr: DSID-03152492, problem 4003 (INSUFF_ACCESS_RIGHTS), data 0\n', 'desc': 'Insufficient access'}
This is the script:
import ldap
import ldap.modlist as modlist
server = 'hidden'
user_dn = 'hidden'
user_pw = 'hidden'
fs_dn = 'ou=fssecuritygroups,ou=tkogroups,ou=tokyo,dc=unit,dc=xyz,dc=intra'
l = ldap.initialize("ldaps://"+server)
l.bind_s(user_dn, user_pw)
groupname = 'mytestfs'
attr = {}
attr['objectClass'] = ['group','top']
attr['groupType'] = '-2147483646'
attr['cn'] = groupname
attr['name'] = groupname
attr['sAMAccountName'] = groupname
ldif = modlist.addModlist(attr)
print(l.add_s(fs_dn,ldif))
I got the same error when I try to add a new object under a dn where I am not allowed to add.
E.g. I have access rights to the ldap-server (binding works), I'm allowed to add group-objects under ou=germany,ou=groups,dc=ACME - but I'm not allowed to add a group-object under ou=groups,dc=ACME.
Maybe you checkout the constraints of the ldap or the like.

Categories

Resources