How to authenticate LDAP properly? - python-3.x

I am working on a project that must use LDAP authentication. I am using the server at ldap.forumsys.com after finding the link on Stack Overflow to practice before adding to my Flask application.
If I run the ldapsearch bash command inside of my python code I get a whole bunch of usernames (Tesla etc...) and their associated data (there are no password hashes though). I am able to extract the usernames/user-data as shown here:
username = request.form['username']
password = request.form['password']
cmd = "ldapsearch -h ldap.forumsys.com -D cn=read-only-admin,dc=example,dc=com -w" + os.environ['LDAP_PWD'] + " -b dc=example,dc=com"
ldap_query = os.popen(cmd).read()
user_str = re.sub("\n", "", ldap_query)
users = user_str.split("#")
user_data = ""
for line in users:
if username in line:
user_data = line
break
But then I realized that I LDAP is not the same as a database. I was hoping to find password hashes that I could use to authenticate a user's login information.
So then I tried the python-ldap3 module:
>>> conn = Connection(server, 'uid=tesla,dc=example,dc=com', 'password', auto_bind=True)
>>> conn.bound
True
>>> conn.entries
[]
Unfortunately I can't seem to get any data returned in the list after calling conn.entries.
I can see that the ldap3 module binded the connection. Does the ldapsearch command bind as well? If there are no password hashes, how should I authenticate the username/password entered by the user on the client side?
Thank you all very much.

If the statement...
conn.bound == True
Then the connection has been authenticated via LDAP

Related

Python3 telnetlib - telnet with username and password and then execute other commands

I would like to be able to telnet, input login and password credentials and then execute commands once connected but my code seems to not continue after password is entered.
import getpass
import telnetlib
HOST = "172.25.1.1"
user = input("Enter your remote account: ")
password = getpass.getpass()
tn = telnetlib.Telnet(HOST)
tn.read_until(b"login: ")
tn.write(user.encode('utf-8') + "\n")
if password:
tn.read_until(b"Password: ")
tn.write(password.encode('utf-8') + "\n")
tn.write(b"command to be issued")
print(tn.read_all())
with this code I want to telnet, input login credentials, input password, and once connected issue a command
Looks like the problem was a timing issue, I needed to import time and add time.sleep(2) after issuing the command before print(tn.read_all()).

LDAP Query in Python3

I have an LDAP Query which is running perfectly fine in my terminal
ldapsearch -h ldap.mygreatcompany.com -D user#mygreatcompany.COM -w "$ldappassword" -b "DC=abc,DC=mygreatcompany,DC=com" -s sub "(mail=user1#mygreatcompany.COM)" sAMAccountName
I want to run this command in python3, I followed other answers from StackOverflow and wrote something like this,
import ldap
l = ldap.initialize('ldap://ldap.mygreatcompany.com')
binddn = "user#mygreatcompany.COM"
pw = #ldappassword
basedn = "DC=abc,DC=mygreatcompany,DC=com"
searchAttribute = ["sAMAccountName"]
searchFilter = "(&(mail=user1#mygreatcompany.COM')(objectClass=*))"
searchScope = ldap.SCOPE_SUBTREE
l.simple_bind_s(binddn, pw)
ldap_result_id = l.search_s(basedn, searchScope, searchFilter, searchAttribute)
#Get result
l.unbind_s()
But Here I am not getting the result from ldap_result_id. Can anybody help what is the correct way to do this query?
Thanks
It turns out that I was not using connection.set_option(ldap.OPT_REFERRALS, 0) in the code and there is some issue in LDAP which automatically chases the referrals internally with anonymous access which fails.
Here is the working code:
def get_user_id(email):
# Seach fiter for user mail
searchFilter = "mail={}".format(email)
try:
# binding to ldap server
connection = ldap.initialize('ldap://yourcompanyhost')
connection.set_option(ldap.OPT_REFERRALS, 0)
connection.protocol_version = ldap.VERSION3
connection.simple_bind_s(binddn, pwd)
# get result
ldap_result_id = connection.search_s(basedn, searchScope, searchFilter, searchAttribute)
# extract the id
saMAccount = ldap_result_id[0][1]["sAMAccountName"][0].decode('utf-8')
except ldap.INVALID_CREDENTIALS:
print("Your username or password is incorrect.")
except ldap.LDAPError as e:
print(e)
except:
print("Data doesn't exist for this user")
connection.unbind_s()
print(get_user_id("user1#mygreatcompany.COM"))

How we can find the message id which we have to provide to gamil api to get the message via python (imap,email module)

I am able to get the uid and message-id but unable to get decode that message id to use through google api where i can find further information about it.
I want to get the thread id from that message id
Using python3.7
import imaplib, email
mail = imaplib.IMAP4_SSL('imap.gmail.com')
username = 'id'
password = 'password'
mail.login(username, password)
mail.list()
# Out: list of "folders" aka labels in gmail.
mail.select("inbox") # connect to inbox.
date = (datetime.date.today() - datetime.timedelta(1)).strftime("%d-%b-%Y")
result, data = mail.uid('search', None, '(SENTSINCE {date})'.format(date=date))
email_uid = data[0].split()
for uid in email_uid[:
print(mail.uid('fetch', uid, '(RFC822)'))
please help as soon as possible
Most likely you need a uid.
Read it https://www.rfc-editor.org/rfc/rfc3501#page-8
This lib may help you: https://github.com/ikvk/imap_tools

ldap3 add user to group after conn.search

currently, I am writing an AWS Lambda function and the idea is, that someone can send an email to a specific address with a username and AD group and it will trigger the function and add this person to the desired group.
I am using the python module ldap3 and the conn.search part is working, aswell as the addUsersInGroup, but only if I run it separately. If I create a script where I already have the cn or dn name of both user and group and use the addUsersInGroup Function it works, but if I do a conn.search somewhere before it somehow can't establish the connection for the add-to-group part.
from ldap3 import Server, Connection, ALL, NTLM, SUBTREE
from ldap3.extend.microsoft.addMembersToGroups import ad_add_members_to_groups as addUsersInGroups
import email
import os
import json
email = "sample#test.com"
subject = "username,ad-group"
user = subject.split(",")[0]
group = subject.split(",")[1]
emaildomain = email.split("#")[1]
domaingroup = ["test.com"]
adgroups = ["group1","group2"]
server = Server('serverIP', use_ssl=True, get_info=ALL)
conn = Connection(server, OU,
password, auto_bind=True)
def find_user():
user_criteria = "(&(objectClass=user)(sAMAccountName=%s))"%user
if conn.search("OU", user_criteria):
result = str(conn.entries)
user_dn = result.split("-")[0].replace("[DN: ","")
return user_dn
return nouser
def find_group():
group_criteria = "(&(objectClass=group)(sAMAccountName=%s))"%group
if conn.search("OU", group_criteria):
result_group = str(conn.entries)
group_dn = result_group.split("-")[0].replace("[DN: ","")
return group_dn
return nogroup
def add_to_group(user,group):
addUsersInGroups(conn,user,group)
if emaildomain in domaingroup:
user = find_user()
group = find_group()
add_to_group(user,group)
Please note that I had to delete some things off the script for security reasons.
The connection to search for a user or group is working and if I run the add-to-group function it works too, but only running it without any search beforehand.
Somehow I have the feeling that making the conn.search blocks the connection for anything search related and if try to use the same connection for something different e.g. adding a user to group, that request gets blocked.
Here is the error I receive:
Error_Message
Found the solution on this website:
https://github.com/cannatag/ldap3/issues/442
You are getting this error probably due to auto_referrals=True in Connection by default. Try to use:
conn = Connection(server, "cn=xxx,cn=users,dc=wwww,dc=zzzz,dc=com", "my_pass", auto_bind=True, auto_referrals=False) and do not search and another DC.

call OAUTH2 api in python script

i have found this interesting article here https://developer.byu.edu/docs/consume-api/use-api/oauth-20/oauth-20-python-sample-code
in this article there is an example how to call an oauth2 api using authorization_code flow. the problem with this approach is that you need to open a new browser, get the code and paste in the script. i would open and get the code directly from python script. is it possible?
print "go to the following url on the browser and enter the code from the
returned url: "
print "--- " + authorization_redirect_url + " ---"
access_token = raw_input('access_token: ')
I have been battling with this same problem today and found that the following worked for me. You'll need:
An API ID
A secret key
the access token url
I then used requests_oauthlib: https://github.com/requests/requests-oauthlib
from requests_oauthlib import OAuth2Session
# Both id and secret should be provided by whoever owns the api
myid = 'ID_Supplied'
my_secret = 'Secret_pass'
access_token_url = "https://example.com/connect/token" # suffix is also an example
client = BackendApplicationClient(client_id=myid)
oauth = OAuth2Session(client=client)
token = oauth.fetch_token(token_url=access_token_url, client_id=myid,
client_secret=my_secret)
print(token)

Resources