diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2008-01-26 10:49:18 +0000 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2008-01-26 10:49:18 +0000 |
commit | da63099262e71310b7c8b6af3ba85214b430ef72 (patch) | |
tree | eec5e02502c4ad855ad51dddb5722ba2c456d3d4 | |
parent | d24c1397d377a4bb4174e4e690bbc964c31b34eb (diff) |
move code to get information from socket peer to the compat directory because it is very platform specific
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-ldapd@565 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r-- | Makefile.am | 4 | ||||
-rw-r--r-- | compat/Makefile.am | 25 | ||||
-rw-r--r-- | compat/getpeercred.c | 93 | ||||
-rw-r--r-- | compat/getpeercred.h | 35 | ||||
-rw-r--r-- | configure.ac | 16 | ||||
-rw-r--r-- | nslcd/Makefile.am | 5 | ||||
-rw-r--r-- | nslcd/nslcd.c | 27 |
7 files changed, 180 insertions, 25 deletions
diff --git a/Makefile.am b/Makefile.am index dc61fe0..c5caee4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,7 +2,7 @@ # # Copyright (C) 2006 Luke Howard # Copyright (C) 2006 West Consulting -# Copyright (C) 2006, 2007 Arthur de Jong +# Copyright (C) 2006, 2007, 2008 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -19,7 +19,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA -SUBDIRS = common nss nslcd man tests +SUBDIRS = compat common nss nslcd man tests DEBIAN_FILES = debian/changelog debian/compat debian/control \ debian/copyright debian/rules \ diff --git a/compat/Makefile.am b/compat/Makefile.am new file mode 100644 index 0000000..480d207 --- /dev/null +++ b/compat/Makefile.am @@ -0,0 +1,25 @@ +# Makefile.am - use automake to generate Makefile.in +# +# Copyright (C) 2008 Arthur de Jong +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA + +noinst_LIBRARIES = libcompat.a + +AM_CPPFLAGS=-I$(top_srcdir) +AM_CFLAGS = -fPIC + +libcompat_a_SOURCES = getpeercred.c getpeercred.h diff --git a/compat/getpeercred.c b/compat/getpeercred.c new file mode 100644 index 0000000..101a492 --- /dev/null +++ b/compat/getpeercred.c @@ -0,0 +1,93 @@ +/* + getpeercred.h - function for determining information about the + other end of a unix socket + This file is part of the nss-ldapd library. + + Copyright (C) 2008 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#include "config.h" + +#include <stdlib.h> +#include <unistd.h> +#include <sys/socket.h> +#include <sys/un.h> +#ifdef HAVE_SYS_UCRED_H +#include <sys/ucred.h> +#endif /* HAVE SYS_UCRED_H */ +#include <errno.h> + +#include "getpeercred.h" + +int getpeercred(int sock,uid_t *uid,gid_t *gid,pid_t *pid) +{ +#if defined(SO_PEERCRED) + socklen_t l; + struct ucred cred; + /* initialize client information (in case getsockopt() breaks) */ + cred.pid=(pid_t)0; + cred.uid=(uid_t)-1; + cred.gid=(gid_t)-1; + /* look up process information from peer */ + l=(socklen_t)sizeof(struct ucred); + if (getsockopt(sock,SOL_SOCKET,SO_PEERCRED,&cred,&l) < 0) + return -1; /* errno already set */ + /* return the data */ + if (uid!=NULL) *uid=cred.uid; + if (gid!=NULL) *gid=cred.gid; + if (pid!=NULL) *pid=cred.pid; + return 0; +#elif defined(LOCAL_PEERCRED) + socklen_t l; + struct xucred cred; + /* initialize client information (in case getsockopt() breaks) */ + cred.pid=(pid_t)0; + cred.uid=(uid_t)-1; + cred.gid=(gid_t)-1; + /* look up process information from peer */ + l=(socklen_t)sizeof(struct xucred); + if (getsockopt(sock,SOL_SOCKET,LOCAL_PEERCRED,&cred,&l) < 0) + return -1; /* errno already set */ + if (cred.cr_version!=XUCRED_VERSION) + { + errno=EINVAL; + return -1; + } + /* return the data */ + if (uid!=NULL) *uid=cred.uid; + if (gid!=NULL) *gid=cred.gid; + if (pid!=NULL) *pid=cred.pid; + return 0; +#elif defined(HAVE_GETPEEREID) + uid_t tuid; + gid_t tgid; + if (uid==NULL) uid=&tuid; + if (gid==NULL) gid=&tguid; + if (getpeereid(sock,uid,gid)) + return -1; + /* return the data */ + if (uid!=NULL) *uid=cred.uid; + if (gid!=NULL) *gid=cred.gid; + if (pid!=NULL) *pid=-1; /* we return a -1 pid because we have no usable pid */ + return 0; +#else + /* nothing found that is supported */ + errno=ENOSYS; + return -1; +#endif +} diff --git a/compat/getpeercred.h b/compat/getpeercred.h new file mode 100644 index 0000000..8a103e1 --- /dev/null +++ b/compat/getpeercred.h @@ -0,0 +1,35 @@ +/* + getpeercred.h - function for determining information about the + other end of a unix socket + This file is part of the nss-ldapd library. + + Copyright (C) 2008 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +#ifndef _COMPAT_GETPEERCRED_H +#define _COMPAT_GETPEERCRED_H 1 + +/* This function tries to determine the user id, group id and process + id of the other end of the specified socket. + Any of the uid, gid and pid paramaters may be NULL to not update + that information. + On success, zero is returned. On error, -1 is returned, and errno + is set appropriately. */ +int getpeercred(int sock,uid_t *uid,gid_t *gid,pid_t *pid); + +#endif /* not _COMPAT_GETPEERCRED_H */ diff --git a/configure.ac b/configure.ac index e394f2e..9826569 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # # Copyright (C) 2006 Luke Howard # Copyright (C) 2006 West Consulting -# Copyright (C) 2006, 2007 Arthur de Jong +# Copyright (C) 2006, 2007, 2008 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -23,7 +23,7 @@ AC_PREREQ(2.59) AC_COPYRIGHT( [Copyright (C) 2006 Luke Howard Copyright (C) 2006 West Consulting -Copyright (C) 2006, 2007 Arthur de Jong +Copyright (C) 2006, 2007, 2008 Arthur de Jong This configure script is derived from configure.ac which is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser @@ -136,6 +136,7 @@ AC_CHECK_HEADERS(gsssasl.h) AC_CHECK_HEADERS(gssapi/gssapi_krb5.h gssapi.h) AC_CHECK_HEADERS(grp.h) AC_CHECK_HEADERS(sys/socket.h) +AC_CHECK_HEADERS(sys/ucred.h) # set up directory with compatibility replacement files AC_CONFIG_LIBOBJ_DIR([compat]) @@ -167,6 +168,7 @@ AC_CHECK_FUNCS(gethostbyname) AC_CHECK_FUNCS(ether_aton_r) AC_CHECK_FUNCS(ether_ntoa_r) AC_CHECK_FUNCS(setgroups) +AC_CHECK_FUNCS(getpeereid) # checks for types AC_C_CONST @@ -206,6 +208,13 @@ AC_CHECK_TYPE(struct sockaddr_storage,, #include <sys/types.h> #include <sys/socket.h>]) +# check for support for the struct ucred structure +AC_CHECK_TYPE(struct ucred, + AC_DEFINE(HAVE_STRUCT_UCRED,1,[Define to 1 if you have a `struct ucred' definition.]),,[ + #include <sys/socket.h> + #include <sys/un.h> + #include <sys/types.h>]) + # checks for LDAP library save_LIBS="$LIBS" LIBS="$nslcd_LIBS" @@ -287,5 +296,6 @@ AC_SUBST(nss_ldap_so_LIBS) AC_SUBST(nslcd_LIBS) # generate files -AC_CONFIG_FILES([Makefile common/Makefile nss/Makefile nslcd/Makefile man/Makefile tests/Makefile]) +AC_CONFIG_FILES([Makefile compat/Makefile common/Makefile + nss/Makefile nslcd/Makefile man/Makefile tests/Makefile]) AC_OUTPUT diff --git a/nslcd/Makefile.am b/nslcd/Makefile.am index c69c611..c939a10 100644 --- a/nslcd/Makefile.am +++ b/nslcd/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am - use automake to generate Makefile.in # # Copyright (C) 2006, 2007 West Consulting -# Copyright (C) 2006, 2007 Arthur de Jong +# Copyright (C) 2006, 2007, 2008 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -33,4 +33,5 @@ nslcd_SOURCES = nslcd.c ../nslcd.h ../nslcd-common.h \ attmap.c attmap.h \ alias.c ether.c group.c host.c netgroup.c network.c \ passwd.c protocol.c rpc.c service.c shadow.c -nslcd_LDADD = @nslcd_LIBS@ ../common/libtio.a ../common/libdict.a +nslcd_LDADD = @nslcd_LIBS@ ../common/libtio.a ../common/libdict.a \ + ../compat/libcompat.a diff --git a/nslcd/nslcd.c b/nslcd/nslcd.c index 8dab128..eb8299d 100644 --- a/nslcd/nslcd.c +++ b/nslcd/nslcd.c @@ -51,6 +51,7 @@ #include "cfg.h" #include "common.h" #include "compat/attrs.h" +#include "compat/getpeercred.h" /* the definition of the environment */ extern char **environ; @@ -231,7 +232,6 @@ static void exithandler(void) log_log(LOG_INFO,"version %s bailing out",VERSION); } - /* returns a socket ready to answer requests from the client, exit()s on error */ static int open_socket(void) @@ -318,26 +318,17 @@ static int read_header(TFILE *fp,int32_t *action) static void handleconnection(int sock,MYLDAP_SESSION *session) { TFILE *fp; - socklen_t alen; - struct ucred client; int32_t action; struct timeval readtimeout,writetimeout; - /* initialize client information (in case getsockopt() breaks) */ - client.pid=(pid_t)0; - client.uid=(uid_t)-1; - client.gid=(gid_t)-1; - /* look up process information from client */ - alen=(socklen_t)sizeof(struct ucred); - if (getsockopt(sock,SOL_SOCKET,SO_PEERCRED,&client,&alen) < 0) - { - log_log(LOG_ERR,"getsockopt(SO_PEERCRED) failed: %s",strerror(errno)); - if (close(sock)) - log_log(LOG_WARNING,"problem closing socket: %s",strerror(errno)); - return; - } + uid_t uid; + gid_t gid; + pid_t pid; /* log connection */ - log_log(LOG_DEBUG,"connection from pid=%d uid=%d gid=%d", - (int)client.pid,(int)client.uid,(int)client.gid); + if (getpeercred(sock,&uid,&gid,&pid)) + log_log(LOG_DEBUG,"connection from unknown client"); + else + log_log(LOG_DEBUG,"connection from pid=%d uid=%d gid=%d", + (int)pid,(int)uid,(int)gid); /* set the timeouts */ readtimeout.tv_sec=0; /* clients should send there request quickly */ readtimeout.tv_usec=500000; |