--- /dev/null
+authbind
+helper
+libauthbind.o
+libauthbind.so.0.1
--- /dev/null
+#
+OPTIMISE= -O2
+CFLAGS= -g $(OPTIMISE) \
+ -Wall -Wwrite-strings -Wpointer-arith -Wimplicit \
+ -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes
+
+TARGETS= authbind helper libauthbind.so.0.1
+
+all: $(TARGETS)
+
+libauthbind.o: libauthbind.c
+ gcc -D_REENTRANT -g $(CFLAGS) -c -o libauthbind.o -fPIC libauthbind.c
+
+libauthbind.so.0.1: libauthbind.o
+ gcc -g -shared -Wl,-soname,libauthbind.so.0.1 -o libauthbind.so.0.1 libauthbind.o -ldl -lc
+
+clean distclean:
+ rm -f $(TARGETS) *.o *~ ./#*# *.bak debian/*~
+ rm -f core libauthbind.so*
--- /dev/null
+/**/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#define LD_PRELOAD "LD_PRELOAD"
+#define AUTHBINDLIB "AUTHBIND_LIB"
+#define LIBAUTHBIND "/usr/lib/authbind/libauthbind.so.0"
+
+int main(int argc, char *const *argv) {
+ const char *expreload, *authbindlib, *preload;
+ char *newpreload;
+
+ authbindlib= getenv(AUTHBINDLIB);
+ if (!authbindlib) {
+ if (setenv(AUTHBINDLIB,LIBAUTHBIND,0)) {
+ perror("authbind: setenv " AUTHBINDLIB);
+ exit(-1);
+ }
+ authbindlib= LIBAUTHBIND;
+ }
+
+ if ((expreload= getenv(LD_PRELOAD))) {
+ newpreload= malloc(strlen(expreload)+strlen(authbindlib)+2);
+ strcpy(newpreload,expreload);
+ strcat(newpreload,":");
+ strcat(newpreload,authbindlib);
+ preload= newpreload;
+ } else {
+ preload= authbindlib;
+ }
+ if (setenv(LD_PRELOAD,preload,1)) { perror("authbind: setenv"); exit(-1); }
+
+ execvp(argv[1],argv+1);
+ perror(argv[1]); exit(-1);
+}
--- /dev/null
+files
+substvars
+tmp
--- /dev/null
+authbind (0.1-1) experimental; urgency=low
+
+ * Initial release.
+
+ -- Ian Jackson <ian@davenant.greenend.org.uk> Sat, 29 Aug 1998 20:10:37 +0100
+
+Local variables:
+mode: debian-changelog
+End:
--- /dev/null
+Source: authbind
+Section: utils
+Priority: extra
+Maintainer: Ian Jackson <ian@chiark.greenend.org.uk>
+Standards-Version: 2.1.1.0
+
+Package: authbind
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: Allows non-root programs to bind() to low ports
+ This package allows a package to be started as non-root but
+ still bind to low ports. The ports allowed to who are in
+ /etc/authbind/<number> - make it executable to allow.
--- /dev/null
+GNU copyleft joost witteveen, <joostje@debian.org>.
--- /dev/null
+#! /usr/bin/make -f
+# -*- mode: makefile; -*-
+#
+# Modified by Ian Jackson for authbind.
+# Then last updated: Sat Dec 17 10:52:20 EST 1994 by imurdock.
+#
+# To make the binary distribution package, the ``Debianized'' source package
+# and the context diff to the original package, type `./debian.rules dist'.
+# Make sure that `debian.rules' is executable before the final distribution
+# is made.
+#
+# Invoke each target with `./debian.rules <target>'. All targets should be
+# invoked with the package root as the current directory.
+#
+# The `binary' target must be run as root, as it needs to install files with
+# specific ownerships. The `diff' target assumes that you have the original
+# source package available, unpacked, in ../$(p)-$(v).orig, or that you have
+# the previous revision of the ``Debianized'' source package and context diff
+# in the parent directory.
+
+CC = gcc
+
+package=authbind
+major=0
+minor=1
+
+arch = $(shell dpkg --print-architecture)
+
+build:
+ $(MAKE)
+
+clean:
+ rm -rf debian/{files,substvars,tmp} build
+ $(MAKE) distclean
+
+binary-indep: checkroot build
+ $(checkdir)
+# There are no architecture-independent files to be uploaded
+# generated by this package. If there were any they would be
+# made here.
+
+lab=libauthbind.so.$(major).$(minor)
+
+binary-arch: checkroot build
+ rm -rf debian/tmp
+ install -d -g root -m 755 -o root debian/tmp/DEBIAN \
+ debian/tmp/usr/{bin,lib/$(package),doc/$(package)} \
+ debian/tmp/etc/authbind/{byport,byname,byuid}
+ install -s -g root -o root -m 755 authbind debian/tmp/usr/bin/.
+ install -s -g root -o root -m 4755 helper debian/tmp/usr/lib/authbind/.
+ install -s -g root -o root -m 755 $(lab) debian/tmp/usr/lib/authbind/.
+ ln -s $(lab) debian/tmp/usr/lib/authbind/libauthbind.so.$(major)
+ strip --strip-unneeded debian/tmp/usr/lib/authbind/$(lab)
+ install -g root -o root -m 644 debian/copyright debian/tmp/usr/doc/$(package)/
+ install -g root -o root -m 644 debian/changelog \
+ debian/tmp/usr/doc/$(package)/changelog.Debian
+ gzip -9 debian/tmp/usr/doc/$(package)/*
+ifneq ($(arch),alpha)
+ install -g root -o root -m 644 debian/shlibs debian/tmp/DEBIAN
+else
+ install -g root -o root -m 644 debian/shlibs.alpha debian/tmp/DEBIAN/shlibs
+endif
+ dpkg-shlibdeps ./authbind
+ dpkg-gencontrol
+ chown -R root.root debian/tmp
+ chmod -R g-ws debian/tmp
+ #/bin/bash #-c "ls debian/tmp"
+ #bash -c "dpkg --build debian/tmp .."
+ dpkg --build debian/tmp ..
+
+binary: binary-indep binary-arch
+
+checkroot:
+ $(checkdir)
+ test root = "`whoami`"
--- /dev/null
+/usr/lib/libfakeroot/libfakeroot 0 libc6
--- /dev/null
+/usr/lib/libfakeroot/libfakeroot 0 libc6.1
--- /dev/null
+/*
+ * setuid. Invoked with socket on stdin.
+ * Usage: helper <addr> <port>
+ * both are hex strings, padded to the right length.
+ * they are pairs of hex digits for each byte (network byte order)
+ *
+ * If /etc/authbind cannot be chdir'd into, is an error.
+ *
+ * First, check /etc/authbind/byport/<port> with access(2,X_OK).
+ * If OK, then authorised.
+ * If ENOENT then keep looking.
+ * Otherwise, not authorised, errno=whatever
+ *
+ * Then check /etc/authbind/byboth/<addr>:<port> likewise.
+ *
+ * Then try to read /etc/authbind/byuid/<uid> (with superuser privs!)
+ * If ENOENT, then not authorised, errno=EPERM
+ * If cannot open, then not authorised, errno=whatever
+ * If it contains a line of the form
+ * <addr>/<length>:<port-min>,<port-max>
+ * then authorised, otherwise not authorised, errno=ENOENT
+ * If read error then is an error
+ *
+ * In each case,
+ * <addr> is dotted quad
+ * <port> is decimal in host order
+ * <length> is prefix length (so 0.0.0.0/32 matches any)
+ * <uid> is decimal unsigned
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#define CONFIGDIR "/etc/authbind"
+
+static void exiterrno(int e) {
+ exit(e>0 && e<128 ? e : ENOSYS);
+}
+
+static void perrorfail(const char *m) {
+ int e;
+ e= errno;
+ fprintf(stderr,"libauthbind's helper: %s: %s\n",m,strerror(e));
+ exiterrno(e);
+}
+
+static void badusage(void) {
+ fputs("libauthbind's helper: bad usage\n",stderr);
+ exit(ENOSYS);
+}
+
+static struct sockaddr_in saddr;
+
+static void authorised(void) {
+ if (bind(0,&saddr,sizeof(saddr))) exiterrno(errno);
+ else _exit(0);
+}
+
+int main(int argc, const char *const *argv) {
+ uid_t uid;
+ char fnbuf[100];
+ char *ep;
+ const char *np;
+ unsigned long addr, port, haddr, thaddr, thmask;
+ unsigned int hport, a1,a2,a3,a4, alen,pmin,pmax;
+ int nchar;
+ FILE *file;
+
+ if (argc != 3) badusage();
+ addr= strtoul(argv[1],&ep,16); if (*ep || addr&~0x0ffffffffUL) badusage();
+ port= strtoul(argv[2],&ep,16); if (*ep || port&~0x0ffffUL) badusage();
+
+ if (chdir(CONFIGDIR)) perrorfail("chdir " CONFIGDIR);
+
+ fnbuf[sizeof(fnbuf)-1]= 0;
+ memset(&saddr,0,sizeof(saddr));
+ saddr.sin_family= AF_INET;
+ saddr.sin_port= port;
+ saddr.sin_addr.s_addr= addr;
+ hport= htons(port);
+
+ snprintf(fnbuf,sizeof(fnbuf)-1,"byport/%u",hport);
+ if (!access(fnbuf,X_OK)) authorised();
+ if (errno != ENOENT) exiterrno(errno);
+
+ np= inet_ntoa(saddr.sin_addr); assert(np);
+ snprintf(fnbuf,sizeof(fnbuf)-1,"byaddr/%s:%u",np,hport);
+ if (!access(fnbuf,X_OK)) authorised();
+ if (errno != ENOENT) exiterrno(errno);
+
+ uid= getuid(); if (uid==(uid_t)-1) perrorfail("getuid");
+ snprintf(fnbuf,sizeof(fnbuf)-1,"byuid/%lu",(unsigned long)uid);
+
+ file= fopen(fnbuf,"r");
+ if (!file) exiterrno(errno==ENOENT ? EPERM : errno);
+
+ haddr= ntohl(addr);
+
+ while (fgets(fnbuf,sizeof(fnbuf)-1,file)) {
+ nchar= -1;
+ sscanf(fnbuf," %u.%u.%u.%u/%u:%u,%u %n",
+ &a1,&a2,&a3,&a4,&alen,&pmin,&pmax,&nchar);
+ if (nchar != strlen(fnbuf) ||
+ alen>32 || pmin&~0x0ffff || pmax&~0x0ffff ||
+ a1&~0x0ff || a2&~0xff || a3&~0x0ff || a4&~0x0ff)
+ continue;
+
+ if (hport<pmin || hport>pmax) continue;
+
+ thaddr= (a1<<24)|(a2<<16)|(a3<<8)|(a4);
+ thmask= 0x0ffffffffUL<<(32-alen);
+ if ((haddr&thmask) != thaddr) continue;
+ authorised();
+ }
+ if (ferror(file)) perrorfail("read per-uid file");
+ _exit(ENOENT);
+}
--- /dev/null
+/*
+ */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+
+#define AUTHBIND_NESTED "AUTHBIND_NESTED"
+#define HELPER "/usr/lib/authbind/helper"
+
+typedef void anyfn_type(void);
+typedef int bindfn_type(int fd, const struct sockaddr *addr, socklen_t addrlen);
+
+#define STDERRSTR_CONST(m) write(2,m,sizeof(m)-1)
+#define STDERRSTR_STRING(m) write(2,m,strlen(m))
+
+static int find_any(const char *name, anyfn_type **keep) {
+ static const char *dlerr;
+ anyfn_type *kv;
+
+ if (*keep) return 0;
+ kv= dlsym(RTLD_NEXT,name);
+ if (kv) { *keep= kv; return 0; }
+ dlerr= dlerror(); if (!dlerr) dlerr= "dlsym() failed for no reason";
+ STDERRSTR_CONST("libauthbind: error finding original version of ");
+ STDERRSTR_STRING(name);
+ STDERRSTR_CONST(": ");
+ STDERRSTR_STRING(dlerr);
+ STDERRSTR_STRING("\n");
+ errno= ENOSYS;
+ return -1;
+}
+
+static bindfn_type find_bind, *old_bind= find_bind;
+
+int find_bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
+ anyfn_type *anyfn;
+ if (find_any("bind",&anyfn)) return -1;
+ old_bind= (bindfn_type*)anyfn;
+ return old_bind(fd,addr,addrlen);
+}
+
+static int exiterrno(int e) {
+ _exit(e>0 && e<128 ? e : -1);
+}
+
+int bind(int fd, const struct sockaddr *addr, socklen_t addrlen) {
+ pid_t child, rchild;
+ char portarg[5], addrarg[9];
+ int status;
+
+ if (addr->sa_family != AF_INET || addrlen != sizeof(struct sockaddr_in) ||
+ ntohs(((struct sockaddr_in*)addr)->sin_port) >= 1024 || !geteuid())
+ return old_bind(fd,addr,addrlen);
+
+ if (getenv(AUTHBIND_NESTED)) {
+ STDERRSTR_CONST("libauthbind: possible installation problem - "
+ "nested invocation, perhaps helper is not setuid\n");
+ return old_bind(fd,addr,addrlen);
+ }
+
+ sprintf(addrarg,"%08lx",
+ ((unsigned long)(((struct sockaddr_in*)addr)->sin_addr.s_addr))&0x0ffffffffUL);
+ sprintf(portarg,"%04x",
+ ((unsigned int)(((struct sockaddr_in*)addr)->sin_port))&0x0ffff);
+
+ child= fork(); if (child==-1) return -1;
+
+ if (!child) {
+ if (dup2(fd,0)) exiterrno(errno);
+ if (setenv(AUTHBIND_NESTED,"1",1)) exiterrno(errno);
+ execl(HELPER,HELPER,addrarg,portarg,(char*)0);
+ status= errno;
+ STDERRSTR_CONST("libauthbind: possible installation problem - "
+ "could not invoke " HELPER "\n");
+ exiterrno(status);
+ }
+
+ rchild= waitpid(child,&status,0);
+ if (rchild==-1) return -1;
+ if (rchild!=child) { errno= ECHILD; return -1; }
+
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status)) { errno= WEXITSTATUS(status); return -1; }
+ return 0;
+ } else {
+ errno= ENOSYS;
+ return -1;
+ }
+}