26.2.12

Samba 4: scripts for Linux integration

** Update 2020: I'd forgotten this was here. Guys, you really are still using AD? You really are still employing a sysadmin? Go cloud and forget all the on-the-ground DNS rubbish!

** Update 2014: full suite of tested scripts here: s4bind

Scripts to help make s4 users and groups play nice with Linux. warning Tested but not idiot proof by any means. You may want to make a backup of sam.ldb and idmap.ldb;-)
Our domain
reference
The POSIX sections of the Microsoft AD schema

1. s4group
Creates a posix group suitable for accommodating both Linux and Windows users

  cat s4group
#!/bin/bash
#creates a posix group suitable for containing Linux users
#usage s4group <name>
echo "Creating s4 posix group "$1
samba-tool group add $1
strgid=$(wbinfo --group-info=$1)
gid=$(echo $strgid | cut -d ":" -f 3)
echo "dn: cn=$1,cn=Users,dc=hh3,dc=site
changetype: modify
add:objectclass
objectclass: posixGroup
-
add: gidnumber
gidnumber: $gid" > /tmp/$1
ldbmodify --url=/usr/local/samba/private/sam.ldb -b dc=hh3,dc=site /tmp/$1
rm /tmp/$1

2. s4domaingroup-change-gid
Take the group you created above and change it's gidNumber into a value of your choice.


 cat s4domaingroup-change-gid
#!/bin/bash
#usage s4domaingroup-change-gid <Domain Group> <new-gidNumber>
#e.g. a group created with s4group 
#sets the xid in idmap.ldb to <xidNumber>
#and updates the gidNumber=xid in sam.ldb
#this can help prevent collision with existing Linux groups
#typical use: s4group mygroup then s4domaingroup-change-gid mygroup 2001
echo "Modifying s4 posix group "$1
sid=$(wbinfo --name-to-sid="$1")
echo $sid
gsid=$(echo "$sid" | cut -d " " -f1)
echo "found $1 sid= $gsid" 
echo "dn: cn=$gsid
changetype: modify
replace: xidNumber
xidNumber: $2" > /tmp/xid.ldif
echo "sleeping. . ."
sleep 2
ldbmodify --url=/usr/local/samba/private/idmap.ldb /tmp/xid.ldif
echo "dn: CN=$1,CN=Users,DC=hh3,DC=site
changetype: modify
replace: gidNumber
gidNumber: $2" > /tmp/gid.ldif
echo "sleeping. . ."
sleep 2
ldbmodify --url=/usr/local/samba/private/sam.ldb /tmp/gid.ldif
echo "$1 changed from gid $gsid to $2"
echo "pls change your users to reflect this"
sleep 2
echo "getent group:"
getent group $1

3. s4user
Creates a user and places him in a posix group created by s4group. It set's his default windows group to be the posix group.

 cat s4user
#!/bin/bash
#creates a s4 user, posix-ifies him, places him in a posix group
#sets his windows primaryGroup=posixGroup and set's some common
#defaults for logging onto windows
#usage s4user <user> <group>
echo "Creating s4 posix user "$1
echo "Pls enter pwd for "$1
samba-tool user add $1
sleep 2
#get the uid
struid=$(wbinfo -i $1)
uid=$(echo $struid | cut -d ":" -f 3)
#get the gid
strgid=$(wbinfo --group-info=$2)
gid=$(echo $strgid | cut -d ":" -f 3)
#get the group from the sid
strsid=$(wbinfo --gid-to-sid=$gid)
primarygid=$(echo $strsid | cut -d "-" -f 8)
strwg=$(echo $struid | cut -d "\\" -f 1)
#add the posix attributes to the user
echo "dn: CN=$1,CN=Users,DC=hh3,DC=site
changetype: modify
add: objectclass
objectclass: posixaccount
-
add: uidnumber
uidnumber: $uid
-
add: gidnumber
gidnumber: $gid
-
add:unixhomedirectory
unixhomedirectory: /home/$strwg/$1
-
add: loginshell
loginshell: /bin/bash" > /tmp/$1
ldbmodify --url=/usr/local/samba/private/sam.ldb -b dc=hh3,dc=site /tmp/$1
samba-tool group addmembers $2 $1
#set the user to the posix group
echo "dn: CN=$1,CN=Users,DC=hh3,DC=site
changetype: modify
replace: primarygroupid
primarygroupid: $primarygid" > /tmp/$1
echo "sleeping. . ."
sleep 5
ldbmodify --url=/usr/local/samba/private/sam.ldb -b dc=hh3,dc=site /tmp/$1
mkdir /home/$strwg/$1
chown -R $1:$2 /home/$strwg/$1
rm /tmp/$1
hostname=$(hostname -s)
echo "dn: CN=$1,CN=Users,DC=hh3,DC=site
changetype: modify
add: profilePath
profilePath: \\\\$hostname\\profiles\\$1
-
add: homeDrive
homeDrive: Z:
-
add: homeDirectory
homeDirectory: \\\\$hostname\\home\\$1" > /tmp/$1
echo "sleeping. . ."
sleep 5
ldbmodify --url=/usr/local/samba/private/sam.ldb -b dc=hh3,dc=site /tmp/$1
echo "New user: "  $1 "POSIX-ified as follows:"
echo "uid " $uid
echo "gid " $gid
echo "primaryGroupID " $primarygid " :$2"
echo "getent passwd $1"
echo $(getent passwd $1)
echo "sid " $(wbinfo --gid-to-sid=$gid)
db=/usr/local/samba/private/sam.ldb
ldbsearch --url=$db cn=$1 | grep \\\\$hostname
ldbsearch --url=$db cn=$1 | grep homeDrive
rm /tmp/$1

4. s4domaingroup
This was written to help make the posix <--> windows group mapping make more sense. The s4user script works but maps gidNumber=xidNumber. Adding the posixGroup class to the Domain Users entry in sam.ldb and mapping xidNumber to gidNumber didn't make sense as this collided with the popular Linux group users. Here is an example which allows you to change the xid in /usr/local/samba/private/idmap.ldb. s4group followed by s4domaingroup-change-gid is probably the better way to go.

 cat s4domaingroup
#!/bin/bash
#usage s4domaingroup <Domain Group> <xidNumber>
#adds posix attributes to Domain Users group
#sets the xid to <xidNumber>
#sets the posix gidNumber = xidNumber
#this can help prevent collision with the existing Linux groups
echo "Modifying  s4 group "$1
sid=$(wbinfo --name-to-sid="$1")
echo $sid
gsid=$(echo "$sid" | cut -d " " -f1)
echo "found $1 sid= $gsid"
echo "dn: cn=$gsid
changetype: modify
replace: xidNumber
xidNumber: $2" > /tmp/xid.ldif
echo "sleeping. . ."
sleep 2
ldbmodify --url=/usr/local/samba/private/idmap.ldb /tmp/xid.ldif
#academic exercise: we've set it so let's use it
strgid=$(wbinfo --group-info="$1")
gid=$(echo $strgid | cut -d ":" -f 3)
echo "dn: cn="$1",cn=Users,dc=hh3,dc=site
changetype: modify
add: objectclass
objectclass: posixGroup
-
add: gidNumber
gidNumber: $gid" > /tmp/gid.ldif
echo "sleeping. . ."
sleep 5
ldbmodify --url=/usr/local/samba/private/sam.ldb -b dc=hh3,dc=site /tmp/gid.ldif
echo $1 "rfc2307-ified"

5. s4domainuser
This script can be used to add a user to a group which has been modified by the s4domaingroup script. Unlike the s4user script, this script does not modify the windows primaryGroupID.

 cat s4domainuser
#!/bin/bash
#adds posix attributes to a user in the default Domain Users group
#adds windows home path profiles and logon drive
#pls see s4user to specify a different default group
#usage s4domainuser <user>
echo "Creating s4 POSIX Domain User "$1
echo "Pls enter pwd for "$1
samba-tool user add $1
sleep 2
#get the uid
struid=$(wbinfo -i $1)
uid=$(echo $struid | cut -d ":" -f 3)
#get the gid
strgid=$(wbinfo --group-info='Domain Users')
gid=$(echo $strgid | cut -d ":" -f 3)
strwg=$(echo $struid | cut -d "\\" -f 1)
#add the posix attributes to the user
echo "dn: CN=$1,CN=Users,DC=hh3,DC=site
changetype: modify
add: objectclass
objectclass: posixaccount
-
add: uidnumber
uidnumber: $uid
-
add: gidnumber
gidnumber: $gid
-
add:unixhomedirectory
unixhomedirectory: /home/$strwg/$1
-
add: loginshell
loginshell: /bin/bash" > /tmp/$1
echo "sleeping . . ."
sleep 2
ldbmodify --url=/usr/local/samba/private/sam.ldb -b dc=hh3,dc=site /tmp/$1
mkdir /home/$strwg/$1
chown -R $1:$gid /home/$strwg/$1
rm /tmp/$1
db=/usr/local/samba/private/sam.ldb
hostname=$(hostname -s)
echo "dn: CN=$1,CN=Users,DC=hh3,DC=site
changetype: modify
add: profilePath
profilePath: \\\\$hostname\\profiles\\$1
-
add: homeDrive
homeDrive: Z:
-
add: homeDirectory
homeDirectory: \\\\$hostname\\home\\$1" > /tmp/$1
echo "sleeping. . ."
sleep 5
ldbmodify --url=$db /tmp/$1
echo "New user: "  $1 "POSIX-ified as follows:"
echo "uid " $uid
echo "gid " $gid
echo "getent passwd $1"
echo $(getent passwd $1)
echo "sid " $(wbinfo --gid-to-sid=$gid)
ldbsearch --url=$db cn=$1 | grep \\\\$hostname
ldbsearch --url=$db cn=$1 | grep homeDrive
rm /tmp/$1

prototype
Deleteing users and groups leaves the database in a mess. Here is an attempt to tidy up a bit:

 cat s4userdel
#!/bin/sh
#deletes a user and his home and profile folder
#tidies up idmap.ldb
#usage s4userdel <user>
echo "Deleting user $1"
sid=$(wbinfo --name-to-sid="$1")
usersid=$(echo "$sid" | cut -d " " -f1)
echo "found $1 sid= $usersid" 
ldbdel --url=/usr/local/samba/private/idmap.ldb CN=$usersid
samba-tool user delete $1
rm -r /home/CACTUS/$1
rm -r /home/CACTUS/profiles/"$1"*
echo "$1 deleted"


example
Here we set the Domain Users posix gidNumber to 2000 and add a posix user to the group.

1. Modify the xidnumber in idmap.ldb:
 s4group 'Domain Users' 2000

 wbinfo --group-info='Domain Users'
Domain Users:*:2000:
 getent group 'Domain Users'
Domain Users:*:2000:

2. posix-ify steve2 according to Domain Users:
 s4domainuser steve2
Creating s4 POSIX Domain User steve2
Pls enter pwd for steve2
New Password:
User 'steve2' created successfully
sleeping . . .
Modified 1 records with 0 failures
sleeping. . .
Modified 1 records with 0 failures
New user:  steve2 POSIX-ified as follows:
uid  3000016
gid  2000
getent passwd steve2
steve2:*:3000016:2000:steve2:/home/CACTUS/steve2:/bin/bash
sid  S-1-5-21-2871321456-443247610-264051687-513
profilePath: \\hh3\profiles\steve2
homeDirectory: \\hh3\home\steve2
homeDrive: Z:

3. test

 steve2@hh3:~$ id
uid=3000016(steve2) gid=2000(Domain Users) groups=2000(Domain Users)
 steve2@hh3:~$ touch hola.txt
 steve2@hh3:~$ ls -la hola.txt
-rw-r--r-- 1 steve2 Domain Users 0 2012-02-26 09:55 hola.txt
Domain Users and debusers as posix domain groups under Samba4 on Ubuntu
Co-starring the Samba4 wiki creating a makes you look twice effect
bugs
ldbmodify has to be done in stages with a pause inbetween. Probably our slow hardware rather than a bug. Adding the posixGroup class to a group prevents you being able to list group members. It works, but it is inconvenient. Best to leave Domain Users as it is and just posix-ify the groups themselves. Must write a script to be able to list all members in a group. Posix or not.

man cut(1)
SYNOPSIS
     cut -b list [-n] [file ...]
     cut -c list [file ...]
     cut -f list [-d delim] [-s] [file ...]