Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Samba] samba4: samba-tool and (unix) uids

884 views
Skip to first unread message

Thomas Karmann

unread,
Sep 24, 2012, 5:10:02 PM9/24/12
to
Hello,

at my universities CS computer pools we're trying to migrate our
samba3 based NT domain to AD with samba4-rc1.
In the past we had a little script which our users could run on their
own from their linux account which created a samba user with
their own uid/gid and set their password (via smbpasswd).

We're trying to recreate this behaviour with "samba-tool user create" but we couldn't
find a parameter to set the mapping SID <-> uid.
Without the correct mapping we can't get the users profile/home permissions right.

Will we have to manually correct the private/idmap.ldb each time we
add a user or are we missing something? Is it save to edit the idmap on
the fly?

With kind regards,
Thomas


--
Thomas Karmann Department of Computer Science IV
Martensstrasse 1 D-91058 Erlangen Germany University of Erlangen-Nuremberg
http://wwwcip.informatik.uni-erlangen.de/
--
To unsubscribe from this list go to the following URL and read the
instructions: https://lists.samba.org/mailman/options/samba

Alexander Wuerstlein

unread,
Sep 25, 2012, 12:20:02 AM9/25/12
to
From: Alexander Wuerstlein <a...@arw.name>

Reads Unix UID from NSS or commandline and creates a
UID/SID mapping when creating a new user.
---
source4/scripting/python/samba/netcmd/user.py | 38 ++++++++++++++++++++----
1 files changed, 31 insertions(+), 7 deletions(-)

diff --git a/source4/scripting/python/samba/netcmd/user.py b/source4/scripting/python/samba/netcmd/user.py
index 1172f4e..44a37fd 100644
--- a/source4/scripting/python/samba/netcmd/user.py
+++ b/source4/scripting/python/samba/netcmd/user.py
@@ -22,6 +22,8 @@ import ldb
from getpass import getpass
from samba.auth import system_session
from samba.samdb import SamDB
+from samba.idmap import IDmapDB
+import pwd
from samba import (
dsdb,
gensec,
@@ -48,6 +50,8 @@ A user account enables a user to logon to a computer and domain with an identity

The command may be run from the root userid or another authorized userid. The -H or --URL= option can be used to execute the command against a remote server.

+With --match-unix-uid a SID/UID-mapping is created for the new user which is used to map filesystem permissions from Unix filesystems to Windows. Optionally, a UID can be explicitly given via --unix-uid, without an explicit UID NSS is used to obtain the UID if possible. Creation of a SID/UID-mapping is not possible when running samba-tool on a remote server.
+
Example1:
samba-tool user add User1 passw0rd --given-name=John --surname=Smith --must-change-at-next-login -H ldap://samba.samdom.example.com -Uadministrator%passw1rd

@@ -63,6 +67,11 @@ samba-tool user add User3 passw3rd --userou=OrgUnit

Example3 shows how to create a new user in the OrgUnit organizational unit.

+Example4:
+samba-tool user create unixgod passw4rd --match-unix-uid --unix-uid 31337
+
+Example4 shows how to create a new user and map his windows SID to his Unix UID 31337.
+
"""
synopsis = "%prog <username> [<password>] [options]"

@@ -96,6 +105,8 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
Option("--internet-address", help="User's home page", type=str),
Option("--telephone-number", help="User's phone number", type=str),
Option("--physical-delivery-office", help="User's office location", type=str),
+ Option("--match-unix-uid", help="Set User's Unix UID from NSS or from --unix-uid", action="store_true"),
+ Option("--unix-uid", help="Unix UID of the new user", type=str),
]

takes_args = ["username", "password?"]
@@ -107,13 +118,12 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
}

def run(self, username, password=None, credopts=None, sambaopts=None,
- versionopts=None, H=None, must_change_at_next_login=False,
- random_password=False, use_username_as_cn=False, userou=None,
- surname=None, given_name=None, initials=None, profile_path=None,
- script_path=None, home_drive=None, home_directory=None,
+ versionopts=None, H=None, must_change_at_next_login=False, random_password=False,
+ use_username_as_cn=False, userou=None, surname=None, given_name=None, initials=None,
+ profile_path=None, script_path=None, home_drive=None, home_directory=None,
job_title=None, department=None, company=None, description=None,
- mail_address=None, internet_address=None, telephone_number=None,
- physical_delivery_office=None):
+ mail_address=None, internet_address=None, telephone_number=None, physical_delivery_office=None,
+ match_unix_uid=False, unix_uid=None):

if random_password:
password = generate_random_password(128, 255)
@@ -133,12 +143,26 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
try:
samdb = SamDB(url=H, session_info=system_session(),
credentials=creds, lp=lp)
- samdb.newuser(username, password, force_password_change_at_next_login_req=must_change_at_next_login,
+ samdb.newuser(username, password,
+ force_password_change_at_next_login_req=must_change_at_next_login,
useusernameascn=use_username_as_cn, userou=userou, surname=surname, givenname=given_name, initials=initials,
profilepath=profile_path, homedrive=home_drive, scriptpath=script_path, homedirectory=home_directory,
jobtitle=job_title, department=department, company=company, description=description,
mailaddress=mail_address, internetaddress=internet_address,
telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office)
+ if match_unix_uid:
+ idmap = IDmapDB(lp=lp)
+ sids = samdb.search(samdb.get_default_basedn(), scope=ldb.SCOPE_SUBTREE,
+ expression=("(&(objectClass=user)(samaccountname=%s))" % username),
+ attrs=["objectSid"])
+ if (len(sids) != 1):
+ raise CommandError("Failed to set Unix UID for '%s'" % username, e)
+ if not unix_uid:
+ pwent = pwd.getpwnam(username)
+ unix_uid = pwent[2]
+ sid = samdb.schema_format_value("objectSid", sids[0]["objectSid"][0])
+ self.outf.write("User '%s' matched to UID '%u' and SID '%s'\n" % (username,unix_uid,sid))
+ idmap.setup_name_mapping(sid, idmap.TYPE_UID, unix_uid)
except Exception, e:
raise CommandError("Failed to add user '%s': " % username, e)

--
1.7.2.5

Alexander Wuerstlein

unread,
Sep 25, 2012, 12:20:02 AM9/25/12
to

Hello,

perhaps fixing the problem mentioned by my colleague, please see the attached
patch to samba-tool.

It adds an option to create a UID/SID mapping when creating a user, replacing
the ldbedit step in
https://wiki.samba.org/index.php/Samba4/HOWTO#Step_1:_Adding_Users_into_Samba_4_Active_Directory
by
samba-tool create user alice --match-unix-uid --unix-uid 12345

I guess using samba-tool this way will not work on a remote server since using
IDmapDB needs access to the local ldb files. Also, perhaps some similar mechanism
for groups should be implemented.



Ciao,

Alexander Wuerstlein.

Gémes Géza

unread,
Sep 25, 2012, 1:20:02 AM9/25/12
to
2012-09-24 22:52 keltezéssel, Thomas Karmann írta:
> Hello,
>
> at my universities CS computer pools we're trying to migrate our
> samba3 based NT domain to AD with samba4-rc1.
> In the past we had a little script which our users could run on their
> own from their linux account which created a samba user with
> their own uid/gid and set their password (via smbpasswd).
>
> We're trying to recreate this behaviour with "samba-tool user create" but we couldn't
> find a parameter to set the mapping SID <-> uid.
> Without the correct mapping we can't get the users profile/home permissions right.
>
> Will we have to manually correct the private/idmap.ldb each time we
> add a user or are we missing something? Is it save to edit the idmap on
> the fly?
>
> With kind regards,
> Thomas
>
>
Hi,

If you migrate via samba-tool classicupgrade it takes care of migrating
existing uids gids shells and homedirectories to samba4. At the same
time it sets idmap_ldb:use rfc2307 = yes in the global section of Samba4
smb.conf. That means, that Samba4 winbind retrieves uids, gids from the
directory.
Because of that you don't need to fiddle with idmap.ldb. So until
samba-tool gets support for manipulating posix attributes I would
recommend setting up those attributes by ldmodify against the directory
(or if you prefer a gui via ADUC (if you install RSAT on Windows Vista/7))

Regards

Geza Gemes

Andrew Bartlett

unread,
Sep 25, 2012, 1:50:02 AM9/25/12
to
On Tue, 2012-09-25 at 00:19 +0200, Alexander Wuerstlein wrote:
> From: Alexander Wuerstlein <a...@arw.name>
>
> Reads Unix UID from NSS or commandline and creates a
> UID/SID mapping when creating a new user.

As Gémes Géza mentions this really needs to honour idmap_ldb:use rfc2307
= yes and set it in the sam.ldb if that is set, and while useful in the
general case, for the case you are targeting, the classicupgrade will
work better.

Andrew Bartlett

--
Andrew Bartlett http://samba.org/~abartlet/
Authentication Developer, Samba Team http://samba.org

Gémes Géza

unread,
Sep 25, 2012, 11:00:02 AM9/25/12
to
2012-09-25 11:58 keltezéssel, Alexander Wuerstlein írta:

> On Tue, 25 Sep 2012 15:49:11 +1000
> Andrew Bartlett <abar...@samba.org> wrote:
>
>> On Tue, 2012-09-25 at 00:19 +0200, Alexander Wuerstlein wrote:
>>> From: Alexander Wuerstlein <a...@arw.name>
>>>
>>> Reads Unix UID from NSS or commandline and creates a
>>> UID/SID mapping when creating a new user.
>> As Gémes Géza mentions this really needs to honour idmap_ldb:use
>> rfc2307 = yes and set it in the sam.ldb if that is set, and while
>> useful in the general case, for the case you are targeting, the
>> classicupgrade will work better.
> Classicupgrade would only handle the initial import, not later addition
> of users which is the more frequent case here. But idmap_ldb:use
> rfc2307 = yes seems to work fine, and it seems to be a lot less ugly
> than fiddling with idmap.ldb.
>
> I'll try to get samba-tool to create the RFC2307 attributes and send a
> patch if its not too ugly.
>
>
> Ciao,
>
> Alexander Wuerstlein.
Hi,

Just a suggestion:

In my homemade (I hadn't time to develop a proper patch with tests) bash
scripts I look for the RID part of the newly created users SID and
search for the uidNumber and gidNumber attributes with that value. If
none found assign it as uidNumber or gidNumber dependending on if a user
or group is going to be created. If the given RID has been assigned as
an uidNumber or gidNumber increment it and then try again, until it
isn't in use.

Cheers

Geza Gemes

Alexander Wuerstlein

unread,
Sep 28, 2012, 12:30:02 AM9/28/12
to
Optionally set RFC2307 (NIS Schema) attributes in samba-tool create.
Mainly needed for UID mapping to be usable.
Not all attributes are set-able, only harmless and non-overlapping
ones (uid, uidNumber, gidNumber, loginShell, gecos). Description and
homeDirectory should already be set, userPassword seems problematic.
---
source4/scripting/python/samba/netcmd/user.py | 35 +++++++++++++++++++++++-
source4/scripting/python/samba/samdb.py | 26 +++++++++++++++++-
2 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/source4/scripting/python/samba/netcmd/user.py b/source4/scripting/python/samba/netcmd/user.py
index 1172f4e..d753c7f 100644
--- a/source4/scripting/python/samba/netcmd/user.py
+++ b/source4/scripting/python/samba/netcmd/user.py
@@ -19,6 +19,7 @@

import samba.getopt as options
import ldb
+import pwd
from getpass import getpass
from samba.auth import system_session
from samba.samdb import SamDB
@@ -46,6 +47,8 @@ User accounts may represent physical entities, such as people or may be used as

A user account enables a user to logon to a computer and domain with an identity that can be authenticated. To maximize security, each user should have their own unique user account and password. A user's access to domain resources is based on permissions assigned to the user account.

+Unix (RFC2307) attributes may be added to the user account. Attributes taken from NSS are obtained on the local machine. Explicitly given values override values obtained from NSS. Configure 'idmap_ldb:use rfc2307 = Yes' to use these attributes for UID/GID mapping.
+
The command may be run from the root userid or another authorized userid. The -H or --URL= option can be used to execute the command against a remote server.

Example1:
@@ -63,6 +66,11 @@ samba-tool user add User3 passw3rd --userou=OrgUnit

Example3 shows how to create a new user in the OrgUnit organizational unit.

+Example4:
+samba-tool user create User4 passw4rd --rfc2307-from-nss --gecos 'some text'
+
+Example4 shows how to create a new user with Unix UID, GID and login-shell set from the local NSS and GECOS set to 'some text'.
+
"""
synopsis = "%prog <username> [<password>] [options]"

@@ -96,6 +104,14 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
Option("--internet-address", help="User's home page", type=str),
Option("--telephone-number", help="User's phone number", type=str),
Option("--physical-delivery-office", help="User's office location", type=str),
+ Option("--rfc2307-from-nss",
+ help="Copy Unix user attributes from NSS (will be overridden by explicit UID/GID/GECOS/shell)",
+ action="store_true"),
+ Option("--uid", help="User's Unix/RFC2307 username", type=int),
+ Option("--uid-number", help="User's Unix/RFC2307 numeric UID", type=int),
+ Option("--gid-number", help="User's Unix/RFC2307 primary GID number", type=int),
+ Option("--gecos", help="User's Unix/RFC2307 GECOS field", type=str),
+ Option("--login-shell", help="User's Unix/RFC2307 login shell", type=str),
]

takes_args = ["username", "password?"]
@@ -113,7 +129,8 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
script_path=None, home_drive=None, home_directory=None,
job_title=None, department=None, company=None, description=None,
mail_address=None, internet_address=None, telephone_number=None,
- physical_delivery_office=None):
+ physical_delivery_office=None, rfc2307_from_nss=False,
+ uid=None, uid_number=None, gid_number=None, gecos=None, login_shell=None):

if random_password:
password = generate_random_password(128, 255)
@@ -127,6 +144,19 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
password = None
self.outf.write("Sorry, passwords do not match.\n")

+ if rfc2307_from_nss:
+ pwent = pwd.getpwnam(username)
+ if uid is None:
+ uid = username
+ if uid_number is None:
+ uid_number = pwent[2]
+ if gid_number is None:
+ gid_number = pwent[3]
+ if gecos is None:
+ gecos = pwent[4]
+ if login_shell is None:
+ login_shell = pwent[6]
+
lp = sambaopts.get_loadparm()
creds = credopts.get_credentials(lp)

@@ -138,7 +168,8 @@ Example3 shows how to create a new user in the OrgUnit organizational unit.
profilepath=profile_path, homedrive=home_drive, scriptpath=script_path, homedirectory=home_directory,
jobtitle=job_title, department=department, company=company, description=description,
mailaddress=mail_address, internetaddress=internet_address,
- telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office)
+ telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office,
+ uidnumber=uid_number, gidnumber=gid_number, gecos=gecos, loginshell=login_shell)
except Exception, e:
raise CommandError("Failed to add user '%s': " % username, e)

diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py
index d83e0a6..331ec77 100644
--- a/source4/scripting/python/samba/samdb.py
+++ b/source4/scripting/python/samba/samdb.py
@@ -290,7 +290,8 @@ member: %s
homedirectory=None, jobtitle=None, department=None, company=None,
description=None, mailaddress=None, internetaddress=None,
telephonenumber=None, physicaldeliveryoffice=None, sd=None,
- setpassword=True):
+ setpassword=True, uidnumber=None, gidnumber=None, gecos=None,
+ loginshell=None, uid=None):
"""Adds a new user with additional parameters

:param username: Name of the new user
@@ -316,6 +317,11 @@ member: %s
:param physicaldeliveryoffice: Office location of the new user
:param sd: security descriptor of the object
:param setpassword: optionally disable password reset
+ :param uidnumber: RFC2307 Unix numeric UID of the new user
+ :param gidnumber: RFC2307 Unix primary GID of the new user
+ :param gecos: RFC2307 Unix GECOS field of the new user
+ :param loginshell: RFC2307 Unix login shell of the new user
+ :param uid: RFC2307 Unix username of the new user
"""

displayname = ""
@@ -395,9 +401,27 @@ member: %s
if sd is not None:
ldbmessage["nTSecurityDescriptor"] = ndr_pack(sd)

+ ldbmessage2 = None
+ if any(map(lambda b: b is not None, (uid, uidnumber, gidnumber, gecos, loginshell))):
+ ldbmessage2 = ldb.Message()
+ ldbmessage2.dn = ldb.Dn(self, user_dn)
+ ldbmessage2["objectClass"] = ldb.MessageElement('posixAccount', ldb.FLAG_MOD_ADD, 'objectClass')
+ if uid is not None:
+ ldbmessage2["uid"] = ldb.MessageElement(str(uid), ldb.FLAG_MOD_REPLACE, 'uid')
+ if uidnumber is not None:
+ ldbmessage2["uidNumber"] = ldb.MessageElement(str(uidnumber), ldb.FLAG_MOD_REPLACE, 'uidNumber')
+ if gidnumber is not None:
+ ldbmessage2["gidNumber"] = ldb.MessageElement(str(gidnumber), ldb.FLAG_MOD_REPLACE, 'gidNumber')
+ if gecos is not None:
+ ldbmessage2["gecos"] = ldb.MessageElement(str(gecos), ldb.FLAG_MOD_REPLACE, 'gecos')
+ if loginshell is not None:
+ ldbmessage2["loginShell"] = ldb.MessageElement(str(loginshell), ldb.FLAG_MOD_REPLACE, 'loginShell')
+
self.transaction_start()
try:
self.add(ldbmessage)
+ if ldbmessage2:
+ self.modify(ldbmessage2)

# Sets the password for it
if setpassword:
--
1.7.2.5

Alexander Wuerstlein

unread,
Sep 28, 2012, 12:30:02 AM9/28/12
to
On Tue, 25 Sep 2012 15:49:11 +1000
Andrew Bartlett <abar...@samba.org> wrote:

> On Tue, 2012-09-25 at 00:19 +0200, Alexander Wuerstlein wrote:
> > From: Alexander Wuerstlein <a...@arw.name>
> >
> > Reads Unix UID from NSS or commandline and creates a
> > UID/SID mapping when creating a new user.
>
> As Gémes Géza mentions this really needs to honour idmap_ldb:use
> rfc2307 = yes and set it in the sam.ldb if that is set, and while
> useful in the general case, for the case you are targeting, the
> classicupgrade will work better.

Classicupgrade would only handle the initial import, not later addition


of users which is the more frequent case here. But idmap_ldb:use
rfc2307 = yes seems to work fine, and it seems to be a lot less ugly
than fiddling with idmap.ldb.

I'll try to get samba-tool to create the RFC2307 attributes and send a
patch if its not too ugly.


Ciao,

Alexander Wuerstlein.

Alexander Wuerstlein

unread,
Sep 28, 2012, 12:30:02 AM9/28/12
to
Hello,

attached the patch I promised to add RFC2307 attributes to a newly
created user in samba-tool. Values for those attributes can either
be explicitly given or obtained from NSS. shadowAccount and posixGroup are not
handled, only posixAccount, and from posixAccount only attributes that
didn't overlap (so not homeDirectory, description) and didn't seem problematic
(so not userPassword).

This also solves the UID/SID-mapping problem that started this thread
(at least if 'idmap_ldb:use rfc2307 = Yes' is set in smb.conf).

Michael Wood

unread,
Sep 28, 2012, 3:40:01 AM9/28/12
to
Hi

You should rather post patches to the samba-technical list. I have
copied by reply there.

On 25 September 2012 16:54, Alexander Wuerstlein <a...@arw.name> wrote:
> Optionally set RFC2307 (NIS Schema) attributes in samba-tool create.
> Mainly needed for UID mapping to be usable.
> Not all attributes are set-able, only harmless and non-overlapping
> ones (uid, uidNumber, gidNumber, loginShell, gecos). Description and
> homeDirectory should already be set, userPassword seems problematic.
> ---
> source4/scripting/python/samba/netcmd/user.py | 35 +++++++++++++++++++++++-
> source4/scripting/python/samba/samdb.py | 26 +++++++++++++++++-
> 2 files changed, 58 insertions(+), 3 deletions(-)
[...]

--
Michael Wood <esio...@gmail.com>
0 new messages