Using Python to administer Samba-AD

You can find the official documentation of the api on the Samba website.

Note

Samba Python API are based on Python 3.6 or higher.

Importing the necessary Python libraries

#!/usr/bin/python
# -*- coding: utf-8 -*-
import getpass
import ldb
from samba.auth import system_session
from samba.credentials import Credentials
from samba.dcerpc import security
from samba.dcerpc.security import dom_sid
from samba.ndr import ndr_pack, ndr_unpack
from samba.param import LoadParm
from samba.samdb import SamDB

Creating the Python classes that will help you

  • For opening a connection in LDAP mode (with a network access):

    lp = LoadParm()
    creds = Credentials()
    creds.guess(lp)
    creds.set_username('user_account_name')
    creds.set_password('my_super_password')
    samdb = SamDB(url='ldap://127.0.0.1:389', session_info=system_session(),credentials=creds, lp=lp)
    
  • For opening a live connection on the LDB database (direct access to the LDB database files):

    lp = LoadParm()
    creds = Credentials()
    creds.guess(lp)
    samdb = SamDB(url='/var/lib/samba/private/sam.ldb', session_info=system_session(),credentials=creds, lp=lp)
    

Acting on the Organizational Units

Deleting an Organizational Unit

def delete_ou(samdb, dn):
    samdb.transaction_start()
    try:
        samdb.delete(dn)
    except:
        samdb.transaction_cancel()
        raise
    else:
        samdb.transaction_commit()

delete_ou(samdb,'OU=department,OU=city,DC=mydomain,DC=lan')

Creating an Organizational Unit

samdb.create_ou('OU=department,OU=city,DC=mydomain,DC=lan')

Acting on users

Creating a user

samdb.newuser(username="test-toto",password='password')

Deleting a user

samdb.deleteuser(username="jpdrole")

Setting a user’s password

samdb.setpassword("(sAMAccountName=test-toto)", "123456", force_change_at_next_login=False, username=None)

Moving a user to another Organizational Unit

samdb.rename('CN=test-toto,CN=Users,DC=mydomain,DC=lan','CN=test-toto,OU=tata,OU=tranquilit,DC=mydomain,DC=lan')

Acting on groups

Creating a group

samdb.newgroup(groupname='waptselfservice')

Adding a user or machine to a group

samdb.add_remove_group_members(groupname='waptselfservice', members=['test-toto','dcardon','vcardon'], add_members_operation=True)

Deleting a user or machine from a group

samdb.add_remove_group_members(groupname='waptselfservice', members=['test-toto','dcardon','vcardon'], add_members_operation=False)

Searching for objects in an Active Directory Samba Forest

Displaying all user, group, computer objects

query = "(|(objectclass=user)(objectclass=computer)(objectclass=group))"
result = samdb.search('DC=mydomain,DC=lan', expression=query, scope=ldb.SCOPE_SUBTREE)
for item in result:
    if 'sAMAccountName' in item:
        print(item['distinguishedName'])
        print(item['sAMAccountName'])

Searching for an object by its sAMAccountName

query = ("(sAMAccountName=test-toto)")
result = samdb.search('DC=mydomain,DC=lan', expression=query, scope=ldb.SCOPE_SUBTREE)

Acting on attributes

Modifying an attribute

Warning

Watch the indentation. The second line of the LDIF string (here changetype) and all subsequent lines must not be indented as is usually done in Python, because LDIF parsers do not accept spaces at the beginning of lines.

ldif_data = """dn: %s
changetype: modify
replace: mail
mail: test-toto@tranquil.it
""" % dn
samdb.modify_ldif(ldif_data)

Adding an attribute

Warning

Watch the indentation. The second line of the LDIF string (here changetype) and all subsequent lines must not be indented as is usually done in Python, because LDIF parsers do not accept spaces at the beginning of lines.

ldif_data = """dn: CN=test-toto,OU=tata,OU=tranquilit,DC=mydomain,DC=lan
changetype: modify
add: telephoneNumber
telephoneNumber: 0102030405
"""
samdb.modify_ldif(ldif_data)