From 19723ed0fcdf267ece3dbcde503f86093aceb39b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 19 Jun 2009 13:25:28 +1000 Subject: Partially revert restriction of socket_wrapper to 1500 byte writes This keeps the restriction for stream sockets (where the caller will retry), without creating problems on datagram sockets (CLDAP is not defined, as far as I know, across multiple UDP packets). The commit adding this restriction was 47b106c0ae8b91c9cccfc21bf8e4e416b1abfd5d Andrew Bartlett --- lib/socket_wrapper/socket_wrapper.c | 42 ++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c index 8563400dbd..933b1260e4 100644 --- a/lib/socket_wrapper/socket_wrapper.c +++ b/lib/socket_wrapper/socket_wrapper.c @@ -1862,7 +1862,12 @@ _PUBLIC_ ssize_t swrap_recvfrom(int s, void *buf, size_t len, int flags, struct fromlen = &ss_len; } - len = MIN(len, 1500); + if (si->type == SOCK_STREAM) { + /* cut down to 1500 byte packets for stream sockets, + * which makes it easier to format PCAP capture files + * (as the caller will simply continue from here) */ + len = MIN(len, 1500); + } /* irix 6.4 forgets to null terminate the sun_path string :-( */ memset(&un_addr, 0, sizeof(un_addr)); @@ -1902,10 +1907,13 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con tolen = si->peername_len; } - len = MIN(len, 1500); - switch (si->type) { case SOCK_STREAM: + /* cut down to 1500 byte packets for stream sockets, + * which makes it easier to format PCAP capture files + * (as the caller will simply continue from here) */ + len = MIN(len, 1500); + ret = real_send(s, buf, len, flags); break; case SOCK_DGRAM: @@ -2012,7 +2020,12 @@ _PUBLIC_ ssize_t swrap_recv(int s, void *buf, size_t len, int flags) return real_recv(s, buf, len, flags); } - len = MIN(len, 1500); + if (si->type == SOCK_STREAM) { + /* cut down to 1500 byte packets for stream sockets, + * which makes it easier to format PCAP capture files + * (as the caller will simply continue from here) */ + len = MIN(len, 1500); + } ret = real_recv(s, buf, len, flags); if (ret == -1 && errno != EAGAIN && errno != ENOBUFS) { @@ -2036,7 +2049,12 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) return real_send(s, buf, len, flags); } - len = MIN(len, 1500); + if (si->type == SOCK_STREAM) { + /* cut down to 1500 byte packets for stream sockets, + * which makes it easier to format PCAP capture files + * (as the caller will simply continue from here) */ + len = MIN(len, 1500); + } if (si->defer_connect) { struct sockaddr_un un_addr; @@ -2157,10 +2175,12 @@ int swrap_readv(int s, const struct iovec *vector, size_t count) return real_readv(s, vector, count); } - /* we read 1500 bytes as maximum */ - if (count > 0) { + if (si->type == SOCK_STREAM && count > 0) { + /* cut down to 1500 byte packets for stream sockets, + * which makes it easier to format PCAP capture files + * (as the caller will simply continue from here) */ size_t i, len = 0; - + for (i=0; i < count; i++) { size_t nlen; nlen = len + vector[i].iov_len; @@ -2222,8 +2242,10 @@ int swrap_writev(int s, const struct iovec *vector, size_t count) return real_writev(s, vector, count); } - /* we write 1500 bytes as maximum */ - if (count > 0) { + if (si->type == SOCK_STREAM && count > 0) { + /* cut down to 1500 byte packets for stream sockets, + * which makes it easier to format PCAP capture files + * (as the caller will simply continue from here) */ size_t i, len = 0; for (i=0; i < count; i++) { -- cgit From e5a15e6589add409eb76f62a49e2b7a116a56c7c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Jun 2009 13:57:13 +1000 Subject: added a sample script for the "idmap script" option --- examples/scripts/idmap/idmap_nis.sh | 119 ++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100755 examples/scripts/idmap/idmap_nis.sh diff --git a/examples/scripts/idmap/idmap_nis.sh b/examples/scripts/idmap/idmap_nis.sh new file mode 100755 index 0000000000..28d9952eab --- /dev/null +++ b/examples/scripts/idmap/idmap_nis.sh @@ -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 -- cgit From 4c23a9556536561f79fa90bc431fc62fcc4e3c90 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Jun 2009 13:57:30 +1000 Subject: added some basic documentation for the idmap script option --- examples/scripts/idmap/README | 168 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 examples/scripts/idmap/README diff --git a/examples/scripts/idmap/README b/examples/scripts/idmap/README new file mode 100644 index 0000000000..3032493cbc --- /dev/null +++ b/examples/scripts/idmap/README @@ -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 + 2) idmap.sh IDTOSID UID + 2) idmap.sh IDTOSID 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. -- cgit