1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-29 11:21:54 +03:00

Merge branch 'master' of ssh://git.samba.org/data/git/samba into master-devel

This commit is contained in:
Andrew Bartlett 2009-06-19 15:38:33 +10:00
commit d9498aaf1b
2 changed files with 287 additions and 0 deletions

View File

@ -0,0 +1,168 @@
idmap script option for flexible UID/GID handling
-------------------------------------------------
If you are using "idmap backend = tdb2" with winbind in Samba3, then
you have the option of specifying an external script to perform
uid/gid allocation. This can be useful in situations where you are
using AD for authentication, but the AD server is not configured to
supply uid/gid mappings via the services for unix extensions and you
have a need to support a pre-existing system for uid/gid allocation.
One common situation where this arises is where you have a mixture of
NFS and CIFS clients, and the NFS clients are configured to use NIS
for their id mapping. It is quite common to have an administrative
mechanism in place to ensure that all of the NIS users have a
corresponding AD user account, but there may be no direct mechanism to
ensure that any unix uid/gid attributes in AD match those in NIS.
In this situation it would normally not be possible to share files
with correct ownership between the CIFS and NFS clients, as winbind
would normally allocate its own set of UIDs from a reserved pool, and
those uids won't match the existing ones in NIS.
The idmap script option
-----------------------
To resolve this problem the idmap tdb2 module has the ability to call
out to an external script whenever it meeds an unknown SID or UID/GID
for the first time. It is then the job of that script to provide a
mapping consistent with whatever external system is in place (such as
NIS), and return the mapped result to winbind.
Winbind will then persistently store the result of the mapping, so
that the script is not invoked more than once per user/group.
To setup the idmap script you need to set the following options:
idmap backend = tdb2
idmap script = /usr/local/bin/idmap.sh
where the location and name of the script is arbitrary. It just needs
to be executable by winbind.
You then need to stop Samba, delete the key idmap cache files, and
restart Samba. The idmap files that need to be deleted are:
- gencache.tdb
- winbindd_cache.tdb
- idmap2.tdb
Script operation
----------------
The script will be called by winbind in one of three ways.
1) idmap.sh SIDTOID <SID>
2) idmap.sh IDTOSID UID <UID>
2) idmap.sh IDTOSID GID <GID>
In the first form the script is being asked to map a windows SID (in
the string form "S-*") to a UID or GID. In the second form the script
is being asked to map a UID to a SID, and in the third form it is
being asked to map a GID to a SID.
SIDTOID
-------
In the first form the script is expected to output a UID or GID given
a SID. The output format is expected to be like this:
UID:1234
or
GID:1122
If the SID cannot be found, then the script should output an error
like this:
ERR:Some error message
Note that it is common for the external mechanism to not know about
windows SIDs, in which case the script may use the wbinfo command to
ask winbind to change the SID into a username or group name. The
"wbinfo -s" option is the one to use.
IDTOSID UID
-----------
In this form the script is expected to turn a UID into a SID,
returning a result like this:
SID:S-1-5-21-1110277820-2343689819-414998773-1124
or an error like this:
ERR:Some error message
If the external mechanism that the script wants to use cannot produce
a SID, but can produce a username, then the script can convert the
username to a SID using the "wbinfo -n" option.
IDTOSID GID
-----------
In this form the script is expected to turn a GID into a SID,
returning a result like this:
SID:S-1-5-21-1110277820-2343689819-414998773-1120
or an error like this:
ERR:Some error message
If the external mechanism that the script wants to use cannot produce
a SID, but can produce a group name, then the script can convert the
groupname to a SID using the "wbinfo -n" option.
Testing the script
------------------
It is suggested that you test the script on the command line first,
before using it in winbind. To do that first get a list of users you
would like to test using the command "wbinfo -u". Let's assume one of
those users is "DC01\tridge". You would then test the script as
follows:
[root ~]# wbinfo -n 'DC01\tridge'
S-1-5-21-1110277820-2343689819-414998773-1124 User (1)
[root ~]# /usr/local/bin/idmap.sh SIDTOID S-1-5-21-1110277820-2343689819-414998773-1124
UID:1003
[root ~]# /usr/local/bin/idmap.sh IDTOSID UID 1003
SID:S-1-5-21-1110277820-2343689819-414998773-1124
Once those steps pass, you can enable the script in winbind
(remembering to clear the cache tdbs), and test using the id command:
[root ~]# id 'DC01\tridge'
uid=1003(DC01\tridge) gid=10000009(DC01\domain users)
nsswitch.conf
-------------
When using the idmap script option you setup nsswitch.conf as usual
for winbind, with one addition. If your external idmap mechanism
support nsswitch then you may optionally choose to add it to
nsswitch.conf, but you must add it after the winbind entry. So for
example, if using NIS, you could have a nsswitch.conf entry like this:
passwd: files winbind nis
group: files winbind nis
Adding this to nsswitch.conf is not essential, but may be useful for
some local administration tools.
Sample script
-------------
This directory contains a simple example script 'idmap_nis.sh' that
provides idmap script support for NIS. To use it you first need to
enable the NIS client on your Samba server, usually by configuring
/etc/yp.conf. See the manual page for yp.conf for details.
You should test the ypcat and ypmatch commands and make sure they work
before enabling the idmap_nis.sh script.

View File

@ -0,0 +1,119 @@
#!/bin/bash
# idmap script to map SIDs to UIDs/GIDs using NIS
# tridge@samba.org June 2009
DOMAIN=$(ypdomainname)
(
date
echo $*
) >> /var/log/samba/idmap.log
cmd=$1
shift
PATH=/usr/bin:bin:$PATH
shopt -s nocasematch || {
echo "shell option nocasematch not supported"
exit 1
}
# map from a domain and name to a uid/gid
map_name() {
domain="$1"
name="$2"
ntype="$3"
case $ntype in
1)
rtype="UID"
map="passwd"
;;
2)
rtype="GID"
map="group"
;;
*)
echo "ERR: bad name type $ntype"
exit 1
;;
esac
id=$(ypmatch "$name" "$map".byname 2>/dev/null | cut -d: -f3)
[ -z "$id" ] && {
echo "ERR: bad match for $name in map $map"
exit 1
}
echo "$rtype":"$id"
}
# map from a unix id to a name
map_id() {
ntype="$1"
id="$2"
case $ntype in
UID)
map="passwd.byuid"
;;
GID)
map="group.bygid"
;;
*)
echo "ERR: bad name type $ntype"
exit 1
;;
esac
name="$(ypmatch "$id" "$map" 2>/dev/null | cut -d: -f1)"
[ -z "$name" ] && {
echo "ERR: bad match for $name in map $map"
exit 1
}
echo "$name"
}
case $cmd in
SIDTOID)
sid=$1
rid=`echo $sid | cut -d- -f8`
[ -z "$rid" ] && {
echo "ERR: bad rid in SID $sid"
exit 1
}
unset _NO_WINBINDD
# oh, this is ugly. Shell is just not meant for parsing text
fullname=`wbinfo -s $sid 2> /dev/null`
domain=`echo $fullname | cut -d'\' -f1`
[[ "$domain" = $DOMAIN ]] || {
echo "ERR: bad domain $domain"
exit 1
}
name=`echo $fullname | cut -d'\' -f2`
nwords=`echo $name | wc -w`
ntype=`echo $name | cut -d' ' -f$nwords`
nminusone=`expr $nwords - 1`
name=`echo $name | cut -d' ' -f-$nminusone`
[ -z "$name" ] && {
echo "ERR: bad name $fullname for SID $sid"
exit 1
}
map_name "$domain" "$name" "$ntype"
;;
IDTOSID)
ntype=$1
id=$2
name="$(map_id "$ntype" "$id")"
sid="$(wbinfo -n "$name" 2>/dev/null | cut -d' ' -f1)"
[ -z "$sid" ] && {
echo "ERR: name $name not found in ADS"
exit 1
}
echo "SID:$sid"
;;
*)
echo "ERR: Unknown command $cmd"
exit 1;
;;
esac
exit 0