On Sat, 2006-01-14 at 18:58 -0600, Oscar A. Valdez wrote: > I've followed the Samba & Fedora Directory Server Integration How-To > located at http://directory.fedora.redhat.com/wiki/Howto:Samba , and I'm > about to upload my user accounts into the DS. I have two questions > before I proceed, though: > > 1) At the end of the How-To, a "testuser" is added to the Samba server > with the "smbpasswd -a" command. Wouldn't the DS make the user accounts > visible to the Samba server, making it unecessary to add them via > smbpasswd? If it's really necessary to add the accounts via smbpasswd, > then the DS isn't really a backend to the Samba Server: they would be > acting in parallel. Yeah, it sucks. One of the main issues is that for SMB authentication each user's password needs to be stored in LM and NT formats in the sambaNTPassword and sambaLMPassword attributes. So, when the user set its password, some code needs to have access to the plaintext password and translate it into LM and NT format. The easiest way is to use smbpassword, but you could use your own code to set the password in all formats at once .... or, I'm sure you could right a fedora-ds plugin which would save the password in those formats whenever it is set. But it doesn't end there. Even just for SMB authentication, there are other attributes which smbpasswd manages and there's a lot of voodoo involved. To give you idea of the kind of stuff you need to do in order to not use smbpasswd, see the code below. I wish I could explain the code in detail, but I've forgotten a lot of the details. Cheers, Mark. ... # # Copyright (C) 2006 Red Hat, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # SAMBA_RID_MULTIPLIER = 2 SAMBA_RID_BASE = 1000 SAMBA_USER_RID_TYPE = 0x0 SAMBA_USER_GID_TYPE = 0x1 SAMBA_LM_HASH_MAGIC = "KGS!@#$%" ... def _get_machine_sid (self): if not self.machine_sid is None: return self.machine_sid output = commands.getoutput ("net getlocalsid") for line in output.split ("\n"): if line.startswith ("SID for domain"): parts = line.split (":") if len (parts) >= 2: self.machine_sid = parts[1].strip () break return self.machine_sid def _get_user_sid (self, uid): machine_sid = self._get_machine_sid () user_rid = ((uid * SAMBA_RID_MULTIPLIER) + SAMBA_RID_BASE) | SAMBA_USER_RID_TYPE return machine_sid + "-" + str (user_rid) def _get_group_sid (self, gid): machine_sid = self._get_machine_sid () group_rid = ((gid * SAMBA_RID_MULTIPLIER) + SAMBA_RID_BASE) | SAMBA_USER_GID_TYPE return machine_sid + "-" + str (group_rid) def add_user_attributes (self, username, uid, gid, password): def get_nt_password (plaintext): hash = MD4.new () hash.update (plaintext.encode ("utf-16-le")) return hash.hexdigest ().upper () def get_lm_password (plaintext): def lm_hash (pw7): a7 = array.array ("B", pw7.upper ().encode ("850")) while len (a7) < 7: a7.append (0) a8 = array.array ("B") a8.append ( a7[0] >> 1 ) a8.append (((a7[0] & 0x01) << 6) | (a7[1] >> 2)) a8.append (((a7[1] & 0x03) << 5) | (a7[2] >> 3)) a8.append (((a7[2] & 0x07) << 4) | (a7[3] >> 4)) a8.append (((a7[3] & 0x0F) << 3) | (a7[4] >> 5)) a8.append (((a7[4] & 0x1F) << 2) | (a7[5] >> 6)) a8.append (((a7[5] & 0x3F) << 1) | (a7[6] >> 7)) a8.append ( a7[6] & 0x7F ) for i in range (8): a8[i] <<= 1 ciph = DES.new (a8.tostring ()).encrypt (SAMBA_LM_HASH_MAGIC) return ciph.encode ("hex").upper () return lm_hash (plaintext[0:7]) + lm_hash (plaintext[7:14]) samba_user_sid = self._get_user_sid (uid) samba_group_sid = self._get_group_sid (gid) nt_password = get_nt_password (password) lm_password = get_lm_password (password) directory.add_samba_user_attributes (username, samba_user_sid, samba_group_sid, nt_password, lm_password) ... def add_samba_user_attributes (self, username, samba_user_sid, samba_group_sid, nt_password, lm_password): ldap_connection = self.get_ldap_connection () user_suffix = self.get_user_suffix () ldap_connection.modify_s ("uid=%s,%s" % (username, user_suffix), [ ( ldap.MOD_ADD, "objectClass", [ "sambaSamAccount" ] ), ( ldap.MOD_ADD, "sambaSID", [ samba_user_sid ] ), ( ldap.MOD_ADD, "sambaPrimaryGroupSID", [ samba_group_sid ] ), ( ldap.MOD_ADD, "sambaNTPassword", [ nt_password ] ), ( ldap.MOD_ADD, "sambaLMPassword", [ lm_password ] ) ]) ...