summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2008-01-26 10:49:18 +0000
committerArthur de Jong <arthur@arthurdejong.org>2008-01-26 10:49:18 +0000
commitda63099262e71310b7c8b6af3ba85214b430ef72 (patch)
treeeec5e02502c4ad855ad51dddb5722ba2c456d3d4
parentd24c1397d377a4bb4174e4e690bbc964c31b34eb (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.am4
-rw-r--r--compat/Makefile.am25
-rw-r--r--compat/getpeercred.c93
-rw-r--r--compat/getpeercred.h35
-rw-r--r--configure.ac16
-rw-r--r--nslcd/Makefile.am5
-rw-r--r--nslcd/nslcd.c27
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;