diff options
46 files changed, 1250 insertions, 441 deletions
@@ -5,4 +5,5 @@ /nshd.socket /.Makefile.var.* /.tmp.Makefile.var.* +/LICENSE.*.txt *.o diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..cc96954 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,19 @@ +The software in this repository is under a number of licenses: + + src/getgr LGPL v2.1+ + src/inotify LGPL v2.1+ + src/nslcd LGPL v2.1+ + src/dl GPL v2+, with documentation output clarification + src/nshd GPL v2+ + src/sd_daemon Apache v2.0 + test/ LGPL v2.1+ + +The general notion is that the core application is GPL, while +supporting libraries that might be useful outside of this specific +application are LGPL, with the 2 exceptions: + - The sd_daemon package is Apache licensed because of code taken from + CoreOS and Docker. + - The dl package is GPLv2+ licensed because of wording in comments + taken from the Linux Programmer's Manual. + +For more details, see each individual file. @@ -1,3 +1,24 @@ +# 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/>. + MAKEFLAGS += --no-builtin-rules prefix = /usr/local bindir = $(prefix)/bin @@ -23,7 +44,7 @@ GOPATH := $(realpath $(dir $(lastword $(MAKEFILE_LIST)))) vp = .Makefile.var.% deps = gopkg.in/yaml.v2 -subdirs = src/nslcd_proto +subdirs = src/nslcd/proto all: build @@ -31,7 +52,7 @@ include $(addsuffix /Makefile,$(subdirs)) secondary += test/*.o download += $(addprefix src/,$(deps)) -generate += +generate += LICENSE.lgpl-2.1.txt LICENSE.gpl-2.txt LICENSE.apache-2.0.txt build += bin/nshd nshd.service nshd.socket test/runner install += $(addprefix $(DESTDIR),$(bindir)/nshd $(systemddir)/system/nshd.socket $(systemddir)/system/nshd.service) @@ -51,8 +72,15 @@ uninstall: rmdir -p -- $(sort $(dir $(install))) 2>/dev/null || true .PHONY: uninstall + +LICENSE.lgpl-2.1.txt: $(NET) + curl https://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt > $@ +LICENSE.gpl-2.txt: $(NET) + curl https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt > $@ +LICENSE.apache-2.0.txt: $(NET) + curl https://www.apache.org/licenses/LICENSE-2.0 > $@ + $(foreach d,$(deps),$(eval src/$d: $(NET); GOPATH='$(GOPATH)' go get -d -u $d)) -.PHONY: NET bin/nshd: $(download) $(generate) $(gosrc) $(addprefix .Makefile.var.,$(cgo_variables)) @true $(foreach f,$(filter $(vp),$^), && test $@ -nt $f ) || rm -rf -- bin pkg @@ -81,3 +109,4 @@ $(DESTDIR)$(systemddir)/system/%.service: %.service .SECONDARY: .DELETE_ON_ERROR: +.PHONY: NET diff --git a/src/dl/dl_gnu.go b/src/dl/dl_gnu.go index c7c409b..99ec32c 100644 --- a/src/dl/dl_gnu.go +++ b/src/dl/dl_gnu.go @@ -1,44 +1,69 @@ -package dl +// 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 -import "unsafe" +package dl //#define _GNU_SOURCE -//#include <stdlib.h> -//#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 flags to Open() are GNU libc extensions. const ( - RTLD_NOLOAD Flag = C.RTLD_NOLOAD - RTLD_NODELETE Flag = C.RTLD_NODELETE - RTLD_DEEPBIND Flag = C.RTLD_DEEPBIND -) + // 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) -// These are kinda weird in that they aren't required by the standard, -// but they are reserved by the standard (see the documentation for -// `dlsym(3)`). On glibc, it takes _GNU_SOURCE to get them. -// -// There are two special pseudo-handles that may be specified -// in handle: -var ( - RTLD_DEFAULT Handle = Handle{unsafe.Pointer(uintptr(C.rtld_default))} - // Find the first occurrence of the desired symbol using - // the 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_NEXT Handle = Handle{unsafe.Pointer(uintptr(C.rtld_next))} - // Find the next occurrence of the desired symbol in the - // 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). + // 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 diff --git a/src/dl/dlfcn.go b/src/dl/dlfcn.go index d5467f3..3ab5abb 100644 --- a/src/dl/dlfcn.go +++ b/src/dl/dlfcn.go @@ -1,3 +1,25 @@ +// 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 ( @@ -12,26 +34,39 @@ import "C" type Flag int +// POSIX specifies these four flags to Open(). const ( - RTLD_LAZY Flag = C.RTLD_LAZY // Relocations are performed at an - // implementation-defined time. - RTLD_NOW Flag = C.RTLD_NOW // Relocations are performed when the - // object is loaded. - RTLD_GLOBAL Flag = C.RTLD_GLOBAL // All symbols are available for - // relocation processing of other - // modules. - RTLD_LOCAL Flag = C.RTLD_LOCAL // All symbols are not made available - // for relocation processing by other - // modules. + // 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 } +// 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 + } dlerror() ptr := C.dlopen(nameC, C.int(flags)) @@ -41,8 +76,10 @@ func Open(name string, flags Flag) (Handle, error) { return Handle{ptr}, nil } +// Look up a symbol, and return a pointer to it. +// // This returns uintptr instead of unsafe.Pointer so that code using -// reflect cannot obtain unsafe.Pointers without importing the unsafe +// dl cannot obtain unsafe.Pointers without importing the unsafe // package explicitly. func (h Handle) Sym(symbol string) (uintptr, error) { symbolC := C.CString(symbol) @@ -56,6 +93,9 @@ func (h Handle) Sym(symbol string) (uintptr, error) { return uintptr(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 { dlerror() r := C.dlclose(h.c) diff --git a/src/dl/dlsym_reserved.go b/src/dl/dlsym_reserved.go new file mode 100644 index 0000000..081e012 --- /dev/null +++ b/src/dl/dlsym_reserved.go @@ -0,0 +1,63 @@ +// 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 index 5470b2c..5e32826 100644 --- a/src/getgr/getgr.go +++ b/src/getgr/getgr.go @@ -1,3 +1,21 @@ +// 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 ( diff --git a/src/inotify/bits.go b/src/inotify/bits.go index eb0270f..18d8566 100644 --- a/src/inotify/bits.go +++ b/src/inotify/bits.go @@ -1,3 +1,24 @@ +// 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 ( @@ -7,39 +28,39 @@ const ( IN_NONBLOCK int = 00004000 ) -type Fd int -type Wd int +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. + 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). + 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. + 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. diff --git a/src/inotify/inotify.go b/src/inotify/inotify.go index 0d67b44..2fd3a83 100644 --- a/src/inotify/inotify.go +++ b/src/inotify/inotify.go @@ -1,3 +1,21 @@ +// 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 ( @@ -7,7 +25,7 @@ import ( ) type Inotify struct { - fd Fd + fd file fdLock sync.RWMutex buffFull [4096]byte buff []byte @@ -15,12 +33,14 @@ type Inotify struct { } 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 */ + 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{ @@ -30,6 +50,8 @@ func InotifyInit() (*Inotify, error) { 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{ @@ -39,18 +61,29 @@ func InotifyInit1(flags int) (*Inotify, error) { 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() @@ -58,6 +91,10 @@ func (o *Inotify) Close() error { 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() diff --git a/src/inotify/inutil/inotify_util.go b/src/inotify/inutil/inotify_util.go index 3a5eed5..c643e59 100644 --- a/src/inotify/inutil/inotify_util.go +++ b/src/inotify/inutil/inotify_util.go @@ -1,3 +1,20 @@ +// 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 ( @@ -6,25 +23,21 @@ import ( "syscall" ) -const ( - // Flags for the parameter of InotifyInit1(). - // These, oddly, appear to be 24-bit numbers. - IN_CLOEXEC = inotify.IN_CLOEXEC -) - type Watcher struct { Events <-chan inotify.Event - 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) @@ -44,14 +57,19 @@ func newWatcher(in *inotify.Inotify, err error) (*Watcher, error) { 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() diff --git a/src/inotify/syscall.go b/src/inotify/syscall.go index 721a10a..d1b5140 100644 --- a/src/inotify/syscall.go +++ b/src/inotify/syscall.go @@ -1,3 +1,19 @@ +// 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 ( @@ -12,27 +28,27 @@ func newPathError(op string, path string, err error) error { return &os.PathError{Op: op, Path: path, Err: err} } -/* Create and initialize inotify instance. */ -func inotify_init() (Fd, error) { +// Create and initialize inotify instance. +func inotify_init() (file, error) { fd, errno := syscall.InotifyInit() - return Fd(fd), os.NewSyscallError("inotify_init", errno) + return file(fd), os.NewSyscallError("inotify_init", errno) } -/* Create and initialize inotify instance. */ -func inotify_init1(flags int) (Fd, error) { +// Create and initialize inotify instance. +func inotify_init1(flags int) (file, error) { fd, errno := syscall.InotifyInit1(flags) - return Fd(fd), os.NewSyscallError("inotify_init1", errno) + 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 Fd, name string, mask Mask) (Wd, error) { +// 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 Fd, wd Wd) error { +// 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: @@ -49,11 +65,11 @@ func inotify_rm_watch(fd Fd, wd Wd) error { panic("should never happen") } -func sysclose(fd Fd) error { +func sysclose(fd file) error { return os.NewSyscallError("close", syscall.Close(int(fd))) } -func sysread(fd Fd, p []byte) (int, error) { +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/check_password.go b/src/nshd/hackers_git/check_password.go index c112641..81ad932 100644 --- a/src/nshd/hackers_git/check_password.go +++ b/src/nshd/hackers_git/check_password.go @@ -1,3 +1,24 @@ +// 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 hackers_git import "unsafe" diff --git a/src/nshd/hackers_git/db_config.go b/src/nshd/hackers_git/db_config.go index 7e96059..ffacf00 100644 --- a/src/nshd/hackers_git/db_config.go +++ b/src/nshd/hackers_git/db_config.go @@ -1,8 +1,32 @@ +// 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 hackers_git -import p "nslcd_proto" +import ( + p "nslcd/proto" + s "syscall" +) -func (o *Hackers) Config_Get(cred p.Ucred, req p.Request_Config_Get) <-chan p.Config { +func (o *Hackers) Config_Get(cred s.Ucred, req p.Request_Config_Get) <-chan p.Config { o.lock.RLock() ret := make(chan p.Config) go func() { diff --git a/src/nshd/hackers_git/db_group.go b/src/nshd/hackers_git/db_group.go index 3122bd2..4f27627 100644 --- a/src/nshd/hackers_git/db_group.go +++ b/src/nshd/hackers_git/db_group.go @@ -1,6 +1,30 @@ +// 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 hackers_git -import p "nslcd_proto" +import ( + p "nslcd/proto" + s "syscall" +) func (o *Hackers) groupByName(name string, users bool) p.Group { members_set, found := o.groups[name] @@ -48,7 +72,7 @@ func (o *Hackers) groupByGid(gid int32, users bool) p.Group { } } -func (o *Hackers) Group_ByName(cred p.Ucred, req p.Request_Group_ByName) <-chan p.Group { +func (o *Hackers) Group_ByName(cred s.Ucred, req p.Request_Group_ByName) <-chan p.Group { o.lock.RLock() ret := make(chan p.Group) go func() { @@ -64,7 +88,7 @@ func (o *Hackers) Group_ByName(cred p.Ucred, req p.Request_Group_ByName) <-chan return ret } -func (o *Hackers) Group_ByGid(cred p.Ucred, req p.Request_Group_ByGid) <-chan p.Group { +func (o *Hackers) Group_ByGid(cred s.Ucred, req p.Request_Group_ByGid) <-chan p.Group { o.lock.RLock() ret := make(chan p.Group) go func() { @@ -81,7 +105,7 @@ func (o *Hackers) Group_ByGid(cred p.Ucred, req p.Request_Group_ByGid) <-chan p. } // note that the BYMEMBER call returns an empty members list -func (o *Hackers) Group_ByMember(cred p.Ucred, req p.Request_Group_ByMember) <-chan p.Group { +func (o *Hackers) Group_ByMember(cred s.Ucred, req p.Request_Group_ByMember) <-chan p.Group { o.lock.RLock() ret := make(chan p.Group) go func() { @@ -102,7 +126,7 @@ func (o *Hackers) Group_ByMember(cred p.Ucred, req p.Request_Group_ByMember) <-c return ret } -func (o *Hackers) Group_All(cred p.Ucred, req p.Request_Group_All) <-chan p.Group { +func (o *Hackers) Group_All(cred s.Ucred, req p.Request_Group_All) <-chan p.Group { o.lock.RLock() ret := make(chan p.Group) go func() { diff --git a/src/nshd/hackers_git/db_pam.go b/src/nshd/hackers_git/db_pam.go index 126c403..230e111 100644 --- a/src/nshd/hackers_git/db_pam.go +++ b/src/nshd/hackers_git/db_pam.go @@ -1,12 +1,34 @@ +// 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 hackers_git import ( "crypto/rand" "math/big" - p "nslcd_proto" + p "nslcd/proto" + s "syscall" ) -func (o *Hackers) PAM_Authentication(cred p.Ucred, req p.Request_PAM_Authentication) <-chan p.PAM_Authentication { +func (o *Hackers) PAM_Authentication(cred s.Ucred, req p.Request_PAM_Authentication) <-chan p.PAM_Authentication { o.lock.RLock() ret := make(chan p.PAM_Authentication) go func() { @@ -35,7 +57,7 @@ func (o *Hackers) PAM_Authentication(cred p.Ucred, req p.Request_PAM_Authenticat return ret } -func (o *Hackers) PAM_Authorization(cred p.Ucred, req p.Request_PAM_Authorization) <-chan p.PAM_Authorization { +func (o *Hackers) PAM_Authorization(cred s.Ucred, req p.Request_PAM_Authorization) <-chan p.PAM_Authorization { o.lock.RLock() ret := make(chan p.PAM_Authorization) go func() { @@ -58,7 +80,7 @@ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 var alphabet_len = big.NewInt(int64(len(alphabet))) -func (o *Hackers) PAM_SessionOpen(cred p.Ucred, req p.Request_PAM_SessionOpen) <-chan p.PAM_SessionOpen { +func (o *Hackers) PAM_SessionOpen(cred s.Ucred, req p.Request_PAM_SessionOpen) <-chan p.PAM_SessionOpen { ret := make(chan p.PAM_SessionOpen) go func() { defer close(ret) @@ -76,7 +98,7 @@ func (o *Hackers) PAM_SessionOpen(cred p.Ucred, req p.Request_PAM_SessionOpen) < return ret } -func (o *Hackers) PAM_SessionClose(cred p.Ucred, req p.Request_PAM_SessionClose) <-chan p.PAM_SessionClose { +func (o *Hackers) PAM_SessionClose(cred s.Ucred, req p.Request_PAM_SessionClose) <-chan p.PAM_SessionClose { ret := make(chan p.PAM_SessionClose) go close(ret) return ret diff --git a/src/nshd/hackers_git/db_passwd.go b/src/nshd/hackers_git/db_passwd.go index cc8c711..1283ec1 100644 --- a/src/nshd/hackers_git/db_passwd.go +++ b/src/nshd/hackers_git/db_passwd.go @@ -1,6 +1,30 @@ +// 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 hackers_git -import p "nslcd_proto" +import ( + p "nslcd/proto" + s "syscall" +) /* Note that the output password hash value should be one of: <empty> - no password set, allow login without password @@ -9,7 +33,7 @@ import p "nslcd_proto" often used to indicate that the password is defined elsewhere other - encrypted password, in crypt(3) format */ -func (o *Hackers) Passwd_ByName(cred p.Ucred, req p.Request_Passwd_ByName) <-chan p.Passwd { +func (o *Hackers) Passwd_ByName(cred s.Ucred, req p.Request_Passwd_ByName) <-chan p.Passwd { o.lock.RLock() ret := make(chan p.Passwd) go func() { @@ -27,7 +51,7 @@ func (o *Hackers) Passwd_ByName(cred p.Ucred, req p.Request_Passwd_ByName) <-cha return ret } -func (o *Hackers) Passwd_ByUID(cred p.Ucred, req p.Request_Passwd_ByUID) <-chan p.Passwd { +func (o *Hackers) Passwd_ByUID(cred s.Ucred, req p.Request_Passwd_ByUID) <-chan p.Passwd { o.lock.RLock() ret := make(chan p.Passwd) go func() { @@ -45,7 +69,7 @@ func (o *Hackers) Passwd_ByUID(cred p.Ucred, req p.Request_Passwd_ByUID) <-chan return ret } -func (o *Hackers) Passwd_All(cred p.Ucred, req p.Request_Passwd_All) <-chan p.Passwd { +func (o *Hackers) Passwd_All(cred s.Ucred, req p.Request_Passwd_All) <-chan p.Passwd { o.lock.RLock() ret := make(chan p.Passwd) go func() { diff --git a/src/nshd/hackers_git/db_shadow.go b/src/nshd/hackers_git/db_shadow.go index 594e7a1..c83f223 100644 --- a/src/nshd/hackers_git/db_shadow.go +++ b/src/nshd/hackers_git/db_shadow.go @@ -1,8 +1,32 @@ +// 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 hackers_git -import p "nslcd_proto" +import ( + p "nslcd/proto" + s "syscall" +) -func (o *Hackers) Shadow_ByName(cred p.Ucred, req p.Request_Shadow_ByName) <-chan p.Shadow { +func (o *Hackers) Shadow_ByName(cred s.Ucred, req p.Request_Shadow_ByName) <-chan p.Shadow { o.lock.RLock() ret := make(chan p.Shadow) go func() { @@ -29,7 +53,7 @@ func (o *Hackers) Shadow_ByName(cred p.Ucred, req p.Request_Shadow_ByName) <-cha return ret } -func (o *Hackers) Shadow_All(cred p.Ucred, req p.Request_Shadow_All) <-chan p.Shadow { +func (o *Hackers) Shadow_All(cred s.Ucred, req p.Request_Shadow_All) <-chan p.Shadow { o.lock.RLock() ret := make(chan p.Shadow) go func() { diff --git a/src/nshd/hackers_git/gid.go b/src/nshd/hackers_git/gid.go index ee8c10d..d8293d7 100644 --- a/src/nshd/hackers_git/gid.go +++ b/src/nshd/hackers_git/gid.go @@ -1,3 +1,24 @@ +// 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 hackers_git import "getgr" diff --git a/src/nshd/hackers_git/hackers.go b/src/nshd/hackers_git/hackers.go index 1eca0f6..5b57a63 100644 --- a/src/nshd/hackers_git/hackers.go +++ b/src/nshd/hackers_git/hackers.go @@ -1,11 +1,34 @@ +// 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 hackers_git is an nslcd_server Backend that speaks to +// hackers.git. package hackers_git import ( "inotify" "inotify/inutil" - "nslcd_proto" - "nslcd_proto/util" - "nslcd_systemd" + "nslcd/proto" + "nslcd/proto/server" + "nslcd/systemd" "sd_daemon/logger" "sync" ) @@ -21,7 +44,7 @@ type Config struct { } type Hackers struct { - util.NullBackend + nslcd_server.NilBackend Cfg Config lock sync.RWMutex workers sync.WaitGroup @@ -37,7 +60,7 @@ type Hackers struct { } var _ nslcd_systemd.Backend = &Hackers{} -var _ nslcd_proto.Backend = &Hackers{} +var _ nslcd_server.Backend = &Hackers{} func (o *Hackers) Init() error { err := o.Reload() diff --git a/src/nshd/hackers_git/hackers_parse.go b/src/nshd/hackers_git/hackers_parse.go index 46c878e..63e5c0f 100644 --- a/src/nshd/hackers_git/hackers_parse.go +++ b/src/nshd/hackers_git/hackers_parse.go @@ -1,3 +1,24 @@ +// 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 hackers_git import ( diff --git a/src/nshd/hackers_git/hackers_watch.go b/src/nshd/hackers_git/hackers_watch.go index 8559f88..d2c5bce 100644 --- a/src/nshd/hackers_git/hackers_watch.go +++ b/src/nshd/hackers_git/hackers_watch.go @@ -1,3 +1,24 @@ +// 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 hackers_git import ( diff --git a/src/nshd/hackers_git/set.go b/src/nshd/hackers_git/set.go index 9faf0f4..dc1d443 100644 --- a/src/nshd/hackers_git/set.go +++ b/src/nshd/hackers_git/set.go @@ -1,3 +1,24 @@ +// 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 hackers_git func set2list(set map[string]bool) []string { diff --git a/src/nshd/main.go b/src/nshd/main.go index 775aca2..d9c1277 100644 --- a/src/nshd/main.go +++ b/src/nshd/main.go @@ -1,8 +1,30 @@ +// 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/>. + +// Command nshd is an implementation of nslcd that talks to hackers.git instead of LDAP. package main import ( "nshd/hackers_git" - "nslcd_systemd" + "nslcd/systemd" "os" ) diff --git a/src/nslcd/proto/.gitignore b/src/nslcd/proto/.gitignore new file mode 100644 index 0000000..b3f9749 --- /dev/null +++ b/src/nslcd/proto/.gitignore @@ -0,0 +1,4 @@ +/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 new file mode 100644 index 0000000..2335374 --- /dev/null +++ b/src/nslcd/proto/Makefile @@ -0,0 +1,56 @@ +# 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 -- $(generate) $(secondary) +.PHONY: 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 new file mode 100644 index 0000000..70929f3 --- /dev/null +++ b/src/nslcd/proto/doc.go @@ -0,0 +1,22 @@ +// 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 index a6ff582..3c0c5be 100644 --- a/src/nslcd_proto/io.go +++ b/src/nslcd/proto/io.go @@ -1,3 +1,20 @@ +// 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 ( @@ -9,18 +26,27 @@ import ( "syscall" ) -type NslcdObject interface { - NslcdWrite(fd io.Writer) +type NslcdError string + +func (o NslcdError) Error() string { + return string(o) } -type NslcdObjectPtr interface { - NslcdRead(fd io.Reader) + +type nslcdObject interface { + nslcdWrite(fd io.Writer) +} + +type nslcdObjectPtr interface { + nslcdRead(fd io.Reader) } -func write(fd io.Writer, data interface{}) { +// 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 nslcdObject: + data.nslcdWrite(fd) case []byte: _, err := fd.Write(data) if err != nil { @@ -33,12 +59,12 @@ func write(fd io.Writer, data interface{}) { } // composite datatypes case string: - write(fd, int32(len(data))) - write(fd, []byte(data)) + Write(fd, int32(len(data))) + Write(fd, []byte(data)) case []string: - write(fd, int32(len(data))) + Write(fd, int32(len(data))) for _, item := range data { - write(fd, item) + Write(fd, item) } case net.IP: var af int32 = -1 @@ -54,20 +80,20 @@ func write(fd io.Writer, data interface{}) { } else { bytes = data } - write(fd, af) - write(fd, int32(len(bytes))) - write(fd, bytes) + Write(fd, af) + Write(fd, int32(len(bytes))) + Write(fd, bytes) case []net.IP: - write(fd, int32(len(data))) + Write(fd, int32(len(data))) for _, item := range data { - write(fd, item) + 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()) + Write(fd, v.Field(i).Interface()) } default: panic(fmt.Sprintf("Invalid structure to write NSLCD protocol data from: %T ( %#v )", data, data)) @@ -75,11 +101,13 @@ func write(fd io.Writer, data interface{}) { } } -func read(fd io.Reader, data interface{}) { +// 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 nslcdObjectPtr: + data.nslcdRead(fd) case *[]byte: _, err := fd.Read(*data) if err != nil { @@ -93,20 +121,20 @@ func read(fd io.Reader, data interface{}) { // composite datatypes case *string: var len int32 - read(fd, &len) + Read(fd, &len) buf := make([]byte, len) - read(fd, &buf) + Read(fd, &buf) *data = string(buf) case *[]string: var num int32 - read(fd, &num) + Read(fd, &num) *data = make([]string, num) for i := 0; i < int(num); i++ { - read(fd, &((*data)[i])) + Read(fd, &((*data)[i])) } case *net.IP: var af int32 - read(fd, &af) + Read(fd, &af) var _len int32 switch af { case syscall.AF_INET: @@ -117,28 +145,28 @@ func read(fd io.Reader, data interface{}) { panic(NslcdError(fmt.Sprintf("incorrect address family specified: %d", af))) } var len int32 - read(fd, &len) + Read(fd, &len) if len != _len { panic(NslcdError(fmt.Sprintf("address length incorrect: %d", len))) } buf := make([]byte, len) - read(fd, &buf) + Read(fd, &buf) *data = buf case *[]net.IP: var num int32 - read(fd, &num) + Read(fd, &num) *data = make([]net.IP, num) for i := 0; i < int(num); i++ { - read(fd, &((*data)[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.read() must be a pointer: %T ( %#v )", data, data)) + 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()) + Read(fd, v.Field(i).Addr().Interface()) } } } diff --git a/src/nslcd_proto/nslcd_h.go b/src/nslcd/proto/nslcd_h.go index 9d53e52..cb210cd 100644 --- a/src/nslcd_proto/nslcd_h.go +++ b/src/nslcd/proto/nslcd_h.go @@ -46,8 +46,8 @@ import ( [result(s)] INT32 NSLCD_RESULT_END A single result entry looks like: - NSLCD_RESULT_BEGIN int32 - [result value(s)] + 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 @@ -78,11 +78,11 @@ import ( const NSLCD_VERSION int32 = 0x00000002 /* Get a NSLCD configuration option. There is one request parameter: */ -type Request_Config_Get struct{ +type Request_Config_Get struct { Key int32 /* NSLCD_CONFIG_* */ } /* the result value is: */ -type Config struct{ +type Config struct { Value string /* interpretation depending on request */ } const NSLCD_ACTION_CONFIG_GET int32 = 0x00010001 @@ -99,8 +99,8 @@ 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{} +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: */ @@ -108,9 +108,9 @@ 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{} +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: */ @@ -121,10 +121,10 @@ type Group struct { 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{} +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: */ @@ -133,9 +133,9 @@ type Host struct { 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{} +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: @@ -156,32 +156,34 @@ type Netgroup_Netgroup struct { Name string } type Netgroup_Triple struct { - Host string - User string + Host string + User string Domain string } type Netgroup_PartList []interface{} -func (data Netgroup_PartList) NslcdWrite(fd io.Writer) { +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 + 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, t) + Write(fd, part) } - write(fd, NSLCD_NETGROUP_TYPE_END) + Write(fd, NSLCD_NETGROUP_TYPE_END) } -func (data *Netgroup_PartList) NslcdRead(fd io.Reader) { +func (data *Netgroup_PartList) nslcdRead(fd io.Reader) { *data = make([]interface{}, 0) for { var t int32 var v interface{} - read(fd, &t) + Read(fd, &t) switch t { case NSLCD_NETGROUP_TYPE_NETGROUP: v = Netgroup_Netgroup{} @@ -192,18 +194,18 @@ func (data *Netgroup_PartList) NslcdRead(fd io.Reader) { default: panic(NslcdError(fmt.Sprintf("unrecognized netgroup type: %#08x", t))) } - read(fd, &v) + Read(fd, &v) *data = append(*data, v) } } -var _ NslcdObject = Netgroup_PartList{} -var _ NslcdObjectPtr = &Netgroup_PartList{} +var _ nslcdObject = Netgroup_PartList{} +var _ nslcdObjectPtr = &Netgroup_PartList{} type Netgroup struct { - Name string + 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_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 @@ -217,9 +219,9 @@ type Network struct { 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{} +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 { @@ -231,9 +233,9 @@ type Passwd struct { 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{} +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 { @@ -241,9 +243,9 @@ type Protocol struct { 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{} +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 { @@ -251,9 +253,9 @@ type RPC struct { 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{} +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 @@ -264,9 +266,9 @@ type Service struct { 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{} +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: */ @@ -283,8 +285,8 @@ type Shadow struct { 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{} +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: */ @@ -319,7 +321,7 @@ const NSLCD_ACTION_PAM_AUTHENTICATION int32 = 0x000d0001 /* PAM authorisation check request. The result value consists of: */ type PAM_Authorization struct { Result int32 - Error string + Error string } /* The authentication check may have already returned some authorisation information. The authorisation error message, if supplied, will be used @@ -341,7 +343,7 @@ type Request_PAM_SessionClose struct { SessionID string } /* and this calls only returns an empty response value. */ -type PAM_SessionClose struct{} +type PAM_SessionClose struct {} const NSLCD_ACTION_PAM_SESSIONCLOSE int32 = 0x000d0004 /* PAM password modification request. This requests has the following extra @@ -380,27 +382,27 @@ type UserMod_Item struct { Value string } type UserMod_ItemList []UserMod_Item -func (data UserMod_ItemList) NslcdWrite(fd io.Writer) { +func (data UserMod_ItemList) nslcdWrite(fd io.Writer) { for _, item := range data { - write(fd, item) + Write(fd, item) } - write(fd, NSLCD_USERMOD_END) + Write(fd, NSLCD_USERMOD_END) } -func (data *UserMod_ItemList) NslcdRead(fd io.Reader) { +func (data *UserMod_ItemList) nslcdRead(fd io.Reader) { *data = make([]UserMod_Item, 0) for { var t int32 - read(fd, &t) + Read(fd, &t) if t == NSLCD_USERMOD_END { return } var v UserMod_Item - read(fd, &v) + Read(fd, &v) *data = append(*data, v) } } -var _ NslcdObject = UserMod_ItemList{} -var _ NslcdObjectPtr = &UserMod_ItemList{} +var _ nslcdObject = UserMod_ItemList{} +var _ nslcdObjectPtr = &UserMod_ItemList{} type Request_UserMod struct { UserName string AsRoot int32 @@ -434,11 +436,11 @@ const ( /* 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_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 */ diff --git a/src/nslcd/proto/server/doc.go b/src/nslcd/proto/server/doc.go new file mode 100644 index 0000000..72ae2fe --- /dev/null +++ b/src/nslcd/proto/server/doc.go @@ -0,0 +1,23 @@ +// 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 new file mode 100755 index 0000000..3ef2758 --- /dev/null +++ b/src/nslcd/proto/server/func_handlerequest.go.sh @@ -0,0 +1,101 @@ +#!/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 new file mode 100755 index 0000000..e6eeb66 --- /dev/null +++ b/src/nslcd/proto/server/interface_backend.go.sh @@ -0,0 +1,39 @@ +#!/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 new file mode 100755 index 0000000..17aad63 --- /dev/null +++ b/src/nslcd/proto/server/type_nilbackend.go.sh @@ -0,0 +1,40 @@ +#!/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 index 90d4edb..c19ba0c 100644 --- a/src/nslcd_systemd/disable_nss_module.go +++ b/src/nslcd/systemd/disable_nss_module.go @@ -1,3 +1,20 @@ +// 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 ( diff --git a/src/nslcd_systemd/nslcd_systemd.go b/src/nslcd/systemd/nslcd_systemd.go index f592279..f5d4881 100644 --- a/src/nslcd_systemd/nslcd_systemd.go +++ b/src/nslcd/systemd/nslcd_systemd.go @@ -1,9 +1,41 @@ +// 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" + "nslcd/proto/server" "os" "os/signal" sd "sd_daemon" @@ -14,7 +46,7 @@ import ( ) type Backend interface { - nslcd_proto.Backend + nslcd_server.Backend Init() error Reload() error Close() @@ -37,18 +69,18 @@ func get_socket() (socket net.Listener, err error) { return } -func getpeercred(conn *net.UnixConn) (cred nslcd_proto.Ucred, err error) { +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 = nslcd_proto.Ucred(*_cred) + cred = *_cred return } -func handler(conn *net.UnixConn, backend nslcd_proto.Backend) { +func handler(conn *net.UnixConn, backend nslcd_server.Backend) { defer conn.Close() cred, err := getpeercred(conn) if err != nil { @@ -57,7 +89,7 @@ func handler(conn *net.UnixConn, backend nslcd_proto.Backend) { logger.Debug("Connection from pid=%v uid=%v gid=%v", cred.Pid, cred.Uid, cred.Gid) } - err = nslcd_proto.HandleRequest(backend, conn, conn, cred) + err = nslcd_server.HandleRequest(backend, conn, conn, cred) if err != nil { logger.Notice("Error while handling request: %v", err) } diff --git a/src/nslcd_proto/.gitignore b/src/nslcd_proto/.gitignore deleted file mode 100644 index 0915898..0000000 --- a/src/nslcd_proto/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -/interface_backend.go -/util/struct_null_backend.go -/func_handlerequest.go -/requests.txt -/responses.txt diff --git a/src/nslcd_proto/Makefile b/src/nslcd_proto/Makefile deleted file mode 100644 index 9e3ba4e..0000000 --- a/src/nslcd_proto/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -_ := $(MAKEFILE_LIST) -d := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) - -generate := $(generate) $d/interface_backend.go $d/func_handlerequest.go $d/util/struct_null_backend.go -secondary := $d/requests.txt - -ifeq (,$(filter clean,$(MAKECMDGOALS))) --include $d/enumerator-list.mk -endif - -ifeq (1,$(words $_)) - -all: generate -.PHONY: all - -generate: $(generate) -.PHONY: generate - -clean: - rm -f -- $(generate) $(secondary) -.PHONY: clean - -.DELETE_ON_ERROR: -.SECONDARY: - -endif - -$d/requests.txt: $d/nslcd_h.go $d/Makefile - < $< grep -Eo '\btype Request_([^_ ]+)(_\S+)?' | sed 's/^type Request_//' > $@ - -%.go: %.go.sh - ./$^ > $@ - -$d/interface_backend.go: $d/requests.txt -$d/func_handlerequest.go: $d/requests.txt -$d/util/struct_null_backend.go: $d/interface_backend.go diff --git a/src/nslcd_proto/func_handlerequest.go.sh b/src/nslcd_proto/func_handlerequest.go.sh deleted file mode 100755 index 4b89a8a..0000000 --- a/src/nslcd_proto/func_handlerequest.go.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash -# -*- Mode: Go -*- -requests=$1 -cat <<EOF -package nslcd_proto - -import ( - "fmt" - "io" - "os" -) - -func handleRequest(backend Backend, in io.Reader, out io.Writer, cred Ucred) { - var version int32 - read(in, &version) - if version != NSLCD_VERSION { - panic(NslcdError(fmt.Sprintf("Version mismatch: server=%#08x client=%#08x", NSLCD_VERSION, version))) - } - var action int32 - read(in, &action) - - ch := make(chan interface{}) - switch action { -$( -while read -r request; do - cat <<EOT - case NSLCD_ACTION_${request^^}: - var req Request_${request} - 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(NslcdError(fmt.Sprintf("Unknown request action: %#08x", action))) - } - write(out, NSLCD_VERSION) - write(out, action) - - for result := range ch { - write(out, NSLCD_RESULT_BEGIN) - write(out, result) - } - write(out, NSLCD_RESULT_END) -} -EOF diff --git a/src/nslcd_proto/interface_backend.go.sh b/src/nslcd_proto/interface_backend.go.sh deleted file mode 100755 index a5b76a4..0000000 --- a/src/nslcd_proto/interface_backend.go.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -# -*- Mode: Go -*- -requests=$1 -cat <<EOF | gofmt -package nslcd_proto - -import "syscall" - -type Ucred syscall.Ucred - -type Backend interface { - $(sed -rn 's/([^_]+)(.*)/\1\2(Ucred, Request_\1\2) <-chan \1/p' "$requests" | grep -v PAM) - $(sed -rn 's/(PAM)(.*)/\1\2(Ucred, Request_\1\2) <-chan \1\2/p' "$requests") -} -EOF diff --git a/src/nslcd_proto/util.go b/src/nslcd_proto/util.go deleted file mode 100644 index de00445..0000000 --- a/src/nslcd_proto/util.go +++ /dev/null @@ -1,57 +0,0 @@ -package nslcd_proto - -import "io" - -type NslcdError string - -func (o NslcdError) Error() string { - return string(o) -} - -func Write(fd io.Writer, data interface{}) (err error) { - err = nil - defer func() { - if r := recover(); r != nil { - switch r := r.(type) { - case error: - err = r - default: - panic(r) - } - } - }() - write(fd, data) - return -} - -func Read(fd io.Reader, data interface{}) (err error) { - err = nil - defer func() { - if r := recover(); r != nil { - switch r := r.(type) { - case error: - err = r - default: - panic(r) - } - } - }() - read(fd, data) - return -} - -func HandleRequest(backend Backend, in io.Reader, out io.Writer, cred 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 -} diff --git a/src/nslcd_proto/util/struct_null_backend.go.sh b/src/nslcd_proto/util/struct_null_backend.go.sh deleted file mode 100755 index 1714e9a..0000000 --- a/src/nslcd_proto/util/struct_null_backend.go.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -# -*- Mode: Go -*- -interface=$1 -cat <<EOF | gofmt -package util - -import p "nslcd_proto" - -type NullBackend struct{} - -$(< "$interface" sed -rn 's/^\t([^(]+)\(Ucred, ([^)]+)\) <-chan (\S+)$/func (o NullBackend) \1(p.Ucred, p.\2) <-chan p.\3 { r := make(chan p.\3); close(r); return r }/p') - -var _ p.Backend = NullBackend{} -EOF diff --git a/src/sd_daemon/doc.go b/src/sd_daemon/doc.go new file mode 100644 index 0000000..665e25e --- /dev/null +++ b/src/sd_daemon/doc.go @@ -0,0 +1,16 @@ +// 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 index 45ef699..fbd2247 100644 --- a/src/sd_daemon/listen_fds.go +++ b/src/sd_daemon/listen_fds.go @@ -13,8 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package activation implements primitives for systemd socket activation. -package sd_daemon +package sd import ( "os" @@ -25,6 +24,15 @@ import ( //#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") diff --git a/src/sd_daemon/logger/logger.go b/src/sd_daemon/logger/logger.go index f8f3bd6..850df1c 100644 --- a/src/sd_daemon/logger/logger.go +++ b/src/sd_daemon/logger/logger.go @@ -12,6 +12,8 @@ // 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 ( @@ -23,15 +25,23 @@ import ( import "C" func log(level string, format string, a ...interface{}) { - f := level + format + "\n" - fmt.Fprintf(os.Stderr, f, a...) + 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...); } + +// 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 index 41eaafd..cc1604d 100644 --- a/src/sd_daemon/lsb/exit-status.go +++ b/src/sd_daemon/lsb/exit-status.go @@ -1,3 +1,19 @@ +// 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 ( @@ -5,11 +21,10 @@ import ( "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 - */ +// 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 @@ -19,13 +34,13 @@ const ( 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 */ + // 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` */ + // 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 @@ -49,7 +64,7 @@ const ( EXIT_SETSID uint8 = 220 EXIT_CONFIRM uint8 = 221 EXIT_STDERR uint8 = 222 - _EXIT_RESERVED uint8 = 223 /* used to be tcpwrap don't reuse! */ + _EXIT_RESERVED uint8 = 223 // used to be tcpwrap don't reuse! EXIT_PAM uint8 = 224 EXIT_NETWORK uint8 = 225 EXIT_NAMESPACE uint8 = 226 @@ -66,6 +81,8 @@ const ( 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) diff --git a/src/sd_daemon/notify.go b/src/sd_daemon/notify.go index a038f54..8fce6da 100644 --- a/src/sd_daemon/notify.go +++ b/src/sd_daemon/notify.go @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package sd_daemon +package sd import ( "errors" @@ -22,11 +22,22 @@ import ( "os" ) -// ErrNotifyNoSocket is an error returned if no socket was specified. -var ErrNotifyNoSocket = errors.New("No socket") +// errNotifyNoSocket is an error returned if no socket was specified. +var errNotifyNoSocket = errors.New("No socket") -// Notify sends a message to the init daemon. It is common to ignore -// the error. +// 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") @@ -38,7 +49,7 @@ func Notify(unsetEnv bool, state string) error { } if socketAddr.Name == "" { - return ErrNotifyNoSocket + return errNotifyNoSocket } conn, err := net.DialUnix(socketAddr.Net, nil, socketAddr) diff --git a/test/runner.c b/test/runner.c index 9edd191..110819d 100644 --- a/test/runner.c +++ b/test/runner.c @@ -1,3 +1,20 @@ +/* Copyright (C) 2015 Luke Shumaker <lukeshu@sbcglobal.net> + * + * This program 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 program 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 program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301 USA + */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> |