Python LDAP authentication to a Security Group in Active Directory - python

the authentication to Active directory using python-ldap works well with the code below, now trying to find how can I verify
if a user belongs to a Security Group to be successfully authentificate but cannot figure out how to do that.
I have this code integrated in a flask website.
Here is my code:
import ldap
def authenticate():
conn = ldap.initialize('ldap://ldap.example.com')
conn.protocol_version = 3
conn.set_option(ldap.OPT_REFERRALS, 0)
try:
username = 'user_id'
password = 'motdepasse'
user = "%s#domain" %username
result = conn.simple_bind_s('user', 'password')
except ldap.INVALID_CREDENTIALS:
print "Invalid credentials"
return "Invalid credentials"
except ldap.SERVER_DOWN:
print "Server down"
return "Server down"
except ldap.LDAPError, e:
if type(e.message) == dict and e.message.has_key('desc'):
return "Other LDAP error: " + e.message['desc']
else:
print "Other LDAP error: "
return "Other LDAP error: " + e
finally:
conn.unbind_s()
print "Succesfully"
return "Succesfully authenticated"
authenticate()
Thanks for your help

To restrict the LDAP authentication to a specific AD group I used the "search_s function" which find if the authenticated user is part of a AD group.
conn.search_s("OU={AD Security Group},OU=group,OU=Groups,dc=twpn,dc=root,dc=domain,dc=com", ldap.SCOPE_SUBTREE, "(cn=userid)")

Related

pysmb listpath method return error "SMB connection not authenticated"

I'm using pysmb to connect a server (192.168.1.54) the code are:
host = '192.168.1.54' # server IP
username = 'Test'
password = 'test'
my_name = "localmac"
remote_name = "servermac"
try:
conn = SMBConnection(username, password, my_name, remote_name, is_direct_tcp=True)
except Exception as e:
print (e)
return
try:
conn.connect(host,445) #
except Exception as e:
print (e)
return
bytedata = 'hello'.encode()
print(conn.echo(bytedata, timeout=10))
print(conn.is_using_smb2)
for i in conn.listPath('misc', ''):
print(i.filename, i.create_time)
the two 'print' codes run smoothly and the listPath function returned the error "SMB connection not authenticated". Why? if not authenticated, why the echo sentence didn't return error?
Any comments or helps are appreciated!
1) If you are sure that the username and password correct, check the version of pysmb.
I had similar problem with pysmb==1.2.6, so if you're using this version too, update to 1.2.8.
The problem was with pysmb's own implementation of MD4 algorithm.
When there is no MD4 in Python's hashlib pysmb uses its own algorithm:
try:
import hashlib
hashlib.new('md4')
def MD4(): return hashlib.new('md4')
except ( ImportError, ValueError ):
from .utils.md4 import MD4
So if it possible update to pysmb==1.2.8 where this problem was fixed.
2) if not authenticated, why the echo sentence didn't return error?
The echo command does not require authentication, it just sends data to the remote server and remote server replies with the same data.

Error handling in python with ldap

I have this bit of code below, it is part of a python script iv been working on(piecing it together blocks at a time as learning curve). This bit binds to an ldap directory to query, so the rest of the script can to the queries.
When successful, it will print the below message in the block. When not successful it will throw an error- or at least i want to control the error.
If im not domain bound/vpn it will throw this message:
{'desc': "Can't contact LDAP server"}
if incorrect credentials :
Invalid credentials
nowhere in my script is it defined for the error message, how can i find where its fetching what to print that messsage- and possibly create or customize it?
(for what its worth i am using PyCharm)
try:
l = ldap.open(server)
l.simple_bind_s(user, pwd)
#if connection is successful print:
print "successfully bound to %s.\n" %server
l.protocol_version = ldap.VERSION3
except ldap.LDAPError, e:
print e
thanks
you can do something like this to provide a specific message for a specific exception.
try:
foo = 'hi'
bar = 'hello'
#do stuff
except ValueError:
raise ValueError("invalid credientials: {},{}".format(foo, bar))
so in your example it could become
except ldap.LDAPError:
raise ldap.LDAPError("invalid credientials: {},{}".format(user, pwd))
or if you literally just want to print it
except ldap.LDAPError:
print("invalid credientials: {},{}".format(user, pwd))

How can we check if our app is installed for some organizations but not all of them?

We created an application for Google Apps Marketplace. Our app works only if it's installed for everyone. But the problem is, some customers install our app for some organizations, not everyone. We want to display a specific message to those customers, but the problem is that we don't know if our app is installed for some organizations, or not installed at all. Therefore, customers who installed our app for some organizations get a message which is intended for customers who didn't install our app at all. We show them the install button but nothing happens when they install our app again, because it's already installed. We want to give them instructions how to change our app's status to "on for everyone".
How can we check if our app is installed for some organizations? We get the following error message from Google:
Failed to retrieve access token: {
"error" : "unauthorized_client",
"error_description" : "Unauthorized client or scope in request."
}
Which is the same error message we receive for cutomers who didn't install our app at all.
This is the Python function who throws the exception:
def _do_refresh_request(self, http_request):
"""Refresh the access_token using the refresh_token.
Args:
http_request: callable, a callable that matches the method signature of
httplib2.Http.request, used to make the refresh request.
Raises:
AccessTokenRefreshError: When the refresh fails.
"""
body = self._generate_refresh_request_body()
headers = self._generate_refresh_request_headers()
logger.info('Refreshing access_token')
resp, content = http_request(
self.token_uri, method='POST', body=body, headers=headers)
if resp.status == 200:
# TODO(jcgregorio) Raise an error if loads fails?
d = simplejson.loads(content)
self.token_response = d
self.access_token = d['access_token']
self.refresh_token = d.get('refresh_token', self.refresh_token)
if 'expires_in' in d:
self.token_expiry = datetime.timedelta(
seconds=int(d['expires_in'])) + datetime.datetime.utcnow()
else:
self.token_expiry = None
if self.store:
self.store.locked_put(self)
else:
# An {'error':...} response body means the token is expired or revoked,
# so we flag the credentials as such.
logger.info('Failed to retrieve access token: %s' % content)
error_msg = 'Invalid response %s.' % resp['status']
try:
d = simplejson.loads(content)
if 'error' in d:
error_msg = d['error']
self.invalid = True
if self.store:
self.store.locked_put(self)
except StandardError:
pass
raise AccessTokenRefreshError(error_msg)
Update 1: in Apps > Marketplace apps, an app can be on for everyone, on for selected orgs or off. We need to know the status of our app.
Update 2: I tried calling check_general_access but also when our application is uninstalled we receive True (Application has general access). This is after we confirmed that check_access returned False.
#staticmethod
def check_access(admin_email):
http = httplib2.Http()
credentials = SignedJwtAssertionCredentials(
SERVICE_EMAIL,
PRIVATE_KEY,
scope='https://apps-apis.google.com/a/feeds/emailsettings/2.0/ https://www.googleapis.com/auth/admin.directory.user.readonly',
sub=str(admin_email),
)
http = credentials.authorize(http)
try:
service = build(serviceName='admin', version='directory_v1', http=http)
logging.info("Application has access to admin's %s domain" % (admin_email))
return True
except Exception as e:
logging.info("Application does not have access to admin's %s domain (exception: %s)" % (admin_email, e.message))
return False
#staticmethod
def check_general_access():
http = httplib2.Http()
credentials = SignedJwtAssertionCredentials(
SERVICE_EMAIL,
PRIVATE_KEY,
scope='https://apps-apis.google.com/a/feeds/emailsettings/2.0/ https://www.googleapis.com/auth/admin.directory.user.readonly',
)
http = credentials.authorize(http)
try:
service = build(serviceName='admin', version='directory_v1', http=http)
logging.info("Application has general access")
return True
except Exception as e:
logging.info("Application does not have general access (exception: %s)" % e.message)
return False
Not sure, but may have found a way. From the documentation I asserted that domain wide access is needed to impersonate a user within the target domain. Service apps do not need this for other tasks. While convoluted, you can test if you get credentials without the sub parameter to SignedJwtAssertionCredentials. If this succeeds, but adding the sub parameter fails, you're installed but not domain wide.
Let us know if this works and obviously Google has some work to do there still.
You can add ping back, every hour or so call some end point. If the ping was too long ago they probably remove the app

Exception Handling in google app engine

i am raising exception using
if UserId == '' and Password == '':
raise Exception.MyException , "wrong userId or password"
but i want print the error message on same page
class MyException(Exception):
def __init__(self,msg):
Exception.__init__(self,msg)
You are not using the Users API? Assuming you are handling a POST request, how about this:
class LoginError(Exception):
CODES = { 'mismatch': 'Wrong credentials', 'disabled': 'Account disabled' }
...
try:
// your authentication code
raise LoginError('mismatch')
...
raise LoginError('disabled')
except LoginError as e:
self.redirect(your_login_url + '?err=' + e)
# In login page you must not print arbitrary GET parameter directly
err_reason = LoginError.CODES[self.request.get('err')]`
(Login request should be using POST method because it changes the server's state, and it's good habit to redirect after a POST, thus a redirect.)
Why raising an exception instead of just stop function execution and redirect to new page using return statement

Python2.6 xmpp Jabber Error

I am using xmpp with python and I want create a simple client to communicate with a gmail
id.
#!/usr/bin/python
import xmpp
login = 'Your.Login' # #gmail.com
pwd = 'YourPassword'
cnx = xmpp.Client('gmail.com')
cnx.connect( server=('talk.google.com',5223) )
cnx.auth(login,pwd, 'botty')
cnx.send( xmpp.Message( "YourFriend#gmail.com" ,"Hello World form Python" ) )
When I run the last line I get an exception
IOError: Disconnected from server.
Also when I run the other statements I get debug messages in the console.
What could be the issue and how can I resolve it ?
Here is how it did on my PyTalk client.
Don't forget the #gmail.com in the userID.
I think you should try to connect talk.google.com on the 5222 port.
Also try to specify a ressource for the auth.
import xmpp
import sys
userID = 'Your.Login#gmail.com'
password = 'YourPassword'
ressource = 'Script'
jid = xmpp.protocol.JID(userID)
jabber = xmpp.Client(jid.getDomain(), debug=[])
connection = jabber.connect(('talk.google.com',5222))
if not connection:
sys.stderr.write('Could not connect\n')
else:
sys.stderr.write('Connected with %s\n' % connection)
auth = jabber.auth(jid.getNode(), password, ressource)
if not auth:
sys.stderr.write("Could not authenticate\n")
else:
sys.stderr.write('Authenticate using %s\n' % auth)
jabber.sendInitPresence(requestRoster=1)
jabber.send(xmpp.Message( "YourFriend#gmail.com" ,"Hello World form Python" ))
By the way, it looks very close from Philip Answer
Try this code snippet. I didn't handle the error conditions for simplicity's sake.
import xmpp
login = 'Your.Login' # #gmail.com
pwd = 'YourPassword'
jid = xmpp.protocol.JID(login)
cl = xmpp.Client(jid.getDomain(), debug=[])
if cl.connect(('talk.google.com',5223)):
print "Connected"
else:
print "Connectioned failed"
if cl.auth(jid.getNode(), pwd):
cl.sendInitPresence()
cl.send(xmpp.Message( "YourFriend#gmail.com" ,"Hello World form Python" ))
else:
print "Authentication failed"
To switch off the debugging messages, pass debug=[] for the 2nd parameter on the Client class's constructor:
cl = xmpp.Client(jid.getDomain(), debug=[])
i think you must write this. i test it in python 2.7 with xmpppy 0.5.0rc1 and work IT very nice :P :) :
import xmpp
login = 'your mail#gmail.com' # #gmail.com
pwd = 'your pass'
text='Hello worlD!'
tojid='your friend #gmail.com'
jid = xmpp.protocol.JID(login)
cl = xmpp.Client(jid.getDomain(), debug=[])
if cl.connect(('talk.google.com',5223)):
print "Connected"
else:
print "Connectioned failed"
if cl.auth(jid.getNode(), pwd):
cl.sendInitPresence()
cl.send(xmpp.protocol.Message(tojid,text))
else:
print "Authentication failed"
I think you need to call sendInitPresence before sending the first message:
...
cnx.auth(login,pwd, 'botty')
cnx.sendInitPresence()
cnx.send( xmpp.Message( "YourFriend#gmail.com" ,"Hello World form Python" ) )

Categories