diff options
38 files changed, 156 insertions, 2323 deletions
@@ -3,7 +3,7 @@ /src/*.*/ /nshd.service /nshd.socket -/.Makefile.var.* -/.tmp.Makefile.var.* +.var.* +.tmp.* /LICENSE.*.txt *.o @@ -20,95 +20,73 @@ # <http://www.gnu.org/licenses/>. MAKEFLAGS += --no-builtin-rules + prefix = /usr/local bindir = $(prefix)/bin libdir = $(prefix)/lib systemddir = $(libdir)/systemd +Q ?= @ +#NET ?= FORCE + user = nshd group = nshd -NET ?= FORCE - CFLAGS = -std=c99 -Wall -Wextra -Werror -pedantic CGO_CFLAGS = $(CFLAGS) -Wno-unused-parameter CGO_ENABLED = 1 -export CGO_ENABLED - -cgo_variables = CGO_ENABLED CGO_CFLAGS CGO_CPPFLAGS CGO_CXXFLAGS CGO_LDFLAGS CC CXX -goext = go c s S cc cpp cxx h hh hpp hxx -gosrc_cmd = find -L src -name '.*' -prune -o \( -type f \( -false $(foreach e,$(goext),-o -name '*.$e') \) -o -type d \) -print -gosrc = $(shell $(gosrc_cmd)) -GOPATH := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) - -vp = .Makefile.var.% - -deps = gopkg.in/yaml.v2 -subdirs = src/nslcd/proto +deps += gopkg.in/yaml.v2 +deps += lukeshu.com/git/go/libgnulinux.git/dl +deps += lukeshu.com/git/go/libgnulinux.git/getgr +deps += lukeshu.com/git/go/libgnulinux.git/inotify +deps += lukeshu.com/git/go/libnslcd.git/proto +deps += lukeshu.com/git/go/libnslcd.git/systemd +deps += lukeshu.com/git/go/libsystemd.git/sd_daemon -all: build +srcdir := $(abspath $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))) +topdir := $(srcdir) -include $(addsuffix /Makefile,$(subdirs)) +subdirs = src/lukeshu.com/git/go/libnslcd.git/proto -secondary += test/*.o -download += $(addprefix src/,$(deps)) -generate += LICENSE.lgpl-2.1.txt LICENSE.gpl-2.txt LICENSE.apache-2.0.txt -build += bin/nshd nshd.service nshd.socket test/runner +generate += $(addprefix $(topdir)/src/,$(deps)) +generate += $(topdir)/LICENSE.lgpl-2.1.txt $(topdir)/LICENSE.gpl-2.txt $(topdir)/LICENSE.apache-2.0.txt +generate_secondary += $(topdir)/src/*.*/ +build += $(topdir)/bin/nshd $(topdir)/nshd.service $(topdir)/nshd.socket $(topdir)/test/runner +build_secondary += $(topdir)/test/*.o install += $(addprefix $(DESTDIR),$(bindir)/nshd $(systemddir)/system/nshd.socket $(systemddir)/system/nshd.service) - -download: $(download) -generate: $(generate) -build: $(build) -install: $(install) -.PHONY: download generate build install - -clean: - rm -rf -- pkg bin src/*.*/ - rm -f -- $(build) $(secondary) -.PHONY: clean -maintainer-clean: clean - rm -f -- $(generate) -.PHONY: maintainer-clean -uninstall: - rm -f -- $(install) - rmdir -p -- $(sort $(dir $(install))) 2>/dev/null || true -.PHONY: uninstall +ifeq (1,$(words $(MAKEFILE_LIST))) + include $(topdir)/common.mk +endif -LICENSE.lgpl-2.1.txt: $(NET) +$(topdir)/LICENSE.lgpl-2.1.txt: $(NET) curl https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt > $@ -LICENSE.gpl-2.txt: $(NET) +$(topdir)/LICENSE.gpl-2.txt: $(NET) curl https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt > $@ -LICENSE.apache-2.0.txt: $(NET) +$(topdir)/LICENSE.apache-2.0.txt: $(NET) curl https://www.apache.org/licenses/LICENSE-2.0 > $@ + +include $(topdir)/golang.mk -$(foreach d,$(deps),$(eval src/$d: $(NET); GOPATH='$(GOPATH)' go get -d -u $d)) +$(call goget,$(topdir),$(deps)) -bin/nshd: $(download) $(generate) $(gosrc) $(addprefix .Makefile.var.,$(cgo_variables)) - @true $(foreach f,$(filter $(vp),$^), && test $@ -nt $f ) || rm -rf -- bin pkg - GOPATH='$(GOPATH)' CGO_CFLAGS='$(CGO_CFLAGS)' go install nshd +$(topdir)/bin/nshd: $(generate) $(configure) $(call gosrc,$(topdir)) + $(call goinstall,$(topdir),nshd) -%: %.in - < $< sed $(foreach v,$(patsubst $(vp),%,$(filter $(vp),$^)), -e 's|@$v@|$($v)|g' ) > $@ -nshd.service: .Makefile.var.bindir .Makefile.var.user .Makefile.var.group -nshd.socket: .Makefile.var.user .Makefile.var.group +%.o: %.c .var.CC .var.CPPFLAGS .var.CFLAGS + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $(filter-out .var.%,$^) +%: %.o .var.CC .var.LDFLAGS .var.LOADLIBES .var.LDLIBS + $(CC) $(LDFLAGS) -o $@ $(filter-out .var.%,$^) $(LOADLIBES) $(LDLIBS) +%: %.in + < $< sed $(foreach v,$(patsubst .var.%,%,$(filter .var.%,$^)), -e 's|@$v@|$($v)|g' ) > $@ +$(topdir)/nshd.service: .var.bindir .var.user .var.group +$(topdir)/nshd.socket: .var.user .var.group + $(DESTDIR)$(bindir)/%: bin/% install -TDm755 $< $@ $(DESTDIR)$(systemddir)/system/%.socket: %.socket install -TDm644 $< $@ $(DESTDIR)$(systemddir)/system/%.service: %.service install -TDm644 $< $@ - -%.o: %.c .Makefile.var.CC .Makefile.var.CPPFLAGS .Makefile.var.CFLAGS - $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $(filter-out $(vp),$^) -%: %.o .Makefile.var.CC .Makefile.var.LDFLAGS .Makefile.var.LOADLIBES .Makefile.var.LDLIBS - $(CC) $(LDFLAGS) -o $@ $(filter-out $(vp),$^) $(LOADLIBES) $(LDLIBS) - -.Makefile.var.%: FORCE - @printf '%s' '$($*)' > .tmp$@ && { cmp -s .tmp$@ $@ && rm -f -- .tmp$@ || mv -Tf .tmp$@ $@; } || { rm -f -- .tmp$@; false; } -.PHONY: FORCE - -.SECONDARY: -.DELETE_ON_ERROR: diff --git a/common.mk b/common.mk new file mode 100644 index 0000000..7fd7964 --- /dev/null +++ b/common.mk @@ -0,0 +1,71 @@ +# Copyright 2015 Luke Shumaker +# +# This is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# The GNU General Public License's references to "object code" and +# "executables" are to be interpreted to also include the output of +# any document formatting or typesetting system, including +# intermediate and printed output. +# +# This software 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this manual; if not, see +# <http://www.gnu.org/licenses/>. + +rel = $(patsubst $(abspath .)/%,./%,$(abspath $1)) + +all: build +.PHONY: all + +-include $(addsuffix /Makefile,$(subdirs)) + +generate: $(generate) +.PHONY: generate + +configure: generate $(configure) +.PHONY: configure + +build: configure $(build) +.PHONY: build + +install: build $(install) +.PHONY: install + +# un-build +clean: + rm -rf -- $(build) $(build_secondary) +.PHONY: clean + +# un-configure +distclean: clean + rm -rf -- $(configure) $(configure_secondary) +.PHONY: distclean + +# un-generate +maintainer-clean: distclean + rm -rf -- $(generate) $(generate_secondary) +.PHONY: maintainer-clean + +# un-install +uninstall: + rm -f -- $(install) + rmdir -p -- $(sort $(dir $(install))) 2>/dev/null || true +.PHONY: uninstall + + +# Now, this is magic. It stores the values of environment variables, +# so that if you change them in a way that would cause something to be +# rebuilt, then Make knows. +.var.%: FORCE + $(Q)printf '%s' '$($*)' > .tmp$@ && { cmp -s .tmp$@ $@ && rm -f -- .tmp$@ || mv -Tf .tmp$@ $@; } || { rm -f -- .tmp$@; false; } + +.DELETE_ON_ERROR: +.SECONDARY: +.PHONY: FORCE diff --git a/golang.mk b/golang.mk new file mode 100644 index 0000000..222bbdf --- /dev/null +++ b/golang.mk @@ -0,0 +1,26 @@ +# Copyright 2015 Luke Shumaker + +_golang_cgo_variables = CGO_ENABLED CGO_CFLAGS CGO_CPPFLAGS CGO_CXXFLAGS CGO_LDFLAGS CC CXX +export $(_golang_cgo_variables) +_golang_src_cmd = find -L $1/src -name '.*' -prune -o \( -type f \( -false $(foreach e,go c s S cc cpp cxx h hh hpp hxx,-o -name '*.$e') \) -o -type d \) -print + +# Iterate over external dependencies, and create a rule to download it +goget = $(foreach d,$2,$(eval $1/src/$d: $(NET); GOPATH='$(abspath $1)' go get -d -u $d)) + +#|| { rm -rf -- $$@; false; })) + +gosrc = $(shell $(_golang_src_cmd)) $(addprefix .var.,$(_golang_cgo_variables)) +define goinstall + $(Q)for target in $(addprefix $1/bin/,$(notdir $2)); do \ + if test -e $$target; then \ + for dep in $(filter .var.%,$^); do \ + if test $$dep -nt $$target; then \ + rm -rf -- $1/bin $1/pkg || exit $$?; \ + exit 0; \ + fi \ + done \ + fi \ + done + GOPATH='$(abspath $1)' go install $2 + $(Q)true $(foreach e,$(notdir $2), && test -f $1/bin/$e -a -x $1/bin/$e && touch $1/bin/$e) +endef diff --git a/src/dl/dl_gnu.go b/src/dl/dl_gnu.go deleted file mode 100644 index 771e9c4..0000000 --- a/src/dl/dl_gnu.go +++ /dev/null @@ -1,82 +0,0 @@ -// The code in this file is trivial, and not eligable for copyright. -// -// The documentation in this file is taken from the Linux Programmer's -// Manual page for dlopen(3). -// -// Copyright 1995 Yggdrasil Computing, Incorporated. -// written by Adam J. Richter (adam@yggdrasil.com), -// with typesetting help from Daniel Quinlan (quinlan@yggdrasil.com). -// and Copyright 2003, 2015 Michael Kerrisk (mtk.manpages@gmail.com). -// -// This is free documentation; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// The GNU General Public License's references to "object code" -// and "executables" are to be interpreted as the output of any -// document formatting or typesetting system, including -// intermediate and printed output. -// -// This manual 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// <http://www.gnu.org/licenses/>. -// -// Modified by David A. Wheeler <dwheeler@dwheeler.com> 2000-11-28. -// Applied patch by Terran Melconian, aeb, 2001-12-14. -// Modified by Hacksaw <hacksaw@hacksaw.org> 2003-03-13. -// Modified by Matt Domsch, 2003-04-09: _init and _fini obsolete -// Modified by Michael Kerrisk <mtk.manpages@gmail.com> 2003-05-16. -// Modified by Walter Harms: dladdr, dlvsym -// Modified by Petr Baudis <pasky@suse.cz>, 2008-12-04: dladdr caveat - -package dl - -//#define _GNU_SOURCE -//#include <dlfcn.h> -import "C" - -// These flags to Open() are GNU libc extensions. -const ( - // Do not unload the shared object during Close(). - // Consequently, the object's static variables are not - // reinitialized if the object is reloaded with Open() at a - // later time. - RTLD_NODELETE Flag = C.RTLD_NODELETE // (since glibc 2.2, also present on Solaris) - - // Don't load the shared object. This can be used to test if - // the object is already resident (Open() returns nil if it - // is not, or the object's handle if it is resident). This - // flag can also be used to promote the flags on a shared - // object that is already loaded. For example, a shared - // object that was previously loaded with RTLD_LOCAL can be - // reopened with RTLD_NOLOAD | RTLD_GLOBAL. - RTLD_NOLOAD Flag = C.RTLD_NOLOAD // (since glibc 2.2, also present on Solaris) - - // Place the lookup scope of the symbols in this shared object - // ahead of the global scope. This means that a - // self-contained object will use its own symbols in - // preference to global symbols with the same name contained - // in objects that have already been loaded. - RTLD_DEEPBIND Flag = C.RTLD_DEEPBIND // (since glibc 2.3.4) -) - -// TODO: dlmopen -// TODO: dlvsym -// TODO: dladdr -// - dladdr1 -// TODO: dlinfo -// - RTLD_DI_LMID -// - RTLD_DI_LINKMAP -// - RTLD_DI_ORIGIN -// - RTLD_DI_SERINFO -// - RTLD_DI_SERINFOSIZE -// - RTLD_DI_MODID -// - RTLD_DI_DATA -// TODO: dl_iterate_phdr -// TODO: rtld-audit(7) diff --git a/src/dl/dlfcn.go b/src/dl/dlfcn.go deleted file mode 100644 index e240540..0000000 --- a/src/dl/dlfcn.go +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright 2015 Luke Shumaker <lukeshu@sbcglobal.net>. -// -// This is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// The GNU General Public License's references to "object code" and -// "executables" are to be interpreted to also include the output of -// any document formatting or typesetting system, including -// intermediate and printed output. -// -// This software 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// <http://www.gnu.org/licenses/>. - -// Package dl provides an interface to the POSIX runtime linker. -package dl - -import ( - "errors" - "sync" - "unsafe" -) - -//#cgo LDFLAGS: -ldl -//#include <stdlib.h> -//#include <dlfcn.h> -import "C" - -var HandleClosedError = errors.New("Handle is already closed") - -type Flag int - -// POSIX specifies these four flags to Open(). -const ( - // Relocations are performed at an implementation-defined - // time. - RTLD_LAZY Flag = C.RTLD_LAZY - - // Relocations are performed when the object is loaded. - RTLD_NOW Flag = C.RTLD_NOW - - // All symbols are available for relocation processing of - // other modules. - RTLD_GLOBAL Flag = C.RTLD_GLOBAL - - // All symbols are not made available for relocation - // processing by other modules. - RTLD_LOCAL Flag = C.RTLD_LOCAL -) - -type Handle struct { - c unsafe.Pointer - o int -} - -var dllock sync.Mutex - -// Open a shared object file, returning a Handle to it, or an error. -// If name is an empty string, then the returned handle is the global -// symbol table for the current process; if the name contains a slash, -// then it is interpretted as a pathname; otherwise, it is -// interpretted in an implementation-defined manner. -func Open(name string, flags Flag) (Handle, error) { - nameC := C.CString(name) - defer C.free(unsafe.Pointer(nameC)) - if name == "" { - nameC = nil - } - - dllock.Lock() - defer dllock.Unlock() - dlerror() - ptr := C.dlopen(nameC, C.int(flags)) - if ptr == nil { - return Handle{}, dlerror() - } - return Handle{c: ptr, o: 1}, nil -} - -// Look up a symbol, and return a pointer to it. -func (h Handle) Sym(symbol string) (unsafe.Pointer, error) { - dllock.Lock() - defer dllock.Unlock() - - if h.o == 0 { - return nil, HandleClosedError - } - - symbolC := C.CString(symbol) - defer C.free(unsafe.Pointer(symbolC)) - - dlerror() - ptr := C.dlsym(h.c, symbolC) - if ptr == nil { - return nil, dlerror() - } - return ptr, nil -} - -// Close this handle on a shared object; decrementint the reference -// count; if the reference count drops below 0, then the object is -// unloaded. -func (h Handle) Close() error { - dllock.Lock() - defer dllock.Unlock() - - if h.o == 0 { - return HandleClosedError - } - - dlerror() - r := C.dlclose(h.c) - if r != 0 { - return dlerror() - } - if h.o == 1 { - h.o = 0 - } - return nil -} - -func dlerror() error { - strC := C.dlerror() - if strC == nil { - return nil - } - return errors.New(C.GoString(strC)) -} diff --git a/src/dl/dlsym_reserved.go b/src/dl/dlsym_reserved.go deleted file mode 100644 index 081e012..0000000 --- a/src/dl/dlsym_reserved.go +++ /dev/null @@ -1,63 +0,0 @@ -// The documentation for RTLD_DEFAULT and RTLD_NEXT is taken from the -// Linux Programmer's Manual page for dlsym(3). -// -// Copyright 1995 Yggdrasil Computing, Incorporated. -// Copyright 2003, 2015 Michael Kerrisk <mtk.manpages@gmail.com>. -// Copyright 2015 Luke Shumaker <lukeshu@sbcglobal.net>. -// -// This is free documentation; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// The GNU General Public License's references to "object code" -// and "executables" are to be interpreted as the output of any -// document formatting or typesetting system, including -// intermediate and printed output. -// -// This manual 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 General Public License for more details. -// -// You should have received a copy of the GNU General Public -// License along with this manual; if not, see -// <http://www.gnu.org/licenses/>. - -package dl - -import "unsafe" - -//#define _GNU_SOURCE -//#include <stdint.h> -//#include <dlfcn.h> -//const uintptr_t rtld_next = (uintptr_t)RTLD_NEXT; -//const uintptr_t rtld_default = (uintptr_t)RTLD_DEFAULT; -import "C" - -// These constant values for Handles are reserved by POSIX for future -// use with these meanings. They are available in GNU libdl if -// _GNU_SOURCE is defined. -var ( - // This Handle represents the default default shared object - // search order. The search will include global symbols in - // the executable and its dependencies, as well as symbols in - // shared objects that were dynamically loaded with the - // RTLD_GLOBAL flag. - RTLD_DEFAULT Handle - - // This Handle represents the shared object search order after - // the current object. This allows one to provide a wrapper - // around a function in another shared object, so that, for - // example, the definition of a function in a preloaded shared - // object (see LD_PRELOAD in ld.so(8)) can find and invoke the - // "real" function provided in another shared object (or for - // that matter, the "next" definition of the function in cases - // where there are multiple layers of preloading). - RTLD_NEXT Handle -) - -func init() { - RTLD_DEFAULT = Handle{c: unsafe.Pointer(uintptr(C.rtld_default)), o: 2} - RTLD_DEFAULT = Handle{c: unsafe.Pointer(uintptr(C.rtld_next)), o: 2} -} diff --git a/src/getgr/getgr.go b/src/getgr/getgr.go deleted file mode 100644 index 5e32826..0000000 --- a/src/getgr/getgr.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2015 Luke Shumaker <lukeshu@sbcglobal.net>. -// -// This 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 software 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 manual; if not, see -// <http://www.gnu.org/licenses/>. - -// Package getgr provides an interface to query the POSIX group -// database. -package getgr - -import ( - "syscall" - "unsafe" -) - -//#define _POSIX_SOURCE // for getgrnam_r(3) in grp.h -//#include <stdlib.h> // for free(3) -//#include <unistd.h> // for sysconf(3) -//#include <grp.h> // for getgrnam_r(3) -//static char *strary(char **ary, unsigned int n) { return ary[n]; } -import "C" - -type Gid uint - -type Group struct { - Name string - Passwd string - Gid Gid - Mem []string -} - -func strary(c **C.char) (g []string) { - g = make([]string, 0) - for i := C.uint(0); true; i++ { - cstr := C.strary(c, i) - if cstr == nil { - return - } - g = append(g, C.GoString(cstr)) - } - panic("not reached") -} - -// A wrapper around C getgrnam_r -func ByName(name string) (*Group, error) { - nameC := C.CString(name) - defer C.free(unsafe.Pointer(nameC)) - - buflen := C.sysconf(C._SC_GETGR_R_SIZE_MAX) - if buflen < 1 { - buflen = 1024 - } - buf := make([]byte, buflen) - var grp C.struct_group - var ret *C.struct_group - for { - success, errno := C.getgrnam_r(nameC, &grp, (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(buflen), &ret) - if success >= 0 { - break - } - if errno == syscall.ERANGE { - buflen += 256 - buf = make([]byte, buflen) - } else { - return nil, errno - } - } - if ret == nil { - return nil, nil - } - return &Group{ - Name: C.GoString(ret.gr_name), - Passwd: C.GoString(ret.gr_passwd), - Gid: Gid(ret.gr_gid), - Mem: strary(ret.gr_mem), - }, nil -} - -// A wrapper around C getgrgid_r -func ByGid(gid int32) (*Group, error) { - gidC := C.__gid_t(gid) - - buflen := C.sysconf(C._SC_GETGR_R_SIZE_MAX) - if buflen < 1 { - buflen = 1024 - } - buf := make([]byte, buflen) - var grp C.struct_group - var ret *C.struct_group - for { - success, errno := C.getgrgid_r(gidC, &grp, (*C.char)(unsafe.Pointer(&buf[0])), C.size_t(buflen), &ret) - if success >= 0 { - break - } - if errno == syscall.ERANGE { - buflen += 256 - buf = make([]byte, buflen) - } else { - return nil, errno - } - } - if ret == nil { - return nil, nil - } - return &Group{ - Name: C.GoString(ret.gr_name), - Passwd: C.GoString(ret.gr_passwd), - Gid: Gid(ret.gr_gid), - Mem: strary(ret.gr_mem), - }, nil -} diff --git a/src/inotify/bits.go b/src/inotify/bits.go deleted file mode 100644 index 18d8566..0000000 --- a/src/inotify/bits.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (C) 2015 Luke Shumaker -// -// Many of the comments in this file are taken from the GNU libc -// header file <sys/inotify.h> -// -// Copyright (C) 2005-2015 Free Software Foundation, Inc. -// -// The GNU C 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. -// -// The GNU C 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 the GNU C Library; if not, see -// <http://www.gnu.org/licenses/>. - -package inotify - -const ( - // Flags for the parameter of InotifyInit1(). - // These, oddly, appear to be 24-bit numbers. - IN_CLOEXEC int = 02000000 - IN_NONBLOCK int = 00004000 -) - -type file int // File Descriptor -type Wd int // Watch Descriptor - -type Mask uint32 - -const ( - // Supported events suitable for the `mask` parameter of Inotify.AddWatch(). - IN_ACCESS Mask = (1 << 0) // File was accessed. - IN_MODIFY Mask = (1 << 1) // File was modified. - IN_ATTRIB Mask = (1 << 2) // Metadata changed. - IN_CLOSE_WRITE Mask = (1 << 3) // Writtable file was closed. - IN_CLOSE_NOWRITE Mask = (1 << 4) // Unwrittable file closed. - IN_OPEN Mask = (1 << 5) // File was opened. - IN_MOVED_FROM Mask = (1 << 6) // File was moved from X. - IN_MOVED_TO Mask = (1 << 7) // File was moved to Y. - IN_CREATE Mask = (1 << 8) // Subfile was created. - IN_DELETE Mask = (1 << 9) // Subfile was deleted. - IN_DELETE_SELF Mask = (1 << 10) // Self was deleted. - IN_MOVE_SELF Mask = (1 << 11) // Self was moved. - - // Events that appear in output without subscribing to them. - IN_UNMOUNT Mask = (1 << 13) // Backing fs was unmounted. - IN_Q_OVERFLOW Mask = (1 << 14) // Event queued overflowed. - IN_IGNORED Mask = (1 << 15) // File was ignored (expect no more events). - - // Special flags that you may pass to Inotify.AddWatch()... - // except for IN_ISDIR, which is a flag that is set on output events. - IN_ONLYDIR Mask = (1 << 24) // Only watch the path if it is a directory. - IN_DONT_FOLLOW Mask = (1 << 25) // Do not follow a sym link. - IN_EXCL_UNLINK Mask = (1 << 26) // Exclude events on unlinked objects. - IN_MASK_ADD Mask = (1 << 29) // Add to the mask of an already existing watch. - IN_ISDIR Mask = (1 << 30) // Event occurred against dir. - IN_ONESHOT Mask = (1 << 31) // Only send event once. - - // Convenience macros */ - IN_CLOSE Mask = (IN_CLOSE_WRITE | IN_CLOSE_NOWRITE) // Close. - IN_MOVE Mask = (IN_MOVED_FROM | IN_MOVED_TO) // Moves. - IN_ALL_EVENTS Mask = 0x00000FFF // All events which a program can wait on. -) - -var in_bits [32]string = [32]string{ - // mask - /* 0 */ "IN_ACCESS", - /* 1 */ "IN_MODIFY", - /* 2 */ "IN_ATTRIB", - /* 3 */ "IN_CLOSE_WRITE", - /* 4 */ "IN_CLOSE_NOWRITE", - /* 5 */ "IN_OPEN", - /* 6 */ "IN_MOVED_FROM", - /* 7 */ "IN_MOVED_TO", - /* 8 */ "IN_CREATE", - /* 9 */ "IN_DELETE", - /* 10 */ "IN_DELETE_SELF", - /* 11 */ "IN_MOVE_SELF", - /* 12 */ "(1<<12)", - // events sent by the kernel - /* 13 */ "IN_UNMOUNT", - /* 14 */ "IN_Q_OVERFLOW", - /* 15 */ "IN_IGNORED", - /* 16 */ "(1<<16)", - /* 17 */ "(1<<17)", - /* 18 */ "(1<<18)", - /* 19 */ "(1<<19)", - /* 20 */ "(1<<20)", - /* 21 */ "(1<<21)", - /* 22 */ "(1<<22)", - /* 23 */ "(1<<23)", - // special flags - /* 24 */ "IN_ONLYDIR", - /* 25 */ "IN_DONT_FOLLOW", - /* 26 */ "IN_EXCL_UNLINK", - /* 27 */ "(1<<27)", - /* 28 */ "(1<<28)", - /* 29 */ "IN_MASK_ADD", - /* 30 */ "IN_ISDIR", - /* 31 */ "IN_ONESHOT", -} - -func (mask Mask) String() string { - out := "" - for i, name := range in_bits { - if mask&(Mask(1)<<uint(i)) != 0 { - if len(out) > 0 { - out += "|" - } - out += name - } - } - return out -} diff --git a/src/inotify/inotify.go b/src/inotify/inotify.go deleted file mode 100644 index 2fd3a83..0000000 --- a/src/inotify/inotify.go +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2015 Luke Shumaker <lukeshu@sbcglobal.net>. -// -// This 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 software 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 manual; if not, see -// <http://www.gnu.org/licenses/>. - -// Package inotify provides an interface to the Linux inotify system. -// The inotify system is a mechanism for monitoring filesystem events. -package inotify - -import ( - "sync" - "syscall" - "unsafe" -) - -type Inotify struct { - fd file - fdLock sync.RWMutex - buffFull [4096]byte - buff []byte - buffLock sync.Mutex -} - -type Event struct { - Wd Wd // Watch descriptor - Mask Mask // Mask describing event - Cookie uint32 // Unique cookie associating related events (for rename(2)) - Name *string // Optional name -} - -// Create an inotify instance. The variant InotifyInit1() allows -// flags to access extra functionality. -func InotifyInit() (*Inotify, error) { - fd, err := inotify_init() - o := Inotify{ - fd: fd, - } - o.buff = o.buffFull[:0] - return &o, err -} - -// Create an inotify instance, with flags specifying extra -// functionality. -func InotifyInit1(flags int) (*Inotify, error) { - fd, err := inotify_init1(flags) - o := Inotify{ - fd: fd, - } - o.buff = o.buffFull[:0] - return &o, err -} - -// Add a watch to the inotify instance, or modifies an existing watch -// item. -func (o *Inotify) AddWatch(path string, mask Mask) (Wd, error) { - o.fdLock.RLock() - defer o.fdLock.RUnlock() - return inotify_add_watch(o.fd, path, mask) -} - -// Remove a watch from the inotify instance. -func (o *Inotify) RmWatch(wd Wd) error { - o.fdLock.RLock() - defer o.fdLock.RUnlock() - return inotify_rm_watch(o.fd, wd) -} - -// Close the inotify instance; further calls to this object will -// error. -// -// Events recieved before Close() is called may still be Read() after -// the call to Close(). -// -// Beware that if Close() is called while waiting on Read(), it will -// block until events are read. -func (o *Inotify) Close() error { - o.fdLock.Lock() - defer o.fdLock.Unlock() - defer func() { o.fd = -1 }() - return sysclose(o.fd) -} - -// Read an event from the inotify instance. -// -// Events recieved before Close() is called may still be Read() after -// the call to Close(). -func (o *Inotify) Read() (Event, error) { - o.buffLock.Lock() - defer o.buffLock.Unlock() - - if len(o.buff) == 0 { - o.fdLock.RLock() - len, err := sysread(o.fd, o.buffFull[:]) - o.fdLock.RUnlock() - if len == 0 { - return Event{Wd: -1}, o.Close() - } else if len < 0 { - return Event{Wd: -1}, err - } - o.buff = o.buffFull[0:len] - } - - raw := (*syscall.InotifyEvent)(unsafe.Pointer(&o.buff[0])) - ret := Event{ - Wd: Wd(raw.Wd), - Mask: Mask(raw.Mask), - Cookie: raw.Cookie, - Name: nil, - } - if raw.Len > 0 { - bytes := (*[syscall.NAME_MAX]byte)(unsafe.Pointer(&o.buff[syscall.SizeofInotifyEvent])) - name := string(bytes[:raw.Len-1]) - ret.Name = &name - } - o.buff = o.buff[0 : syscall.SizeofInotifyEvent+raw.Len] - return ret, nil -} diff --git a/src/inotify/inutil/inotify_util.go b/src/inotify/inutil/inotify_util.go deleted file mode 100644 index c643e59..0000000 --- a/src/inotify/inutil/inotify_util.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2015 Luke Shumaker <lukeshu@sbcglobal.net>. -// -// This 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 software 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 manual; if not, see -// <http://www.gnu.org/licenses/>. - -// Package inutil provides a channel-based interface to inotify. -package inutil - -import ( - "inotify" - "os" - "syscall" -) - -type Watcher struct { - Events <-chan inotify.Event - Errors <-chan error - events chan<- inotify.Event - errors chan<- error - in *inotify.Inotify -} - -// Wraps inotify.InotifyInit() -func WatcherInit() (*Watcher, error) { - in, err := inotify.InotifyInit() - return newWatcher(in, err) -} - -// Wraps inotify.InotifyInit1() -func WatcherInit1(flags int) (*Watcher, error) { - in, err := inotify.InotifyInit1(flags &^ inotify.IN_NONBLOCK) - return newWatcher(in, err) -} - -func newWatcher(in *inotify.Inotify, err error) (*Watcher, error) { - events := make(chan inotify.Event) - errors := make(chan error) - o := &Watcher{ - Events: events, - events: events, - Errors: errors, - errors: errors, - in: in, - } - go o.worker() - return o, err -} - -// Wraps inotify.Inotify.AddWatch(); adds or modifies a watch. -func (o *Watcher) AddWatch(path string, mask inotify.Mask) (inotify.Wd, error) { - return o.in.AddWatch(path, mask) -} - -// Wraps inotify.Inotify.RmWatch(); removes a watch. -func (o *Watcher) RmWatch(wd inotify.Wd) error { - return o.in.RmWatch(wd) -} - -// Wraps inotify.Inotify.Close(). Unlike inotify.Inotify.Close(), -// this cannot block. Also unlike inotify.Inotify.Close(), nothing -// may be received from the channel after this is called. -func (o *Watcher) Close() { - func() { - defer recover() - close(o.events) - close(o.errors) - }() - go o.in.Close() -} - -func (o *Watcher) worker() { - defer recover() - for { - ev, err := o.in.Read() - if ev.Wd >= 0 { - o.events <- ev - } - if err != nil { - if err.(*os.SyscallError).Err == syscall.EBADF { - o.Close() - } - o.errors <- err - } - } -} diff --git a/src/inotify/syscall.go b/src/inotify/syscall.go deleted file mode 100644 index d1b5140..0000000 --- a/src/inotify/syscall.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2015 Luke Shumaker <lukeshu@sbcglobal.net>. -// -// This 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 software 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 manual; if not, see -// <http://www.gnu.org/licenses/>. - -package inotify - -import ( - "os" - "syscall" -) - -func newPathError(op string, path string, err error) error { - if err == nil { - return nil - } - return &os.PathError{Op: op, Path: path, Err: err} -} - -// Create and initialize inotify instance. -func inotify_init() (file, error) { - fd, errno := syscall.InotifyInit() - return file(fd), os.NewSyscallError("inotify_init", errno) -} - -// Create and initialize inotify instance. -func inotify_init1(flags int) (file, error) { - fd, errno := syscall.InotifyInit1(flags) - return file(fd), os.NewSyscallError("inotify_init1", errno) -} - -// Add watch of object NAME to inotify instance FD. Notify about -// events specified by MASK. -func inotify_add_watch(fd file, name string, mask Mask) (Wd, error) { - wd, errno := syscall.InotifyAddWatch(int(fd), name, uint32(mask)) - return Wd(wd), newPathError("inotify_add_watch", name, errno) -} - -// Remove the watch specified by WD from the inotify instance FD. -func inotify_rm_watch(fd file, wd Wd) error { - success, errno := syscall.InotifyRmWatch(int(fd), uint32(wd)) - switch success { - case -1: - if errno == nil { - panic("should never happen") - } - os.NewSyscallError("inotify_rm_watch", errno) - case 0: - if errno != nil { - panic("should never happen") - } - return nil - } - panic("should never happen") -} - -func sysclose(fd file) error { - return os.NewSyscallError("close", syscall.Close(int(fd))) -} - -func sysread(fd file, p []byte) (int, error) { - n, err := syscall.Read(int(fd), p) - return n, os.NewSyscallError("read", err) -} diff --git a/src/nshd/hackers_git/db_config.go b/src/nshd/hackers_git/db_config.go index ffacf00..dc3b99e 100644 --- a/src/nshd/hackers_git/db_config.go +++ b/src/nshd/hackers_git/db_config.go @@ -22,7 +22,7 @@ package hackers_git import ( - p "nslcd/proto" + p "lukeshu.com/git/go/libnslcd.git/proto" s "syscall" ) diff --git a/src/nshd/hackers_git/db_group.go b/src/nshd/hackers_git/db_group.go index 4f27627..7b820e8 100644 --- a/src/nshd/hackers_git/db_group.go +++ b/src/nshd/hackers_git/db_group.go @@ -22,7 +22,7 @@ package hackers_git import ( - p "nslcd/proto" + p "lukeshu.com/git/go/libnslcd.git/proto" s "syscall" ) diff --git a/src/nshd/hackers_git/db_pam.go b/src/nshd/hackers_git/db_pam.go index 3fc773c..e21ba63 100644 --- a/src/nshd/hackers_git/db_pam.go +++ b/src/nshd/hackers_git/db_pam.go @@ -24,7 +24,7 @@ package hackers_git import ( "crypto/rand" "math/big" - p "nslcd/proto" + p "lukeshu.com/git/go/libnslcd.git/proto" s "syscall" ) diff --git a/src/nshd/hackers_git/db_passwd.go b/src/nshd/hackers_git/db_passwd.go index 1283ec1..0be3910 100644 --- a/src/nshd/hackers_git/db_passwd.go +++ b/src/nshd/hackers_git/db_passwd.go @@ -22,7 +22,7 @@ package hackers_git import ( - p "nslcd/proto" + p "lukeshu.com/git/go/libnslcd.git/proto" s "syscall" ) diff --git a/src/nshd/hackers_git/db_shadow.go b/src/nshd/hackers_git/db_shadow.go index c83f223..c2719b3 100644 --- a/src/nshd/hackers_git/db_shadow.go +++ b/src/nshd/hackers_git/db_shadow.go @@ -22,7 +22,7 @@ package hackers_git import ( - p "nslcd/proto" + p "lukeshu.com/git/go/libnslcd.git/proto" s "syscall" ) diff --git a/src/nshd/hackers_git/gid.go b/src/nshd/hackers_git/gid.go index d8293d7..f7bbac7 100644 --- a/src/nshd/hackers_git/gid.go +++ b/src/nshd/hackers_git/gid.go @@ -21,7 +21,7 @@ package hackers_git -import "getgr" +import "lukeshu.com/git/go/libgnulinux.git/getgr" func name2gid(name string) int32 { gr, err := getgr.ByName(name) diff --git a/src/nshd/hackers_git/hackers.go b/src/nshd/hackers_git/hackers.go index 5b57a63..2e9edc1 100644 --- a/src/nshd/hackers_git/hackers.go +++ b/src/nshd/hackers_git/hackers.go @@ -24,12 +24,11 @@ package hackers_git import ( - "inotify" - "inotify/inutil" - "nslcd/proto" - "nslcd/proto/server" - "nslcd/systemd" - "sd_daemon/logger" + "lukeshu.com/git/go/libgnulinux.git/inotify" + "lukeshu.com/git/go/libnslcd.git/proto" + "lukeshu.com/git/go/libnslcd.git/proto/server" + "lukeshu.com/git/go/libnslcd.git/systemd" + "lukeshu.com/git/go/libsystemd.git/sd_daemon/logger" "sync" ) @@ -52,7 +51,7 @@ type Hackers struct { users map[int32]user groups map[string]map[string]bool - in_fd *inutil.Watcher + in_fd *inotify.Watcher in_wd_home inotify.Wd in_wd_yaml inotify.Wd in_uid2wd map[int32]inotify.Wd diff --git a/src/nshd/hackers_git/hackers_parse.go b/src/nshd/hackers_git/hackers_parse.go index 63e5c0f..0525c56 100644 --- a/src/nshd/hackers_git/hackers_parse.go +++ b/src/nshd/hackers_git/hackers_parse.go @@ -27,7 +27,7 @@ import ( "io/ioutil" "os" "path" - "sd_daemon/logger" + "lukeshu.com/git/go/libsystemd.git/sd_daemon/logger" "strconv" "strings" ) diff --git a/src/nshd/hackers_git/hackers_watch.go b/src/nshd/hackers_git/hackers_watch.go index d2c5bce..5bcecbc 100644 --- a/src/nshd/hackers_git/hackers_watch.go +++ b/src/nshd/hackers_git/hackers_watch.go @@ -22,12 +22,11 @@ package hackers_git import ( - "inotify" - "inotify/inutil" + "lukeshu.com/git/go/libgnulinux.git/inotify" "os" "path/filepath" - "sd_daemon/logger" - "sd_daemon/lsb" + "lukeshu.com/git/go/libsystemd.git/sd_daemon/logger" + "lukeshu.com/git/go/libsystemd.git/sd_daemon/lsb" ) const ( @@ -83,7 +82,7 @@ func (o *Hackers) close() { func (o *Hackers) reload() (err error) { o.close() - o.in_fd, err = inutil.WatcherInit() ; if err != nil { return } + o.in_fd, err = inotify.WatcherInit() ; if err != nil { return } o.in_wd_home, err = o.in_fd.AddWatch("/home" , in_DIR|in_CHILD_ADD); if err != nil { return } o.in_wd_yaml, err = o.in_fd.AddWatch(o.Cfg.Yamldir, in_DIR|in_CHILD_ANY); if err != nil { return } diff --git a/src/nshd/main.go b/src/nshd/main.go index d9c1277..08d2a97 100644 --- a/src/nshd/main.go +++ b/src/nshd/main.go @@ -24,7 +24,7 @@ package main import ( "nshd/hackers_git" - "nslcd/systemd" + "lukeshu.com/git/go/libnslcd.git/systemd" "os" ) diff --git a/src/nslcd/proto/.gitignore b/src/nslcd/proto/.gitignore deleted file mode 100644 index b3f9749..0000000 --- a/src/nslcd/proto/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/requests.txt -/server/func_handlerequest.go -/server/interface_backend.go -/server/type_nilbackend.go diff --git a/src/nslcd/proto/Makefile b/src/nslcd/proto/Makefile deleted file mode 100644 index e4730d5..0000000 --- a/src/nslcd/proto/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> -# -# 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 - -d := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) - -generate += $d/server/interface_backend.go -generate += $d/server/func_handlerequest.go -generate += $d/server/type_nilbackend.go -secondary += $d/requests.txt - -ifeq (1,$(words $(MAKEFILE_LIST))) - -all: generate -.PHONY: all - -generate: $(generate) -.PHONY: generate - -clean: - rm -f -- $(secondary) -.PHONY: clean -maintainer-clean: clean - rm -f -- $(generate) -.PHONY: maintainer-clean - -.DELETE_ON_ERROR: -.SECONDARY: - -else - -# fix these to the current value of `d` -generate := $(generate) -secondary := $(secondary) - -endif - -$d/requests.txt: $d/nslcd_h.go $d/Makefile - < $< grep -Eo '\btype Request_([^_ ]+)(_\S+)?' | sed 's/^type Request_//' > $@ - -%.go: %.go.sh - ./$^ > $@ - -$d/server/interface_backend.go: $d/requests.txt -$d/server/func_handlerequest.go: $d/requests.txt -$d/server/type_nilbackend.go: $d/server/interface_backend.go diff --git a/src/nslcd/proto/doc.go b/src/nslcd/proto/doc.go deleted file mode 100644 index 70929f3..0000000 --- a/src/nslcd/proto/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> -// -// 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 - -// Package nslcd_proto implements the nslcd protocol of nss-pam-ldapd. -// -// The godoc documentation for this packages isn't very good; you -// should look at the source file nslcd_h.go. -package nslcd_proto diff --git a/src/nslcd/proto/io.go b/src/nslcd/proto/io.go deleted file mode 100644 index 3c0c5be..0000000 --- a/src/nslcd/proto/io.go +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> -// -// 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 - -package nslcd_proto - -import ( - "encoding/binary" - "fmt" - "io" - "net" - "reflect" - "syscall" -) - -type NslcdError string - -func (o NslcdError) Error() string { - return string(o) -} - -type nslcdObject interface { - nslcdWrite(fd io.Writer) -} - -type nslcdObjectPtr interface { - nslcdRead(fd io.Reader) -} - -// Write an object to a stream. In the event of an error, this -// function may panic! Handle it! -func Write(fd io.Writer, data interface{}) { - switch data := data.(type) { - // basic data types - case nslcdObject: - data.nslcdWrite(fd) - case []byte: - _, err := fd.Write(data) - if err != nil { - panic(err) - } - case int32: - err := binary.Write(fd, binary.BigEndian, data) - if err != nil { - panic(err) - } - // composite datatypes - case string: - Write(fd, int32(len(data))) - Write(fd, []byte(data)) - case []string: - Write(fd, int32(len(data))) - for _, item := range data { - Write(fd, item) - } - case net.IP: - var af int32 = -1 - switch len(data) { - case net.IPv4len: - af = syscall.AF_INET - case net.IPv6len: - af = syscall.AF_INET6 - } - var bytes []byte - if af < 0 { - bytes = make([]byte, 0) - } else { - bytes = data - } - Write(fd, af) - Write(fd, int32(len(bytes))) - Write(fd, bytes) - case []net.IP: - Write(fd, int32(len(data))) - for _, item := range data { - Write(fd, item) - } - default: - v := reflect.ValueOf(data) - switch v.Kind() { - case reflect.Struct: - for i, n := 0, v.NumField(); i < n; i++ { - Write(fd, v.Field(i).Interface()) - } - default: - panic(fmt.Sprintf("Invalid structure to write NSLCD protocol data from: %T ( %#v )", data, data)) - } - } -} - -// Read an object from a stream. In the event of an error, this -// function may panic! Handle it! -func Read(fd io.Reader, data interface{}) { - switch data := data.(type) { - // basic data types - case nslcdObjectPtr: - data.nslcdRead(fd) - case *[]byte: - _, err := fd.Read(*data) - if err != nil { - panic(err) - } - case *int32: - err := binary.Read(fd, binary.BigEndian, data) - if err != nil { - panic(err) - } - // composite datatypes - case *string: - var len int32 - Read(fd, &len) - buf := make([]byte, len) - Read(fd, &buf) - *data = string(buf) - case *[]string: - var num int32 - Read(fd, &num) - *data = make([]string, num) - for i := 0; i < int(num); i++ { - Read(fd, &((*data)[i])) - } - case *net.IP: - var af int32 - Read(fd, &af) - var _len int32 - switch af { - case syscall.AF_INET: - _len = net.IPv4len - case syscall.AF_INET6: - _len = net.IPv6len - default: - panic(NslcdError(fmt.Sprintf("incorrect address family specified: %d", af))) - } - var len int32 - Read(fd, &len) - if len != _len { - panic(NslcdError(fmt.Sprintf("address length incorrect: %d", len))) - } - buf := make([]byte, len) - Read(fd, &buf) - *data = buf - case *[]net.IP: - var num int32 - Read(fd, &num) - *data = make([]net.IP, num) - for i := 0; i < int(num); i++ { - Read(fd, &((*data)[i])) - } - default: - p := reflect.ValueOf(data) - v := reflect.Indirect(p) - if p == v || v.Kind() != reflect.Struct { - panic(fmt.Sprintf("The argument to nslcd_proto/internal.Read() must be a pointer: %T ( %#v )", data, data)) - } - for i, n := 0, v.NumField(); i < n; i++ { - Read(fd, v.Field(i).Addr().Interface()) - } - } -} diff --git a/src/nslcd/proto/nslcd_h.go b/src/nslcd/proto/nslcd_h.go deleted file mode 100644 index cb210cd..0000000 --- a/src/nslcd/proto/nslcd_h.go +++ /dev/null @@ -1,454 +0,0 @@ -// This file is based heavily on nslcd.h from nss-pam-ldapd -// Copyright (C) 2015 Luke Shumaker -/* - nslcd.h - file describing client/server protocol - - Copyright (C) 2006 West Consulting - Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012, 2013 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 -*/ - -package nslcd_proto - -import ( - "fmt" - "io" - "net" -) - -/* - The protocol used between the nslcd client and server is a simple binary - protocol. It is request/response based where the client initiates a - connection, does a single request and closes the connection again. Any - mangled or not understood messages will be silently ignored by the server. - - A request looks like: - INT32 NSLCD_VERSION - INT32 NSLCD_ACTION_* - [request parameters if any] - A response looks like: - INT32 NSLCD_VERSION - INT32 NSLCD_ACTION_* (the original request type) - [result(s)] - INT32 NSLCD_RESULT_END - A single result entry looks like: - NSLCD_RESULT_BEGIN int32 - [result value(s)] - If a response would return multiple values (e.g. for NSLCD_ACTION_*_ALL - functions) each return value will be preceded by a NSLCD_RESULT_BEGIN - value. After the last returned result the server sends - NSLCD_RESULT_END. If some error occurs (e.g. LDAP server unavailable, - error in the request, etc) the server terminates the connection to signal - an error condition (breaking the protocol). - - These are the available basic data types: - INT32 - 32-bit integer value - TYPE - a typed field that is transferred using sizeof() - STRING - a string length (32bit) followed by the string value (not - null-terminted) the string itself is assumed to be UTF-8 - STRINGLIST - a 32-bit number noting the number of strings followed by - the strings one at a time - - Furthermore the ADDRESS compound data type is defined as: - INT32 type of address: e.g. AF_INET or AF_INET6 - INT32 lenght of address - RAW the address itself - With the ADDRESSLIST using the same construct as with STRINGLIST. - - The protocol uses network byte order for all types. -*/ -// These basic data types are implemented in `io.go` - -/* The current version of the protocol. This protocol should only be - updated with major backwards-incompatible changes. */ -const NSLCD_VERSION int32 = 0x00000002 - -/* Get a NSLCD configuration option. There is one request parameter: */ -type Request_Config_Get struct { - Key int32 /* NSLCD_CONFIG_* */ -} -/* the result value is: */ -type Config struct { - Value string /* interpretation depending on request */ -} -const NSLCD_ACTION_CONFIG_GET int32 = 0x00010001 - -const ( - /* return the message, if any, that is presented to the user when password - modification through PAM is prohibited */ - NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE int32 = 1 -) - -/* Email alias (/etc/aliases) NSS requests. The result values for a - single entry are: */ -type Alias struct { - Name string - Recipients []string -} -const NSLCD_ACTION_ALIAS_BYNAME int32 = 0x00020001; type Request_Alias_ByName struct { Name string } -const NSLCD_ACTION_ALIAS_ALL int32 = 0x00020008; type Request_Alias_All struct {} - -/* Ethernet address/name mapping NSS requests. The result values for a - single entry are: */ -type Ether struct { - Name string - Address [6]byte -} -const NSLCD_ACTION_ETHER_BYNAME int32 = 0x00030001; type Request_Ether_ByName struct { Name string } -const NSLCD_ACTION_ETHER_BYETHER int32 = 0x00030002; type Request_Ether_ByEther struct { Ether [6]byte } -const NSLCD_ACTION_ETHER_ALL int32 = 0x00030008; type Request_Ether_All struct {} - -/* Group and group membership related NSS requests. The result values - for a single entry are: */ -type Group struct { - Name string - PwHash string - ID int32 - Members []string -} -/* (note that the BYMEMER call returns an emtpy members list) */ -const NSLCD_ACTION_GROUP_BYNAME int32 = 0x00040001; type Request_Group_ByName struct { Name string } -const NSLCD_ACTION_GROUP_BYGID int32 = 0x00040002; type Request_Group_ByGid struct { Gid int32 } -const NSLCD_ACTION_GROUP_BYMEMBER int32 = 0x00040006; type Request_Group_ByMember struct { Member string } -const NSLCD_ACTION_GROUP_ALL int32 = 0x00040008; type Request_Group_All struct {} - -/* Hostname (/etc/hosts) lookup NSS requests. The result values - for an entry are: */ -type Host struct { - Name string - Aliases []string - Addresses []net.IP -} -const NSLCD_ACTION_HOST_BYNAME int32 = 0x00050001; type Request_Host_ByName struct { Name string } -const NSLCD_ACTION_HOST_BYADDR int32 = 0x00050002; type Request_Host_ByAddr struct { Addr net.IP } -const NSLCD_ACTION_HOST_ALL int32 = 0x00050008; type Request_Host_All struct {} - -/* Netgroup NSS result entries contain a number of parts. A result entry - starts with: - STRING netgroup name - followed by zero or more references to other netgroups or netgroup - triples. A reference to another netgroup looks like: - INT32 NSLCD_NETGROUP_TYPE_NETGROUP - STRING other netgroup name - A a netgroup triple looks like: - INT32 NSLCD_NETGROUP_TYPE_TRIPLE - STRING host - STRING user - STRING domain - A netgroup result entry is terminated by: - INT32 NSLCD_NETGROUP_TYPE_END - */ -type Netgroup_Netgroup struct { - Name string -} -type Netgroup_Triple struct { - Host string - User string - Domain string -} -type Netgroup_PartList []interface{} -func (data Netgroup_PartList) nslcdWrite(fd io.Writer) { - for _, part := range data { - var t int32 = -1 - switch part.(type) { - case Netgroup_Netgroup: - t = NSLCD_NETGROUP_TYPE_NETGROUP - case Netgroup_Triple: - t = NSLCD_NETGROUP_TYPE_TRIPLE - } - if t < 0 { - panic("unrecognized netgroup type") - } - Write(fd, t) - Write(fd, part) - } - Write(fd, NSLCD_NETGROUP_TYPE_END) -} -func (data *Netgroup_PartList) nslcdRead(fd io.Reader) { - *data = make([]interface{}, 0) - for { - var t int32 - var v interface{} - Read(fd, &t) - switch t { - case NSLCD_NETGROUP_TYPE_NETGROUP: - v = Netgroup_Netgroup{} - case NSLCD_NETGROUP_TYPE_TRIPLE: - v = Netgroup_Triple{} - case NSLCD_NETGROUP_TYPE_END: - return - default: - panic(NslcdError(fmt.Sprintf("unrecognized netgroup type: %#08x", t))) - } - Read(fd, &v) - *data = append(*data, v) - } -} -var _ nslcdObject = Netgroup_PartList{} -var _ nslcdObjectPtr = &Netgroup_PartList{} -type Netgroup struct { - Name string - Parts Netgroup_PartList -} -const NSLCD_ACTION_NETGROUP_BYNAME int32 = 0x00060001; type Request_Netgroup_ByName struct { Name string } -const NSLCD_ACTION_NETGROUP_ALL int32 = 0x00060008; type Request_Netgroup_All struct {} -const ( - NSLCD_NETGROUP_TYPE_NETGROUP int32 = 1 - NSLCD_NETGROUP_TYPE_TRIPLE int32 = 2 - NSLCD_NETGROUP_TYPE_END int32 = 3 -) - -/* Network name (/etc/networks) NSS requests. Result values for a single - entry are: */ -type Network struct { - Name string - Aliases []string - Addresses []net.IP -} -const NSLCD_ACTION_NETWORK_BYNAME int32 = 0x00070001; type Request_Network_ByName struct { Name string } -const NSLCD_ACTION_NETWORK_BYADDR int32 = 0x00070002; type Request_Network_ByAddr struct { Addr net.IP } -const NSLCD_ACTION_NETWORK_ALL int32 = 0x00070008; type Request_Network_All struct {} - -/* User account (/etc/passwd) NSS requests. Result values are: */ -type Passwd struct { - Name string - PwHash string - UID int32 - GID int32 - GECOS string - HomeDir string - Shell string -} -const NSLCD_ACTION_PASSWD_BYNAME int32 = 0x00080001; type Request_Passwd_ByName struct { Name string } -const NSLCD_ACTION_PASSWD_BYUID int32 = 0x00080002; type Request_Passwd_ByUID struct { UID int32 } -const NSLCD_ACTION_PASSWD_ALL int32 = 0x00080008; type Request_Passwd_All struct {} - -/* Protocol information requests. Result values are: */ -type Protocol struct { - Name string - Aliases []string - Number int32 -} -const NSLCD_ACTION_PROTOCOL_BYNAME int32 = 0x00090001; type Request_Protocol_ByName struct { Name string } -const NSLCD_ACTION_PROTOCOL_BYNUMBER int32 = 0x00090002; type Request_Protocol_ByNumber struct { Number int32 } -const NSLCD_ACTION_PROTOCOL_ALL int32 = 0x00090008; type Request_Protocol_All struct {} - -/* RPC information requests. Result values are: */ -type RPC struct { - Name string - Aliases []string - Number int32 -} -const NSLCD_ACTION_RPC_BYNAME int32 = 0x000a0001; type Request_RPC_ByName struct { Name string } -const NSLCD_ACTION_RPC_BYNUMBER int32 = 0x000a0002; type Request_RPC_ByNumber struct { Number int32 } -const NSLCD_ACTION_RPC_ALL int32 = 0x000a0008; type Request_RPC_All struct {} - -/* Service (/etc/services) information requests. The BYNAME and BYNUMBER - requests contain an extra protocol string in the request which, if not - blank, will filter the services by this protocol. Result values are: */ -type Service struct { - Name string - Aliases []string - PortNumber int32 - Protocol string -} -const NSLCD_ACTION_SERVICE_BYNAME int32 = 0x000b0001; type Request_Service_ByName struct { Name string } -const NSLCD_ACTION_SERVICE_BYNUMBER int32 = 0x000b0002; type Request_Service_ByNumber struct { Number int32 } -const NSLCD_ACTION_SERVICE_ALL int32 = 0x000b0008; type Request_Service_All struct {} - -/* Extended user account (/etc/shadow) information requests. Result - values for a single entry are: */ -type Shadow struct { - // It is my understanding that an empty value for an INT32 - // field is expressed with a negative number. -- lukeshu - Name string - PwHash string - LastChangeDate int32 - MinDays int32 - MaxDays int32 - WarnDays int32 - InactDays int32 - ExpireDate int32 - Flag int32 -} -const NSLCD_ACTION_SHADOW_BYNAME int32 = 0x000c0001; type Request_Shadow_ByName struct { Name string } -const NSLCD_ACTION_SHADOW_ALL int32 = 0x000c0008; type Request_Shadow_All struct {} - -/* PAM-related requests. The request parameters for all these requests - begin with: */ -type PAM_Base struct { - UserName string - ServiceName string - RUser string - RHost string - TTY string -} -/* If the user is not known in LDAP no result may be returned (immediately - return NSLCD_RESULT_END instead of a PAM error code). */ - -/* PAM authentication check request. The extra request values are: */ -type Request_PAM_Authentication struct { - PAM_Base - Password string -} -/* and the result value consists of: */ -type PAM_Authentication struct { - AuthenticationResult int32 - UserName string - AuthorizationResult int32 - AuthorizationError string -} -/* If the username is empty in this request an attempt is made to - authenticate as the administrator (set using rootpwmoddn). - Some authorisation checks are already done during authentication so the - response also includes authorisation information. */ -const NSLCD_ACTION_PAM_AUTHENTICATION int32 = 0x000d0001 - -/* PAM authorisation check request. The result value consists of: */ -type PAM_Authorization struct { - Result int32 - Error string -} -/* The authentication check may have already returned some authorisation - information. The authorisation error message, if supplied, will be used - by the PAM module instead of a message that is generated by the PAM - module itself. */ -const NSLCD_ACTION_PAM_AUTHORIZATION int32 = 0x000d0002; type Request_PAM_Authorization PAM_Base - -/* PAM session open request. The result value consists of: */ -type PAM_SessionOpen struct { - SessionID string -} -/* This session id may be used to close this session with. */ -const NSLCD_ACTION_PAM_SESSIONOPEN int32 = 0x000d0003; type Request_PAM_SessionOpen PAM_Base - -/* PAM session close request. This request has the following - extra request value: */ -type Request_PAM_SessionClose struct { - PAM_Base - SessionID string -} -/* and this calls only returns an empty response value. */ -type PAM_SessionClose struct {} -const NSLCD_ACTION_PAM_SESSIONCLOSE int32 = 0x000d0004 - -/* PAM password modification request. This requests has the following extra - request values: */ -type Request_PAM_PwMod struct { - PAM_Base - AsRoot int32 /* 0=oldpasswd is user passwd, 1=oldpasswd is root passwd */ - OldPassword string - NewPassword string -} -/* and returns the result values: */ -type PAM_PwMod struct { - Result int32 - Error string -} -const NSLCD_ACTION_PAM_PWMOD int32 = 0x000d0005 - -/* User information change request. This request allows one to change - their full name and other information. The request parameters for this - request are: - STRING user name - INT32 asroot: 0=passwd is user passwd, 1=passwd is root passwd - STRING password - followed by one or more of the below, terminated by NSLCD_USERMOD_END - INT32 NSLCD_USERMOD_* - STRING new value - the response consists of one or more of the entries below, terminated - by NSLCD_USERMOD_END: - INT32 NSLCD_USERMOD_* - STRING response - (if the response is blank, the change went OK, otherwise the string - contains an error message) - */ -type UserMod_Item struct { - Key int32 - Value string -} -type UserMod_ItemList []UserMod_Item -func (data UserMod_ItemList) nslcdWrite(fd io.Writer) { - for _, item := range data { - Write(fd, item) - } - Write(fd, NSLCD_USERMOD_END) -} -func (data *UserMod_ItemList) nslcdRead(fd io.Reader) { - *data = make([]UserMod_Item, 0) - for { - var t int32 - Read(fd, &t) - if t == NSLCD_USERMOD_END { - return - } - var v UserMod_Item - Read(fd, &v) - *data = append(*data, v) - } -} -var _ nslcdObject = UserMod_ItemList{} -var _ nslcdObjectPtr = &UserMod_ItemList{} -type Request_UserMod struct { - UserName string - AsRoot int32 - Password string - Items UserMod_ItemList -} -type UserMod struct { - Items []UserMod_Item -} -const NSLCD_ACTION_USERMOD int32 = 0x000e0001 - -/* These are the possible values for the NSLCD_ACTION_USERMOD operation - above. */ -const ( - NSLCD_USERMOD_END int32 = 0 /* end of change values */ - NSLCD_USERMOD_RESULT int32 = 1 /* global result value */ - NSLCD_USERMOD_FULLNAME int32 = 2 /* full name */ - NSLCD_USERMOD_ROOMNUMBER int32 = 3 /* room number */ - NSLCD_USERMOD_WORKPHONE int32 = 4 /* office phone number */ - NSLCD_USERMOD_HOMEPHONE int32 = 5 /* home phone number */ - NSLCD_USERMOD_OTHER int32 = 6 /* other info */ - NSLCD_USERMOD_HOMEDIR int32 = 7 /* home directory */ - NSLCD_USERMOD_SHELL int32 = 8 /* login shell */ -) - -/* Request result codes. */ -const ( - NSLCD_RESULT_BEGIN int32 = 1 - NSLCD_RESULT_END int32 = 2 -) - -/* Partial list of PAM result codes. */ -const ( - NSLCD_PAM_SUCCESS int32 = 0 /* everything ok */ - NSLCD_PAM_PERM_DENIED int32 = 6 /* Permission denied */ - NSLCD_PAM_AUTH_ERR int32 = 7 /* Authc failure */ - NSLCD_PAM_CRED_INSUFFICIENT int32 = 8 /* Cannot access authc data */ - NSLCD_PAM_AUTHINFO_UNAVAIL int32 = 9 /* Cannot retrieve authc info */ - NSLCD_PAM_USER_UNKNOWN int32 = 10 /* User not known */ - NSLCD_PAM_MAXTRIES int32 = 11 /* Retry limit reached */ - NSLCD_PAM_NEW_AUTHTOK_REQD int32 = 12 /* Password expired */ - NSLCD_PAM_ACCT_EXPIRED int32 = 13 /* Account expired */ - NSLCD_PAM_SESSION_ERR int32 = 14 /* Cannot make/remove session record */ - NSLCD_PAM_AUTHTOK_ERR int32 = 20 /* Authentication token manipulation error */ - NSLCD_PAM_AUTHTOK_DISABLE_AGING int32 = 23 /* Password aging disabled */ - NSLCD_PAM_IGNORE int32 = 25 /* Ignore module */ - NSLCD_PAM_ABORT int32 = 26 /* Fatal error */ - NSLCD_PAM_AUTHTOK_EXPIRED int32 = 27 /* authentication token has expired */ -) diff --git a/src/nslcd/proto/server/doc.go b/src/nslcd/proto/server/doc.go deleted file mode 100644 index 72ae2fe..0000000 --- a/src/nslcd/proto/server/doc.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> -// -// 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 - -// Package nslcd_server is a framework for implementing an nslcd -// server. -// -// You write an implementation of the Backend interface, then pass -// that to the HandleRequest function for each connection. -package nslcd_server diff --git a/src/nslcd/proto/server/func_handlerequest.go.sh b/src/nslcd/proto/server/func_handlerequest.go.sh deleted file mode 100755 index 3ef2758..0000000 --- a/src/nslcd/proto/server/func_handlerequest.go.sh +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env bash -# -*- Mode: Go -*- -# Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> -# -# 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 - -requests=$1 -printf '//' -printf ' %q' "$0" "$@" -printf '\n// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n' -cat <<EOF | gofmt -package nslcd_server - -import ( - "fmt" - "io" - p "nslcd/proto" - "os" - s "syscall" -) - -// Handle a request to nslcd -func HandleRequest(backend Backend, in io.Reader, out io.Writer, cred s.Ucred) (err error) { - err = nil - defer func() { - if r := recover(); r != nil { - switch r := r.(type) { - case error: - err = r - default: - panic(r) - } - } - }() - handleRequest(backend, in, out, cred) - return -} - -func handleRequest(backend Backend, in io.Reader, out io.Writer, cred s.Ucred) { - var version int32 - p.Read(in, &version) - if version != p.NSLCD_VERSION { - panic(p.NslcdError(fmt.Sprintf("Version mismatch: server=%#08x client=%#08x", p.NSLCD_VERSION, version))) - } - var action int32 - p.Read(in, &action) - - ch := make(chan interface{}) - switch action { -$( -while read -r request; do - cat <<EOT - case p.NSLCD_ACTION_${request^^}: - var req p.Request_${request} - p.Read(in, &req) - $( - if [[ $request == PAM_Authentication ]]; then - echo '_req := req' - echo '_req.Password = "<omitted-from-log>"' - echo 'fmt.Fprintf(os.Stderr, "Request: %#v\n", _req)' - else - echo 'fmt.Fprintf(os.Stderr, "Request: %#v\n", req)' - fi - ) - _ch := backend.${request}(cred, req) - go func() { - defer close(ch) - for obj := range _ch { - ch <- obj - } - }() -EOT -done < "$requests" -) - default: - close(ch) - panic(p.NslcdError(fmt.Sprintf("Unknown request action: %#08x", action))) - } - p.Write(out, p.NSLCD_VERSION) - p.Write(out, action) - - for result := range ch { - p.Write(out, p.NSLCD_RESULT_BEGIN) - p.Write(out, result) - } - p.Write(out, p.NSLCD_RESULT_END) -} -EOF diff --git a/src/nslcd/proto/server/interface_backend.go.sh b/src/nslcd/proto/server/interface_backend.go.sh deleted file mode 100755 index e6eeb66..0000000 --- a/src/nslcd/proto/server/interface_backend.go.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bash -# Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> -# -# 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 - -requests=$1 -printf '//' -printf ' %q' "$0" "$@" -printf '\n// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n' -cat <<EOF | gofmt -package nslcd_server - -import ( - s "syscall" - p "nslcd/proto" -) - -// The Backend interface allows the backend store to be implemented -// separately from the protocol implementation. Each request type -// that the nslcd server may reply to is implemented simply as a -// method that returns a channel of the resulting values. -type Backend interface { - $(sed -rn 's/([^_]+)(.*)/\1\2(s.Ucred, p.Request_\1\2) <-chan p.\1/p' "$requests" | grep -v PAM) - $(sed -rn 's/(PAM)(.*)/\1\2(s.Ucred, p.Request_\1\2) <-chan p.\1\2/p' "$requests") -} -EOF diff --git a/src/nslcd/proto/server/type_nilbackend.go.sh b/src/nslcd/proto/server/type_nilbackend.go.sh deleted file mode 100755 index 17aad63..0000000 --- a/src/nslcd/proto/server/type_nilbackend.go.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env bash -# Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> -# -# 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 - -interface=$1 -printf '//' -printf ' %q' "$0" "$@" -printf '\n// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n' -cat <<EOF | gofmt -package nslcd_server - -import ( - p "nslcd/proto" - s "syscall" -) - -// NilBackend implements the Backend interface, but only returns empty -// responses. It is useful to add as an anonymous member of a backend -// implementation that does not return results for all of the -// databases. -type NilBackend struct{} - -$(< "$interface" sed -rn 's/^\t([^(]+)\(s.Ucred, ([^)]+)\) <-chan (\S+)$/func (o NilBackend) \1(s.Ucred, \2) <-chan \3 { r := make(chan \3); close(r); return r }/p') - -var _ Backend = NilBackend{} -EOF diff --git a/src/nslcd/systemd/disable_nss_module.go b/src/nslcd/systemd/disable_nss_module.go deleted file mode 100644 index 24d7f79..0000000 --- a/src/nslcd/systemd/disable_nss_module.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> -// -// 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 - -package nslcd_systemd - -import ( - "dl" - "sd_daemon/logger" -) - -//static char *strary(char **ary, unsigned int n) { return ary[n]; } -import "C" - -const ( - nss_module_soname = "libnss_ldap.so.2" - nss_module_sym_version = "_nss_ldap_version" - nss_module_sym_enablelookups = "_nss_ldap_enablelookups" -) - -func disable_nss_module() { - handle, err := dl.Open(nss_module_soname, dl.RTLD_LAZY|dl.RTLD_NODELETE) - if err == nil { - defer handle.Close() - } else { - logger.Warning("NSS module %s not loaded: %v", nss_module_soname, err) - return - } - - c_version_info, err := handle.Sym(nss_module_sym_version) - if err == nil { - g_version_info := (**C.char)(c_version_info) - logger.Debug("NSS module %s version %s %s", nss_module_soname, - C.GoString(C.strary(g_version_info, 0)), - C.GoString(C.strary(g_version_info, 1))) - } else { - logger.Warning("NSS module %s version missing: %v", nss_module_soname, err) - } - c_enable_flag, err := handle.Sym(nss_module_sym_enablelookups) - if err != nil { - logger.Warning("Unable to disable NSS ldap module for nslcd process: %v", err) - return - } - g_enable_flag := (*C.int)(c_enable_flag) - *g_enable_flag = 0 -} diff --git a/src/nslcd/systemd/nslcd_systemd.go b/src/nslcd/systemd/nslcd_systemd.go deleted file mode 100644 index 5589627..0000000 --- a/src/nslcd/systemd/nslcd_systemd.go +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> -// -// 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 - -// Package nslcd_systemd does the legwork for implementing a systemd -// socket-activated nslcd server. -// -// You just need to implement the Backend interface, then pass it to -// Main, which will return the exit code for the process. Everything -// but the backend is taken care of for you! -// -// package main -// -// import "nslcd/systemd" -// -// func main() { -// backend := ... -// os.Exit(int(nslcd_systemd.Main(backend))) -// } -package nslcd_systemd - -import ( - "fmt" - "net" - "nslcd/proto/server" - "os" - "os/signal" - sd "sd_daemon" - "sd_daemon/logger" - "sd_daemon/lsb" - "sync" - "syscall" -) - -type Backend interface { - nslcd_server.Backend - Init() error - Reload() error - Close() -} - -func get_socket() (socket net.Listener, err error) { - socket = nil - err = nil - fds := sd.ListenFds(true) - if fds == nil { - err = fmt.Errorf("Failed to aquire sockets from systemd") - return - } - if len(fds) != 1 { - err = fmt.Errorf("Wrong number of sockets from systemd: expected %d but got %d", 1, len(fds)) - return - } - socket, err = net.FileListener(fds[0]) - fds[0].Close() - return -} - -func getpeercred(conn *net.UnixConn) (cred syscall.Ucred, err error) { - file, err := conn.File() - if err != nil { - return - } - defer file.Close() - _cred, err := syscall.GetsockoptUcred(int(file.Fd()), syscall.SOL_SOCKET, syscall.SO_PEERCRED) - cred = *_cred - return -} - -func handler(conn *net.UnixConn, backend nslcd_server.Backend) { - defer conn.Close() - cred, err := getpeercred(conn) - if err != nil { - logger.Debug("Connection from unknown client") - } else { - logger.Debug("Connection from pid=%v uid=%v gid=%v", - cred.Pid, cred.Uid, cred.Gid) - } - err = nslcd_server.HandleRequest(backend, conn, conn, cred) - if err != nil { - logger.Notice("Error while handling request: %v", err) - } -} - -func Main(backend Backend) uint8 { - var err error = nil - - sigs := make(chan os.Signal) - signal.Notify(sigs, syscall.SIGTERM, syscall.SIGHUP) - - disable_nss_module() - - err = backend.Init() - if err != nil { - logger.Err("Could not initialize backend: %v", err) - sd.Notify(false, "STOPPING=1") - return lsb.EXIT_FAILURE - } - defer backend.Close() - - socket, err := get_socket() - if err != nil { - logger.Err("%v", err) - sd.Notify(false, "STOPPING=1") - return lsb.EXIT_NOTRUNNING - } - defer socket.Close() - sock := make(chan *net.UnixConn) - go func() { - defer lsb.Recover() - for { - conn, err := socket.Accept() - if err != nil { - logger.Notice("%v", err) - } - if conn != nil { - sock <- conn.(*net.UnixConn) - } - } - }() - - var wg sync.WaitGroup - defer wg.Wait() - defer sd.Notify(false, "STOPPING=1") - sd.Notify(false, "READY=1") - for { - select { - case sig := <-sigs: - switch sig { - case syscall.SIGTERM: - logger.Notice("Received SIGTERM, shutting down") - return lsb.EXIT_SUCCESS - case syscall.SIGHUP: - sd.Notify(false, "RELOADING=1") - err := backend.Reload() - if err != nil { - logger.Notice("Could not reload backend: %s", err.Error()) - return lsb.EXIT_NOTRUNNING - } - sd.Notify(false, "READY=1") - } - case conn := <-sock: - wg.Add(1) - go func() { - defer lsb.Recover() - defer wg.Done() - handler(conn, backend) - }() - } - } -} diff --git a/src/sd_daemon/doc.go b/src/sd_daemon/doc.go deleted file mode 100644 index 665e25e..0000000 --- a/src/sd_daemon/doc.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015 Luke Shumaker -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package sd provides APIs for systemd new-style daemons. -package sd diff --git a/src/sd_daemon/listen_fds.go b/src/sd_daemon/listen_fds.go deleted file mode 100644 index fbd2247..0000000 --- a/src/sd_daemon/listen_fds.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// Copyright 2015 Luke Shumaker -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package sd - -import ( - "os" - "strconv" - "syscall" -) - -//#include <systemd/sd-daemon.h> -import "C" - -// Returns a list of file descriptors passed in by the service manager -// as part of the socket-based activation logic. -// -// If unsetEnv is true, then (regarless of whether the function call -// itself succeeds or not) it will unset the environmental variables -// LISTEN_FDS and LISTEN_PID, which will cause further calls to this -// function to fail. -// -// In the case of an error, this function returns nil. -func ListenFds(unsetEnv bool) []*os.File { - if unsetEnv { - defer os.Unsetenv("LISTEN_PID") - defer os.Unsetenv("LISTEN_FDS") - } - - pid, err := strconv.Atoi(os.Getenv("LISTEN_PID")) - if err != nil || pid != os.Getpid() { - return nil - } - - nfds, err := strconv.Atoi(os.Getenv("LISTEN_FDS")) - if err != nil || nfds == 0 { - return nil - } - - files := make([]*os.File, 0, nfds) - for fd := C.SD_LISTEN_FDS_START; fd < C.SD_LISTEN_FDS_START+nfds; fd++ { - syscall.CloseOnExec(fd) - files = append(files, os.NewFile(uintptr(fd), "LISTEN_FD_"+strconv.Itoa(fd))) - } - - return files -} diff --git a/src/sd_daemon/logger/logger.go b/src/sd_daemon/logger/logger.go deleted file mode 100644 index c15475a..0000000 --- a/src/sd_daemon/logger/logger.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2015 Luke Shumaker -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package logger implements a simple stderr-based logger with systemd -// log levels. -package logger - -import ( - "fmt" - "os" -) - -//#include <systemd/sd-daemon.h> -import "C" - -func log(level string, format string, a ...interface{}) { - f := level + format + "\n" - fmt.Fprintf(os.Stderr, f, a...) -} - -// system is unusable -func Emerg( /* */ format string, a ...interface{}) { log(C.SD_EMERG /* */, format, a...) } - -// action must be taken immediately -func Alert( /* */ format string, a ...interface{}) { log(C.SD_ALERT /* */, format, a...) } - -// critical conditions -func Crit( /* */ format string, a ...interface{}) { log(C.SD_CRIT /* */, format, a...) } - -// error conditions -func Err( /* */ format string, a ...interface{}) { log(C.SD_ERR /* */, format, a...) } - -// warning conditions -func Warning( /**/ format string, a ...interface{}) { log(C.SD_WARNING /**/, format, a...) } - -// normal but significant condition -func Notice( /* */ format string, a ...interface{}) { log(C.SD_NOTICE /* */, format, a...) } - -// informational -func Info( /* */ format string, a ...interface{}) { log(C.SD_INFO /* */, format, a...) } - -// debug-level messages -func Debug( /* */ format string, a ...interface{}) { log(C.SD_DEBUG /* */, format, a...) } diff --git a/src/sd_daemon/lsb/exit-status.go b/src/sd_daemon/lsb/exit-status.go deleted file mode 100644 index cc1604d..0000000 --- a/src/sd_daemon/lsb/exit-status.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2015 Luke Shumaker -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Package lsb provides constant exit codes specified by the Linux -// Standard Base. -package lsb - -import ( - "os" - "sd_daemon/logger" -) - -// systemd daemon(7) recommends using the exit codes defined in the -// "LSB recomendations for SysV init scripts"[1]. -// -// [1]: http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html -const ( - EXIT_SUCCESS uint8 = 0 - EXIT_FAILURE uint8 = 1 - EXIT_INVALIDARGUMENT uint8 = 2 - EXIT_NOTIMPLEMENTED uint8 = 3 - EXIT_NOPERMISSION uint8 = 4 - EXIT_NOTINSTALLED uint8 = 5 - EXIT_NOTCONFIGURED uint8 = 6 - EXIT_NOTRUNNING uint8 = 7 - // 8- 99 are reserved for future LSB use - // 100-149 are reserved for distribution use - // 150-199 are reserved for application use - // 200-254 are reserved for init system use - - // Therefore, the following are taken from systemd's - // `src/basic/exit-status.h` - EXIT_CHDIR uint8 = 200 - EXIT_NICE uint8 = 201 - EXIT_FDS uint8 = 202 - EXIT_EXEC uint8 = 203 - EXIT_MEMORY uint8 = 204 - EXIT_LIMITS uint8 = 205 - EXIT_OOM_ADJUST uint8 = 206 - EXIT_SIGNAL_MASK uint8 = 207 - EXIT_STDIN uint8 = 208 - EXIT_STDOUT uint8 = 209 - EXIT_CHROOT uint8 = 210 - EXIT_IOPRIO uint8 = 211 - EXIT_TIMERSLACK uint8 = 212 - EXIT_SECUREBITS uint8 = 213 - EXIT_SETSCHEDULER uint8 = 214 - EXIT_CPUAFFINITY uint8 = 215 - EXIT_GROUP uint8 = 216 - EXIT_USER uint8 = 217 - EXIT_CAPABILITIES uint8 = 218 - EXIT_CGROUP uint8 = 219 - EXIT_SETSID uint8 = 220 - EXIT_CONFIRM uint8 = 221 - EXIT_STDERR uint8 = 222 - _EXIT_RESERVED uint8 = 223 // used to be tcpwrap don't reuse! - EXIT_PAM uint8 = 224 - EXIT_NETWORK uint8 = 225 - EXIT_NAMESPACE uint8 = 226 - EXIT_NO_NEW_PRIVILEGES uint8 = 227 - EXIT_SECCOMP uint8 = 228 - EXIT_SELINUX_CONTEXT uint8 = 229 - EXIT_PERSONALITY uint8 = 230 - EXIT_APPARMOR_PROFILE uint8 = 231 - EXIT_ADDRESS_FAMILIES uint8 = 232 - EXIT_RUNTIME_DIRECTORY uint8 = 233 - EXIT_MAKE_STARTER uint8 = 234 - EXIT_CHOWN uint8 = 235 - EXIT_BUS_ENDPOINT uint8 = 236 - EXIT_SMACK_PROCESS_LABEL uint8 = 237 -) - -// This is a utility function to defer at the beginning of a goroutine -// in order to have the correct exit code in the case of a panic. -func Recover() { - if r := recover(); r != nil { - logger.Err("panic: %v", r) - os.Exit(int(EXIT_FAILURE)) - } -} diff --git a/src/sd_daemon/notify.go b/src/sd_daemon/notify.go deleted file mode 100644 index 8fce6da..0000000 --- a/src/sd_daemon/notify.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2013-2015 Docker, Inc. -// Copyright 2014 CoreOS, Inc. -// Copyright 2015 Luke Shumaker -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package sd - -import ( - "errors" - "net" - "os" -) - -// errNotifyNoSocket is an error returned if no socket was specified. -var errNotifyNoSocket = errors.New("No socket") - -// Notify sends a message to the service manager aobout state -// changes. It is common to ignore the error. -// -// If unsetEnv is true, then (regarless of whether the function call -// itself succeeds or not) it will unset the environmental variable -// NOTIFY_SOCKET, which will cause further calls to this function to -// fail. -// -// The state parameter should countain a newline-separated list of -// variable assignments. -// -// See the documentation for sd_notify(3) for well-known variable -// assignments. -func Notify(unsetEnv bool, state string) error { - if unsetEnv { - defer os.Unsetenv("NOTIFY_SOCKET") - } - - socketAddr := &net.UnixAddr{ - Name: os.Getenv("NOTIFY_SOCKET"), - Net: "unixgram", - } - - if socketAddr.Name == "" { - return errNotifyNoSocket - } - - conn, err := net.DialUnix(socketAddr.Net, nil, socketAddr) - if err != nil { - return err - } - defer conn.Close() - - _, err = conn.Write([]byte(state)) - return err -} |