简体   繁体   中英

Using Python win32 to lookup list of user emails in Windows LDAP

This GUI program allows one to supply a username ("auser001") and return their name, email, etc. I'd like to be able to script in Python a lookup for a list of hundreds of users, say using win32 or win32api , because this leverages my existing Windows login on the domain to authenticate with the LDAP server. That is, it doesn't require me to know the LDAP's hostname and login credentials, as other solutions posted on SO propose when using other packages (python-LDAP, etc.).

The closest I've come is getting my own email with the GetUserName() method:

import win32api
win32api.GetUserNameEx(8)

returns myemail@mydomain.com

The TranslateName() method looks like it provides the functionality I seek , but it's not in win32 or win32api from what I can tell. If win32 is not the way to go, then I'd appreciate a simple snippet using another package that leverages my domain's auth, so I don't have to track down my LDAP's creds. Thanks!

All traditional Win32 API functions can be called through ctypes :

import ctypes
from ctypes.wintypes import LPWSTR, ULONG, PULONG, BOOLEAN

_TranslateName = ctypes.windll["secur32"].TranslateNameW
#_TranslateName.argtypes = (LPWSTR, ULONG, ULONG, LPWSTR, PULONG)
_TranslateName.restype = BOOLEAN

def TranslateName(name, from_type, to_type):
    buf = ctypes.create_unicode_buffer(256)
    bufsz = ULONG(256)
    ret = _TranslateName(name,
                         from_type,
                         to_type,
                         buf,
                         ctypes.byref(bufsz))
    if not ret:
        raise ctypes.WinError()
    # I think I'm supposed to check the returned bufsz? Well, whatever
    return ctypes.wstring_at(buf)

name = TranslateName("test", NameUnknown, NameUserPrincipal)
print(f"=> {name!r}")

To be clear, GetUserNameEx() and TranslateName() return your UPN, not your email address – in some AD environments the two may be identical, but in many others they're completely unrelated.

a simple snippet using another package that leverages my domain's auth, so I don't have to track down my LDAP's creds. Thanks!

You're probably looking for the adsi module, which is the Win32 interface to AD (and pre-AD) directory services.

(The page says you need to download ADSI as well as provide credentials, but I have a suspicion that's very old documentation, possibly from before MS AD became a thing, because the same ADSI interface is always available eg through PowerShell and uses Kerberos automatically.)


You don't need to "know" credentials as long as your LDAP client supports GSSAPI or GSS-SPNEGO authentication – then it'll use your Kerberos tickets just like the actual Windows tools do.

It'll probably be more efficient because you get all results in batch from a single 'Search' operation, too.

Unfortunately ldap3 doesn't do GSSAPI-level encryption, so it'll only work if the DCs have TLS (LDAPS) set up (but if you're allowed to use password auth then TLS is probably available) and ldap probably won't build on Windows at all due to requiring libldap.

serv = ldap3.Server("ldaps://" + host,
                    tls=ldap3.Tls(validate=ssl.CERT_REQUIRED),
                    get_info=ldap3.DSA)
conn = ldap3.Connection(serv,
                        authentication=ldap3.SASL,
                        sasl_mechanism=ldap3.GSSAPI,
                        raise_exceptions=True)
with conn:
    # base_dn = serv.info.naming_contexts[0]
    # filter = "(sAMAccountName=%s)" % ldap3.utils.conv.escape_filter_chars(user)
    base_dn = "OU=Staff,O=Contoso Corp"
    ok = conn.search(base_dn, filter, ldap3.SUBTREE,
                     attributes=["userPrincipalName"])
    for e in conn.entries:
        something

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM