diff options
Diffstat (limited to 'source4/scripting')
-rw-r--r-- | source4/scripting/python/samba/upgrade.py | 109 |
1 files changed, 108 insertions, 1 deletions
diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index c19c7078ca..3779794ab5 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -31,6 +31,8 @@ from samba.samba3 import passdb from samba.samba3 import param as s3param from samba.dcerpc import lsa, samr, security from samba.dcerpc.security import dom_sid +from samba.credentials import Credentials +from samba.auth import system_session from samba import dsdb from samba.ndr import ndr_pack from samba import unix2nttime @@ -84,6 +86,38 @@ def import_sam_policy(samdb, policy, logger): except ldb.LdbError, e: logger.warn("Could not set account policy, (%s)", str(e)) +def add_posix_attrs(logger, samdb, sid, name, nisdomain, xid_type, home=None, shell=None, pgid=None): + """Add posix attributes for the user/group + + :param samdb: Samba4 sam.ldb database + :param sid: user/group sid + :param sid: user/group name + :param nisdomain: name of the (fake) NIS domain + :param xid_type: type of id (ID_TYPE_UID/ID_TYPE_GID) + :param home: user homedir (Unix homepath) + :param shell: user shell + :param pgid: users primary group id + """ + + try: + m = ldb.Message() + m.dn = ldb.Dn(samdb, "<SID=%s>" % str(sid)) + if xid_type == "ID_TYPE_UID": + m['unixHomeDirectory'] = ldb.MessageElement( + str(home), ldb.FLAG_MOD_REPLACE, 'unixHomeDirectory') + m['loginShell'] = ldb.MessageElement( + str(shell), ldb.FLAG_MOD_REPLACE, 'loginShell') + m['gidNumber'] = ldb.MessageElement( + str(pgid), ldb.FLAG_MOD_REPLACE, 'gidNumber') + + m['msSFU30NisDomain'] = ldb.MessageElement( + str(nisdomain), ldb.FLAG_MOD_REPLACE, 'msSFU30NisDomain') + + samdb.modify(m) + except ldb.LdbError, e: + logger.warn( + 'Could not add posix attrs for AD entry for sid=%s, (%s)', + str(sid), str(e)) def add_ad_posix_idmap_entry(samdb, sid, xid, xid_type, logger): """Create idmap entry @@ -484,6 +518,25 @@ def import_registry(samba4_registry, samba3_regdb): for (value_name, (value_type, value_data)) in samba3_regdb.values(key).items(): key_handle.set_value(value_name, value_type, value_data) +def get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, user, attr): + """Get posix attributes from a samba3 ldap backend + :param ldbs: a list of ldb connection objects + :param base_dn: the base_dn of the connection + :param user: the user to get the attribute for + :param attr: the attribute to be retrieved + """ + try: + msg = ldb_object.search(base_dn, scope=ldb.SCOPE_SUBTREE, + expression=("(&(objectClass=posixAccount)(uid=%s))" + % (user)), attrs=[attr]) + except ldb.LdbError, e: + logger.warning("Failed to retrieve attribute %s for user %s, the error is: %s", attr, user, e) + else: + if msg.count == 1: + return msg[0][attr][0] + else: + logger.warning("LDAP entry for user %s contains more than one %s", user, attr) + return None def upgrade_from_samba3(samba3, logger, targetdir, session_info=None, useeadb=False, dns_backend=None): """Upgrade from samba3 database to samba4 AD database @@ -529,6 +582,16 @@ def upgrade_from_samba3(samba3, logger, targetdir, session_info=None, useeadb=Fa except KeyError: machinepass = None + if samba3.lp.get("passdb backend").split(":")[0].strip() == "ldapsam": + base_dn = samba3.lp.get("ldap suffix") + ldapuser = samba3.lp.get("ldap admin dn") + ldappass = (secrets_db.get_ldap_bind_pw(ldapuser)).strip('\x00') + ldap = True + else: + ldapuser = None + ldappass = None + ldap = False + # We must close the direct pytdb database before the C code loads it secrets_db.close() @@ -672,7 +735,6 @@ Please fix this account before attempting to upgrade again logger.warn("Ignoring group memberships of '%s' %s: %s", username, user.user_sid, e) - logger.info("Next rid = %d", next_rid) # Check for same username/groupname @@ -733,6 +795,46 @@ Please fix this account before attempting to upgrade again logger.info("Importing idmap database") import_idmap(result.idmap, samba3, logger) + # Get posix attributes from ldap or the os + homes = {} + shells = {} + pgids = {} + if ldap: + creds = Credentials() + creds.guess(result.lp) + creds.set_bind_dn(ldapuser) + creds.set_password(ldappass) + urls = samba3.lp.get("passdb backend").split(":",1)[1].strip('"') + for url in urls.split(): + try: + ldb_object = Ldb(url, session_info=system_session(result.lp), credentials=creds, lp=result.lp) + except ldb.LdbError, e: + logger.warning("Could not open ldb connection to %s, the error message is: %s", url, e) + else: + break + logger.info("Exporting posix attributes") + userlist = s3db.search_users(0) + for entry in userlist: + username = entry['account_name'] + if username in uids.keys(): + if ldap: + homes[username] = get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, username, "homeDirectory") + shells[username] = get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, username, "loginShell") + pgids[username] = get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, username, "gidNumber") + else: + try: + homes[username] = pwd.getpwnam(username).pw_dir + except KeyError: + pass + try: + shells[username] = pwd.getpwnam(username).pw_shell + except KeyError: + pass + try: + pgids[username] = pwd.getpwnam(username).pw_gid + except KeyError: + pass + # Set the s3 context for samba4 configuration new_lp_ctx = s3param.get_context() new_lp_ctx.load(result.lp.configfile) @@ -750,6 +852,7 @@ Please fix this account before attempting to upgrade again if g.gid != -1: add_group_from_mapping_entry(result.samdb, g, logger) add_ad_posix_idmap_entry(result.samdb, g.sid, g.gid, "ID_TYPE_GID", logger) + add_posix_attrs(samdb=result.samdb, sid=g.sid, name=g.nt_name, nisdomain=domainname.lower(), xid_type="ID_TYPE_GID", logger=logger) # Export users to samba4 backend logger.info("Importing users") @@ -766,6 +869,10 @@ Please fix this account before attempting to upgrade again s4_passdb.add_sam_account(userdata[username]) if username in uids: add_ad_posix_idmap_entry(result.samdb, userdata[username].user_sid, uids[username], "ID_TYPE_UID", logger) + if (username in homes) and (homes[username] != None) and \ + (username in shells) and (shells[username] != None) and \ + (username in pgids) and (pgids[username] != None): + add_posix_attrs(samdb=result.samdb, sid=userdata[username].user_sid, name=username, nisdomain=domainname.lower(), xid_type="ID_TYPE_UID", home=homes[username], shell=shells[username], pgid=pgids[username], logger=logger) logger.info("Adding users to groups") for g in grouplist: |